Bonjour à tous,
J'ai un souci : dans le cadre d'un userform, j'ai une procédure (Initialize) utilisant une collection pour ne charger que des occurences uniques dans une listbox comme il se devrait.
Ca marche dans d'autres procédures de mes projets, d'ailleurs.
Mais là, la collection ne fait pas le ménage. Pourriez vous me dire pourquoi ?
Je vous joint 2 codes : l'un simplifié pour test simple (La Liste contient six fois la valeur 6 et la collection contient six fois la valeur 6.
Code:
Dim i As Byte
Dim Unique As Collection
Dim Liste(6)
Set Unique = New Collection
For i = 1 To 6
Liste(i) = 6
Next i
For i = 1 To 6
Unique.Add Liste(i)
Next i
For Each Valeur In Unique
Debug.Print Valeur
Next Valeur
L'autre est celui de mon UF, où SaisieCommercial est un UF, LotsDispo2 une ListBox multiselect de 27 colonnes.
La première colonne peut comporter plusieurs fois le même numéro.
Dans cette procédure, le but est de récupérer les occurences uniques des listes sélectionnées pour pouvoir les manipuler dans d'autres listbox.
Code:
Dim i As Byte
Dim LotRegroupt As Integer
Dim Tablo() As Byte
Dim Unique As Collection
For i = 0 To SaisieCommercial.LotsDispo2.ListCount - 1
If SaisieCommercial.LotsDispo2.Selected(i) = True Then
LotRegroupt = SaisieCommercial.LotsDispo2.List(i)
Unique.Add SaisieCommercial.LotsDispo2.List(i)
End If
Next i
For Each Valeur In Unique
Debug.Print Valeur
Next Valeur
Mais aucun des deux ne livre de résultat unique. Dans le cas réel si je sélectionne deux lignes dont le contenu d"e la première colonne est le même, la collection contient deux fois ce nombre.
J'ai même envisagé que ma listbox initiale, étant multicolonnes, le problème venait du fait que la valeur était considérée comme différente à chaque fois car les autres colonnes sont différentes, bien que la valeur que je présente à la collection n'est qu'un nombre. D'où mon essai plus simple ci-dessus.
Où est l'erreur ?
Te dire ce qui ne vas pas, il y a tellement longtemps que je n'utilise plus les Collections pour les doublons... Il me semble qu'il manque une clé...
En revanche, je te conseille d'utiliser plutôt la méthode avec un objet Dictionary qui est beaucoup plus rapide qu'avec une Collection. Ton exemple simplifié avec cette méthode :
Regarde l'excellent travail à ce sujet de jacques Boisgontier ICI.
VB:
Sub Macro1()
Dim i As Byte
Dim D As Object
Dim Liste(6)
Dim TMP As Variant
Set D = CreateObject("Scripting.Dictionary")
For i = 1 To 6
Liste(i) = 6
Next i
For i = 1 To 6
D(Liste(i)) = ""
Next i
TMP = D.Keys
For i = 0 To UBound(TMP)
Debug.Print TMP(i)
Next i
End Sub
Bonsoir Robert,
J'ai toujours aimé ton cerveau de la taille d'un pois chiche (Nota : c'est toi même qui le disait à l'époque !) mais qui sait prodiguer des conseils de poids sans que ce soit chiche...
Merci du conseil, je vais regarder ça.
Mais si quelqu'un a une idée sur la collection.
Je ne pense pas qu'il manque une clé, car celles ci sont toutes facultatives, sauf erreur....
Et pourtant avec une clef (comme Robert l'avais suggéré) ...
VB:
Sub test()
Dim i As Long, Unique As Collection, Liste(6)
Set Unique = New Collection
For i = 1 To 6: Liste(i) = i: Next i
On Error Resume Next
For i = 1 To 6: Unique.Add Range("a" & i), CStr(Liste(i)): Next i
On Error GoTo 0
For Each Valeur In Unique: Debug.Print Valeur: Next Valeur
End Sub
Bonjour à tous,
et merci pour vos propositions.
Soit je suis complètement à la masse, soit je suis fatigué (c'est mieux pour l'ego...) mais :
-je ne comprends rien au post de Robert et au tuto de Jacques Boisgontier. J'ai un plus petit cerveau que Robert
-Pour mapomme, je dois être mûr car je ne vois pas comment cela règle mon problème : Mes données ne sont pas dans des cellules de feuille et si j'applique ta macro il ne se passe rien ou plutôt cela affiche 6 résultats "".
Reproduction partielle de l'aide en ligne sur les collections qui précise bien que la clé est facultative. Mais il est vrai qu'il n'est pas indiqué qu'avec ou sans clé on obtient une liste unique. Add, méthode
Ajoute un membre à un objet Collection. Syntaxe object.Add item,key,before,after
La syntaxe de la méthode Add comprend le qualificateur d'objet et les arguments nommés suivants :
ÉlémentDescription object Expression d'objet qui prend la valeur d'un objet figurant dans la liste Application. item Expression de n'importe quel type indiquant le membre à ajouter à la collection. keyFacultatif. Expression de chaîne unique indiquant une chaîne de clé susceptible d'être utilisée à la place de l'index de position pour accéder à un membre de la collection.
Bonjour Klin89,
Je suis vraiment à la masse !!!!!
Merci mais je ne comprends rien à ce que tu me dis !?!
Ou alors tu m'indiques que la différence entre collection et dictionnary c'est l'inversion de item et de key ?
Re à tous,
Quelle différence y a t il entre le code de Nicole qui fonctionne :
Code:
For i = 1 To n
temp = Int(Rnd * n)
Maliste.Add Item:=temp, Key:=CStr(temp)
Next i
et
Code:
For i = 0 To SaisieCommercial.LotsDispo2.ListCount - 1
If SaisieCommercial.LotsDispo2.Selected(i) = True Then
Unique.Add Item:=SaisieCommercial.LotsDispo2.List(i), Key:=CStr(SaisieCommercial.LotsDispo2.List(i))
End If
Next i
Qui ne fonctionne pas et m'indique que la clé est déjà utilisée (Erreur 457 : cette clé est déjà associée à un élément de cette collection) ????
où Maliste et Unique sont des collections déclarées
Merci Nicole de tes précisions. Il y a effectivement une très nette différence de rapidité !
Mais vois tu pourquoi le code, que j'ai indiqué dans mon dernier post précédent ta dernière réponse, ne fonctionne pas ?
Je ne vois pas de différence avec le tien mais ça ne marche pas : j'ai essayé
Un grand MERCI Nicole, et à tous ceux qui se sont penchés sur le sujet.
J'utilisais des collection dans diverses procédures pour traiter les doublons sans cette instruction d'erreur et ça fonctionnait mais après vérification, mon code disposait dans ces procédures d'une instruction On error resume next pour une autre raison. Ainsi comme M Jourdain qui faisait de la prose sans le savoir, je traitais le problème sans le savoir...