Cascade de Combobox dans userform

Bonjour à Tous,

Tout d'abord, je vais commencer par vous dire que je suis débutant en vba mais je travaille dessus depuis quelques semaines et cela me plait...

Je travaille sur un fichier dans lequel je lance un userform comprenant 3 combobox et j'aimerais pouvoir les lier en cascade. Après une recherche sur votre forum, j'ai pû trouver ce code :

Option Explicit

Dim Ws As Worksheet
Dim NbLignes As Integer

Private Sub UserForm_Initialize()
    'Définit la feuille contenant les données
    Set Ws = Worksheets("Base")
    'Définit le nombre de lignes dans la colonne A
    NbLignes = Ws.Range("A65536").End(xlUp).Row

    'Remplissage du ComboBox1
    Alim_Combo 1

End Sub

Private Sub ComboBox1_Change()
    'Remplissage Combo2
    Alim_Combo 2, ComboBox1.Value
End Sub

Private Sub ComboBox2_Change()
    'Remplissage Combo3
    Alim_Combo 3, ComboBox2.Value
End Sub

'Procédure pour alimenter les ComboBox
Private Sub Alim_Combo(CbxIndex As Integer, Optional Cible As Variant)
    Dim j As Integer
    Dim Obj As Control

    'Définit le ComboBox à remplir
    Set Obj = Me.Controls("ComboBox" & CbxIndex)
    'Supprime les anciennes données
    Obj.Clear

    'alimente le Combobox initial (Combobox1)
    If CbxIndex = 1 Then
        'Boucle sur les lignes de la colonne A (à partir de la 2eme ligne)
        For j = 2 To NbLignes
            Obj = Ws.Range("A" & j)
            'Remplit le ComboBox sans doublons
            If Obj.ListIndex = -1 Then Obj.AddItem Ws.Range("A" & j)
        Next j
    Else
        'Alimentation conditionnelle des autres Combobox en fonction de
        'ce qui est sélectionnée dans le contrôle précédent:
        '(La sélection du ComboBox1 définit le contenu du ComboBox2,
        'La sélection du ComboBox2 définit le contenu du ComboBox3 ?etc...)
        For j = 2 To NbLignes
            If Ws.Range("A" & j).Offset(0, CbxIndex - 2) = Cible Then
                Obj = Ws.Range("A" & j).Offset(0, CbxIndex - 1)
                If Obj.ListIndex = -1 Then Obj.AddItem Ws.Range("A" & j).Offset(0, CbxIndex - 1)
            End If
        Next j
   End If

   'Enlève la sélection dans le ComboBox
   Obj.ListIndex = -1
End Sub

J'ai donc adapté ce code mais un problème subsiste : le combobox2 n'est pas alimenté et donc le combobox3 non plus. Mais mes connaissances ne me permettent pas de voir où le code déconne...

Merci d'avance à ceux qui me consacreront de leur temps.

450fab1-essai.rar (44.15 Ko)

Bonjour à Tous,

Personne ne voit d'où vient le problème ?

Bonjour

Le problème vient que dans la feuille "Base" tu as des chiffres et que la macro les compare avec du texte

Modifies la macro correspondante (Partie surlignée en jaune)

