Objet : afficher dans combobox liste sans doublon

Sebast

XLDnaute Impliqué
Bonjour à toutes et à tous,

je n'arrive pas à comprendre pourquoi mon code plante quand je veux charger un userform …

La simple instruction


VB:
Sub Montrer()

Dialogue_codes_articles.Show

End Sub

débouche sur un message "Erreur d'exécution 424 : objet requis"


En fait, je me suis inspiré d'un code existant qui charge dans un userform une liste de valeurs uniques :


VB:
Private Sub UserForm_Initialize()

Dim j As Integer

Dim Dialogue_codes_articles

'Récuperer les données da la colonne A

For j = 1 To Range("A2").End(xlUp).Row

Dialogue_codes_articles = Range("A" & j)

'Filtrer les doublons

If Dialogue_codes_articles.ListIndex = -1 Then Dialogue_codes_articles.AddItem Range("A" & j)

Next j

End Sub

… et comme ce code a le mérite de la simplicité, je l'ai adapté mais ne peux pas voir s'il opère car je n'arrive pas à faire apparaître la combo …


Quelqu'un peut-il me dire ce qui coince chez moi ?
Au passage, quand ce sera debbugué, si quelqu'un peut m'expliquer le pourquoi du - 1 dans
If Dialogue_codes_articles.ListIndex = -1


Merci d'avance
 

Fichiers joints

vgendron

XLDnaute Barbatruc
Hello
il y a plusieurs erreurs dans ton code

For j = 2 To Range("A2").End(xlUp).Row

J va s'arreter à 2....

Dialogue_codes_articles = Range("A" & j)
tu essaies de placer le contenu du range Aj dans le formulaire... au lieu de le mettre dans ta listbox1

et ListBox1.listindex=-1 l'index de l'élément sélectionné dans ListBox est à -1 si RIEN n'est sélectionné



VB:
Private Sub UserForm_Initialize()
Dim j As Integer
Dim Dialogue_codes_articles

'Récuperer les données da la colonne A
With Sheets("BD")
    For j = 2 To .Range("A" & .Rows.Count).End(xlUp).Row
        Dialogue_codes_articles = .Range("A" & j)
        'Filtrer les doublons
        If Me.ListBox1.ListIndex = -1 Then Me.ListBox1.AddItem .Range("A" & j)
    Next j
End With

End Sub
 

vgendron

XLDnaute Barbatruc
et il me semble que pour remplir ta liste SANS doublons, tu utilises une méthode valable pour les COMBOBOX

