ComboBox en cascade

Fermé
melissa64 - 21 mars 2015 à 12:06
cs_Le Pivert Messages postés 7904 Date d'inscription jeudi 13 septembre 2007 Statut Contributeur Dernière intervention 14 août 2024 - 23 mars 2015 à 18:01
Bonjour,

J'aimerais faire une combobox en cascade dans un formulaire à partir de données d'une autre feuille. Est-ce possible?
J'ai un bouton "valider" à la fin du formulaire? Par conséquent, est-ce que je dois taper le code pour faire la combobox en cascade dans l'espace dédié au bouton valider?
Je donnerai plus d'information dès que je recevrais une réponse.
Merci d'avance



17 réponses

Boisgontierjacques Messages postés 175 Date d'inscription jeudi 19 septembre 2013 Statut Membre Dernière intervention 26 décembre 2018 64
Modifié par Boisgontierjacques le 21/03/2015 à 12:51
Bonjour,

On répondra lorsqu'on aura plus d'informations et un fichier

http://boisgontierjacques.free.fr/pages_site/formulairecascade.htm

JB
http://boisgontierjacques.free.fr
0
Ok. Donc j'ai créé un formulaire pour faire l'inventaire d'achats d'ingrédients sur une année. Dans ce formulaire, on peut rentrer :
-la date d'achat
-le fournisseur (son numéro)
-l'ingrédient
-la quantité
-le coût du transport
Le fournisseur(numéro) et l'ingrédient sont en combobox.
Il y a un bouton "valider" et un bouton "quitter" la fin.

Sur une autre feuille, j'ai dans un tableau :
-en colonne I le numéro du fournisseur
-en colonne J son ingrédient
Comme un fournisseur peut vendre plusieurs ingrédients, il y a plusieurs fois le même numéro de fournisseur en I.
Aussi, comme un ingrédient peut avoir plusieurs fournisseurs, le même ingrédient peut être répété plusieurs fois en J mais avec des num de fournisseurs en I différents.

Par conséquent, lors d'un achat, j'aimerais pouvoir d'abord choisir le fournisseur dans la 1ère combobox. Puis, dans la 2è combobox, j'aimerais que s'affichent SEULEMENT les ingrédients que ce fournisseur livre.

Jusqu'à présent, je taper la majorité du code dans :Private Sub CmdValider_Click(). J'avais juste une petite partie à part pour le bouton "quitter". J'ai lu plusieurs tutos sur internet à propos des combobox en cascade, mais je n'arrive pas à les adapter à mon cas.

Pouvez-vous m'aider s'il vous plait? J'espère que vous avez pu comprendre même si je sais que mes explications ne sont pas très claires.
0
cs_Le Pivert Messages postés 7904 Date d'inscription jeudi 13 septembre 2007 Statut Contributeur Dernière intervention 14 août 2024 729
21 mars 2015 à 14:07
Bonjour,

Voici un exemple:

http://www.cjoint.com/data3/3CvossSb0GZ.htm
0
Merci pour votre réponse mais je ne parviens toujours pas à coder. De plus, il faudrait d'abord que quand je choisisse mon fournisseur, il ne soit pas proposé plusieurs fois. En effet, vu que dans mon tableau, les fournisseurs apparaissent plusieurs fois, c'est le cas aussi dans la combobox.
Que faire?
J'ai chercher plusieurs astuces sur internet : elles partent toutes de Private Sub Userform_Initialize(). Sauf qu'il n'apparaît nulle part dans mon code et quand je le tape il détecte une erreur de validation des données.
0
Voici mon code actuel :
Private Sub CmdValider_Click()


Dim ctrl As Control, ctrlerr As Control
Dim erreur As Boolean

For Each ctrl In frmAchats.Controls
erreur = False
If TypeOf ctrl Is MSForms.TextBox Then
If ctrl.Text = "" Then
erreur = True
Set ctrlerr = ctrl
Exit For
End If
End If
Next ctrl

If erreur = True Then
MsgBox "Vous n'avez pas rempli toutes les zones"
ctrlerr.SetFocus
Set ctrlerr = Nothing
Else

If txtDateAchat.Value <> "" Then
If Not IsDate(txtDateAchat.Value) Then
MsgBox "Date incorrecte.", vbCritical + vbOKOnly, "Erreur"
txtDateAchat.Value = ""
txtDateAchat.SetFocus
frmAchats.Hide
frmAchats.Show

