IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Macros et VBA Excel Discussion :

UserForm qui pose problème


Sujet :

Macros et VBA Excel

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Responsable des études
    Inscrit en
    Mars 2013
    Messages
    72
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Responsable des études
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2013
    Messages : 72
    Par défaut UserForm qui pose problème
    Bonjour,

    Je suis bloqué avec le développement de mon application et je ne parviens pas à trouver mon erreur.

    Cet USF est destiné à recueillir les informations clients et certaines procédures ont été inspirées d'exemple trouvés sur le NET.

    Le problème est double:

    1) le USF disparaît subitement sans message d'erreur et de manière tout à fait aléatoire

    2) Certainement lié au point précédent, l'application plante avec redémarrage d'excel.

    Avant d'aller plus loin il est donc nécessaire pour moi de résoudre ces problèmes ce que j'espère réaliser avec votre aide. Pour cela j'ai mis une copie du fichier en pièce jointe.

    Attention pour des raisons de taille du fichier, j'ai supprimé des données de la BDD_rues mais retenez que celle=ci comporte en réalité plus de 150K de lignes.

    Merci d'avance pour votre intérêt

    test-factures.xlsm

  2. #2
    Rédacteur
    Avatar de Philippe Tulliez
    Homme Profil pro
    Formateur, développeur et consultant Excel, Access, Word et VBA
    Inscrit en
    Janvier 2010
    Messages
    13 186
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Formateur, développeur et consultant Excel, Access, Word et VBA

    Informations forums :
    Inscription : Janvier 2010
    Messages : 13 186
    Billets dans le blog
    53
    Par défaut
    Bonjour,
    Pour isoler le problème et savoir à quelle ligne le programme bogue, mettez un point d'arrêt sur la ligne NomUserForm.Show (Raccourci clavier F9) et ensuite faîtes tourner votre programme au "Pas à pas" (Raccourci clavier F8)

    A lire éventuellement
    Le débogage sous Visual Basic 6 et Visual Basic pour Application(1re partie)
    Philippe Tulliez
    Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément. (Nicolas Boileau)
    Lorsque vous avez la réponse à votre question, n'oubliez pas de cliquer sur et si celle-ci est pertinente pensez à voter
    Mes tutoriels : Utilisation de l'assistant « Insertion de fonction », Les filtres avancés ou élaborés dans Excel
    Mon dernier billet : Utilisation de la fonction Dir en VBA pour vérifier l'existence d'un fichier

  3. #3
    Membre extrêmement actif Avatar de mjpmjp
    Homme Profil pro
    Retraité
    Inscrit en
    Avril 2012
    Messages
    1 133
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hautes Alpes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Santé

    Informations forums :
    Inscription : Avril 2012
    Messages : 1 133
    Par défaut
    bonjour,

    est ce que tu lances ton form avec show(0) ?

    @+JP
    Caractéristiques (WEB) phpMyAdmin 4-74 , PHP 5-631 , Apache 2-427 , MySQL 5-719
    Présentation NAS DS-3615xs + 20Go , DSM 6.1.6-15266 Up1 , 12 * WD 4To WD4000F9YZ (10 raid 6+ )+(2 raid 1+) , LinkSys comutateur-switch lgs528p-eu , Onduleur UPS 720W Power Boxx Lcd (4*UPS + 4*MOD)
    Mes contributions (EXCEL) Form GRAPHIQUE: Gestion des boutons , Liste Onglet dynamique...GESTION de FILM

  4. #4
    Membre confirmé
    Homme Profil pro
    Responsable des études
    Inscrit en
    Mars 2013
    Messages
    72
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Responsable des études
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2013
    Messages : 72
    Par défaut
    Bonjour,

    voici les lignes de commande:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Private Sub CommandButton1_Click()
        nouv_client.Show
    End Sub
    Comme indiqué le USF en question porte le nom de "nouv_client" et non je n'ouvre pas avec show(0) mais le USF est non modal dans les propriétés.

    merci pour votre intérêt

  5. #5
    Rédacteur/Modérateur


    Homme Profil pro
    Formateur et développeur chez EXCELLEZ.net
    Inscrit en
    Novembre 2003
    Messages
    19 125
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : Belgique

    Informations professionnelles :
    Activité : Formateur et développeur chez EXCELLEZ.net
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 19 125
    Billets dans le blog
    131
    Par défaut
    Salut.

    Je ne connais pas ton niveau de VBA, donc je propose d'aller au plus simple.

    Ta proc événementielle sur l'ouverture du fichier pose problème, car ta fenêtre n'est pas encore active. Tu ne peux donc pas manipuler ActiveWindows, mais tu dois activer ThisWorkbook.Windows(1). Tu aurais intérêt à travailler avec les codename des feuilles plutôt qu'avec Worksheets("..."). Si tu renommes une feuille, tu vas devoir modifier ton code. (voir le billet de Philippe, que je salue: https://www.developpez.net/forums/bl...sant-codename/)

    Je serais toi, je me tournerais vers une saisie des données dans une feuille de calcul. Prioritairement, dans la base de données clients où tu peux gérer facilement la validation des données grâce aux outils natifs d'Excel, notamment les listes de validation et la validation des dates. Ça te simplifierait grandement la vie, à mon avis.

    Si tu veux passer par un formulaire, je te conseillerais un formulaire feuille de calcul. Tu gardes ainsi les mêmes possibilités de validation dans une feuille mieux construite que la table des clients, et comme tu transfères d'Excel à Excel, tu évites les problèmes cités plus haut avec les dates et les valeurs numériques.

    Si tu veux vraiment passer par un userform, ok, mais tu vas devoir mettre en place par code la validation des données, tant sur leur cohérence (une date attendue est-elle bien une date? Quel séparateur a été utilisé pour des valeurs décimales? etc) que sur la validation métier (les champs obligatoires sont-ils bien remplis? etc...).

    Quel que soit le choix du formulaire, je te conseille d'utiliser le même formulaire pour les nouvelles données et pour la modification d'un enregistrement. Ca t'évite deux formulaires avec deux fois les codes de vérification, etc.


    Quoi qu'il en soit, je te conseille de travailler avec les tableaux structurés (voir mon tuto https://fauconnier.developpez.com/tu...ux-structures/). Cela te simplifiera grandement la vie pour ton travail de codage, surtout que j'imagine qu'après les clients, il va y avoir les factures, ... Tu pourras alors facilement travailler avec des procédures génériques qui assureront le transfert dans les deux sens entre ton formulaire, qu'il soit Excel ou VBA, et tes tables de données. Pour cela, l'idéal est une table de mappage qui reprend les paires de valeurs pour les échanges (nom de la colonne de la table et nom de la cellule ou du contrôle du userform selon ton type de formulaire.

    Ton code utilise des variables publiques pour le transfert des données et ce n'est nullement nécessaire. Sauf pour quelques très rares cas bien circonscrits, je pense que les variables publiques sont à bannir de son code.
    "Plus les hommes seront éclairés, plus ils seront libres" (Voltaire)
    ---------------
    Mes billets de blog sur DVP
    Mes remarques et critiques sont purement techniques. Ne les prenez jamais pour des attaques personnelles...
    Pensez à utiliser les tableaux structurés. Ils vous simplifieront la vie, tant en Excel qu'en VBA ==> mon tuto
    Le VBA ne palliera jamais une mauvaise conception de classeur ou un manque de connaissances des outils natifs d'Excel...
    Ce ne sont pas des bonnes pratiques parce que ce sont les miennes, ce sont les miennes parce que ce sont des bonnes pratiques
    VBA pour Excel? Pensez D'ABORD en EXCEL avant de penser en VBA...
    ---------------

  6. #6
    Rédacteur/Modérateur


    Homme Profil pro
    Formateur et développeur chez EXCELLEZ.net
    Inscrit en
    Novembre 2003
    Messages
    19 125
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : Belgique

    Informations professionnelles :
    Activité : Formateur et développeur chez EXCELLEZ.net
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 19 125
    Billets dans le blog
    131
    Par défaut
    Pour te donner des pistes de travail, je te propose le classeur suivant. Ici, j'ai tout mis sur la même feuille mais, bien entendu, dans la réalité, il faudra que le tableau t_Clients soit une feuille, le formulaire sur une autre et le mappage sur une troisième.

    Nom : 2022-03-15_200842.png