pour une ListeBox: voir le code ci dessous qui vient de silkyroad (http://silkyroad.developpez.com/VBA/ControlesUserForm/#LII-G)
VB:
Private Sub UserForm_Initialize()

Dim Cell As Range
Dim Unique As New Collection
Dim Valeur As Range
Dim i As Integer

With Sheets("BD")
    i = .Range("A" & .Rows.Count).End(xlUp).Row

    On Error Resume Next
    'boucle sur les cellules de la colonne A
    For Each Cell In .Range("A1:A" & i)
        'Stocke les données dans une collection
        '(La collection n'accepte que des données uniques et permet donc
        ' de filtrer facilement les doublons).
        Unique.Add Cell, CStr(Cell)
    Next Cell
    On Error GoTo 0

    'Boucle sur le contenu de la collection pour alimenter la ListBox
    For Each Valeur In Unique
        Me.ListBox1.AddItem Valeur
    Next Valeur
End With
End Sub
 

Sebast

XLDnaute Impliqué
Bonjour Vgendron,

merci pour cette correction, je m'étais inspiré d'un tuto sur YouTube avec un fichier à télécharger, qui semblait fonctionner …


Effectivement, j'allais te poser la question concernant les doublons mais tu as devancé l'appel.

Peux-tu m'éclairer sur : Unique.Add Cell, CStr(Cell)
Par ailleurs, je pensais qu'un dictionary était mieux en ce cas qu'un collection
Tu écris que la collection n'accepte que des données uniques, mais est-ce le résultat de Unique.Add … ou de façon générale ?

Et enfin, vu la masse de données dans la combo, peut-on afficher une liste triée alpha ?

Merci d'avance

PS : quelques pb WIFI font que je ne pourrai peut-être pas répondre dans l'immédiate après-midi
 

Sebast

XLDnaute Impliqué
Nicole,

merci pour cette proposition.
Je l'ai testée et adaptée (déclaré variables) mais ça coince sur Me.ComboBox1.List = mondico.keys
même si j'actualise le nom par celui de ma combo (chez moi Dialogue_codes_articles) avec ou sans Me devant ça s'arrête sur ce point, alors que tout paraît d'équerre ...
 

vgendron

XLDnaute Barbatruc
j'actualise le nom par celui de ma combo (chez moi Dialogue_codes_articles)
non non. justement..
chez toi. ceci est le nom du USERFORM.. PAS du combo..
soit tu mets: Dialogue_codes_articles.listbox1
soit tu mets Me.listBox1 Me voulant dire à peu près.. "Userform actif"

et il ne faut pas confondre Listbox et Combobox... c'est pas le meme control
 

vgendron

XLDnaute Barbatruc
donc... avec ton fichier posté au début
l'USF s'appelle: "Dialogue_codes_articles"
il contient une listbox "LISTBOX1"

et pour la remplir avec un dictionnaire
VB:
Private Sub UserForm_Initialize()
Dim mondico As Variant
Dim a, fin, i As Integer
Set mondico = CreateObject("Scripting.Dictionary")
With Sheets("BD")
    fin = .Range("A" & .Rows.Count).End(xlUp).Row
    a = .Range("A2:A" & fin)  ' tableau a(n,1) pour rapidité
    For i = LBound(a) To UBound(a)
        If a(i, 1) <> "" Then mondico(a(i, 1)) = ""
    Next i
    Me.ListBox1.List = mondico.keys
End With
End Sub
 

Sebast

XLDnaute Impliqué
je pense avoir compris mon erreur : je prenais en compte la boîte complète (userform) et pas la case où la liste déroulante doit s'afficher (listbox1)… je pouvais toujours chercher !

Merci de m'avoir ouvert les yeux !

Concernant la liste triée, en fait il suffit de trier la liste contenat les doublons (feuille "BD") pour que la liste sans doublons soit triée

Encore merci à toi et à Nicole pour ces propositions et corrections instructives
 

Sebast

XLDnaute Impliqué
Dernière question (peut-être pas la moindre …)

Code:
If a(i, 1) <> "" Then mondico(a(i, 1)) = ""
Je ne comprends pas, pour moi ça signifie que si l’entrée n’est pas vide, alors la key elle serait vide ; j’aurais pensé l’inverse, c’est-à-dire si on a une entrée, on la charge dans le dictionary.

Comment faut-il interpréter cette ligne ?

Merci d'avance
 

vgendron

XLDnaute Barbatruc
pour cette instruction.. je t'avoue que je l'ai déjà vue ailleurs. et que.. comme toi. je n'ai jamais bien compris..
ce que je crois que ca dit:
if a(i,1)<>""
si l'élément "ligne i colonne 1 du tablo a" est non vide alors

mondico(a(i,1))=""
la clé a(i,1) EST AJOUTEE si elle n'existe pas déjà (et c'est ce test: SI n'existe pas qui semble être implicite)
="" et on lui met une chaine vide comme valeur (tu pourrais lui mettre autre chose. c'est pas genant, mais comme on utilise pas les valeurs par la suite..autant ne pas charger le dico pour rien..

Ceci n'est que ma compréhension du moment.. je n'ai jamais approfondi.. pour l'instant.
 

Sebast

XLDnaute Impliqué
Bonsoir,

moi aussi je dois un peu digérer tout ça mais tu as raison, j'ai remplacé le "" par "turlututu" et effectivement, ça n'a pas d'incidence (si ce n'est la place - probablement - mais ici pas significatif !).

Encore merci pour ton aide

Sebast
 

Discussions similaires


Haut Bas