Else
txtDateAchat.Value = Format(txtDateAchat.Value, "dd/mm/yyyy")
End If
End If




With frmAchats

Dim nblig As Integer
Dim nbcol As Integer
nbcol = 1
nblig = 9
Do Until IsEmpty(Cells(nblig, nbcol))
nblig = nblig + 1
Loop

Dim dernière_ligne As Integer
dernière_ligne = Range("A1").End(xlDown).Row
Dim TabAchats()
ReDim TabAchats(dernière_ligne + 1, 0)

feuille.Range("Achats!A" & nblig).Value = .txtDateAchat.Value
feuille.Range("Achats!B" & nblig).Value = .ComboBoxIngrédientAchat.Value
feuille.Range("Achats!D" & nblig).Value = .txtQuantité.Value
feuille.Range("Achats!E" & nblig).Value = .ComboBoxFournisseur.Value
feuille.Range("Achats!H" & nblig).Value = .txtCoûtTransport.Value

End With
frmAchats.Hide
End If

End Sub
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_Le Pivert Messages postés 7904 Date d'inscription jeudi 13 septembre 2007 Statut Contributeur Dernière intervention 14 août 2024 729
21 mars 2015 à 18:44
Si tu veux avancer, il va te falloir une petite révision en vba:

https://silkyroad.developpez.com/VBA/ControlesUserForm/

https://silkyroad.developpez.com/VBA/UserForm/

On verra ensuite
0
via55 Messages postés 14495 Date d'inscription mercredi 16 janvier 2013 Statut Membre Dernière intervention 7 novembre 2024 2 734
21 mars 2015 à 21:58
Bonsoir à tous

@Melissa
Ce serait plus simple si au lieu de morceaux de codes tu envoyais un fichier complet comme demandé
Ceci dit il te faut 2 macros :
- l'une qui à l'initialisation de l'Userform alimente le 1er combo avec les fournisseurs à partir de la colonne I de ta feuille de donnée (que j'ai nommée BASE dans la macro)
Private Sub UserForm_Initialize()
'*** A INITIALISATION DE UF
'**** ETABLIT LA LISTE DES ITEMS DE COMBOBOX1
    Dim j As Integer
    Dim Ligne As Long
    'derniere ligne rempli en colonne I de BASE
Ligne = Sheets("BASE").Columns(9).Find("*", , , , xlByColumns, xlPrevious).Row
    'Récupère les données de la colonne Ide BASE
    For j = 2 To Ligne 'on commence en ligne 2 car titre
        ComboBox1 = Sheets("BASE").Range("I" & j)
        '...et filtre les doublons
        If ComboBox1.ListIndex = -1 Then ComboBox1.AddItem Sheets("BASE").Range("I" & j)
    Next j
End Sub

- l'autre qui à chaque modification de choix dans le Combobox 1 alimente le 2eme combo avec les ingrédients pris en colonne J si correspondance de fournisseur en colonne I . J'ai adaptée celle de Le Pivert (que je salue au passage) dans ce sens :
Private Sub ComboBox1_Change()
'*** A CHAQUE CHANGEMENT DE CHOIX DANS COMBOBOX1
'*** ETABLIT LA LISTE DES ITEMS DE LA COMBOBOX2
' fournisseur choisi
f = ComboBox1.Value
    NoAction = True
    ComboBox2.Clear
    Dim Ligne As Long
    'derniere ligne rempli en colonne Ide BASE
Ligne = Sheets("BASE").Columns(9).Find("*", , , , xlByColumns, xlPrevious).Row
 'Boucle sur les lignes de BASE
    For i = 2 To Ligne
    ' si fournisseur choisi on ajoute l'ingredient de cette ligne à combobox2
    If Sheets("BASE").Range("I" & i) = f Then
        ComboBox2.AddItem Sheets("BASE").Range("J" & i)
        End If
    Next i
    
    ComboBox2.ListIndex = 0
    SendKeys "^(F4)"
    NoAction = False
  
End Sub


Dans l'editeur VBA Clic droit sur l'Userform dans l'arborescence et Code pour afficher la page où coller les macros (en les adaptant si nécessaire)

Cdlmnt
0
Bonjour,

Merci pour votre dévouement.
J'ai essayé la première partie du code que vous avez posté en l'adaptant à mes données, ce qui donne :

Private Sub UserForm_Initialize()

