Combo et doublons

Résolu
skyzino Messages postés 32 Statut Membre -  
Patrice33740 Messages postés 8400 Date d'inscription   Statut Membre Dernière intervention   -
Bonjour,

Question toute idiote... Suppression de doublon d'une combo. Voici le code que j'utilise (marche du tonnerre mais il ajoute toutes les données...)

'Alimentation des noms en combobox2 via la feuille (NomUtilisateur)
        Sheets(NomUtilisateur).Activate
        'Selection de la derniere ligne utilisée colonne de la feuille FTP
        D_L = Range("E" & Rows.Count).End(xlUp).Row
        'Definition liste combo
        ComboBox2.RowSource = Sheets(NomUtilisateur).Range(Cells(2, 5), Cells(D_L, 5)).Address


Merci d'avance de votre coup de main :)

4 réponses

  1. Patrice33740 Messages postés 8400 Date d'inscription   Statut Membre Dernière intervention   1 783
     
    Bonjour,

    Tout d'abord, ajouter une référence à Microsoft Scripting Runtime (Outils/Références..)

    Si les noms sont triés :
    Private Sub UserForm_Initialize()
    Dim d As New Scripting.Dictionary
    Dim c As Range
    
    NomUtilisateur = "Feuil1"
    
      'Alimentation des noms à partir de la feuille (NomUtilisateur)
      Sheets(NomUtilisateur).Activate
      D_L = Range("E" & Rows.Count).End(xlUp).Row
      'Dictionnaire sans doublons
      For Each c In Range(Cells(2, "E"), Cells(D_L, "E")).Cells
        If Not d.Exists(c.Value) Then d.Add c.Value, ""
      Next c
      'Définition liste combo
      ComboBox2.List =d.Keys
    
    End Sub


    Si il faut aussi trier les noms :
    Private Sub UserForm_Initialize()
    Dim d As New Scripting.Dictionary
    Dim t As Variant
    Dim c As Range
    
    NomUtilisateur = "Feuil1"
    
      'Alimentation des noms à partir de la feuille (NomUtilisateur)
      Sheets(NomUtilisateur).Activate
      D_L = Range("E" & Rows.Count).End(xlUp).Row
      'Dictionnaire sans doublons
      For Each c In Range(Cells(2, "E"), Cells(D_L, "E")).Cells
        If Not d.Exists(c.Value) Then d.Add c.Value, ""
      Next c
      'Tableau à trier
      t = d.Keys
      d.RemoveAll
      'Tri
      Call Tri(t, LBound(t), UBound(t))
      'Definition liste combo
      ComboBox2.List = t
    
    End Sub
    
    Private Sub Tri(table As Variant, premier As Integer, dernier As Integer)
    ' Tri rapide (Quick sort), répartit les éléments de part et d'autre d'un pivot médian :
    '  - éléments inférieurs, avant le pivot
    '  - éléments supérieurs, après le pivot
    ' S'appelle récursivement pour chaque partie jusqu'à ce que chaque éléments soit en place.
    '
    ' Arguments : table               [in/out] Table à trier
    '             premier             [in] index du premier élément à trier
    '             dernier             [in] index du dernier élément à trier
    '
    Dim pivot As Variant
    Dim temp As Variant
    Dim p As Integer
    Dim d  As Integer
    
      p = premier
      d = dernier
      pivot = table((p + d) \ 2)
      Do
        Do While table(p) < pivot
          p = p + 1
        Loop
        Do While pivot < table(d)
          d = d - 1
        Loop
        If p <= d Then
          'permuter
          temp = table(p): table(p) = table(d): table(d) = temp
          p = p + 1
          d = d - 1
        End If
      Loop While p <= d
      'Appels récursifs
      If p < dernier Then Call Tri(table, p, dernier)
      If premier < d Then Call Tri(table, premier, d)
    
    End Sub
    0
  2. skyzino Messages postés 32 Statut Membre
     
    Bonjour le forum, bonjour Patrice,

    Ce que tu propose là me paraît vachement compliqué par rapport à ce que je veux faire.
    Simplement si valeur existe déjà dans la combo alors ne s'inscrit pas. N'y a-t-il pas plus simple que cela comme code ?

    Merci
    0
  3. Patrice33740 Messages postés 8400 Date d'inscription   Statut Membre Dernière intervention   1 783
     
    Bonjour,

    Avec simplement 8 lignes de code, la première procédure (sans trier les noms) est relativement simple.

    comme tu veux que le contenu du combobox soit différent de la plage source (par exemple en supprimant les doublons) il faut créer la liste des valeurs. Cette méthode est des plus simples et en plus, elle est particulièrement rapide

    La seconde proposition n'est utile que si les noms de la liste doivent être triés par ordre croissant. Comme son nom l'indique le Quick Sort est un tri rapide.

    Patrice
    0
  4. lermite222 Messages postés 9042 Statut Contributeur 1 199
     
    Bonjour, bonjour Patrice,
    J'aurais bien une solution plus simple ! :-)
    Option Explicit
    Option Compare Text 'Ne fait pas de différence entre Maju et Minus.
    
    Sub InitCombo()
    Dim Lig As Long, D_L As Long
        With Sheets(NomUtilisateur)
            'Selection de la derniere ligne utilisée colonne de la feuille FTP
            D_L = .Range("E" & Rows.Count).End(xlUp).Row
            'Definition liste combo
            For Lig = 2 To D_L
                ComboBox2.Text = .Cells(Lig, 5)
                If ComboBox2.ListIndex < 0 Then
                    ComboBox2.AddItem .Cells(Lig, 5)
                End If
            Next Lig
        End With
    End Sub

    Et si tu veux par ordre alpha, tu met la propriété "Sort" du combo à True
    @+

    Si tu te cognes à un pot et que ça sonne creux, c'est pas forcément le pot qui est vide. ;-)(Confucius)
    Note: Je ne répond pas aux MP pour les questions techniques. Et ma boule de cristal est cassée .
    0
    1. Patrice33740 Messages postés 8400 Date d'inscription   Statut Membre Dernière intervention   1 783
       
      Bonjour lermite222,

      Je dirais aussi simple mais tellement plus lent !!!
      Avec un dictionnaire c'est 10 à 12 fois plus rapide. Regarde ce test :
      https://www.cjoint.com/c/CFAslMgNdvG

      Cordialement
      Patrice

      PS je n'ai pas de propriété Sort dans mes Combo (MSform), quel type de combo utilises-tu ?
      0
    2. lermite222 Messages postés 9042 Statut Contributeur 1 199
       
      Re,
      je suppose que tu veux rire là...
      En règle générale ont met quelque lignes dans un combo sinon où est l'avantage.
      Que ça mette 120 milliardièmes de seconde à la place de 10.. personnellement je ne vois pas de différence..
      Pour la propriété Sorted, j'ai confondu avec VB6 , c'est d'ailleurs pour cela que je suis intervenu sur ce topic. :-(
      A+
      0
    3. Patrice33740 Messages postés 8400 Date d'inscription   Statut Membre Dernière intervention   1 783
       
      Je suppose que tu n'utilises pas les combobox pour leur capacité d'auto-complétion (sans DropButton) ...
      0
    4. skyzino Messages postés 32 Statut Membre
       
      Merci à vous 2 pour tous ces échanges.
      Si jamais vous connaissez la solution pour faire apparaitre la combo vide au lancement, je suis preneur (J'utilise normalement combo list index = -1 mais dans ce cas cela ne marche pas)
      0
    5. Patrice33740 Messages postés 8400 Date d'inscription   Statut Membre Dernière intervention   1 783
       
      «J'utilise normalement combo list index = -1 mais dans ce cas cela ne marche pas»
      Surprenant !!!

      Avec mon code il n'y en a pas besoin et avec celui lermite222 il suffit de mettre
      ComboBox2.ListIndex = -1
      juste avant le End Sub

      Patrice
      0