Combobox et ListIndex
Résolu/Fermé
wire less
pijaku
- Messages postés
- 211
- Date d'inscription
- lundi 5 octobre 2009
- Statut
- Membre
- Dernière intervention
- 29 août 2018
pijaku
- Messages postés
- 12257
- Date d'inscription
- jeudi 15 mai 2008
- Statut
- Modérateur
- Dernière intervention
- 3 septembre 2021
A voir également:
- Combobox listindex
- Listindex vba - Meilleures réponses
- Vba combobox listindex - Meilleures réponses
- Vba combobox listindex ✓ - Forum - VB / VBA
- Selectionner un item dans une combobox ✓ - Forum - VB / VBA
- ListIndex d'une combobox ? ✓ - Forum - VB / VBA
- Récupérer la ligne d'une valeur dans combobox ✓ - Forum - Programmation
- Utilisation de listindex ✓ - Forum - Excel
6 réponses
ThauTheme
7 juil. 2015 à 19:12
- Messages postés
- 1436
- Date d'inscription
- mardi 21 octobre 2014
- Statut
- Membre
- Dernière intervention
- 27 avril 2022
7 juil. 2015 à 19:12
Bonjour Wireless, bonjour le forum,
la méthode la plus rapide pour alimenter une ListBox/ComboBox sans doublons est l'utilisation d'un dictionnaire. Généralement cette alimentation se fait via l'initialisation de l'UserForm qui la contient.
Regarde l'exemple commenté ci-dessous :
L'utilisation d'une variable "Tableau de cellules" est bien plus rapide que de parcourir réellement les cellules d'un tableau. Cela accroît aussi considérablement l'exécution du code...
http://www.cjoint.com/c/EGhrkgxVzeR
la méthode la plus rapide pour alimenter une ListBox/ComboBox sans doublons est l'utilisation d'un dictionnaire. Généralement cette alimentation se fait via l'initialisation de l'UserForm qui la contient.
Regarde l'exemple commenté ci-dessous :
Private O As Worksheet 'déclare la variable O (Onglet) Private TC As Variant 'déclare la variable TC (Tableau de Cellules) Private Sub UserForm_Initialize() 'à l'initialisation de l'UserForm Dim I As Long 'déclare la variable I (Incrément) Dim D As Object 'déclare la variable D (Dictionnaire) Set O = Sheets("Feuil1") 'définit l'onglet O TC = O.Range("A1").CurrentRegion 'définit le tableau de cellules TC Set D = CreateObject("Scripting.Dictionary") 'définit le dictionanire D For I = 2 To UBound(TC, 1) 'boucle sur toutes les lignes I du tableau de cellules TC (en partant de la seconde) D(TC(I, 1)) = "" 'alimente le dictionnaire D Next I 'prochaine ligne de la boucle Me.ComboBox1.List = D.keys 'alimente la Combobox1 avec la liste des éléments du dictionnaire D sans doublons End Sub
L'utilisation d'une variable "Tableau de cellules" est bien plus rapide que de parcourir réellement les cellules d'un tableau. Cela accroît aussi considérablement l'exécution du code...
http://www.cjoint.com/c/EGhrkgxVzeR
ThauTheme
8 juil. 2015 à 16:41
- Messages postés
- 1436
- Date d'inscription
- mardi 21 octobre 2014
- Statut
- Membre
- Dernière intervention
- 27 avril 2022
8 juil. 2015 à 16:41
Re,
Je suis content pour toi. Tu devrais marquer le fil comme "résolu"...
Je suis content pour toi. Tu devrais marquer le fil comme "résolu"...
ThauTheme
8 juil. 2015 à 21:11
- Messages postés
- 1436
- Date d'inscription
- mardi 21 octobre 2014
- Statut
- Membre
- Dernière intervention
- 27 avril 2022
8 juil. 2015 à 21:11
Re,
Pas besoin de filtrer. Regarde l'exemple ci-dessous :
http://www.cjoint.com/c/EGitkzkIIRR
Pas besoin de filtrer. Regarde l'exemple ci-dessous :
http://www.cjoint.com/c/EGitkzkIIRR
wire less
8 juil. 2015 à 22:49
- Messages postés
- 211
- Date d'inscription
- lundi 5 octobre 2009
- Statut
- Membre
- Dernière intervention
- 29 août 2018
8 juil. 2015 à 22:49
Wonderfull !!!
Merci ThauTheme !!
ça marche du feu de dieu !!
Merci ThauTheme !!
ça marche du feu de dieu !!
wire less
9 juil. 2015 à 10:29
- Messages postés
- 211
- Date d'inscription
- lundi 5 octobre 2009
- Statut
- Membre
- Dernière intervention
- 29 août 2018
9 juil. 2015 à 10:29
Juste une dernière question :-/
C'est quoi la différence entre "_Click()" et "_Change()" ???
et
C'est quoi la différence entre "_Click()" et "_Change()" ???
Private Sub ComboBox1_Click() End Sub
et
Private Sub ComboBox1_Change() End Sub
wire less
9 juil. 2015 à 17:58
- Messages postés
- 211
- Date d'inscription
- lundi 5 octobre 2009
- Statut
- Membre
- Dernière intervention
- 29 août 2018
9 juil. 2015 à 17:58
J'ai bien une dernière vrai question ThauTheme.
J'ai un gros problème avec mes tests :
Premier test :
If TC(I, 1) = Me.ComboBox1.Value ... ' Ok tout marche bien. J'ai bien 'Toto' = 'Toto' ...
Second Test :
If TC(I, 2) = Me.ComboBox2.Value ... ' Cette fois j'ai 1 =/= "1" ... et là je suis vraiment embêté !
J'ai essayé de définir ma variable TC As String pour imposer un "1" = "1" mais alors VBA ne reconnait plus TC comme un tableau !!
Aurais-tu une idée ???
Merci.
Private TC As Variant 'déclare la variable TC (Tableau de Cellules) For I = 2 To UBound(TC, 1) 'boucle sur toutes les lignes I du tableau de cellules TC (en partant de la seconde) If TC(I, 1) = Me.ComboBox1.Value And TC(I, 2) = Me.ComboBox2.Value Then D(TC(I, 3)) = "" 'alimente le dictionnaire D Next I 'prochaine ligne de la boucle
J'ai un gros problème avec mes tests :
Premier test :
If TC(I, 1) = Me.ComboBox1.Value ... ' Ok tout marche bien. J'ai bien 'Toto' = 'Toto' ...
Second Test :
If TC(I, 2) = Me.ComboBox2.Value ... ' Cette fois j'ai 1 =/= "1" ... et là je suis vraiment embêté !
J'ai essayé de définir ma variable TC As String pour imposer un "1" = "1" mais alors VBA ne reconnait plus TC comme un tableau !!
Aurais-tu une idée ???
Merci.
wire less
8 juil. 2015 à 17:49
- Messages postés
- 211
- Date d'inscription
- lundi 5 octobre 2009
- Statut
- Membre
- Dernière intervention
- 29 août 2018
8 juil. 2015 à 17:49
:-) Je sais ... je sais ... Mais j'attendais encore un peu de voir s'il ne me restait pas un problème caché quelques part ... :-p
Merci encore.
A+
Merci encore.
A+
For i = 1 to 1000 Call Msgbox(" MERCI ") Next i
wire less
8 juil. 2015 à 18:20
- Messages postés
- 211
- Date d'inscription
- lundi 5 octobre 2009
- Statut
- Membre
- Dernière intervention
- 29 août 2018
8 juil. 2015 à 18:20
Hey hey !! :-/
J'ai bien une autre question ...
Je vais essayer de faire court et clair ...
J'aimerais utiliser mes combobox avec la fonction Autofilter de Excel...
Ainsi
J'ai une Combobox1 associé au dictionnaire d'une colonne 1
une Combobox2 associé au dictionnaire d'une colonne 2
une Combobox3 associé au dictionnaire d'une colonne 3
Ainsi, après avoir cliqué sur ma Combobox1, je fais un
Je réinitialise mes combobox1&2&3 , et j'aimerais que mes combobox2&3 aient pris en compte que des éléments on étaient filtré ...
comment faire :-/ ??
Merci :-|
J'ai bien une autre question ...
Je vais essayer de faire court et clair ...
J'aimerais utiliser mes combobox avec la fonction Autofilter de Excel...
Ainsi
J'ai une Combobox1 associé au dictionnaire d'une colonne 1
une Combobox2 associé au dictionnaire d'une colonne 2
une Combobox3 associé au dictionnaire d'une colonne 3
Ainsi, après avoir cliqué sur ma Combobox1, je fais un
Sheets("Ma_feuille").Range("A1").CurrentRegion.AutoFilter Field:=1, Criteria1:=ComboBox1.Value
Je réinitialise mes combobox1&2&3 , et j'aimerais que mes combobox2&3 aient pris en compte que des éléments on étaient filtré ...
comment faire :-/ ??
Merci :-|
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
ThauTheme
10 juil. 2015 à 00:37
- Messages postés
- 1436
- Date d'inscription
- mardi 21 octobre 2014
- Statut
- Membre
- Dernière intervention
- 27 avril 2022
10 juil. 2015 à 00:37
Re,
Oui tu as raison, c'est de ma faute il faut convertir les valeurs en String :
Mais laisse la variable TC de type Variant !
Pour ta question au-dessus, regarde l'aide VBA...
Oui tu as raison, c'est de ma faute il faut convertir les valeurs en String :
If CStr(TC(I, 1)) = Me.Combobox1.Value If Cstr(TC(I, 2)) = Me.ComboBox2.Value
Mais laisse la variable TC de type Variant !
Pour ta question au-dessus, regarde l'aide VBA...
wire less
Modifié par wire less le 10/07/2015 à 10:41
- Messages postés
- 211
- Date d'inscription
- lundi 5 octobre 2009
- Statut
- Membre
- Dernière intervention
- 29 août 2018
Modifié par wire less le 10/07/2015 à 10:41
Thank you !
ça marche super bien. Bonne journée et bon WE.
ça marche super bien. Bonne journée et bon WE.
pijaku
Modifié par pijaku le 17/07/2015 à 15:41
- Messages postés
- 12257
- Date d'inscription
- jeudi 15 mai 2008
- Statut
- Modérateur
- Dernière intervention
- 3 septembre 2021
Modifié par pijaku le 17/07/2015 à 15:41
Bonjour vous deux,
Je vais essayer de répondre aux questions de wire less.
1- que fait ce code :
Une ComboBox est un "mix" entre le textbox et la listbox. Il s'agit d'une liste dans laquelle on peut y saisir ce que l'on veut.
Donc, la ligne :
Que se passe t'il lors de la saisie "manuelle", d'une valeur dans une ComboBox?
Tout simplement, si la valeur saisie fait déjà partie de la ComboBox.List, alors elle est sélectionnée. Ceci à pour conséquence de changer la propriété ListIndex par la valeur de l'index de la valeur saisie.
Si elle n'en fait pas partie, il ne se passe rien, tu l'as saisi c'est tout.
C'est tout? Et bien en fait non. Si la valeur saisie ne fait pas partie de la ComboBox.List, la propriété ListIndex reste sur -1 (le premier index des ComboBox non vide étant 0).
Donc, le code ci-dessus :
Si le ListIndex est toujours à -1, cela veut dire que la valeur saisie ne fait pas encore partie de ComboBox.List, donc... Tu peut l'ajouter avec .AddItem...
2- Existe-t-il un moyen de désactiver les événements d'un USerForm?
Oui, à l'aide d'une variable publique de type boolean.
Un petit test que tu reconnaitras ;-)
En mode pas à pas, tu verras l'entrée et la sortie de la Private Sub _Change()
3-C'est quoi la différence entre "_Click()" et "_Change()"?
Click est l'événement qui se produit lorsque tu cliques sur la ComboBox.
Change est l'événement qui se produit lorsque tu saisis dans ta ComboBox.
Lors d'un clic, l'événement Change se produit, si la valeur de la combobox change...
Lors d'un changement via une saisie manuelle dans une combobox, Click ne se déclenche pas.
Ceci pose le vrai problème, la vraie question : dois-je permettre la saisie de valeur dans ma ComboBox?
Bien souvent la réponse est non, mais le développeur n'a pas pensé à cet état de fait : l'utilisateur peut-être un imbécile.
Si l'utilisateur saisi n'importe nawak dans le ComboBox, cela peut planter l'outil.
Pour pallier à cela, il suffit d'empêcher la saisie de valeur non inclues dans ComboBox.List.
Comment faire?
Tout simplement penser à régler la propriété .Style de la ComboBox sur : 2 (fmStyleDropDownList)
Un exemple basé sur le code ci-dessus :
ps : je vais le répéter ici, mais c'est important, il n'est nul besoin de variables aussi gourmandes que l'objet dictionary pour remplir une ComboBox.
A++
🎼 Cordialement,
Franck 🎶
Je vais essayer de répondre aux questions de wire less.
1- que fait ce code :
ComboBox1 = Variable_A_Ajouté_N°1 If ComboBox1.ListIndex = -1 Then ComboBox1.AddItem Variable_A_Ajouté_N°1
Une ComboBox est un "mix" entre le textbox et la listbox. Il s'agit d'une liste dans laquelle on peut y saisir ce que l'on veut.
Donc, la ligne :
ComboBox1 = Variable_A_Ajouté_N°1(sous-entendu :
ComboBox1.Value = Variable_A_Ajouté_N°1) ne fait que saisir, dans la combobox, le contenu de la variable Variable_A_Ajouté_N°1.
Que se passe t'il lors de la saisie "manuelle", d'une valeur dans une ComboBox?
Tout simplement, si la valeur saisie fait déjà partie de la ComboBox.List, alors elle est sélectionnée. Ceci à pour conséquence de changer la propriété ListIndex par la valeur de l'index de la valeur saisie.
Si elle n'en fait pas partie, il ne se passe rien, tu l'as saisi c'est tout.
C'est tout? Et bien en fait non. Si la valeur saisie ne fait pas partie de la ComboBox.List, la propriété ListIndex reste sur -1 (le premier index des ComboBox non vide étant 0).
Donc, le code ci-dessus :
- saisie ta variable dans la combobox
- teste le ListIndex de ta combobox.
Si le ListIndex est toujours à -1, cela veut dire que la valeur saisie ne fait pas encore partie de ComboBox.List, donc... Tu peut l'ajouter avec .AddItem...
2- Existe-t-il un moyen de désactiver les événements d'un USerForm?
Oui, à l'aide d'une variable publique de type boolean.
Un petit test que tu reconnaitras ;-)
En mode pas à pas, tu verras l'entrée et la sortie de la Private Sub _Change()
Public Evenements_Actifs As Boolean Private Sub ComboBox1_Change() If Me.Evenements_Actifs = False Then Exit Sub MsgBox "Change" End Sub Private Sub ComboBox1_Click() MsgBox "Clic" End Sub Private Sub UserForm_Initialize() Dim TABLEAU As Variant, I As Long TABLEAU = Sheets("Feuil1").Range("A2:A6") Call Tri(TABLEAU, LBound(TABLEAU), UBound(TABLEAU)) Me.Evenements_Actifs = False For I = 1 To UBound(TABLEAU, 1) ComboBox1.Value = TABLEAU(I, 1) 'on évite les doublons If ComboBox1.ListIndex = -1 Then ComboBox1.AddItem TABLEAU(I, 1) Next I Me.Evenements_Actifs = True End Sub Sub Tri(a, gauc, droi) ' Quick sort Dim ref, g, d, tmp 'Comme remplissage du tableau initial par l'objet Range 'il convient d'ajouter la dimension ( , 1) sous peine d'erreur 9 ref = a((gauc + droi) \ 2, 1) g = gauc: d = droi Do Do While a(g, 1) < ref: g = g + 1: Loop Do While ref < a(d, 1): d = d - 1: Loop If g <= d Then tmp = a(g, 1): a(g, 1) = a(d, 1): a(d, 1) = tmp g = g + 1: d = d - 1 End If Loop While g <= d If g < droi Then Call Tri(a, g, droi) If gauc < d Then Call Tri(a, gauc, d) End Sub
3-C'est quoi la différence entre "_Click()" et "_Change()"?
Click est l'événement qui se produit lorsque tu cliques sur la ComboBox.
Change est l'événement qui se produit lorsque tu saisis dans ta ComboBox.
Lors d'un clic, l'événement Change se produit, si la valeur de la combobox change...
Lors d'un changement via une saisie manuelle dans une combobox, Click ne se déclenche pas.
Ceci pose le vrai problème, la vraie question : dois-je permettre la saisie de valeur dans ma ComboBox?
Bien souvent la réponse est non, mais le développeur n'a pas pensé à cet état de fait : l'utilisateur peut-être un imbécile.
Si l'utilisateur saisi n'importe nawak dans le ComboBox, cela peut planter l'outil.
Pour pallier à cela, il suffit d'empêcher la saisie de valeur non inclues dans ComboBox.List.
Comment faire?
Tout simplement penser à régler la propriété .Style de la ComboBox sur : 2 (fmStyleDropDownList)
Un exemple basé sur le code ci-dessus :
Public Evenements_Actifs As Boolean Private Sub ComboBox1_Change() If Me.Evenements_Actifs = False Then Exit Sub MsgBox "Change" End Sub Private Sub ComboBox1_Click() MsgBox "Clic" End Sub Private Sub UserForm_Initialize() Dim TABLEAU As Variant, I As Long TABLEAU = Sheets("Feuil1").Range("A2:A6") Call Tri(TABLEAU, LBound(TABLEAU), UBound(TABLEAU)) Me.ComboBox1.Style = fmStyleDropDownCombo ' ====> Sinon problème : saisie impossible Me.Evenements_Actifs = False For I = 1 To UBound(TABLEAU, 1) ComboBox1.Value = TABLEAU(I, 1) ' ===> Or ICI on a une saisie !!! 'on évite les doublons If ComboBox1.ListIndex = -1 Then ComboBox1.AddItem TABLEAU(I, 1) Next I Me.Evenements_Actifs = True Me.ComboBox1.Style = fmStyleDropDownList ' ====> Saisie de n'importe nawak impossible End Sub Sub Tri(a, gauc, droi) ' Quick sort Dim ref, g, d, tmp 'Comme remplissage du tableau initial par l'objet Range 'il convient d'ajouter la dimension ( , 1) sous peine d'erreur 9 ref = a((gauc + droi) \ 2, 1) g = gauc: d = droi Do Do While a(g, 1) < ref: g = g + 1: Loop Do While ref < a(d, 1): d = d - 1: Loop If g <= d Then tmp = a(g, 1): a(g, 1) = a(d, 1): a(d, 1) = tmp g = g + 1: d = d - 1 End If Loop While g <= d If g < droi Then Call Tri(a, g, droi) If gauc < d Then Call Tri(a, gauc, d) End Sub
ps : je vais le répéter ici, mais c'est important, il n'est nul besoin de variables aussi gourmandes que l'objet dictionary pour remplir une ComboBox.
A++
🎼 Cordialement,
Franck 🎶
wire less
17 juil. 2015 à 18:17
- Messages postés
- 211
- Date d'inscription
- lundi 5 octobre 2009
- Statut
- Membre
- Dernière intervention
- 29 août 2018
17 juil. 2015 à 18:17
Et il est possible d'utiliser le même type de script pour les listbox??
:-/ J'ai l'impression que non ??
ListBox1 = Variable_A_Ajouté_N°1 If ListBox1.ListIndex = -1 Then ListBox1.AddItem Variable_A_Ajouté_N°1
:-/ J'ai l'impression que non ??
pijaku
17 juil. 2015 à 19:39
- Messages postés
- 12257
- Date d'inscription
- jeudi 15 mai 2008
- Statut
- Modérateur
- Dernière intervention
- 3 septembre 2021
- Messages postés
- 211
- Date d'inscription
- lundi 5 octobre 2009
- Statut
- Membre
- Dernière intervention
- 29 août 2018
17 juil. 2015 à 19:39
Non.
ListBox1.Value = Variable_A_Ajouté_N°1
va planter.
ListBox1.Value = Variable_A_Ajouté_N°1
va planter.
8 juil. 2015 à 16:15
ThauTheme :-/ !!!
Ton code marche super bien !! Et en plus, plus de problèmes de déclenchement de "Private Sub ComboBox1_Click()" Intempestif :-D et ça aussi c'est super bien !!
Merci :-)