Remplir une listbox par ordre alphabétique

Résolu
Co_nexion Messages postés 333 Statut Membre -  
Co_nexion Messages postés 333 Statut Membre -
Bonjour,

J'essaie tant bien que mal de réaliser un outil sur excel, et je me retrouve face à un problème dont je ne trouve pas la solution et je sollicite votre aide afin de franchir cette étape...

Je vous explique j'ai crée une listbox et j'y est associer ce code afin de la remplir
   
Private Sub UserForm_Initialize()  
          
        With Sheets("CDD").Range("A1")  
        Me.ListBox1.RowSource = "CDD!A1:J" & Sheets("CDD").Cells(1, 1).End(xlDown).Row  
        NbLigne = WorksheetFunction.CountA(Columns("C:C"))  
        ListBox1.RowSource = Sheets("CDD").Range(Cells(2, 1), Cells(NbLigne, 10)).Address  
    End With   


Puis j'ai voulu ordonner par ordre alphabétique cette listbox et j'ai réussi à trouver ce code qui marche très bien (malgré le fait qu'il différencie majuscule et minuscule)

Dim Tablo As Variant, Tempo As Variant, i As Long, j As Long  
    Worksheets("CDD").Activate 'à défaut d'instancier la feuille  
    Tablo = Range("a2:a" & Range("a" & Rows.Count).End(xlUp).Row).Value  
'triAlpha  
    For i = 1 To UBound(Tablo)  
        For j = 1 To UBound(Tablo)  
            If Tablo(i, 1) < Tablo(j, 1) Then  
                Tempo = Tablo(i, 1)  
                Tablo(i, 1) = Tablo(j, 1)  
                Tablo(j, 1) = Tempo  
            End If  
        Next j  
    Next i  
End sub  


Malheureusement je n'arrive pas à associer les deux. J'espère que vous pourrez m'aider avec le plus d'explication possible parce que ca fait du bien d'avoir compris ;)

8 réponses

Résumé de la discussion

La gestion d'une ListBox dans un formulaire Excel, alimentée par une plage et triée par ordre alphabétique, associant RowSource et un code de tri recherchant une mise à jour dynamique. Des solutions proposées visent à préserver les en-têtes, utiliser RowSource avec l'adresse de plage incluant les entêtes, ou charger les données dans une matrice Tablo et basculer vers ListBox1.List. Plusieurs intervenants recommandent d'éviter RowSource pour les scénarios triés, de paramétrer ColumnCount et ColumnHeads, et d'actualiser la ListBox en réaffectant Tablo à ListBox1.List après tri. Des difficultés de mise à jour dynamique apparaissent lorsque de nouvelles lignes sont ajoutées, nécessitant soit de réouvrir le formulaire, soit de déclencher un rechargement explicite des données.

Généré automatiquement par IA
sur la base des meilleures réponses
  1. f894009 Messages postés 17417 Date d'inscription   Statut Membre Dernière intervention   1 717
     
    Bonjour ccm81
    Merci pour le code de tri. Probleme, il n'aura pas les entetes de colonne.
    Pour avoir les entetes il faut passer par .RowSource= address de plage

    Ici:
    Feuille1:
    Entete: A1 a C1 a modifier pour 10 colonnes
    Plage: de donnees A2 a Cx

    Feuille2
    Entete ideme Feuille1: A1 a C1
    Plage trie pour RowSource: A2 a Cx pour pouvoir donner les address de plage afin d'avoir les entetes.

    Code a copier dans l'UserForm

    'Nombre de colonnes a adapter--->passer a 10
    Const nbcol = 3

    'Nombre de colonnes a adapter
    Const nbcol = 3

    Private Sub UserForm_Initialize()
    'Nombre de colonnes
    ListBox.ColumnCount = nbcol
    'largeur Colonnes a adapter
    ListBox.ColumnWidths = "50 pt;50 pt;50 pt"
    'Entete colonne
    ListBox.ColumnHeads = True
    Call tri
    End Sub

    'Code ccm81 adapte pour les besoins de Co_nexion
    Public Sub tri()
    Dim plage As String
    Dim lifin As Long
    Dim Tablo As Variant, mini As Variant, tempo As Variant
    Dim n As Long, i As Long, j As Long, c As Long, rangmini As Long
    lifin = Sheets(1).Range("A2").End(xlDown).Row
    plage = "A2:C" & lifin
    Tablo = Sheets(1).Range(plage).Value
    n = UBound(Tablo, 1)
    For i = 1 To n - 1
    mini = Tablo(i, 1)
    For j = i + 1 To n
    If Tablo(j, 1) < mini Then
    rangmini = j
    mini = Tablo(rangmini, 1)
    End If
    Next j
    For c = 1 To nbcol
    tempo = Tablo(i, c)
    Tablo(i, c) = Tablo(rangmini, c)
    Tablo(rangmini, c) = tempo
    Next c
    Next i

    Worksheets("Feuil2").Activate
    Worksheets("Feuil2").Range(Cells(2, 1), Cells(11, "c")).Value = Tablo
    Me.ListBox.RowSource = Sheets("Feuil2").Range(Cells(2, 1), Cells(lifin, "c")).Address
    End Sub

    Bonne suite
    1
    1. Co_nexion Messages postés 333 Statut Membre
       
      RE f894009 et ccm81,

      Merci mille fois pour ton code cependant je bloque toujours et ca m'enerve de ne pas y arriver !!!

      Alors voila j'ai repris ton code de cette manière sachant que
      - Ma feuille se nomme "CDD"
      - Ma listbox se nomme listbox1
      -Mes dix colonnes vont de A à J

      Je pense que je dois faire une erreur au niveau de plage. Je n'ai également pas compris pourquoi tu me parlais de deux feuilles dans ta démonstration précédente. En tout cas un grand merci, j'en apprends beaucoup grâce à vous !

      Pour info "erreur d'éxécution 9", l'indice n'appartient pas à la sélection

      Const nbcol = 10  
      
      Const nbcol = 10  
      
      Private Sub UserForm_Initialize()  
      'Nombre de colonnes  
      ListBox1.ColumnCount = nbcol  
      'largeur Colonnes a adapter  
      ListBox1.ColumnWidths = "50 pt;50 pt;50 pt;50 pt;50 pt;50 pt;50 pt;50 pt;50 pt;50 pt"  
      'Entete colonne  
      ListBox1.ColumnHeads = True  
      Call tri  
      End Sub  
      
      
      'Code ccm81 adapte pour les besoins de Co_nexion  
      Public Sub tri()  
      Dim plage As String  
      Dim lifin As Long  
      Dim Tablo As Variant, mini As Variant, tempo As Variant  
      Dim n As Long, i As Long, j As Long, c As Long, rangmini As Long  
      lifin = Sheets(CDD).Range("A1").End(xlDown).Row  
      plage = "A2:J" & lifin  
      Tablo = Sheets(CDD).Range(plage).Value  
      n = UBound(Tablo, 1)  
      For i = 1 To n - 1  
      mini = Tablo(i, 1)  
      For j = i + 1 To n  
      If Tablo(j, 1) < mini Then  
      rangmini = j  
      mini = Tablo(rangmini, 1)  
      End If  
      Next j  
      For c = 1 To nbcol  
      tempo = Tablo(i, c)  
      Tablo(i, c) = Tablo(rangmini, c)  
      Tablo(rangmini, c) = tempo  
      Next c  
      Next i  
      
      Worksheets("CDD").Activate  
      Worksheets("CDD").Range(Cells(2, 1), Cells(11, "c")).Value = Tablo  
      Me.ListBox1.RowSource = Sheets("CDD").Range(Cells(2, 1), Cells(lifin, "j")).Address  
      End Sub  
      
      0
    2. f894009 Messages postés 17417 Date d'inscription   Statut Membre Dernière intervention   1 717
       
      Re,
      Tablo = Sheets(CDD).Range(plage).Value

      manque les "" si c'est a cet endroit qu'il marque l'erreur

      Worksheets("CDD").Range(Cells(2, 1), Cells(11, "c")).Value = Tablo
      Me.ListBox1.RowSource = Sheets("CDD").Range(Cells(2, 1), Cells(lifin, "j")).Address

      Il faut changer de feuille pour copier les donnees triees sinon reecriture sur les donnees d'origine

      Feuille1:
      Entete: A1 a C1 a modifier pour 10 colonnes
      Plage: de donnees A2 a Cx

      Feuille2:
      Entete ideme Feuille1: A1 a C1
      Plage trie pour RowSource: A2 a Cx pour pouvoir donner les address de plage afin d'avoir les entetes.
      0
    3. Co_nexion Messages postés 333 Statut Membre
       
      f894009,

      Cette fois il n'y a plus de bug le userform se lance mais rien ne s'affiche dans la listbox...
      0
    4. f894009 Messages postés 17417 Date d'inscription   Statut Membre Dernière intervention   1 717
       
      Bonjour,
      Pouvez vous mettre votre fichier a dispo?
      0
    5. Co_nexion Messages postés 333 Statut Membre
       
      Bonjour,

      Une simple question : comment puis je mettre le fichier à votre disposition ?
      0
  2. f894009 Messages postés 17417 Date d'inscription   Statut Membre Dernière intervention   1 717
     
    Re,

    https://www.cjoint.com/?BDeqbonfhYt

    Modif faciles a trouver. A essayer
    1
    1. Co_nexion Messages postés 333 Statut Membre
       
      Effectivement... Merci beaucoup f894009 & bonne journée
      0
  3. ccm81 Messages postés 11033 Statut Membre 2 434
     
    bonjour à tous
    1. transfert de la plage dans tablo
    2. tri (selection) de tablo
    3. tranfert de tablo dans la listtbox1

    tablo = Range("A1:A9").Value  
    n = UBound(tablo, 1)  
    For i = 1 To n - 1  
      mini = tablo(i, 1)  
      For j = i + 1 To n - 1  
        If tablo(j, 1) < mini Then  
          rangmini = j  
          mini = tablo(rangmini, 1)  
        End If  
      Next j  
      tempo = tablo(i, 1)  
      tablo(i, 1) = mini  
      tablo(rangmini, 1) = tempo  
    Next i  
    For i = 1 To n  
      ListBox1.List() = tablo  
    Next i

    RQ. on peut s'affranchir de la casse avec la fonction Ucase à appliquer dans la partie tri de tablo

    bonne suite
    0
    1. Co_nexion Messages postés 333 Statut Membre
       
      Bonjour,

      Etant vraiment débutant dans le vaste monde du vba, je vous avoue que je ne sais pas ou incorporer ce bout de code par rapport à la première partie de mon code. En effet, la première partie du code (voir plus haut) me sert à amener les données dans la listbox tout en alimentant une entête.

      Merci de votre aide
      0
  4. ccm81 Messages postés 11033 Statut Membre 2 434
     
    au vu de ton code, je ne comprend pas bien ce que tu veux faire
    celui que je t'ai proposé remplit une listbox1 (à 1 seule colonne) avec le contenu de la plage "A1:A9" )
    la seule chose que tu as à faire c'est
    - un copier/coller du code
    - mettre un Me. devant mes ListBox1 (s'il s'agit bien de la ListMox1 de ta UserForm
    - changer la plage qui va servir à remplir cette ListBox1 via tablo
    tablo = sheets("CDD").Range(.....).Value

    RQ1. tu ne dois pas utiliser RowSource qui lierait ta listbox à une plage, la source de ta Listbox1, c'est tablo!

    RQ2. il y a une boucle inappropriée à la fin de mon code
    remplacer
    For i = 1 To n    
      ListBox1.List() = tablo    
    Next i
    par
    ListBox1.List() = tablo  


    bonne suite
    0
    1. Co_nexion Messages postés 333 Statut Membre
       
      Merci beaucoup pour ces explications.
      Je vais essayer tout ca au plus vite ;)
      0
    2. Co_nexion Messages postés 333 Statut Membre
       
      Re,
      Je viens d'essayer le code et malheureseument ca ne marche pas. Je pense avoir oublié quelque chose ou être totalement passé à côté.

      Voila comment j'ai intégré ton code mais peut être est ce là mon erreur...
       Private Sub UserForm_Initialize()
                
              With Sheets("CDD").Range("A1")
                  Me.ListBox1.RowSource = "CDD!A1:J" & Sheets("CDD").Cells(1, 1).End(xlDown).Row
                  NbLigne = WorksheetFunction.CountA(Columns("C:C"))
                  Me.ListBox1.Tablo = Sheets("CDD").Range(Cells(2, 1), Cells(NbLigne, 10)).Address
              End With
              
              Dim Tablo As Variant, Tempo As Variant, i As Long, j As Long
                  Worksheets("CDD").Activate 'à défaut d'instancier la feuille
                      Tablo = Sheets("CDD").Range("A1:J").Value
                      n = UBound(Tablo, 1)
                  For i = 1 To n - 1
                      mini = Tablo(i, 1)
                  For j = i + 1 To n - 1
                      If Tablo(j, 1) < mini Then
                          rangmini = j
                          mini = Tablo(rangmini, 1)
                      End If
                  Next j
                      Tempo = Tablo(i, 1)
                      Tablo(i, 1) = mini
                      Tablo(rangmini, 1) = Tempo
                  Next i
              Me.ListBox1.List() = Tablo
      
      End Sub
      0
    3. f894009 Messages postés 17417 Date d'inscription   Statut Membre Dernière intervention   1 717
       
      Bonjour Co_nexion et ccm81

      Votre souhait est-il bien celui-ci:
      Afficher dans une listbox de 10 colonnes des informations,avec un tri par ordre alphabetique sur la premiere colonne ( les autres infos doivent suivre le tri), provenant d'une plage de cellules sans faire le tri sur cette plage de cellules.

      ccm81 vous a fourni un code pour une listbox a une seule colonne. Pour l'instant que ce code modifie par vous, ne marche pas, cela n'a pas d'importance.

      Il faut exprimer clairement ce que vous souhaitez.

      Merci
      0
    4. Co_nexion Messages postés 333 Statut Membre
       
      Oui c'est tout à fait ce que vous résumez.

      - Afficher une listbox de dix colonnes (avec entête)
      - Faire un tri alphabétique dans la première colonne (les infos des autres colonnes suivant évidemment ce tri)
      - Pas de tri sur le tableur excel

      Merci pour votre aide
      0
    5. f894009 Messages postés 17417 Date d'inscription   Statut Membre Dernière intervention   1 717
       
      Re,
      Dernier detail, cette listbox est sur une feuille de calcul ou un UserForm??
      Cela a une importance pour vos desir d'entete de colonnes.
      0
  5. Vous n’avez pas trouvé la réponse que vous recherchez ?

    Posez votre question
  6. ccm81 Messages postés 11033 Statut Membre 2 434
     
    ça devrait ressembler à ça

    https://www.cjoint.com/?0Cwosea6qEO

    bonne suite
    0
    1. Co_nexion Messages postés 333 Statut Membre
       
      Mon entreprise me bloque l'accès, n'aurait tu pas un autre moyen pour que je le consulte.

      Merci d'avance
      0
  7. ccm81 Messages postés 11033 Statut Membre 2 434
     
    voila le code

    Const nbcol = 10  
    
    Public Sub UserForm_Initialize()  
    Dim plage As String  
    Dim lifin As Long  
    Dim Tablo As Variant, mini As Variant, tempo As Variant  
    Dim n As Long, i As Long, j As Long, c As Long, rangmini As Long  
    lifin = Sheets("CDD").Range("A1").End(xlDown).Row  
    plage = "A1:J" & lifin  
    Tablo = Sheets("CDD").Range(plage).Value  
    n = UBound(Tablo, 1)  
    For i = 1 To n - 1  
      mini = Tablo(i, 1)  
      For j = i + 1 To n  
        If Tablo(j, 1) < mini Then  
           rangmini = j  
           mini = Tablo(rangmini, 1)  
        End If  
      Next j  
      For c = 1 To nbcol  
        tempo = Tablo(i, c)  
        Tablo(i, c) = Tablo(rangmini, c)  
        Tablo(rangmini, c) = tempo  
      Next c  
    Next i  
    UserForm1.ListBox1.List() = Tablo  
    UserForm1.Show  
    End Sub

    RQ. on peut s'affranchir de la casse avec la fonction UCase

    bonne suite
    0
    1. Co_nexion Messages postés 333 Statut Membre
       
      Re,

      Merci beaucoup de m'accorder ton aide.
      Je viens d'essayer de prendre le code et malheureusement le tri ne marche pas et de plus l'entete est vide. Par contre la listbox est alimentée.

      Aurais-tu une idée de la source du problème ?

      Encore merci
      0
  8. ccm81 Messages postés 11033 Statut Membre 2 434
     
    bonjour

    comme les entêtes de colonnes nous obligent à lier la listbox à une plage d'une feuille, il n'y a plus tellement besoin de programmer !!!
    il te faut faire comme préconise f894009
    1. copier ta plage de données dans une feuille
    2. trier cette plage selon la colonne 1
    3. nommer cette plage plageLB1 par exemple
    3. dans les propriétés de la listbox1, lier directement cette plage à la rowsource

    bonne journée
    0
  9. f894009 Messages postés 17417 Date d'inscription   Statut Membre Dernière intervention   1 717
     
    Bonjour,
    Il serait plus simple de faire votre tri sur vos cellules par programme

    exemple ci-dessous fait avec l'enregistreur de macro

    Sub Macro4()
    Range("A1:C7").Select
    ActiveWorkbook.Worksheets("Feuil1").Sort.SortFields.Clear
    ActiveWorkbook.Worksheets("Feuil1").Sort.SortFields.Add Key:=Range("A1:A7"), _
    SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
    With ActiveWorkbook.Worksheets("Feuil1").Sort
    .SetRange Range("A1:C7")
    .Header = xlGuess
    .MatchCase = False
    .Orientation = xlTopToBottom
    .SortMethod = xlPinYin
    .Apply
    End With
    End Sub

    Bonne suite
    -1
    1. Co_nexion Messages postés 333 Statut Membre
       
      Bonjour,

      Si j'ai bien compris ce que vous me dites, c'est de trier mes données directement dans mon tableur excel. Mais je ne souhaite faire un tri que dans la listbox tout en gardant ses caractéristiques (premier code)...

      Merci en tout cas pour la rapidité
      0
    2. f894009 Messages postés 17417 Date d'inscription   Statut Membre Dernière intervention   1 717
       
      Re,
      Vous pouvez copier cette zone sur une autre feuille et faire le tri.
      Autrement votre listbox a combien de colonnes??
      0
    3. Co_nexion Messages postés 333 Statut Membre
       
      Ma listbox a 10 colonnes mais je ne souhaite que trier la premiere
      0