A voir également:
- Dumoria n'est pas sous cascade
- Liste déroulante en cascade - Guide
- Cascade windows 11 - Guide
- Liste déroulante en cascade google sheet ✓ - Forum Google Docs
- Problème listes déroulantes en cascade sur Google sheet qui se deploient - Forum Bureautique
- Cascade pokemon platine ✓ - Forum Jeux vidéo
17 réponses
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
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
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.
-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.
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.
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.
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
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
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
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
https://silkyroad.developpez.com/VBA/ControlesUserForm/
https://silkyroad.developpez.com/VBA/UserForm/
On verra ensuite
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)
- 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 :
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
@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
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 ?
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 ?
Tu n'as pas bien recopier l'exemple de via 55. Ce n'est quand même pas trop compliqué!
On attend la suite!
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!
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 !!
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
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)
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)
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/
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/
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".
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".
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!
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!