'*** A INITIALISATION DE UF
'**** ETABLIT LA LISTE DES ITEMS DE COMBOBOX1
Dim j As Integer
Dim Ligne As Long
Dim ComboBoxFournisseur As Object
Ligne = Sheets("Fournisseurs").Columns(9).Find("J4:J" & Range("J10000").End(xlUp).Row)
'Récupère les données de la colonne Ide BASE
For j = 1 To Ligne 'on commence en ligne 1 car titre en J3
ComboBoxFournisseur = Sheets("Fournisseurs").Range("I" & j)
'...et filtre les doublons
If ComboBoxFournisseur.ListIndex = -1 Then ComboBoxFournisseur.AddItem Sheets("Fournisseurs").Range("I" & j)
Next j

End Sub


MAIS il y a un problème : lorsque j'exécute, un message d'erreur s'affiche : "Erreur d'exécution '91': Variable objet ou variable de bloc With non définie". Je n'arrive pas à trouver ce qu'il manque dans le code, pouvez-vous m'aider ?
0
cs_Le Pivert Messages postés 7904 Date d'inscription jeudi 13 septembre 2007 Statut Contributeur Dernière intervention 14 août 2024 729
22 mars 2015 à 14:43
Tu n'as pas bien recopier l'exemple de via 55. Ce n'est quand même pas trop compliqué!

Private Sub UserForm_Initialize()
Dim j As Integer
 Dim Ligne As Long
   'derniere ligne rempli en colonne I de Fournisseurs
Ligne = Sheets("Fournisseurs").Columns(9).Find("*", , , , xlByColumns, xlPrevious).Row
 'Boucle sur les lignes de Fournisseurs
For j = 2 To Ligne 'on commence en ligne 2 car titre en I1
 ComboBoxFournisseur = Sheets("Fournisseurs").Range("I" & j)
 '...et filtre les doublons
 If ComboBoxFournisseur.ListIndex = -1 Then ComboBoxFournisseur.AddItem Sheets("Fournisseurs").Range("I" & j)
 Next j
 ComboBoxFournisseur.ListIndex = 0
End Sub


On attend la suite!
0
Avec votre code, ça affiche : "erreur d'exécution '70':accès refusé"...
0
Non c'est bon! merci beaucoup, ça marche pour la première partie ! je vais tester la deuxième partie du code. Seulement, pour la première partie, j'aimerai rajouter une condition : ne pas prendre la case lorsqu'il y a marqué "Nom et Prénom"(titre de la colonne), mais aussi lorsqu'il y a marqué "Fournisseur inexistant". Est-il possible de rajouter du code pour ça ? Merci d'avance !!
0
cs_Le Pivert Messages postés 7904 Date d'inscription jeudi 13 septembre 2007 Statut Contributeur Dernière intervention 14 août 2024 729
22 mars 2015 à 19:01
Pour supprimer les 2 items:

Option Explicit
Private Sub deleteitem(monnom As String)
Dim i As Integer
Dim nom As String
 For i = 0 To ComboBoxFournisseur.ListCount - 1
  nom = ComboBoxFournisseur.List(i)
If nom = monnom Then
 ComboBoxFournisseur.removeitem (i)
Exit Sub
End If
    Next i
End Sub
Private Sub UserForm_Initialize()
Dim j As Integer
 Dim Ligne As Long
   'derniere ligne rempli en colonne I de Fournisseurs
Ligne = Sheets("Fournisseurs").Columns(9).Find("*", , , , xlByColumns, xlPrevious).Row
 'Boucle sur les lignes de Fournisseurs
For j = 2 To Ligne 'on commence en ligne 2 car titre en I1
 ComboBoxFournisseur = Sheets("Fournisseurs").Range("I" & j)
 '...et filtre les doublons
 If ComboBoxFournisseur.ListIndex = -1 Then ComboBoxFournisseur.AddItem Sheets("Fournisseurs").Range("I" & j)
 Next j
 ComboBoxFournisseur.ListIndex = 0
 deleteitem ("Fournisseur inexistant")
deleteitem ("Nom et Prénom")
End Sub

0
Trop cool ça marche! Vous êtes un génie!
Par contre, la 2ème partie du code ne fonctionne pas. J'ai essayé avec votre code, ça ne fonctionnait pas. Du coup, je l'ai modifié comme ceci :

Private Sub ComboBoxFournisseur_Change()