'Procédure pour alimenter les ComboBox
Private Sub Alim_Combo(CbxIndex As Integer, Optional Cible As Variant)
    Dim j As Integer
    Dim Obj As Control

    'Définit le ComboBox à remplir
    Set Obj = Me.Controls("ComboBox" & CbxIndex)
    'Supprime les anciennes données
    Obj.Clear

    'alimente le Combobox initial (Combobox1)
    If CbxIndex = 1 Then
        'Boucle sur les lignes de la colonne A (à partir de la 2eme ligne)
        For j = 2 To NbLignes
            Obj = Ws.Range("A" & j)
            'Remplit le ComboBox sans doublons
            If Obj.ListIndex = -1 Then Obj.AddItem Ws.Range("A" & j)
        Next j
    Else
        'Alimentation conditionnelle des autres Combobox en fonction de
        'ce qui est sélectionnée dans le contrôle précédent:
        '(La sélection du ComboBox1 définit le contenu du ComboBox2,
        'La sélection du ComboBox2 définit le contenu du ComboBox3 ?etc...)
        For j = 2 To NbLignes
            If [surligner=#FFFF80]CStr(Ws.Range("A" & j).Offset(0, CbxIndex - 2)[surligner=#FFFF80]) = Cible Then
                Obj = Ws.Range("A" & j).Offset(0, CbxIndex - 1)
                If Obj.ListIndex = -1 Then Obj.AddItem Ws.Range("A" & j).Offset(0, CbxIndex - 1)
            End If
        Next j
   End If

   'Enlève la sélection dans le ComboBox
   Obj.ListIndex = -1
End Sub

Bonjour Banzai64,

Tout d'abord, merci pour ta réponse, cela marche bien sauf un petit soucis qui persiste.

Lorsque je rentre les valeurs suivantes par exemple :

Nb equipes qualifiées = 8

Nb groupes = 3

dans le combobox3, il me donne la possibilité entre 2,5 ou 10 alors que j'aimerais pouvoir avoir que la combinaison pour 8 -3, à savoir la valeur de 2 correspondant à mon tableau "Base".

Est ce possible d'améliorer ce code dans ce sens ?

Merci d'avance

capture
259fab1-essai.rar (44.84 Ko)

Bonjour

youlig a écrit :

Est ce possible d'améliorer ce code dans ce sens ?

Non

On peut juste le modifier

A tester

Merci beaucoup Banzai64, c'est exactement ça !!!

Bonjour à tous,

J'ai utilisé ce code dans mon projet qui fonctionne très bien, mais le problème que j'ai

c'est que la combo1 prend sa liste dans la colonne A, la 2 dans la colonne B ...etc

Mes colonnes ne sont pas dans l'ordre souhaité et je ne "peux" pas les modifiés. Plus clairement : j'aimerai que

ma combo1 utilise la colonne E,

ma combo2 utilise la colonne G,

ma combo3 utilise la colonne F,

ma combo4 utilise la colonne B

Est ce qu'il est possible de modifier cet ordre ?

Merci d'avance pour votre aide.

Landry

Bonsoir,

Voici un autre programme beaucoup plus rapide.

Il faut changer la ligne:

ColcléCombo = Array(1, 2, 3, 4, 5) ' colonnes des combobox( à adapter)

par

ColcléCombo = Array(5 , 8 , 7, 2, 1) ' colonnes des combobox( à adapter)

Il faut changer la ligne:

BD = f.Range("A2:E" & f.[A65000].End(xlUp).Row).Value ' Array pour rapidité (à adapter)

par

BD = f.Range("A2:G" & f.[A65000].End(xlUp).Row).Value ' Array pour rapidité (à adapter)

Ceuzin

ceuzin a écrit :

Bonsoir,

Voici un autre programme beaucoup plus rapide.

Il faut changer la ligne:

ColcléCombo = Array(1, 2, 3, 4, 5) ' colonnes des combobox( à adapter)

par

ColcléCombo = Array(5 , 8 , 7, 2, 1) ' colonnes des combobox( à adapter)

Il faut changer la ligne:

BD = f.Range("A2:E" & f.[A65000].End(xlUp).Row).Value ' Array pour rapidité (à adapter)

par

BD = f.Range("A2:G" & f.[A65000].End(xlUp).Row).Value ' Array pour rapidité (à adapter)

Ceuzin

Extra!!! Merci

Si je peux abuser, j'aimerai modifier la ligne suivante : Set f = Sheets("BD")

pour déterminer dans quelle feuille s'effectue la recherche (liste contenue dans ma combobox12)

J'ai essayé

Set f = Sheets (Me.ComboBox12)

Set f = Sheets (Me.ComboBox12.value)

Mais ça ne fonctionne pas.

Bonjour,

Pour savoir dans quelle feuille rechercher j'utilise cette macro que NCC1701 m'avais gentillement donné

Dim tabOnglets(1 To 12)
Dim cptOnglet

    ' ATTENTION la liste ci-dessous doit reprendre EXACTEMENT le nom des onglets !!!
    tabOnglets(1) = "JAN" ' dans mon tableur "JAN" est le nom de la feuille
    tabOnglets(2) = "FEV"
    tabOnglets(3) = "MAR"
    tabOnglets(4) = "AVR"
    tabOnglets(5) = "MAI"
    tabOnglets(6) = "JUIN"
    tabOnglets(7) = "JUIL"
    tabOnglets(8) = "AOU"
    tabOnglets(9) = "SEP"
    tabOnglets(10) = "OCT"
    tabOnglets(11) = "NOV"
    tabOnglets(12) = "DEC"
 '...

    For cptOnglet = Sheets("Data").Range("M3").Value To Sheets("Data").Range("N3").Value  'à adapter dans ton exemple pour effectuer la macro dans toute les feuilles le code serait 1 to 12 ; dans mon tableur la valeur du mois de départ ce trouve en cellule M3 et celle de fin en N3 de la feuille Data.

    Sheets(tabOnglets(cptOnglet)).Select

' reste du code pas utile dans ton exemple il me semble

        Set plage1 = Sheets(tabOnglets(cptOnglet)).Range("C7:AG122")

        For Each cel In plage1

                 If cel.Text = Sheets("Para").Range("F3") Then
                Range(Cells(cel.Row - 2, cel.Column), Cells(cel.Row + 1, cel.Column)).Interior.ColorIndex = 4
                'cel.Interior.ColorIndex = 4 (vert)

            Set Cellule = ActiveCell

            Else

            If cel.Text = Sheets("Para").Range("F4") Then
                    Range(Cells(cel.Row - 2, cel.Column), Cells(cel.Row + 1, cel.Column)).Interior.ColorIndex = 3
                    'cel.Interior.ColorIndex = 3 (rouge)

                End If
            End If

            Next cel

            Next

End Sub 

En espérant t'avoir aider

A+

Merci pour ta réponse, mais mon "soucis" est que j'ai beaucoup de feuilles donc cela va être très très long de créer tous les

"tabOnglets(...) = "..."

Et en fait le code fonctionne très bien quand la valeur est définie directement dans l'userform initialize, donc j'ai pensé

qu'il serait facile de la modifié en remplaçant le nom de la feuille ("BD") par la valeur choisie dans une ComboBox (dans le sub combobox_change bien sur).

Je pense que c'est la syntaxe pour appelé cette valeur qui est mauvaise...

J'ai modifié un peu le code donné par Ceuzin en y ajoutant une ComboBox5 qui inscrit une valeur en D1,

puis cette valeur est réutilisée pour alimenter le reste des Cbx.

Oui c'est un peu du bricolage

Cependant bien que la valeur de D1 soit modifiée, l'alimentation des Cbx reste sur celle donnée lors de l'userform_initialize

Je vais partir sur la piste d'une réinitialisation de l'usf lors du ComboBox12_change...

Mais peut être avez vous une meilleur idée?

et le bout de code :

Private Sub ComboBox5_Change()
Sheets("Listedespages").Range("D1").Value = Me.ComboBox5
Set f = Sheets(Sheets("Listedespages").Range("D1").Value)
End Sub

Private Sub UserForm_Initialize()
  Sheets("Listedespages").Range("D1").Value = "BD"
  ColcléCombo = Array(1, 2, 3, 4, 5)                   ' colonnes des combobox( à adapter)
  Set f = Sheets(Sheets("Listedespages").Range("D1").Value)
  Set d1 = CreateObject("Scripting.Dictionary")
  BD = Sheets(Sheets("Listedespages").Range("D1").Value).Range("A2:E" & f.[A65000].End(xlUp).Row).Value  ' Array pour rapidité (à adapter)
  ColClé1 = ColcléCombo(0)
  For i = LBound(BD) To UBound(BD): d1(BD(i, ColClé1)) = "": Next
  Me.ComboBox1.List = d1.keys
  Me.ComboBox5.List = Sheets("Listedespages").Range("A1:A10").Value

Je crois comprendre mon erreur : les valeur de d1 , de BD ne sont pas réinitialisées au changement de la cbx5

donc la combobox1.list non plus...

Non?

C'était bien cela, du coup je donne ma solution si elle peut aider...

En précisant bien que c'est du bricolage et qu'une personne connaissant correctement le vba

s'y prendrait surement autrement

Fichier de Ceuzin modifié avec combobox5 pour choix de la feuille dans laquelle est effectuée

la recherche.

Dim f, BD(), ColcléCombo(), ColClé1, ColClé2, ColClé3, ColClé4

Private Sub ComboBox5_Change()
Sheets("Listedespages").Range("D1").Value = Me.ComboBox5
  ColcléCombo = Array(1, 2, 3, 4, 5)                   ' colonnes des combobox( à adapter)
  Set f = Sheets(Sheets("Listedespages").Range("D1").Value)
  Set d1 = CreateObject("Scripting.Dictionary")
  BD = f.Range("A2:E" & f.[A65000].End(xlUp).Row).Value  ' Array pour rapidité (à adapter)
  ColClé1 = ColcléCombo(0)
  For i = LBound(BD) To UBound(BD): d1(BD(i, ColClé1)) = "": Next
  Me.ComboBox1.List = d1.keys
End Sub

Private Sub ComboBox5_Click()
  Me.ComboBox1.Value = ""
  Me.ComboBox2.Value = ""
  Me.ComboBox3.Value = ""
  Me.ComboBox4.Value = ""
  Me.TextBox1.Value = ""
End Sub

Private Sub UserForm_Initialize()
  Sheets("Listedespages").Range("D1").Value = "BD"
  ColcléCombo = Array(1, 2, 3, 4, 5)                   ' colonnes des combobox( à adapter)
  Set f = Sheets(Sheets("Listedespages").Range("D1").Value)
  Set d1 = CreateObject("Scripting.Dictionary")
  BD = f.Range("A2:E" & f.[A65000].End(xlUp).Row).Value  ' Array pour rapidité (à adapter)
  ColClé1 = ColcléCombo(0)
  For i = LBound(BD) To UBound(BD): d1(BD(i, ColClé1)) = "": Next
  Me.ComboBox1.List = d1.keys
  Me.ComboBox5.List = Sheets("Listedespages").Range("A1:A10").Value
End Sub
Private Sub ComboBox1_click()
  Me.ComboBox2.Clear
  Me.ComboBox3.Clear
  Me.ComboBox4.Clear
  ColClé2 = ColcléCombo(1)
  Set d1 = CreateObject("Scripting.Dictionary")
  For i = LBound(BD) To UBound(BD)
     If BD(i, ColClé1) = Me.ComboBox1 Then d1(BD(i, ColClé2)) = ""
  Next i
  Me.ComboBox2.List = d1.keys
End Sub
Private Sub ComboBox2_click()
  Me.ComboBox3.Clear
  Me.ComboBox4.Clear
  ColClé3 = ColcléCombo(2)
  Set d1 = CreateObject("Scripting.Dictionary")
  For i = LBound(BD) To UBound(BD)
     If BD(i, ColClé1) = Me.ComboBox1 And BD(i, ColClé2) = Me.ComboBox2 Then d1(BD(i, ColClé3)) = ""
  Next i
  Me.ComboBox3.List = d1.keys
End Sub
Private Sub ComboBox3_click()
  Me.ComboBox4.Clear
  ColClé4 = ColcléCombo(3)
  Set d1 = CreateObject("Scripting.Dictionary")
  For i = LBound(BD, 1) To UBound(BD, 1)
    If BD(i, ColClé1) = Me.ComboBox1 And BD(i, ColClé2) = Me.ComboBox2 _
        And BD(i, ColClé3) = Me.ComboBox3 Then d1(BD(i, ColClé4)) = ""
  Next i
  Me.ComboBox4.List = d1.keys
End Sub
Private Sub ComboBox4_click()
  For i = LBound(BD) To UBound(BD)
    If BD(i, ColClé1) = Me.ComboBox1 And BD(i, ColClé2) = Me.ComboBox2 _
        And BD(i, ColClé3) = Me.ComboBox3 And BD(i, ColClé3) = Me.ComboBox3 Then
        Me.TextBox1 = BD(i, ColcléCombo(4))
    End If
  Next i
End Sub

Et merci à vous pour votre aide


ou le fichier plutôt que lien...

Aïe ! Je suis confronté à un nouveau problème, si dans ma liste il y a des chiffres et non des lettres, la cascade de combobox s'arrête

98fichier-modifie.zip (43.69 Ko)
Rechercher des sujets similaires à "cascade combobox userform"