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 :

Alternative à Sub ComboBox1_Change()


Sujet :

Macros et VBA Excel

  1. #1
    Membre émérite
    Avatar de eric4459
    Homme Profil pro
    Ingénieur Gestion de Projets
    Inscrit en
    Avril 2014
    Messages
    605
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes de Haute Provence (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur Gestion de Projets
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2014
    Messages : 605
    Par défaut Alternative à Sub ComboBox1_Change()
    Bonjour j'ai crée un Userform avec 3 Combo-box.
    La premier est chargée avec une liste de 15 éléments (des Pays)
    La seconde est chargée à partir une liste de 135 éléments (des sociétés reparties dans ces 15 pays - en colonne D de ma liste les sociétés et en colonne E les pays associés)
    Le but est de rechercher toutes les valeurs associées a une société dans un pays donné et qui alimenteront le Combo-Box3.
    Le principe est le suivant:
    L'utilisateur choisi un pays dans le premier Combo-box, comme je ne souhaite pas que l'utilisateur se farcisse la liste de toute les sociétés je les filtres en fonction du pays avec le code suivant qui s'active au changement de valeur du Combo-Box1.
    Il est possible qu'aucune donnée ne soit associée a une société dans un pays donné.
    Pour cela j'ai mis une conditions pour vérifier si il y a ou pas des données associées.
    Mon problème est que comme je lance ma macro sur le changement de valeur du Combo-Box 1, si il n'y a pas de données un message s'affiche pour avertir l'utilisateur et je voudrais effacer la valeur qui ne retourne aucun résultat (La valeur du Combo-Box 1) repasse à vide, mais comme je suis dans une Sub Combo-Box_Change, c'est le chien qui se mort la queue
    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
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    Sub ComboBox1_Change()
    Dim Data As Worksheet     
    Dim Reg As Worksheet
    Dim Cy As Range
    Dim Vendor_Ctry As Range
    Dim nbline As Integer
    Set Data = ThisWorkbook.Sheets("Data")
    Set Reg = ThisWorkbook.Sheets("NOI_Reg")
    Set Cy = Data.Range("G5")
    Set Vendor_Ctry = Reg.Range("C3")
     
        With Reg
            nbline = .Cells(.Rows.Count, 1).End(xlUp).Row - 2 
        End With
     
     
    For i = 0 To nbline
     
        If NOI_Selection.ComboBox1.Value = Vendor_Ctry.Offset(i, 0) Then
     
                If NOI_Selection.ComboBox1.Value = Cy.Offset(0, 0) Then
                    NOI_Selection.ComboBox2.List = Data.Range("D5:D6").Value
                    Exit Sub
                ElseIf NOI_Selection.ComboBox1.Value = Cy.Offset(1, 0) Then
                    NOI_Selection.ComboBox2.Value = Data.Range("D7").Value
                    Exit Sub
                ElseIf NOI_Selection.ComboBox1.Value = Cy.Offset(2, 0) Then
                    NOI_Selection.ComboBox2.Value = Data.Range("D8").Value
                    Exit Sub
                ElseIf NOI_Selection.ComboBox1.Value = Cy.Offset(3, 0) Then
                    NOI_Selection.ComboBox2.List = Data.Range("D9:D11").Value
                    Exit Sub
                ElseIf NOI_Selection.ComboBox1.Value = Cy.Offset(4, 0) Then
                    NOI_Selection.ComboBox2.List = Data.Range("D12:D13").Value
                    Exit Sub
                ElseIf NOI_Selection.ComboBox1.Value = Cy.Offset(5, 0) Then
                    NOI_Selection.ComboBox2.List = Data.Range("D14:D27").Value
                    Exit Sub
                ElseIf NOI_Selection.ComboBox1.Value = Cy.Offset(6, 0) Then
                    NOI_Selection.ComboBox2.Value = Data.Range("D28").Value
                    Exit Sub
                ElseIf NOI_Selection.ComboBox1.Value = Cy.Offset(7, 0) Then
                    NOI_Selection.ComboBox2.List = Data.Range("D29:D37").Value
                    Exit Sub
                ElseIf NOI_Selection.ComboBox1.Value = Cy.Offset(8, 0) Then
                    NOI_Selection.ComboBox2.Value = Data.Range("D38").Value
                    Exit Sub
                ElseIf NOI_Selection.ComboBox1.Value = Cy.Offset(9, 0) Then
                    NOI_Selection.ComboBox2.List = Data.Range("D39:D42").Value
                    Exit Sub
                ElseIf NOI_Selection.ComboBox1.Value = Cy.Offset(10, 0) Then
                    NOI_Selection.ComboBox2.Value = Data.Range("D43").Value
                    Exit Sub
                ElseIf NOI_Selection.ComboBox1.Value = Cy.Offset(11, 0) Then
                    NOI_Selection.ComboBox2.Value = Data.Range("D44").Value
                    Exit Sub
                ElseIf NOI_Selection.ComboBox1.Value = Cy.Offset(12, 0) Then
                    NOI_Selection.ComboBox2.Value = Data.Range("D45").Value
                    Exit Sub
                ElseIf NOI_Selection.ComboBox1.Value = Cy.Offset(13, 0) Then
                    NOI_Selection.ComboBox2.List = Data.Range("D46:D121").Value
                    Exit Sub
                ElseIf NOI_Selection.ComboBox1.Value = Cy.Offset(14, 0) Then
                    NOI_Selection.ComboBox2.List = Data.Range("D122:D135").Value
                    Exit Sub
                End If
        Else
     
        A = MsgBox(" No NOI associated with this Country", vbOKOnly + vbExclamation, WARNING)
             If A = vbOK Then
                   Me.Hide
     
             End If
        End If
    Next i
     
    Me.Hide
     
    End Sub
    Mes question sont les suivantes:
    Comment déclencher mon code sans passer par une sub ComboBox_Change ou alors comment gérer le cas qui me pose problème?
    Comment mettre a jour la liste du ComboBox2 (les sociétés) de façon automatique car ici je me tape tout à la main si on ajoute une société dans un pays? (Je sais que mon code est une usine à gaz mais j'ai du le créer rapidement pour répondre a un besoin urgent et n'ai pas vraiment cherché d'autres solutions)
    Nom : Liste Societe.jpg
Affichages : 1355
Taille : 197,4 Ko
    Merci pour vos conseils et votre aide
    Eric
    "Vous n’avez cessé d’essayer ? Vous n’avez cessé d’échouer ? Aucune importance !
    Réessayez, échouez encore, échouez mieux." Samuel Beckett
    Pensez aux balises et
    Visitez les FAQ Excel et allez faire un tour ici
    Tutoriels de SilkyRoad

  2. #2
    Membre très actif
    Homme Profil pro
    Analyste programmeur
    Inscrit en
    Mai 2014
    Messages
    393
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Analyste programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 393
    Par défaut
    Pour empêcher le ComboBox_Change() récursivement, il faut que tu utilises un booléen dedans qui :
    - si vrai alors tu continues le ComboBox_Change()
    - sinon, tu sors du ComboBox_Change()

    Et pour éviter de tout te farcir à la main, pourquoi pas utiliser une boucle for?

  3. #3
    Membre émérite
    Avatar de eric4459
    Homme Profil pro
    Ingénieur Gestion de Projets
    Inscrit en
    Avril 2014
    Messages
    605
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes de Haute Provence (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur Gestion de Projets
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2014
    Messages : 605
    Par défaut
    Bonjour JeanMi
    En fait je souhaite que des que je sélectionne une valeur dans ma ComboBox1 j'alimente aussitôt ma ComboBox2 avec une liste issue de mon code.
    Quelle serait la syntaxe pour ta proposition car j'ai essayé
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    If NOI_Selection.ComboBox1.Change = True Then
    mais j'ai une erreur Compil Error "Method or data member not found"
    Et pour la mise a jour je ne vois pas comment je pourrais utiliser une boucle for car le nouveau pays ou la nouvelle société viendrai s’insérer dans ma liste existante décalant par la même mes references.

    Par exemple si j'insere une ligne en D35 (voir copie d'écran plus du 1er message), je n'aurai plus
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    ElseIf NOI_Selection.ComboBox1.Value = Cy.Offset(7, 0) Then
                    NOI_Selection.ComboBox2.List = Data.Range("D29:D37").Value
                    Exit Sub
                ElseIf NOI_Selection.ComboBox1.Value = Cy.Offset(8, 0) Then
                    NOI_Selection.ComboBox2.Value = Data.Range("D38").Value
                    Exit Sub
    Mais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    ElseIf NOI_Selection.ComboBox1.Value = Cy.Offset(7, 0) Then
                    NOI_Selection.ComboBox2.List = Data.Range("D29:D38").Value
                    Exit Sub
                ElseIf NOI_Selection.ComboBox1.Value = Cy.Offset(8, 0) Then
                    NOI_Selection.ComboBox2.Value = Data.Range("D39").Value
                    Exit Sub
                ElseIf NOI_Selection.ComboBox1.Value = Cy.Offset(9, 0) Then
                    NOI_Selection.ComboBox2.List = Data.Range("D40:D43").Value
                    Exit Sub
                ElseIf NOI_Selection.ComboBox1.Value = Cy.Offset(10, 0) Then
                    NOI_Selection.ComboBox2.Value = Data.Range("D44").Value
                    Exit Sub
    Eric
    "Vous n’avez cessé d’essayer ? Vous n’avez cessé d’échouer ? Aucune importance !
    Réessayez, échouez encore, échouez mieux." Samuel Beckett
    Pensez aux balises et
    Visitez les FAQ Excel et allez faire un tour ici
    Tutoriels de SilkyRoad

  4. #4
    Membre Expert
    Avatar de pijaku
    Homme Profil pro
    Inscrit en
    Août 2010
    Messages
    1 817
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Août 2010
    Messages : 1 817
    Billets dans le blog
    10
    Par défaut ComboBox1.Click ?
    Bonjour,

    Un petit exemple avec 2 combobox.
    A adapter le nom de la feuille, ici Feuil1...

    Dans un module standard :
    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
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    Option Explicit
     
        Public Function derlig_reelle(plage As Range) As Long
           'cas d'absence de données dans la plage à traiter :
           If WorksheetFunction.CountA(plage) = 0 Then derlig_reelle = 1: Exit Function
           'dans tous les autres cas :
           derlig_reelle = plage.Find("*", , , , , xlPrevious).Row
        End Function
     
        Public Function Filtre_Tableau(ByVal Tableau As Variant, _
                                             Colonne As Long, _
                                             Key1 As Variant, _
                                             Optional test As String = "=") As Variant
        'Filtre un tableau à 2 dimensions en fonction du contenu d'une colonne
        '
        '!!!!!!!!! utilise les fonctions : Nb_Dimensions & Transposition
        '
        'PARAMETRES
            'Tableau = Array de variant à 2 dimensions
            'Colonne = numéro de la colonne contenant les données à filtrer
            'Key1 = comparateur, donnée à laquelle comparer les données de la colonne Colonne
            'Test = opérateur parmi : "=", "<", "<=", ">", ">=", "Like", "<>" (à passer en String donc avec guillemets)
     
        Dim Tbl() As Variant, i As Long, j As Long, Cpt As Long, TestColonne As Variant
     
            On Error GoTo Erreur_Colonne
            TestColonne = Tableau(LBound(Tableau, 1), Colonne)
            On Error GoTo 0
            Select Case Nb_Dimensions(Tableau)
                Case 0
                    MsgBox "Le tableau passé en paramètre est vide."
                Case 1
                    MsgBox "Le tableau passé en paramètre ne comporte qu'une colonne. La fonction n'est pas adaptée à ce cas."
                Case 2
                    Select Case test
                        Case "="
                            For i = LBound(Tableau, 1) To UBound(Tableau, 1)
                                If Tableau(i, Colonne) = Key1 Then
                                    Cpt = Cpt + 1
                                    ReDim Preserve Tbl(1 To UBound(Tableau, 2), 1 To Cpt)
                                    For j = LBound(Tableau, 2) To UBound(Tableau, 2)
                                        Tbl(j, Cpt) = Tableau(i, j)
                                    Next j
                                End If
                            Next i
                        Case "<"
                            For i = LBound(Tableau, 1) To UBound(Tableau, 1)
                                If Tableau(i, Colonne) < Key1 Then
                                    Cpt = Cpt + 1
                                    ReDim Preserve Tbl(1 To UBound(Tableau, 2), 1 To Cpt)
                                    For j = LBound(Tableau, 2) To UBound(Tableau, 2)
                                        Tbl(j, Cpt) = Tableau(i, j)
                                    Next j
                                End If
                            Next i
                        Case ">"
                            For i = LBound(Tableau, 1) To UBound(Tableau, 1)
                                If Tableau(i, Colonne) > Key1 Then
                                    Cpt = Cpt + 1
                                    ReDim Preserve Tbl(1 To UBound(Tableau, 2), 1 To Cpt)
                                    For j = LBound(Tableau, 2) To UBound(Tableau, 2)
                                        Tbl(j, Cpt) = Tableau(i, j)
                                    Next j
                                End If
                            Next i
                        Case "<="
                            For i = LBound(Tableau, 1) To UBound(Tableau, 1)
                                If Tableau(i, Colonne) <= Key1 Then
                                    Cpt = Cpt + 1
                                    ReDim Preserve Tbl(1 To UBound(Tableau, 2), 1 To Cpt)
                                    For j = LBound(Tableau, 2) To UBound(Tableau, 2)
                                        Tbl(j, Cpt) = Tableau(i, j)
                                    Next j
                                End If
                            Next i
                        Case ">="
                            For i = LBound(Tableau, 1) To UBound(Tableau, 1)
                                If Tableau(i, Colonne) >= Key1 Then
                                    Cpt = Cpt + 1
                                    ReDim Preserve Tbl(1 To UBound(Tableau, 2), 1 To Cpt)
                                    For j = LBound(Tableau, 2) To UBound(Tableau, 2)
                                        Tbl(j, Cpt) = Tableau(i, j)
                                    Next j
                                End If
                            Next i
                        Case "<>"
                            For i = LBound(Tableau, 1) To UBound(Tableau, 1)
                                If Tableau(i, Colonne) <> Key1 Then
                                    Cpt = Cpt + 1
                                    ReDim Preserve Tbl(1 To UBound(Tableau, 2), 1 To Cpt)
                                    For j = LBound(Tableau, 2) To UBound(Tableau, 2)
                                        Tbl(j, Cpt) = Tableau(i, j)
                                    Next j
                                End If
                            Next i
                        Case "Like"
                            For i = LBound(Tableau, 1) To UBound(Tableau, 1)
                                If Tableau(i, Colonne) Like Key1 Then
                                    Cpt = Cpt + 1
                                    ReDim Preserve Tbl(1 To UBound(Tableau, 2), 1 To Cpt)
                                    For j = LBound(Tableau, 2) To UBound(Tableau, 2)
                                        Tbl(j, Cpt) = Tableau(i, j)
                                    Next j
                                End If
                            Next i
                        Case Else
                            MsgBox "Le paramètre facultatif Test est erroné."
                            Exit Function
                    End Select
                    On Error GoTo resultat_Vide
                    TestColonne = Tbl(UBound(Tbl, 1), UBound(Tbl, 2))
                    On Error GoTo 0
                    Filtre_Tableau = Transposition(Tbl)
                    Erase Tbl
                Case Else
                    MsgBox "Le tableau comporte plus de deux dimensions. La fonction n'est pas adaptée à ce cas."
            End Select
            Exit Function
    Erreur_Colonne:
        MsgBox "Le paramètre Colonne est erroné."
        Exit Function
    resultat_Vide:
        MsgBox "Le filtre renvoie un tableau vide de données."
        End Function
     
        Public Function Nb_Dimensions(Tableau As Variant) As Integer
        'Calcule le nombre de dimensions d'un tableau
        'PARAMETRE
            'Tableau = Array de Variant à 0, 1 ou plusieurs dimensions
        Dim D As Integer, t As Integer
     
            On Error GoTo Fin
            Do: D = D + 1: t = UBound(Tableau, D): Loop
    Fin:
        Nb_Dimensions = D - 1
        End Function
     
        Public Function Range_To_Tb(plage As Range) As Variant()
        'Converti sans faille un range en tableau
     
        '
        '   Le tableau ainsi obtenu est toujours en option base 1
        '   ET à 2 dimensions
        'PARAMETRE
            'plage = Range (plage de cellule(s))
     
            If plage.Cells.Count < 2 Then
               Dim tablo(1 To 1, 1 To 1)
               tablo(1, 1) = plage.Value
               Range_To_Tb = tablo
               Erase tablo
             Else
               Range_To_Tb = plage.Value
             End If
        End Function
     
        Public Function Transposition(ByRef Tableau As Variant) As Variant
        'Transpose, en lignes, un tableau à 2 dimensions de plus de 65536 Colonnes
        '
        '!!!!!!!!! utilise la fonction : Nb_Dimensions
        '
        'PARAMETRE
            'Tableau = Array de Variant à 2 dimensions
     
            Select Case Nb_Dimensions(Tableau)
                Case 0
                    MsgBox "Le tableau passé en paramètre est vide."
                Case 1
                    MsgBox "Le tableau passé en paramètre ne comporte qu'une colonne. La fonction n'est pas adaptée à ce cas."
                Case 2
                    Dim Tabl, i As Long, j As Long
                    ReDim Tabl(1 To UBound(Tableau, 2), 1 To UBound(Tableau, 1))
                    For i = LBound(Tableau, 1) To UBound(Tableau, 1)
                        For j = LBound(Tableau, 2) To UBound(Tableau, 2)
                            Tabl(j, i) = Tableau(i, j)
                        Next j
                    Next i
                    Transposition = Tabl
                    Erase Tabl
                Case Else
                    MsgBox "Le tableau comporte plus de deux dimensions. La fonction n'est pas adaptée à ce cas."
            End Select
        End Function
    Dans le module de l'userform
    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
    Option Explicit
     
     
    Private Sub UserForm_Initialize()
    Dim DL As Long, L As Long
        With Worksheets("Feuil1")
            DL = derlig_reelle(.Columns(5))
            For L = 2 To DL
                ComboBox1.Value = .Cells(L, 5)
                If ComboBox1.ListIndex = -1 Then ComboBox1.AddItem .Cells(L, 5)
            Next
        End With
        'empêche la saisie de valeurs farfelues dans ta combo
        ComboBox1.Style = fmStyleDropDownList
        ComboBox1.ListIndex = -1
    End Sub
     
     
    Private Sub ComboBox1_Click()
        If ComboBox1 = "" Then Exit Sub
        Dim Donnees, DL As Long
        With Worksheets("Feuil1")
            DL = derlig_reelle(.Columns(5))
            Donnees = .Range("D2:E" & DL)
        End With
        ComboBox2.List = Filtre_Tableau(Donnees, 2, ComboBox1.Value, "=")
    End Sub
    Un fichier exemple :
    Pièce jointe 209494

  5. #5
    Membre émérite
    Avatar de eric4459
    Homme Profil pro
    Ingénieur Gestion de Projets
    Inscrit en
    Avril 2014
    Messages
    605
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes de Haute Provence (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur Gestion de Projets
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2014
    Messages : 605
    Par défaut
    Bonjour Franck,
    Merci pour ce code qui fonctionne super bien dans ton exemple mais je ne suis pas parvenu à l'adapter à mon cas.
    J'ai modifié ceci
    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
    Private Sub Open_NOI_Selection()
    Dim DL As Long, L As Long
        With Worksheets("Data")
            DL = derlig_reelle(.Columns(5))
            For L = 5 To DL
                ComboBox1.Value = .Cells(L, 5)
                If ComboBox1.ListIndex = -1 Then ComboBox1.AddItem .Cells(L, 5)
            Next
        End With
        'empêche la saisie de valeurs farfelues dans ta combo
        ComboBox1.Style = fmStyleDropDownList
        ComboBox1.ListIndex = -1
    End Sub
     
     
    Private Sub ComboBox1_Click()
        If ComboBox1 = "" Then Exit Sub
        Dim Donnees, DL As Long
        With Worksheets("Data")
            DL = derlig_reelle(.Columns(5))
            Donnees = .Range("D5:E" & DL) 'Ma liste commence en D5
        End With
        ComboBox2.List = Filtre_Tableau(Donnees, 2, ComboBox1.Value, "=")
    End Sub
    Quand l'UserForm s'ouvre, (je n'ai pas vu quelle est la commande pour l'ouvrir dans ton code -moi j'utilise UserForm1.Show), la liste est vide, j'ai du rater quelque-chose mais ce code est un peu trop complexe pour moi sans l'avoir étudié longuement.
    Eric
    "Vous n’avez cessé d’essayer ? Vous n’avez cessé d’échouer ? Aucune importance !
    Réessayez, échouez encore, échouez mieux." Samuel Beckett
    Pensez aux balises et
    Visitez les FAQ Excel et allez faire un tour ici
    Tutoriels de SilkyRoad

  6. #6
    Membre Expert
    Inscrit en
    Octobre 2010
    Messages
    1 401
    Détails du profil
    Informations forums :
    Inscription : Octobre 2010
    Messages : 1 401
    Par défaut
    Bonjour Eric

    Voici une autre suggestion.
    Fichiers attachés Fichiers attachés

  7. #7
    Membre émérite
    Avatar de eric4459
    Homme Profil pro
    Ingénieur Gestion de Projets
    Inscrit en
    Avril 2014
    Messages
    605
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes de Haute Provence (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur Gestion de Projets
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2014
    Messages : 605
    Par défaut
    Bonjour Doc Marti,
    Merci pour ton aide, ce type de code est un peu plus à ma portée que celui de Franck, que je remercie tout de même également.
    Je vais donc adapter cela à mon contexte et je reviendrai poster ce que j'aurai fait, ou reviendrai vous voir si j'ai d'autres soucis
    Eric
    "Vous n’avez cessé d’essayer ? Vous n’avez cessé d’échouer ? Aucune importance !
    Réessayez, échouez encore, échouez mieux." Samuel Beckett
    Pensez aux balises et
    Visitez les FAQ Excel et allez faire un tour ici
    Tutoriels de SilkyRoad

  8. #8
    Membre Expert
    Avatar de pijaku
    Homme Profil pro
    Inscrit en
    Août 2010
    Messages
    1 817
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Août 2010
    Messages : 1 817
    Billets dans le blog
    10
    Par défaut
    Re-

    Tu as placé mon code de l'UserForm_initialize dans une procédure : Private Sub Open_NOI_Selection()???
    Pourquoi?
    Elle doit être dans UserForm_Initialize pour être déclenchée à l'événement correspondant à l'ouverture de l'userform.

  9. #9
    Membre émérite
    Avatar de eric4459
    Homme Profil pro
    Ingénieur Gestion de Projets
    Inscrit en
    Avril 2014
    Messages
    605
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes de Haute Provence (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur Gestion de Projets
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2014
    Messages : 605
    Par défaut
    Rebonjour Franck,
    J'ai simplement voulu renommer la procédure et effectivement quand je remet UserForm_initialize, cela fonctionne beaucoup mieux, parfaitement même.
    Cependant, comme je le disais plus haut, mon niveau en Vba n'est pas assez élevé pour maîtriser ce code, j'essayes de ne pas reprendre bêtement un code tout fait sans le comprendre et sans savoir comment l'adapter, ça ne me ferai pas avancer or je suis sur ce forum pour cela avancer et partager le peu de connaissance que j'ai en Vba si je pense pouvoir être utile.
    Eric
    "Vous n’avez cessé d’essayer ? Vous n’avez cessé d’échouer ? Aucune importance !
    Réessayez, échouez encore, échouez mieux." Samuel Beckett
    Pensez aux balises et
    Visitez les FAQ Excel et allez faire un tour ici
    Tutoriels de SilkyRoad

  10. #10
    Membre Expert
    Avatar de pijaku
    Homme Profil pro
    Inscrit en
    Août 2010
    Messages
    1 817
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Août 2010
    Messages : 1 817
    Billets dans le blog
    10
    Par défaut
    Bonjour,

    or je suis sur ce forum pour cela avancer
    Et bien justement. Ce n'est pas en "écartant" une solution car tu ne la comprends pas que tu va avancer...

    J'ai simplement voulu renommer la procédure
    On ne renomme pas une procédure événementielle, sinon elle ne fonctionne plus.
    Un événement est une procédure, liée à un objet, qui se déclenche quand l'action concernée est déclenchée sur l'objet.
    Par exemple, si tu souhaites qu'une action soit entreprise lorsque tu clic sur ton bouton nommé "Bouton_1", la procédure événementielle qu'il te faut utiliser est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Private Sub Bouton_1_Click()
    Si tu renommes cette procédure : Sub QuiSeDeclencheQuandJeClicSurBouton1() elle ne fonctionnera jamais.

    sans le comprendre et sans savoir comment l'adapter
    Et bien quelques explications s'imposent.

    Je t'ai fait placer des fonctions dans un module standard. Ces fonctions, tu n'as pas à t'en préoccuper pour l'instant elles fonctionnent seules.
    Toutefois, un petit descriptif de ces fonctions :

    Public Function derlig_reelle(plage As Range) As Long
    Set à déterminer la dernière ligne remplie, masquée ou non, d'une colonne, quel que soit le nombre de plages masquées ou de lignes vides présentes.
    Avec ce code, vous pourrez déterminer, non seulement la dernière ligne réelle d'une colonne, qu'elle que soit la configuration de vos données (lignes vides et/ou masquées), mais également d'une plage de cellules ou même d'une feuille entière. La valeur retournée est de type Long.
    Cette fonction est "fonctionnelle" même en cas d'insertion ou de suppression de lignes.
    Pour l'appeler, il suffit de lui transmettre en paramètre une plage de cellules. Exemples d'appels :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    'Dernière ligne réelle d'une colonne :
    MsgBox derlig_reelle(Worksheets("Feuil1").Columns(1))
    MsgBox derlig_reelle(Worksheets("Feuil1").Columns("A"))
    MsgBox derlig_reelle(Worksheets("Feuil2").Range("B:B"))
     
    'Dernière ligne réelle d'une plage de cellules (fonctionne même si la dernière ligne est située en colonne C)
    MsgBox derlig_reelle(Worksheets("Feuil1").Range("A10:G153"))
     
    'Dernière ligne réelle d'une feuille
    MsgBox derlig_reelle(Sheets("Feuil3").Cells)
    Public Function Filtre_Tableau(ByVal Tableau As Variant, _
    Colonne As Long, _
    Key1 As Variant, _
    Optional test As String = "=") As Variant

    Cette fonction filtre un tableau à 2 dimensions en fonction du contenu d'une colonne.
    Elle retourne un tableau "encapsulé" dans une variable de type Variant.
    Elle utilise les fonctions : Nb_Dimensions & Transposition
    Ces paramètres sont :
    1. Tableau = Array de variant à 2 dimensions
    2. Colonne = numéro de la colonne contenant les données à filtrer
    3. Key1 = comparateur, donnée à laquelle comparer les données de la colonne Colonne
    4. Optional test = opérateur parmi : "=", "<", "<=", ">", ">=", "Like", "<>" (à passer en String donc avec guillemets)

    Si test est omis, il est par défaut considéré comme "=".

    Comme dit précédemment, ces fonctions sont indépendantes de ton code.
    Le plus important pour toi est de comprendre comment fonctionne le code de l'UserForm.

    Procédure Initialize :
    Mis à part la boucle que tu dois comprendre, on utilise ici 4 propriétés des ComboBox pour pouvoir la remplir, sans doublons, et en empêcher la saisie.
    L'extrait de code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ComboBox1.Value = .Cells(L, 5)
    If ComboBox1.ListIndex = -1 Then ComboBox1.AddItem .Cells(L, 5)
    dit :
    ComboBox1.Value = .Cells(L, 5) => je saisis dans la Combo, la valeur contenue ligne L colonne 5 (E).
    Le fait de saisir une valeur dans une combobox fait que, si la valeur est déjà saisie, elle va se sélectionnée d'elle même.
    Autrement dit, si tu saisis une valeur déjà existante (doublon), la propriété ListIndex sera égale à l'index de cette valeur précédemment saisie.
    Donc ListIndex sera différente de -1.
    Si ListIndex = -1 alors la valeur n'a pas été enregistrée dans la ComboBox, donc on l'ajoute via ComboBox1.AddItem
    Ces 2 propriétés (.ListIndex, .Value) et la méthode (.AddItem) te permettent de remplir ta ComboBox sans doublon.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ComboBox1.Style = fmStyleDropDownList 'sert à empêcher une saisie de la part d'un utilisateur mesquin...
    ComboBox1_Click
    C'est le but de ton sujet, je cite :
    Alternative à ComboBox_Change()
    Comment déclencher mon code sans passer par une sub ComboBox_Change
    Tu souhaites, lorsque TU fais un choix dans ta combobox que cela déclenche une action (remplissage de combobox2).
    L'événement lié à cette action (faire un choix dans combobox1) n'est pas l'événement Change!
    Il s'agit de l'événement Click de la ComboBox.
    Dans ce code, il n'y a rien de particulier, tu souhaites avoir les valeurs situées en colonne D ou la valeur en E est celle de ta combobox1.
    Tu souhaites, en quelques sortes, filtrer ta bdd sur la colonne E si elle est égale à ta combo1.
    Pour cela, ne souhaitant pas toucher au contenu de ta feuille, je fait ceci :
    1. Stockage des valeurs contenues en colonnes D et E dans un tableau de type Variant
    2. Filtre de ces données grâce à la fonction Filtre_Tableau
    3. Remplissage de la ComboBox2 grâce à sa propriété List

    Ce qui nous donne le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Private Sub ComboBox1_Click()
        If ComboBox1 = "" Then Exit Sub
        Dim Donnees, DL As Long
        'stockage des données contenues dans D2:Edernièreligne
        With Worksheets("Feuil1")
            DL = derlig_reelle(.Columns(5))
            Donnees = .Range("D2:E" & DL)
        End With
        'le "filtrage" des données sert à alimenter la propriété List de la ComboBox2
        ComboBox2.List = Filtre_Tableau(Donnees, 2, ComboBox1.Value, "=")
    End Sub
    Tu vois, qu'au final, il n'y a rien de bien compliqué dans ce code.
    N'hésite pas à poser toutes questions complémentaires.

  11. #11
    Membre émérite
    Avatar de eric4459
    Homme Profil pro
    Ingénieur Gestion de Projets
    Inscrit en
    Avril 2014
    Messages
    605
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes de Haute Provence (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur Gestion de Projets
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2014
    Messages : 605
    Par défaut
    Bonjour Fanck,
    Merci pour ces éclaircissements, je suis d'accord avec toi quand tu dis
    Ce n'est pas en "écartant" une solution car tu ne la comprends pas que tu va avancer
    , même si je ne l'ecartais pas completement de mon esprit, je suis un peu presse par le temps et
    ce code est un peu trop complexe pour moi sans l'avoir étudié longuement
    .
    J'ai finalement intégré ton code car tes explications m'ont permis de le comprendre d'avantage, il me faudra quand même un peu de temps pour l'assimiler à 100% et être capable de me servir de ces "principes" pour de futures applications.
    Mon application fait appel a plusieurs Userform qui utilisent le même principe : variation de la valeur d'un combobox entraîne un filtre pour affichage dans un autre combobox et comme j'utilise également dans ces Userform les mêmes listes Pays fournisseur, je vais adapter ton code a ces autres UserForm, cela me permettra aussi de le comprendre beaucoup mieux.

    Eric
    "Vous n’avez cessé d’essayer ? Vous n’avez cessé d’échouer ? Aucune importance !
    Réessayez, échouez encore, échouez mieux." Samuel Beckett
    Pensez aux balises et
    Visitez les FAQ Excel et allez faire un tour ici
    Tutoriels de SilkyRoad

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. alterner les couleurs dans un tableau avec xsl
    Par Eithelgul dans le forum XSL/XSLT/XPATH
    Réponses: 14
    Dernier message: 03/05/2015, 23h29
  2. Alternative au dbms_output ?
    Par dam1311 dans le forum Oracle
    Réponses: 10
    Dernier message: 24/11/2004, 08h11
  3. [xsl] alterner de style entre deux apply-template
    Par laouache dans le forum XSL/XSLT/XPATH
    Réponses: 7
    Dernier message: 23/04/2004, 11h49
  4. Alternative(s) a CVS
    Par MrSimon dans le forum SCM
    Réponses: 3
    Dernier message: 06/03/2004, 11h37
  5. [FORMATION] Formations par alternance
    Par chobol dans le forum Etudes
    Réponses: 10
    Dernier message: 20/02/2004, 11h28

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