'*** A CHAQUE CHANGEMENT DE CHOIX DANS COMBOBOX1
'*** ETABLIT LA LISTE DES ITEMS DE LA COMBOBOX2
' fournisseur choisi

Dim f
Dim i As Integer
Dim NoAction As Action

f = ComboBoxFournisseur.Value
NoAction = True
ComboBoxIngrédientAchat.Clear

Dim Ligne As Long
'derniere ligne rempli en colonne Ide BASE
Ligne = Sheets("Fournisseurs").Columns(10).Find("*", , , , xlByColumns, xlPrevious).Row
'Boucle sur les lignes de BASE
For i = 4 To Ligne
' si fournisseur choisi on ajoute l'ingredient de cette ligne à combobox2
If Sheets("Fournisseurs").Range("J" & i) = f Then
ComboBoxIngrédientAchat.AddItem Sheets("Fournisseurs").Range("K" & i)
End If
Next i

ComboBoxIngrédientAchat.ListIndex = 0
SendKeys "^(F4)"
NoAction = False

End Sub

mais il y a un problème au niveau de "NoAction=True)
0
cs_Le Pivert Messages postés 7904 Date d'inscription jeudi 13 septembre 2007 Statut Contributeur Dernière intervention 14 août 2024 729
23 mars 2015 à 08:03
Il faudrait quand même connaître les bases. La déclaration des variables.
NoAction = True
Quand une variable renvoie True ou False, c'est une variable Booleenne, il faut donc la déclarer en tant que tel. Et non pas la déclarer avec un nom fantaisiste:
Dim NoAction As Action

Un petit rappel:

https://silkyroad.developpez.com/VBA/LesVariables/
0
J'ai remplacé le code par:

Private Sub ComboBoxFournisseur_Change()

'*** A CHAQUE CHANGEMENT DE CHOIX DANS COMBOBOX1
'*** ETABLIT LA LISTE DES ITEMS DE LA COMBOBOX2
' fournisseur choisi

Dim f
Dim i As Integer
Dim NoAction As Boolean

f = ComboBoxFournisseur.Value
NoAction = True
ComboBoxIngrédientAchat.Clear

Dim Ligne As Long
'derniere ligne rempli en colonne Ide BASE
Ligne = Sheets("Fournisseurs").Columns(10).Find("*", , , , xlByColumns, xlPrevious).Row
'Boucle sur les lignes de BASE
For i = 4 To Ligne
' si fournisseur choisi on ajoute l'ingredient de cette ligne à combobox2
If Sheets("Fournisseurs").Range("J" & i) = f Then
ComboBoxIngrédientAchat.AddItem Sheets("Fournisseurs").Range("K" & i)
End If
Next i

ComboBoxIngrédientAchat.ListIndex = 0
SendKeys "^(F4)"
NoAction = False


End Sub

Mais il y a maintenant un problème au niveau de ComboBoxIngrédientAchat.Clear. Je reçois un message "erreur non répertoriée".
0
cs_Le Pivert Messages postés 7904 Date d'inscription jeudi 13 septembre 2007 Statut Contributeur Dernière intervention 14 août 2024 729
23 mars 2015 à 13:19
As-tu sur ton UserForm une comboBox nommée ComboBoxIngrédientAchat?

Attention aux accents.

Regarde l'exemple que je t'ai envoyé sur c-joint. En respectant les données dans les colonnes, tu arriveras à faire ce que tu veux. Il suffit de suivre, il y a très peu de code. Analyse bien cet exemple.

Avec ce code tu ajoutes un item seulement, je ne pense pas que ce soit ce que tu veux!
0
Ca ne fonctionne toujours pas. Mais tant pis. Merci beaucoup pour votre aide.
0
via55 Messages postés 14495 Date d'inscription mercredi 16 janvier 2013 Statut Membre Dernière intervention 7 novembre 2024 2 734
23 mars 2015 à 17:45
Bonjour

On t'as déjà demandé plusieurs fois de poster un exemple de ton fichier, tant qu'on ne l'aura pas on ne pourra pas t'aider plus !

Cdlmnt
0
cs_Le Pivert Messages postés 7904 Date d'inscription jeudi 13 septembre 2007 Statut Contributeur Dernière intervention 14 août 2024 729
23 mars 2015 à 18:01
Voilà un exemple adapter à ta feuille et tes combobox, il te suffit de changer les données:

http://www.cjoint.com/data3/3Cxsmrp1UDh.htm
0