Combobox et ListIndex [Résolu/Fermé]

Signaler
Messages postés
211
Date d'inscription
lundi 5 octobre 2009
Statut
Membre
Dernière intervention
29 août 2018
-
Messages postés
12251
Date d'inscription
jeudi 15 mai 2008
Statut
Modérateur
Dernière intervention
17 mars 2021
-
Bonjour,

J'ai deux questions :
Je suis en train d'initialiser un "user form" et j'ai differents combobox et listbox.

1) Tout d'abord, je souhaite implémenter ma liste de combobox

Pour réaliser une liste sans "doublons" j'ai récupéré un code qui circule sur les forum :



ComboBox1 = Variable_A_Ajouté_N°1
If ComboBox1.ListIndex = -1 Then ComboBox1.AddItem Variable_A_Ajouté_N°1


Dans ce morceau de code j'aimerais comprendre que signifie la ligne
ComboBox1 = Variable_A_Ajouté_N°1

et surtout :
If ComboBox1.ListIndex = -1

???



2) Ensuite, j'ai un problème en exécutant ce bout de code.
J'ai inclus ce petit bout de code dans une boucle pour initialiser ma combobox, et périodiquement, celui-ci vient activer

Private Sub ComboBox1_Click()


Existe-t-il un moyen de désactiver tout "click " sur ma ComboBox1 en attendant que mon premier script soit terminé ??

Merci beaucoup


6 réponses

Messages postés
1412
Date d'inscription
mardi 21 octobre 2014
Statut
Membre
Dernière intervention
9 mars 2021
152
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 :

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
1
Merci

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

CCM 65492 internautes nous ont dit merci ce mois-ci

Messages postés
211
Date d'inscription
lundi 5 octobre 2009
Statut
Membre
Dernière intervention
29 août 2018
1
Hey hey hey !!!
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 :-)
Messages postés
1412
Date d'inscription
mardi 21 octobre 2014
Statut
Membre
Dernière intervention
9 mars 2021
152
Re,

Je suis content pour toi. Tu devrais marquer le fil comme "résolu"...
1
Merci

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

CCM 65492 internautes nous ont dit merci ce mois-ci

Messages postés
1412
Date d'inscription
mardi 21 octobre 2014
Statut
Membre
Dernière intervention
9 mars 2021
152
Re,

Pas besoin de filtrer. Regarde l'exemple ci-dessous :

http://www.cjoint.com/c/EGitkzkIIRR
1
Merci

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

CCM 65492 internautes nous ont dit merci ce mois-ci

Messages postés
211
Date d'inscription
lundi 5 octobre 2009
Statut
Membre
Dernière intervention
29 août 2018
1
Wonderfull !!!
Merci ThauTheme !!
ça marche du feu de dieu !!
Messages postés
211
Date d'inscription
lundi 5 octobre 2009
Statut
Membre
Dernière intervention
29 août 2018
1
Juste une dernière question :-/
C'est quoi la différence entre "_Click()" et "_Change()" ???
Private Sub ComboBox1_Click()
End Sub

et
Private Sub ComboBox1_Change()
End Sub
Messages postés
211
Date d'inscription
lundi 5 octobre 2009
Statut
Membre
Dernière intervention
29 août 2018
1
J'ai bien une dernière vrai question ThauTheme.

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.
Messages postés
211
Date d'inscription
lundi 5 octobre 2009
Statut
Membre
Dernière intervention
29 août 2018
1
:-) 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+

For i = 1 to 1000
Call Msgbox(" MERCI ")
Next i
Messages postés
211
Date d'inscription
lundi 5 octobre 2009
Statut
Membre
Dernière intervention
29 août 2018
1
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
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 :-|
Messages postés
1412
Date d'inscription
mardi 21 octobre 2014
Statut
Membre
Dernière intervention
9 mars 2021
152
Re,

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...
Messages postés
211
Date d'inscription
lundi 5 octobre 2009
Statut
Membre
Dernière intervention
29 août 2018
1
Thank you !
ça marche super bien. Bonne journée et bon WE.
Messages postés
12251
Date d'inscription
jeudi 15 mai 2008
Statut
Modérateur
Dernière intervention
17 mars 2021
2 605
Bonjour vous deux,

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 🎶
Messages postés
211
Date d'inscription
lundi 5 octobre 2009
Statut
Membre
Dernière intervention
29 août 2018
1
Et il est possible d'utiliser le même type de script pour les listbox??
ListBox1 = Variable_A_Ajouté_N°1
If ListBox1.ListIndex = -1 Then ListBox1.AddItem Variable_A_Ajouté_N°1

:-/ J'ai l'impression que non ??
Messages postés
12251
Date d'inscription
jeudi 15 mai 2008
Statut
Modérateur
Dernière intervention
17 mars 2021
2 605 >
Messages postés
211
Date d'inscription
lundi 5 octobre 2009
Statut
Membre
Dernière intervention
29 août 2018

Non.
ListBox1.Value = Variable_A_Ajouté_N°1
va planter.