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 :

Lister les Userforms d'un projet et pour chacun, lister les CommandButtons


Sujet :

Macros et VBA Excel

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé

    Profil pro
    Retraité (Travailleur autonome)
    Inscrit en
    Octobre 2008
    Messages
    82
    Détails du profil
    Informations personnelles :
    Âge : 78
    Localisation : Canada

    Informations professionnelles :
    Activité : Retraité (Travailleur autonome)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 82
    Billets dans le blog
    1
    Par défaut Lister les Userforms d'un projet et pour chacun, lister les CommandButtons
    Bonjour,

    J'ai une application qui compte plus de 70 userforms et chacun comporte plusieurs CommandButtons.

    J'ai une liste des boutons pour chaque userform du projet. Je veux pouvoir mettre à jour cette liste quand une nouvelle userform est ajoutée.

    Le tout doit se faire par programmation.

    Voici ce que j'ai préparé: (Les variables ont été déclarées)

    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
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    For i = 1 To Data(Formulaire).NbreRec     'Fichier contenant les listes de boutons pour chaque userform
        Call GetChamp(Formulaire, i, Form.Nom_Du_Formulaire)     'Lecture du nom du formulaire
        For Each LaForm In Application.VBE.ActiveVBProject.VBComponents
            If LaForm.Name = Trim(Data(Formulaire).Champs(Form.Nom_Du_Formulaire)) Then
                Gosub Lister
            End If
        Next LaForm
    Next
     
    Exit Sub
     
    Lister:
    For Each Contrôle In LaForm.Controls
        If TypeOf Contrôle Is MSForms.CommandButton Or (TypeOf Contrôle Is MSForms.Label And LCase(Left(Contrôle.Name, 9)) = "lblbouton") Then
            If Contrôle.Name <> "CmdNouveau" And _
                Contrôle.Name <> "CmdSupprimer" And _
                Contrôle.Name <> "CmdModifier" And _
                Contrôle.Name <> "CmdAnnuler" And _
                Contrôle.Name <> "CmdSauver" And _
                Contrôle.Name <> "CmdRecherche" And _
                Contrôle.Name <> "CmdImprimer" And _
                Contrôle.Name <> "CmdQuitter" And _
                Contrôle.Name <> "CmdEnregistrer" And _
                Contrôle.Name <> "CmdCharger" And _
                Contrôle.Name <> "CmdPlus" And _
                Contrôle.Name <> "CmdMoins" And _
                Contrôle.Name <> "CmdMod" And _
                Contrôle.Name <> "CmdX" And _
                Contrôle.Name <> "CmdDébut" And _
                Contrôle.Name <> "CmdFin" And _
                Left(Contrôle.Name, 9) <> "CmdRetour" Then
     
    'Recherche des boutons existants (Ces procédures sont fiables)
                Call GetChamp(Formulaire, i, Form.Nom_Du_Formulaire)
                Call GetChamp(Formulaire, i, Form.No_Table)
                ReDim Conditions(2)
                Conditions(1).NoChamp = Cnfg.No_Formulaire
                Conditions(1).Opérateur = "="
                Conditions(1).Valeur = i
                Conditions(2).NoChamp = Cnfg.Bouton
                Conditions(2).Opérateur = "="
                Conditions(2).Valeur = Contrôle.Name
                Call ListerRecords(Liste(), TableLocale, Conditions(), False)
    'Si le bouton n'est pas listé alors il est ajouté et sauvé
                If Liste(0) = 0 Then
    'Les paramètres du bouton sont enregistrés dans des contrôles puis sauvés dans le fichier.
                    ComboFormulaire.Value = i
                    txtDescription = "du formulaire " & Chr(34) & Mid(Trim(Data(Formulaire).Champs(Form.Nom_Du_Formulaire)), 5) & Chr(34)
                    txtBouton = Contrôle.Name
                    If Left(Contrôle.Name, 9) = "lblBouton" Then
                        txtLégende = "L'onglet " & Chr(34) & Contrôle.Caption & Chr(34)
                    Else
                        txtLégende = "Le bouton " & Chr(34) & Contrôle.Caption & Chr(34)
                    End If
                    ComboActifOuInactif.Value = 1
                    Nouveau = True
                    Call SauverDossier
                    Call FinaliserSauvegarde(TabNavig, TabPrivé, TableLocale, TableauFiltré(), NumCrit, Critère(), ÉtatDesBoutons)   'Procédure interne nécessaire à la sauvegarde.
                End If
            End If
        End If
    Next Contrôle
    Le problème c'est que la variable objet LaForm est Nothing même si j'en obtient le nom.
    Je ne peux pas en tirer les contrôles qu'elle contient.

    Y a-t-il une solution ?

    Merci pour vos lumières.

  2. #2
    Membre Expert
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Novembre 2011
    Messages
    1 503
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Irlande

    Informations professionnelles :
    Activité : Chef de projet en SSII

    Informations forums :
    Inscription : Novembre 2011
    Messages : 1 503
    Par défaut
    Salut Archampi,

    Alors, il est un peu compliqué de faire des tests avec ce que tu as donné et d'identifier le problème.

    Ce que je ferais pour ma part :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
            If LaForm.Name = Trim(Data(Formulaire).Champs(Form.Nom_Du_Formulaire)) Then
                Lister(LaForm)
            End If
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Function Lister(LaForm As Object)
    '...
    pour être sur que "LaForme" passe bien en paramètre.

    Ne sachant si tes "LaForm" sont des variables globales, c'est ce que je ferais pour avancer dans l'analyse du problème.

    En restant à ta disposition.

    Cordialement,
    Kimy

  3. #3
    Membre confirmé

    Profil pro
    Retraité (Travailleur autonome)
    Inscrit en
    Octobre 2008
    Messages
    82
    Détails du profil
    Informations personnelles :
    Âge : 78
    Localisation : Canada

    Informations professionnelles :
    Activité : Retraité (Travailleur autonome)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 82
    Billets dans le blog
    1
    Par défaut Lister les Userforms d'un projet et pour chacun, lister les CommandButtons
    Voici un bout de code simplifié.

    Si ce code fonctionnait, je n'aurais pas besoin d'aide.

    Malheureusement, ça ne marche pas et je ne sais pas pourquoi.

    Il y a trois Userforms comportant chacun 3 CommandButtons.

    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
    Public Sub Main()
    Dim LaForm As Object
     
    For Each LaForm In Application.VBE.ActiveVBProject.VBComponents
        If TypeOf LaForm Is MSForms.UserForm Then
            Call Lister(LaForm)
        End If
    Next LaForm
     
    End Sub
     
     
    Sub Lister(Formulaire As Object)
    Dim Contrôle As Object
     
    For Each Contrôle In Formulaire.Controls
        If TypeOf Contrôle Is MSForms.CommandButton Then
            MsgBox Contrôle.Name, vbOKOnly, Formulaire.Name
        End If
    Next Contrôle
     
    End Sub


    Le premier problème survient à cette ligne:

    If TypeOf LaForm Is MSForms.CommandButton Then

    Aucun des objets trouvés dans VBComponents n'est reconnu comme Userform !
    Pourtant, si je change cette ligne pour:

    If Left(LaForm.Name, 8) = "UserForm" then
    Alors l'appel à "Lister" s'exécute mais c'est cette autre ligne qui plante:

    For Each Contrôle In Formulaire.Controls

    Propriété ou méthode non gérée par cet objet.

    Voilà où j'en suis.

    Merci

  4. #4
    Invité
    Invité(e)
    Par défaut
    Salut Archampi,

    La collection VBComponents renvoi un Object VBComponent.
    Tu dois aller plus loin dans la hiérarchie object et écrire VBComponent.Designer où le designer représente ton UserForm.
    Les autres composants n'ont pas de designer.
    Cependant, le designer n'est accessible que lorsque le formulaire est déchargé auquel cas il faut le déchargé si il est chargé pour pouvoir accéder à cette propriété ce qui fait par exemple que tu ne peut y accéder (au travers de VBComponent) lorsque le formulaire est en cours de marche.

    Si tu est sûr qu'il est déchargé:
    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
    Sub Main()
     
        Dim VBComponent As Object
     
        For Each VBComponent In Application.VBE.ActiveVBProject.VBComponents
            If StrComp(VBComponent.DesignerID, "Forms.Form", vbTextCompare) = 0 Then
                Call Lister(VBComponent.Designer)
            End If
        Next
     
    End Sub
     
    Sub Lister(Formulaire As Object)
     
        Dim Contrôle As Object
     
        If Not Formulaire Is Nothing Then
            For Each Contrôle In Formulaire.Controls
                If TypeOf Contrôle Is MSForms.CommandButton Then
                    MsgBox Contrôle.Name, vbOKOnly, Formulaire.Name
                End If
            Next
        End If
     
    End Sub


    ------------------------------------------------------------------------------------------------------------------------------------------------------

    Update du midi:

    Petite Mise à jour, car ce matin, je n'ai pas vérifié le résultat et il apparait qu'il faille mieux passer un VBComponent en tant qu'argument de fonction, sinon, on perd la propriété .Name et l'interfaçage avec la bibliothèque "Excel" (propriété .Parent, .VBE, .Application etc...).

    En même temps, ajout de vérifications supplémentaires.

    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
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    Sub Main()
     
        Dim VBComponent As Object
        Dim Form As Object
     
        For Each VBComponent In Excel.Application.VBE.ActiveVBProject.VBComponents
            If StrComp(VBComponent.DesignerID, "Forms.Form", vbTextCompare) = 0 Then
                Call Lister(VBComponent)
            End If
        Next
     
    End Sub
     
    Function Lister(VBComponent As Object)
     
        Dim Contrôle As Object
        Dim Form As Object
        Dim i As Long
     
        If Not VBComponent Is Nothing Then
            ' Histoire (à nouveau) d'être sûr que c'est bien un Userform (Double filtrage, mais bon)
            If StrComp(VBComponent.DesignerID, "Forms.Form", vbTextCompare) = 0 Then
                If VBComponent.Designer Is Nothing Then
                ' Ou alors :
                'If VBComponent.HasOpenDesigner = False Then
                    ' La propriété .Designer/.HasOpenDesigner est à Nothing/False:
                    '    - Soit l'Userform est en cours de marche.
                    '    - Soit l'Userform à été chargé auquel cas.
                    ' Dans les 2 cas, il faut le décharger.
                    For Each Form In VBA.UserForms
                        If StrComp(Form.Name, VBComponent.Name, vbTextCompare) = 0 Then
                            ' Attention ici car l'évènement UserForm_Terminate est exécuté et si il y a du code bloquant dans cette Sub (Msgbox par exemple) ...
                            Unload Form
                            ' Obligatoire de décharger toutes les variables liées à cette userform avec Nothing pour mettre à jour VBComponent.Designer
                            Set Form = Nothing
                            Exit For
                        End If
                    Next
                End If
                ' Après vérif:
                For Each Contrôle In VBComponent.Designer.Controls
                    If StrComp(TypeName(Contrôle), "CommandButton", vbTextCompare) = 0 Then
                        i = i + 1
                        ' Au cas où il y ai trop de Contrôles.
                        If i <= 3 Then MsgBox Contrôle.Name, vbOKOnly, VBComponent.Name
                    End If
                Next
            End If
        Else
            'L'argument qui a été passer dans le paramètre VBComponent est à Nothing
            ' Par exemple, on peut renvoyer Null pour dire qu'il y a un problème
            ' dans cette fonction (c'est juste un exmple), à savoir ici un mauvais passage d'argument.
            ' Libre ensuite de s'en servir ou non.
            Lister = Null
        End If
     
    End Function
    A+
    Dernière modification par AlainTech ; 31/05/2014 à 10h52. Motif: Suppression de la citation inutile

  5. #5
    Membre confirmé

    Profil pro
    Retraité (Travailleur autonome)
    Inscrit en
    Octobre 2008
    Messages
    82
    Détails du profil
    Informations personnelles :
    Âge : 78
    Localisation : Canada

    Informations professionnelles :
    Activité : Retraité (Travailleur autonome)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 82
    Billets dans le blog
    1
    Par défaut Lister les Userforms d'un projet et pour chacun, lister les CommandButtons
    Merci à vous,

    J'apprécie énormément votre implication.

    Cette dernière intervention est vraiment classe !
    Moi qui travaille avec Excel depuis plus de 20 ans, j'en apprends tous les jours grâce à vous.

    Je suis certain de pouvoir mettre ce code à profit dans mon application.

    Merci encore.

Discussions similaires

  1. Réponses: 5
    Dernier message: 19/07/2014, 13h50
  2. Réponses: 0
    Dernier message: 09/11/2010, 14h06
  3. Lister les fichiers et les dépendances liés à un projet
    Par sovo dans le forum Vos contributions VB6
    Réponses: 19
    Dernier message: 24/10/2007, 22h57
  4. Exporter tous les userform d'un projet
    Par ouskel'n'or dans le forum Général VBA
    Réponses: 14
    Dernier message: 14/07/2006, 14h05
  5. Besoin d'aide pour recuperer les fichier d'un projet
    Par barthelv dans le forum Applications et environnements graphiques
    Réponses: 9
    Dernier message: 14/04/2006, 11h47

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