Affichages : 167
Taille : 122,6 Ko


    Transfert générique de données entre un formulaire feuille de travail et le tableau structuré qui y est lié grâce à deux procédures qui s'appuient sur la table de mappage

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    Sub SaveData(FormName As String, Row As ListRow)
      Dim i As Long
     
      For i = 1 To Range("t_Mappage").Rows.Count
        If StrComp(FormName, Range("t_Mappage[Formulaire]")(i).Value, vbTextCompare) = 0 Then
          Row.Range(Row.Parent.ListColumns(Range("t_Mappage[colonne]")(i).Value).Index).Value = _
            Range(Range("t_Mappage[Champ]")(i).Value).Value
        End If
      Next
    End Sub
     
    Sub ReadData(FormName As String, Row As ListRow)
      Dim i As Long
     
      For i = 1 To Range("t_Mappage").Rows.Count
        If StrComp(FormName, Range("t_Mappage[Formulaire]")(i).Value, vbTextCompare) = 0 Then
          Range(Range("t_Mappage[Champ]")(i).Value).Value = _
            Row.Range(Row.Parent.ListColumns(Range("t_Mappage[colonne]")(i).Value).Index).Value
        End If
      Next
    End Sub

    Dans la couche "Clients" (module CustomerLayer), on trouve le code qui permet les échanges particuliers entre le formulaire de saisie et la table des clients. Ces codes sont liés aux boutons situés sous le formulaire.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    Sub SaveCustomer()
      Dim i
      Dim Row As ListRow
     
      i = Application.Match(Range("fc_Id").Value, Range("t_Clients[Id]"), 0)
      If IsError(i) Then
        Set Row = Range("t_Clients").ListObject.ListRows.Add()
      Else
        Set Row = Range("t_Clients").ListObject.ListRows(i)
      End If
      SaveData "Client", Row
    End Sub
     
    Sub ReadActiveCustomer()
      Dim i As Long
     
      i = ActiveCell.Row - Range("t_Clients[#Headers]").Row
      ReadData "Client", Range("t_Clients").ListObject.ListRows(i)
    End Sub
     
    Sub PrepareforNewCustomer()
      Range("fc").ClearContents
      Range("fc_Id") = Application.Max(Range("t_clients[Id]")) + 1
      Range("fc_Nom").Select
    End Sub
     
    Sub ReadCustomerFromForm()
      Dim i
     
      i = Application.Match(Range("fc_Id").Value, Range("t_Clients[Id]"), 0)
      Range("fc").ClearContents
      If IsError(i) Then
        MsgBox "Ce client n'existe pas"
      Else
        ReadData "Client", Range("t_Clients").ListObject.ListRows(i)
      End If
    End Sub
    On peut aussi récupérer un client par double-clic sur sa ligne dans la table. Le code se trouve dans la feuille shCustomer

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
      If Not Intersect(Range("t_Clients"), Target) Is Nothing Then
        Cancel = True
        ReadActiveCustomer
      End If
    End Sub

    Bien entendu, tu pourrais réaliser la même chose au départ d'un userform. Tu devras alors mapper les champs du userform ET ajouter une colonne au mappage pour spécifier le type de donnée (surtout pour les dates et les valeurs numériques).
    Fichiers attachés Fichiers attachés
    "Plus les hommes seront éclairés, plus ils seront libres" (Voltaire)
    ---------------
    Mes billets de blog sur DVP
    Mes remarques et critiques sont purement techniques. Ne les prenez jamais pour des attaques personnelles...
    Pensez à utiliser les tableaux structurés. Ils vous simplifieront la vie, tant en Excel qu'en VBA ==> mon tuto
    Le VBA ne palliera jamais une mauvaise conception de classeur ou un manque de connaissances des outils natifs d'Excel...
    Ce ne sont pas des bonnes pratiques parce que ce sont les miennes, ce sont les miennes parce que ce sont des bonnes pratiques
    VBA pour Excel? Pensez D'ABORD en EXCEL avant de penser en VBA...
    ---------------

  7. #7
    Membre confirmé
    Homme Profil pro
    Responsable des études
    Inscrit en
    Mars 2013
    Messages
    72
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Responsable des études
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2013
    Messages : 72
    Par défaut
    Bonjour Pierre,

    avec un peu de retard, grand merci pour votre intérêt et vos remarques et pour y répondre:
    Tout d'abord, vous l'avez certainement remarqué, le fichier joint est un fichier épuré destiné uniquement à l'examen du problème évoqué. Il y a bien entendu d'autres modules qui ont été mis en place.

    Je ne connais pas ton niveau de VBA, donc je propose d'aller au plus simple.
    Ben, là je dirais qu'il n'est pas des plus élevés, mais j'avance même si le code n'est pas toujours des plus "classique".

    Si tu veux vraiment passer par un userform
    j'avais à l'origine trouvé cette façon de procéder intéressante et j'y ai mis pas mal de contrôles destinés à limiter les erreurs lors de l'encodage des données. De plus en liant une table avec les noms de rues, je souhaite éviter les fautes de frappe qui génèrent souvent des refus de distribution de courrier par la poste pour adresse inconnue.

    je te conseille de travailler avec les tableaux structurés
    c'est bien là la démarche qui était envisagée mais je souhaitais préalablement régler ce problème de USF qui disparaissait sans explication.

    Je vais maintenant regarder le fichier que vous m'avez transmis, je vais certainement y pêcher de bonnes idées car je suis loin d'être à l'aise avec les tableaux structurés.

  8. #8
    Rédacteur/Modérateur


    Homme Profil pro
    Formateur et développeur chez EXCELLEZ.net
    Inscrit en
    Novembre 2003
    Messages
    19 125
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : Belgique

    Informations professionnelles :
    Activité : Formateur et développeur chez EXCELLEZ.net
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 19 125
    Billets dans le blog
    131
    Par défaut
    Bonsoir


    Comme je l'ai dit dans mon premier message, la procédure sur ouverture posait problème dans ton fichier, mais malgré cela, je n'ai pas pu reproduire le problème du userform qui disparaît subitement. Sur mon ordi, ton classeur fonctionne et est stable (après correction de la procédure d'ouverture).

    Quoi qu'il en soit, la technique pour transférer les données du userform vers le tableau et vice-versa est identique que pour un formulaire "feuille de données". On crée les deux fonctions de transfert, en ajoutant au tableau de mappage une colonne pour spécifier les dates et les valeurs numériques, car en provenance d'un userform, elles nécessitent un traitement particulier.
    "Plus les hommes seront éclairés, plus ils seront libres" (Voltaire)
    ---------------
    Mes billets de blog sur DVP
    Mes remarques et critiques sont purement techniques. Ne les prenez jamais pour des attaques personnelles...
    Pensez à utiliser les tableaux structurés. Ils vous simplifieront la vie, tant en Excel qu'en VBA ==> mon tuto
    Le VBA ne palliera jamais une mauvaise conception de classeur ou un manque de connaissances des outils natifs d'Excel...
    Ce ne sont pas des bonnes pratiques parce que ce sont les miennes, ce sont les miennes parce que ce sont des bonnes pratiques
    VBA pour Excel? Pensez D'ABORD en EXCEL avant de penser en VBA...
    ---------------

  9. #9
    Membre confirmé
    Homme Profil pro
    Responsable des études
    Inscrit en
    Mars 2013
    Messages
    72
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Responsable des études
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2013
    Messages : 72
    Par défaut
    J'ai pris un peu de temps pour réagir mais j'ai refait des tests et manifestement, c'est l'usage du USF qui pose problème.

    En effet, l'application ne pose aucun problème tant que je n'appelle pas le formulaire. Une fois celui-ci utilisé le plantage arrive assez rapidement.
    Je vais donc retravailler le formulaire tel que proposé et y intégrer une table de mappage. Alors que le transfert des données vers la feuille "clients" se déroule correctement, j'avoue pour autant ne pas comprendre pourquoi il y a plantage par la suite.

    A noter aussi que j'ai corrigé l'erreur mentionnée dans ton 1er post.

    encore merci pour l'aide apportée, c'est vraiment précieux pour que je puisse avancer.

Discussions similaires

  1. [VBA]: Nom de champ qui pose problème
    Par Amitom dans le forum Access
    Réponses: 4
    Dernier message: 07/06/2007, 10h26
  2. [D5] Transtypage qui pose problème
    Par MelkInarian dans le forum Delphi
    Réponses: 4
    Dernier message: 06/04/2007, 17h38
  3. requete update qui pose problème
    Par kirian dans le forum Requêtes
    Réponses: 2
    Dernier message: 26/02/2007, 12h20
  4. code qui pose problème
    Par onePersonne dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 15/10/2006, 15h27
  5. Un cast de SmartPointer qui pose probléme
    Par Higestromm dans le forum C++
    Réponses: 3
    Dernier message: 13/10/2005, 11h25

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo