IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Macros et VBA Excel Discussion :

Tri ListBox multicolonne


Sujet :

Macros et VBA Excel

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Juillet 2010
    Messages
    121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Doubs (Franche Comté)

    Informations forums :
    Inscription : Juillet 2010
    Messages : 121
    Par défaut
    Bonjour à tous,
    J'ai dans mon projet plusieurs listbox multicolonne que j'alimente de la façon suivante (trois colonnes dans cet exemple) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    With ListeProduit2
        .Clear
        derligne = Split(Worksheets("Produits").UsedRange.Address, "$")(4)
        For j = 2 To derligne
            Select Case Worksheets("Produits").Range("A" & j).Value
                Case Is = ComboNumEssai2.Value
                    .AddItem
                    .List(k, 0) = Worksheets("Produits").Range("A" & j).Value
                    .List(k, 1) = Worksheets("Produits").Range("B" & j).Value
                    .List(k, 2) = Worksheets("Produits").Range("C" & j).Value
                    k = k + 1
                Case Else
            End Select
        Next j
    End With
    Je cherche le moyen de trier les données de cette ListBox, tri sur la 1ere colonne puis la seconde, etc...
    J'ai parcouru le forum sans succès.
    Je parle bien de ListBox et non de Combobox. D'ailleurs je trie mes ComboBox à l'aide d'une fonction trouvée je ne sais plus ou :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    Function ListSort(liSte)
     '  Sorts the List array in ascending order
      Dim First As Integer, Last As Integer
     
     Dim i As Integer, j As Integer
      Dim Temp
     
      First = LBound(liSte)
      Last = UBound(liSte)
      For i = First To Last - 1
        For j = i + 1 To Last
          If liSte(i, 0) > liSte(j, 0) Then
            Temp = liSte(j, 0)
            liSte(j, 0) = liSte(i, 0)
            liSte(i, 0) = Temp
          End If
        Next j
      Next i
      ListSort = liSte
     End Function
    L'idéal serait pour moi de fonctionner également sur le principe d'une fonction à appeler à chaque fois que j'en ai besoin.

    D'avance merci pour vos idées.
    Cordialement,

    J'apporte une précision :
    la fonction que j'utilise fonctionne bien entendu pour trier une listbox mais que sur une colonne.
    ce que je souhaite c'est pouvoir trier sur colonne 1 puis 2 puis 3...
    merci

  2. #2
    Membre chevronné
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    473
    Détails du profil
    Informations personnelles :
    Localisation : France, Vendée (Pays de la Loire)

    Informations forums :
    Inscription : Novembre 2007
    Messages : 473
    Par défaut
    Bonsoir,

    Multi-colonne ou non ce sera le même principe ! Listbox.value sera sur une colonne ! Quel intérêt de trié chaque colonne?

  3. #3
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Juillet 2010
    Messages
    121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Doubs (Franche Comté)

    Informations forums :
    Inscription : Juillet 2010
    Messages : 121
    Par défaut
    Bonjour,
    Merci pour votre contribution.
    Dans mon ensemble de données sur x colonnes, je souhaite trier les données sur la première colonne puis, si il y a des données égales dans la première colonne, les trier sur la deuxième colonne, puis si il y a des données égales sur la deuxième colonne, les trier sur la troisième colonne, etc jusqu'à la x ième colonne.
    Exemple :
    Colonne A - Colonne B - Colonne C
    Lorraine Moselle Metz
    Alsace Haut-Rhin Mulhouse
    Alsace Bas-Rhin Strasbourg
    Alsace Haut-Rhin Colmar

    deviendra après tri :
    Colonne A - Colonne B - Colonne C
    Alsace Bas-Rhin Strasbourg
    Alsace Haut-Rhin Colmar
    Alsace Haut-Rhin Mulhouse
    Lorraine Moselle Metz

    D'ailleurs en avançant dans mes tests, je me suis rendu compte que la fonction que j'utilise trie les données d'une colonne mais ne traite pas les données liées des autres colonnes.
    Je l'ai donc modifiée comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    Function ListSort2(liSte)
     '  Sorts the List array in ascending order
      Dim First As Integer, Last As Integer
     
     Dim i As Integer, j As Integer
      Dim Temp0, Temp1, Temp2
     
      First = LBound(liSte)
      Last = UBound(liSte)
      For i = First To Last - 1
        For j = i + 1 To Last
          If liSte(i, 0) > liSte(j, 0) Then
            Temp0 = liSte(j, 0)
            Temp1 = liSte(j, 1)
            Temp2 = liSte(j, 2)
            liSte(j, 0) = liSte(i, 0)
            liSte(j, 1) = liSte(i, 1)
            liSte(j, 2) = liSte(i, 2)
            liSte(i, 0) = Temp0
            liSte(i, 1) = Temp1
            liSte(i, 2) = Temp2
          End If
        Next j
      Next i
      ListSort2 = liSte
     End Function
    Maintenant le tri est correct, mais ça ne trie que sur une colonne...
    Merci de votre aide

    J'ai simplifié le code de la fonction pour permettre le tri d'une listbox multicolonne, en conservant les données liées, quelque soit le nombre de colonnes. Mais ça ne trie toujours que sur UNE colonne.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    Function ListSort2(liSte, liste2)
    Dim First, Last, i, j, a As Integer
    First = LBound(liSte)
    Last = UBound(liSte)
        For i = First To Last - 1
            For j = i + 1 To Last
                If liSte(i, 2) > liSte(j, 2) Then
                    For a = 0 To liste2.ListCount - 1
                        Temp = liSte(j, a)
                        liSte(j, a) = liSte(i, a)
                        liSte(i, a) = Temp
                    Next a
                End If
            Next j
        Next i
    ListSort2 = liSte
    End Function
    à lancer par :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <nom de votre listebox>.List = ListSort2(<nom de votre listebox>.List, <nom de votre listebox>)

  4. #4
    Rédacteur
    Avatar de Philippe Tulliez
    Homme Profil pro
    Formateur, développeur et consultant Excel, Access, Word et VBA
    Inscrit en
    Janvier 2010
    Messages
    13 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Formateur, développeur et consultant Excel, Access, Word et VBA

    Informations forums :
    Inscription : Janvier 2010
    Messages : 13 173
    Billets dans le blog
    53
    Par défaut
    Bonjour,
    Si j'ai bien compris, tu souhaites faire un tri hiérarchique sur plusieurs colonnes.
    Tu pourrais utiliser une table en concaténant les colonnes à trier en ajoutant le n° de la ligne dans la liste des données avec la fonction Format et ensuite utiliser ton tri d'une colonne.
    Ce qui donnerait suivant ton exemple
    Avant tri
    LorraineMoselleMetz004
    AlsaceHaut-RhinMulhouse010
    AlsaceBas-RhinStrasbourg090
    AlsaceHaut-RhinColmar101
    Après tri
    AlsaceBas-RhinStrasbourg090
    AlsaceHaut-RhinColmar101
    AlsaceHaut-RhinMulhouse010
    LorraineMoselleMetz004
    Il te reste à récupérer à l'aide de la fonction Right les trois derniers caractères de la chaîne triée pour faire le Additem dans la ListBox
    Philippe Tulliez
    Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément. (Nicolas Boileau)
    Lorsque vous avez la réponse à votre question, n'oubliez pas de cliquer sur et si celle-ci est pertinente pensez à voter
    Mes tutoriels : Utilisation de l'assistant « Insertion de fonction », Les filtres avancés ou élaborés dans Excel
    Mon dernier billet : Utilisation de la fonction Dir en VBA pour vérifier l'existence d'un fichier

  5. #5
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Juillet 2010
    Messages
    121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Doubs (Franche Comté)

    Informations forums :
    Inscription : Juillet 2010
    Messages : 121
    Par défaut On avance !!
    Ce bout de code permet de trier une list box de x colonnes, en conservant les données liées, sur la première colonne puis la seconde en cas d'égalité puis la troisième en cas d'égalité
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
     
    Function ListSort2(liSte, liste2)
    'tri d'une ListBox à x colonnes sur les colonnes 0 puis 1 puis 2
    Dim First, Last, i, j, a As Integer
    'premier niveau de tri
    First = LBound(liSte)
    Last = UBound(liSte)
        For i = First To Last - 1
            For j = i + 1 To Last
                If liSte(i, 0) > liSte(j, 0) Then
                    For a = 0 To liste2.ListCount - 1
                        temp = liSte(j, a)
                        liSte(j, a) = liSte(i, a)
                        liSte(i, a) = temp
                    Next a
                End If
            Next j
        Next i
    'second niveau de tri en cas d'égalité au niveau 1
    First = LBound(liSte)
    Last = UBound(liSte)
        For i = First To Last - 1
            For j = i + 1 To Last
                If liSte(i, 1) > liSte(j, 1) And liSte(i, 0) = liSte(j, 0) Then
                    For a = 0 To liste2.ListCount - 1
                        temp = liSte(j, a)
                        liSte(j, a) = liSte(i, a)
                        liSte(i, a) = temp
                    Next a
                End If
            Next j
        Next i
    'troisième niveau de tri en cas d'égalité au niveau 2
    First = LBound(liSte)
    Last = UBound(liSte)
        For i = First To Last - 1
            For j = i + 1 To Last
                If liSte(i, 2) > liSte(j, 2) And liSte(i, 1) = liSte(j, 1) And liSte(i, 0) = liSte(j, 0) Then
                    For a = 0 To liste2.ListCount - 1
                        temp = liSte(j, a)
                        liSte(j, a) = liSte(i, a)
                        liSte(i, a) = temp
                    Next a
                End If
            Next j
        Next i
     
    ListSort2 = liSte
    End Function
    Problème : j'aimerais automatiser ce code pour trier sur les x colonnes sans avoir à dupliquer le pavé de tri x fois...

    Des idées ?

  6. #6
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Août 2010
    Messages
    3 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 3 453
    Par défaut
    Bonjour,

    Excel possède de très bon outils, il suffit d'utiliser une feuille cachée pour utiliser sa fonction de tri :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     
    Private Sub UserForm_Initialize()
     
        Dim Plage As Range
        Dim I As Integer
     
        'défini la plage de A1 à Cx
        With Worksheets("Feuil1") '<-- il est possible d'utiliser une feuille cachée
     
            Set Plage = .Range(.Cells(1, 1), .Cells(.Rows.Count, 3).End(xlUp))
     
        End With
     
        Plage.Sort Plage.Columns(1), xlAscending, Plage.Columns(2), , xlAscending, Plage.Columns(3), xlAscending
     
        With ListBox1
     
            .ColumnCount = 3
            .RowSource = Plage.Address
     
        End With
     
    End Sub
    Hervé.

  7. #7
    Membre Expert
    Inscrit en
    Octobre 2010
    Messages
    1 401
    Détails du profil
    Informations forums :
    Inscription : Octobre 2010
    Messages : 1 401
    Par défaut
    Pour faire le tri à la premiere passe sur colonne 1 et 2,
    Remplace
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    If liSte(i, 0) > liSte(j, 0) Then
    par

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    If liSte(i, 0)  & liSte(i, 1) > liSte(j, 0) & liSte(j, 1) Then

Discussions similaires

  1. [win32] ListBox MultiColonne
    Par edrin17 dans le forum Composants VCL
    Réponses: 4
    Dernier message: 14/11/2007, 20h26
  2. [vc express] listBox multicolonne
    Par k_boy dans le forum VC++ .NET
    Réponses: 1
    Dernier message: 19/09/2006, 09h56
  3. Boucle avec une listbox multicolonne
    Par morgan47 dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 28/08/2006, 21h45
  4. ListBox Multicolonne à largeur variable
    Par ejaecker dans le forum Delphi
    Réponses: 2
    Dernier message: 21/07/2006, 18h32
  5. Réponses: 4
    Dernier message: 21/07/2006, 14h53

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo