Combobox et ListIndex

Résolu/Fermé
wire less Messages postés 210 Date d'inscription lundi 5 octobre 2009 Statut Membre Dernière intervention 29 août 2018 - 7 juil. 2015 à 17:14
pijaku Messages postés 12263 Date d'inscription jeudi 15 mai 2008 Statut Modérateur Dernière intervention 4 janvier 2024 - 17 juil. 2015 à 19:39
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


A voir également:

6 réponses

ThauTheme Messages postés 1442 Date d'inscription mardi 21 octobre 2014 Statut Membre Dernière intervention 29 juillet 2022 160
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 :

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
wire less Messages postés 210 Date d'inscription lundi 5 octobre 2009 Statut Membre Dernière intervention 29 août 2018 5
8 juil. 2015 à 16:15
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 :-)
0
ThauTheme Messages postés 1442 Date d'inscription mardi 21 octobre 2014 Statut Membre Dernière intervention 29 juillet 2022 160
8 juil. 2015 à 16:41
Re,

Je suis content pour toi. Tu devrais marquer le fil comme "résolu"...
1
ThauTheme Messages postés 1442 Date d'inscription mardi 21 octobre 2014 Statut Membre Dernière intervention 29 juillet 2022 160
8 juil. 2015 à 21:11
Re,

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

http://www.cjoint.com/c/EGitkzkIIRR
1
wire less Messages postés 210 Date d'inscription lundi 5 octobre 2009 Statut Membre Dernière intervention 29 août 2018 5
8 juil. 2015 à 22:49
Wonderfull !!!
Merci ThauTheme !!
ça marche du feu de dieu !!
0
wire less Messages postés 210 Date d'inscription lundi 5 octobre 2009 Statut Membre Dernière intervention 29 août 2018 5
9 juil. 2015 à 10:29
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
0
wire less Messages postés 210 Date d'inscription lundi 5 octobre 2009 Statut Membre Dernière intervention 29 août 2018 5
9 juil. 2015 à 17:58
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.
0
wire less Messages postés 210 Date d'inscription lundi 5 octobre 2009 Statut Membre Dernière intervention 29 août 2018 5
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+

For i = 1 to 1000
Call Msgbox(" MERCI ")
Next i
0
wire less Messages postés 210 Date d'inscription lundi 5 octobre 2009 Statut Membre Dernière intervention 29 août 2018 5
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
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 :-|
0

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

Posez votre question
ThauTheme Messages postés 1442 Date d'inscription mardi 21 octobre 2014 Statut Membre Dernière intervention 29 juillet 2022 160
10 juil. 2015 à 00:37
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...
0
wire less Messages postés 210 Date d'inscription lundi 5 octobre 2009 Statut Membre Dernière intervention 29 août 2018 5
Modifié par wire less le 10/07/2015 à 10:41
Thank you !
ça marche super bien. Bonne journée et bon WE.
0
pijaku Messages postés 12263 Date d'inscription jeudi 15 mai 2008 Statut Modérateur Dernière intervention 4 janvier 2024 2 743
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 :
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 🎶
0
wire less Messages postés 210 Date d'inscription lundi 5 octobre 2009 Statut Membre Dernière intervention 29 août 2018 5
17 juil. 2015 à 18:17
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 ??
0
pijaku Messages postés 12263 Date d'inscription jeudi 15 mai 2008 Statut Modérateur Dernière intervention 4 janvier 2024 2 743 > wire less Messages postés 210 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.
0