Ceci est une page optimisée pour les mobiles. Cliquez sur ce texte pour afficher la vraie page.

XL 2021 Tri alpha sur combobox à 2 colonnes

Claudinedu13

XLDnaute Junior
Bonjour,

A l'aide du code ci-dessous, j'affiche un combobox à 2 colonnes, ça marche très bien mais je voudrais faire un classement alpha par rapport à la colonne 1, merci si vous pouvez m'aider...

Private Sub UserForm_Activate()
With ComboBox1
.Clear
.ColumnCount = 2
.ColumnWidths = "100;140"
.List = Feuil4.Range("A2:B" & Feuil4.Range("A" & Rows.Count).End(xlUp).Row).Value
End With
End Sub

Private Sub ComboBox1_Change()
TextBox1.Value = ComboBox1.Column(0)
TextBox2.Value = ComboBox1.Column(1)
End Sub
 
Solution
Bonjour
perso dans le raisonnement je vais un peu plus loin
quand on rempli une combobox à 2 colonnes et que l'on fait un tri Alpha ou (<où > que) il convient d'ajouter une colonne a notre variable tableau(par conséquent à la listbox aussi) a fin de memoriser les index de lignes(quitte à la masquer dans le columnwiths
car le plus souvent dans un userform on retranscrit les donnée par la suite ou la colonne dans la listbow n'est qu'une partie du tableau

là encore une fois (et je m'adresse à @Dudu2) il faudra m'expliquer pourquoi passer par une sub passerelle

le quick sort 2D( la belle histoire)
je ne vais pas vous donner la mienne mais je vais vous ajouter les...

Dudu2

XLDnaute Barbatruc
Bonjour,

Tu prends la liste de la ComboBox pour la mettre dans un tableau à 2 dimensions, puis tu utilises la fonction de tri de Boisgontier, puis tu replaces le tableau dans la liste de la ComboBox.
VB:
'-------------------------------
'Tri d'un tableau à 2 dimensions
'-------------------------------
Sub TriTab2Dim(tt As Variant, ByVal ColonneTri As Variant, Optional ByVal Sens As Integer = 1)
    Call TriT2D(tt, ColonneTri, LBound(tt, 1), UBound(tt, 1), Sens)
End Sub

'------------------------------------------------------------------
'Tri QuickSort Boisgontier
'http://boisgontierj.free.fr/pages_site/tableaux.htm#Tri2DSansIndex
'Exemple: Call TriT2D(tt, 1, LBound(tt, 1), UBound(tt, 1))
'------------------------------------------------------------------
Sub TriT2D(a, ColTri, gauc, droi, Optional sens = 1) ' Quick sort
    Dim ref, g, d, k, temp
    ref = a((gauc + droi) \ 2, ColTri)
    g = gauc: d = droi
    Do
        If sens > 0 Then
            Do While a(g, ColTri) < ref: g = g + 1: Loop
            Do While ref < a(d, ColTri): d = d - 1: Loop
        Else
            Do While a(g, ColTri) > ref: g = g + 1: Loop
            Do While ref > a(d, ColTri): d = d - 1: Loop
        End If
        If g <= d Then
            For k = LBound(a, 2) To UBound(a, 2)
                temp = a(g, k): a(g, k) = a(d, k): a(d, k) = temp
            Next k
            g = g + 1: d = d - 1
        End If
    Loop While g <= d
    If g < droi Then Call TriT2D(a, ColTri, g, droi, sens)
    If gauc < d Then Call TriT2D(a, ColTri, gauc, d, sens)
End Sub
 

Claudinedu13

XLDnaute Junior
Bon pour l'instant, c'est trop compliqué pour moi de mettre ça en place, merci de ta réponse je la garde sous le coude.
 

Dudu2

XLDnaute Barbatruc
Bonjour,
Sur la base de ton code:
VB:
Private Sub UserForm_Activate()
    Dim TabVal() As Variant
    
    With ComboBox1
        .Clear
        .ColumnCount = 2
        .ColumnWidths = "100;140"
        TabVal = Feuil4.Range("A2:B" & Feuil4.Range("A" & Rows.Count).End(xlUp).Row).Value
        Call TriTab2Dim(TabVal, 1)
        .List = TabVal
    End With
End Sub

'-------------------------------
'Tri d'un tableau à 2 dimensions
'-------------------------------
Sub TriTab2Dim(tt As Variant, ByVal ColonneTri As Variant, Optional ByVal sens As Integer = 1)
    Call TriT2D(tt, ColonneTri, LBound(tt, 1), UBound(tt, 1), sens)
End Sub

'------------------------------------------------------------------
'Tri QuickSort Boisgontier
'http://boisgontierj.free.fr/pages_site/tableaux.htm#Tri2DSansIndex
'Exemple: Call TriT2D(tt, 1, LBound(tt, 1), UBound(tt, 1))
'------------------------------------------------------------------
Sub TriT2D(a, ColTri, gauc, droi, Optional sens = 1) ' Quick sort
    Dim ref, g, d, k, temp
    ref = a((gauc + droi) \ 2, ColTri)
    g = gauc: d = droi
    Do
        If sens > 0 Then
            Do While a(g, ColTri) < ref: g = g + 1: Loop
            Do While ref < a(d, ColTri): d = d - 1: Loop
        Else
            Do While a(g, ColTri) > ref: g = g + 1: Loop
            Do While ref > a(d, ColTri): d = d - 1: Loop
        End If
        If g <= d Then
            For k = LBound(a, 2) To UBound(a, 2)
                temp = a(g, k): a(g, k) = a(d, k): a(d, k) = temp
            Next k
            g = g + 1: d = d - 1
        End If
    Loop While g <= d
    If g < droi Then Call TriT2D(a, ColTri, g, droi, sens)
    If gauc < d Then Call TriT2D(a, ColTri, gauc, d, sens)
End Sub
 

Claudinedu13

XLDnaute Junior
Merci beaucoup de l'aide que tu me fournis, il faut que je travaille pour arriver à faire un code seule et non des copier coller, mais je ne sais pas par où commencer ?

Pour ce qui est du code j'ai mis le tien et le tri alphabétique ne se fait pas, il faut rajouter quelque chose ?
 

patricktoulon

XLDnaute Barbatruc
Bonjour
perso dans le raisonnement je vais un peu plus loin
quand on rempli une combobox à 2 colonnes et que l'on fait un tri Alpha ou (<où > que) il convient d'ajouter une colonne a notre variable tableau(par conséquent à la listbox aussi) a fin de memoriser les index de lignes(quitte à la masquer dans le columnwiths
car le plus souvent dans un userform on retranscrit les donnée par la suite ou la colonne dans la listbow n'est qu'une partie du tableau

là encore une fois (et je m'adresse à @Dudu2) il faudra m'expliquer pourquoi passer par une sub passerelle

le quick sort 2D( la belle histoire)
je ne vais pas vous donner la mienne mais je vais vous ajouter les option qu'il convient a fin de vous simplifier la vie
a° le tableau peut être en base 0 où 1
b° à l'instar de ma version quicksort je vais mettre certains argument de la sub de Jacques en optional
cela simplifiera les appels et vous allez le voir les options de ce fait sont nombreuses
et surtout pas besoins de passer par une passerelles(@Dudu2 me pardonnera )

dont je reprends le code de @Dudu2

VB:
Private Sub UserForm_Activate()
    Dim TabVal() As Variant
    With ComboBox1
puis ceci


Code:
'version @dudu2
.Clear
.ColumnCount = 2
.ColumnWidths = "100;140;20"
TabVal = Feuil1.Range("A2:B" & Feuil1.Range("A" & Rows.Count).End(xlUp).Row).Value

ou ma version
VB:
'version @patricktoulon
        .Clear
        .ColumnCount = 3
        .ColumnWidths = "100;140;20"
        TabVal = Feuil1.Range("A2:C" & Feuil1.Range("A" & Rows.Count).End(xlUp).Row).Value'(3 colonnes)
        For i = LBound(TabVal) To UBound(TabVal): TabVal(i, 3) = i: Next'inscription des index du tableau

ensuite toutes méthode d'appels
VB:
        'Call TriT2D(TabVal)                'ordre ALPHA(par défaut A à Z) et par la colonne 1 par defaut

        'Call TriT2D(TabVal, sens:=1)       'ordre ALPHA(A à Z) par la colonne 1 par defaut
        'Call TriT2D(TabVal, sens:=0)       'ordre ALPHA(Z à A) par la colonne 1 par defaut

        'Call TriT2D(TabVal,1, sens:=1)     'ordre ALPHA(A à Z) par la colonne 1 explicite
        'Call TriT2D(TabVal,1, sens:=0)     'ordre ALPHA(Z à A) par la colonne 1 explicite

        'Call TriT2D(TabVal, 2, sens:=1)    'DU PLUS PETIT AU PLUS GRAND  colonne 2 explicite
        Call TriT2D(TabVal, 2, sens:=0)     'DU PLUS GRAND AU PLUS PETIT  colonne 2 explicite
        .List = TabVal
    End With
End Sub

voila pour le activate c'est bon
ensuite la sub de Jacques Boigontier remastered
comme vous pouvez le constater il y a eu du changement
certains arguments sont optionnels et on comprends pourquoi dans les exemples d'appels dans le activate
il vous reste plus qu'a choir l'exemple qui convient a votre besoins (dans le activate )
en supprimant l'apostrophe devant
Code:
'------------------------------------------------------------------
'Tri QuickSort Boisgontier
'http://boisgontierj.free.fr/pages_site/tableaux.htm#Tri2DSansIndex
'Exemple: Call TriT2D(tt, 1, LBound(tt, 1), UBound(tt, 1))
'Remastered Options Arguments to Optional by Patricktoulon
'------------------------------------------------------------------
Sub TriT2D(a, Optional colTri& = -1, Optional gauc = -1, Optional droi = -1, Optional sens& = 1)    ' Quick sort
    Dim ref, g, d, k, temp

    If gauc = -1 Then gauc = LBound(a)
    If droi = -1 Then droi = UBound(a)
    If colTri = -1 Then colTri = LBound(a, 2)

    ref = a((gauc + droi) \ 2, colTri)
    g = gauc: d = droi
    Do
        If sens > 0 Then
            Do While a(g, colTri) < ref: g = g + 1: Loop
            Do While ref < a(d, colTri): d = d - 1: Loop
        Else
            Do While a(g, colTri) > ref: g = g + 1: Loop
            Do While ref > a(d, colTri): d = d - 1: Loop
        End If
        If g <= d Then
            For k = LBound(a, 2) To UBound(a, 2)
                temp = a(g, k): a(g, k) = a(d, k): a(d, k) = temp
            Next k
            g = g + 1: d = d - 1
        End If
    Loop While g <= d
    If g < droi Then Call TriT2D(a, colTri, g, droi, sens)
    If gauc < d Then Call TriT2D(a, colTri, gauc, d, sens)
End Sub

le code compilé
VB:
Private Sub ComboBox1_Change()
    With ComboBox1
        If .ListIndex > -1 Then MsgBox .Value & "/" & .List(.ListIndex, 1) & " ligne originale : " & .List(.ListIndex, 2)+1
    End With
End Sub

Private Sub UserForm_Activate()
    Dim TabVal() As Variant
    With ComboBox1
        'version @dudu2
        '.Clear
        '.ColumnCount = 2
        '.ColumnWidths = "100;140;20"
        'TabVal = Feuil1.Range("A2:B" & Feuil1.Range("A" & Rows.Count).End(xlUp).Row).Value
        '**************************************************
        'version @patricktoulon
        .Clear
        .ColumnCount = 3
        .ColumnWidths = "100;140;20"
        TabVal = Feuil1.Range("A2:C" & Feuil1.Range("A" & Rows.Count).End(xlUp).Row).Value
        For i = LBound(TabVal) To UBound(TabVal): TabVal(i, 3) = i: Next
        '**************************************************

        Call TriT2D(TabVal)                'ordre ALPHA(par défaut de A à Z) et par la colonne 1 par defaut

        'Call TriT2D(TabVal, sens:=1)       'ordre ALPHA(de A à Z) par la colonne 1 par defaut
        'Call TriT2D(TabVal, sens:=0)       'ordre ALPHA(de Z à A) par la colonne 1 par defaut

        'Call TriT2D(TabVal,1, sens:=1)     'ordre ALPHA(de A à Z) par la colonne 1 explicite
        'Call TriT2D(TabVal,1, sens:=0)     'ordre ALPHA(de Z à A) par la colonne 1 explicite

        'Call TriT2D(TabVal, 2, sens:=1)    'DU PLUS PETIT AU PLUS GRAND  colonne 2 explicite
        'Call TriT2D(TabVal, 2, sens:=0)    'DU PLUS GRAND AU PLUS PETIT  colonne 2 explicite
        .List = TabVal
    End With
End Sub


'------------------------------------------------------------------
'Tri QuickSort Boisgontier
'http://boisgontierj.free.fr/pages_site/tableaux.htm#Tri2DSansIndex
'Exemple: Call TriT2D(tt, 1, LBound(tt, 1), UBound(tt, 1))
'Remastered Options Arguments to Optional by Patricktoulon
'------------------------------------------------------------------
Sub TriT2D(a, Optional colTri& = -1, Optional gauc = -1, Optional droi = -1, Optional sens& = 1)    ' Quick sort
    Dim ref, g, d, k, temp

    If gauc = -1 Then gauc = LBound(a)
    If droi = -1 Then droi = UBound(a)
    If colTri = -1 Then colTri = LBound(a, 2)

    ref = a((gauc + droi) \ 2, colTri)
    g = gauc: d = droi
    Do
        If sens > 0 Then
            Do While a(g, colTri) < ref: g = g + 1: Loop
            Do While ref < a(d, colTri): d = d - 1: Loop
        Else
            Do While a(g, colTri) > ref: g = g + 1: Loop
            Do While ref > a(d, colTri): d = d - 1: Loop
        End If
        If g <= d Then
            For k = LBound(a, 2) To UBound(a, 2)
                temp = a(g, k): a(g, k) = a(d, k): a(d, k) = temp
            Next k
            g = g + 1: d = d - 1
        End If
    Loop While g <= d
    If g < droi Then Call TriT2D(a, colTri, g, droi, sens)
    If gauc < d Then Call TriT2D(a, colTri, gauc, d, sens)
End Sub

Voila testez le fichier
@+ patrick
 

Pièces jointes

  • Exemple Combobox triée Méthode QuickSort.xlsm
    19.9 KB · Affichages: 6

Dudu2

XLDnaute Barbatruc
Pour ce qui est du code j'ai mis le tien et le tri alphabétique ne se fait pas, il faut rajouter quelque chose ?
Faudrait voir le code que tu as mis. Le code fourni testé fonctionne.
Si le fichier n'est pas confidentiel joins-le à la réponse par un "drag & drop" dans le texte de ta réponse.
S'il l'est copie le code concerné en prenant soin d'utiliser le formatage de code avec ce symbole

@patricktoulon, elle ne pourra pas utiliser ton système, elle est déjà perdue avec un truc basique.
 

patricktoulon

XLDnaute Barbatruc
bonjour @Dudu2
ben justement c'est du tout maché
et moi ce qui me perd c'est les passerelles
tu te rend compte ,elle ne connait pas et tu lui apprends de cette manière ( des passerelles avec des variables qui se ballade de sub en sub et qui ont un nom différent en plus
c'est a en perdre la boussole ton truc pour un(e) novice
crois tu que c'est une bonne idée de lui montrer de travailler comme ça au depart ?

perso
on lui montre les bonnes pratiques (combien même si c'est compliqué au départ) et si elle comprends pas on lui explique

la mécanique de la fonction; si elle ne le comprend pas tout de suite c'est pas grave ,elle l'utilise c'est tout
quand elle aura un niveau plus costaud elle sera à même de digérer la méthode, si tant est que ca l'intéresse
 

Claudinedu13

XLDnaute Junior
je suis perdu c'est vrai, mais je n'ai pas réussi à faire fonctionner ton système , mais j'ai réussi avec le système de @patrickcoulon
 

Claudinedu13

XLDnaute Junior
Merci à toi , j'ai réussi à mettre en place ton système, un petit classement alpha sur colonne 2,
Call TriT2D(TabVal, 2, sens:=1)

génial l'aide sur ce site.

Merci à Dudu2 également
 

Pièces jointes

  • Capture d’écran 2024-01-05 171845.jpg
    47.8 KB · Affichages: 2

fanch55

XLDnaute Barbatruc
Salut et bonne année à tous,
Je m'interroge et vous aussi : pourquoi ne pas avoir trié le tableau source avant l'affichage de l'USF ?
Une modification de données (existantes) n'influe pas sur le nombre ni la position des lignes .
Une modification de structure ( ajout ou suppression) devra n'importe comment provoquer le rechargement du combobox .
 

Dudu2

XLDnaute Barbatruc
Bonjour @fanch55,
Tu ne connais pas les contraintes utilisateur du tableau source.
Trier le tableau source pour charger la ComboBox, OK. Mais après, comment tu remets les lignes dans le bon ordre si cet ordre est nécessaire d'un point de vue utilisateur ?
Un tri mémoire, surtout un QuickSort, ça dépote tout autant.
 

patricktoulon

XLDnaute Barbatruc
Bonsoir @fanch55
meilleurs veux pour 2024

Allez comme ça on fait plaisir à tout le monde
On peut recharger a tout moment le tableau avec reliste le trier (ou pas)
Et cela dans n'importe quel events
VB:
Dim TabVal() As Variant

Private Sub ComboBox1_Change()
    With ComboBox1
        If .ListIndex > -1 Then MsgBox .Value & "/" & .List(.ListIndex, 1) & " ligne originale : " & .List(.ListIndex, 2) + 1
    End With
End Sub

Private Sub UserForm_Activate()
    With ComboBox1
        'version @dudu2
        '.Clear
        '.ColumnCount = 2
        '.ColumnWidths = "100;140;20"
        'TabVal = Feuil1.Range("A2:B" & Feuil1.Range("A" & Rows.Count).End(xlUp).Row).Value
        '**************************************************
        'version @patricktoulon
        .Clear
        .ColumnCount = 3
        .ColumnWidths = "100;140;20"
        reliste
        Call TriT2D(TabVal)                'ordre ALPHA(par défaut de A à Z) et par la colonne 1 par defaut
        ComboBox1.List = TabVal
        '**************************************************
        'Call TriT2D(TabVal, sens:=1)       'ordre ALPHA(de A à Z) par la colonne 1 par defaut
        'Call TriT2D(TabVal, sens:=0)       'ordre ALPHA(de Z à A) par la colonne 1 par defaut

        'Call TriT2D(TabVal,1, sens:=1)     'ordre ALPHA(de A à Z) par la colonne 1 explicite
        'Call TriT2D(TabVal,1, sens:=0)     'ordre ALPHA(de Z à A) par la colonne 1 explicite

        'Call TriT2D(TabVal, 2, sens:=1)    'DU PLUS PETIT AU PLUS GRAND  colonne 2 explicite
        'Call TriT2D(TabVal, 2, sens:=0)    'DU PLUS GRAND AU PLUS PETIT  colonne 2 explicite
        .List = TabVal
    End With
End Sub
Sub reliste()
    TabVal = Feuil1.Range("A2:C" & Feuil1.Range("A" & Rows.Count).End(xlUp).Row).Value
    For i = LBound(TabVal) To UBound(TabVal): TabVal(i, 3) = i: Next
End Sub

'------------------------------------------------------------------
'Tri QuickSort Boisgontier
'http://boisgontierj.free.fr/pages_site/tableaux.htm#Tri2DSansIndex
'Exemple: Call TriT2D(tt, 1, LBound(tt, 1), UBound(tt, 1))
'Remastered Options Arguments to Optional by Patricktoulon
'------------------------------------------------------------------
Sub TriT2D(a, Optional colTri& = -1, Optional gauc = -1, Optional droi = -1, Optional sens& = 1)    ' Quick sort
    Dim ref, g, d, k, temp

    If gauc = -1 Then gauc = LBound(a)
    If droi = -1 Then droi = UBound(a)
    If colTri = -1 Then colTri = LBound(a, 2)

    ref = a((gauc + droi) \ 2, colTri)
    g = gauc: d = droi
    Do
        If sens > 0 Then
            Do While a(g, colTri) < ref: g = g + 1: Loop
            Do While ref < a(d, colTri): d = d - 1: Loop
        Else
            Do While a(g, colTri) > ref: g = g + 1: Loop
            Do While ref > a(d, colTri): d = d - 1: Loop
        End If
        If g <= d Then
            For k = LBound(a, 2) To UBound(a, 2)
                temp = a(g, k): a(g, k) = a(d, k): a(d, k) = temp
            Next k
            g = g + 1: d = d - 1
        End If
    Loop While g <= d
    If g < droi Then Call TriT2D(a, colTri, g, droi, sens)
    If gauc < d Then Call TriT2D(a, colTri, gauc, d, sens)
End Sub
 

fanch55

XLDnaute Barbatruc
C'est vrai qu'on ne connait pas les contraintes de la demandeuse ...
Moi, j'avais imaginé un code du genre :
  • on sauvegarde les tris en cours
  • on trie les données comme on veut
  • on charge le combobox
  • on affiche l'usf
  • on rétablit les tris précédents à la fermeture de l'Usf
Mais c'est vrai qu'un travail avec un tableau dynamique est plus rapide ...

VB:
Dim Save_Tri As Variant
Private Sub UserForm_Terminate()
    TriCur Feuil4 ' Restauration du tri en cours
End Sub
Private Sub UserForm_Activate()
Dim Tableau As Range
    TriCur Feuil4 ' Sauvegarde du tri en cours
    Set Tableau = Feuil4.Range("A1:C" & Feuil4.Cells(Feuil4.Rows.Count, "A").End(xlUp).Row)
    With Feuil4.Sort
        .SortFields.Clear
        .SortFields.Add2 Key:=Tableau.Columns(2), SortOn:=xlSortOnValues, Order:=xlAscending
        .SetRange Tableau
        .Header = xlYes
        .MatchCase = False
        .Orientation = xlTopToBottom
        .SortMethod = xlPinYin
        .Apply
    End With

    With ComboBox1
        .Clear
        .ColumnCount = 2
        .ColumnWidths = Tableau.Columns(1).Width & ";" & Tableau.Columns(2).Width
        .List = Tableau.Offset(1).Resize(Tableau.Rows.Count - 1).Value
    End With

End Sub
Private Sub ComboBox1_Change()
    TextBox1.Value = ComboBox1.Column(0)
    TextBox2.Value = ComboBox1.Column(1)
End Sub
Function TriCur(Feuil As Worksheet) As Variant
Dim F As SortField
    With Feuil.Sort
        If IsEmpty(Save_Tri) Then ' on sauvegarde les tris existants
            For Each F In .SortFields
                Save_Tri = IIf(Save_Tri = "", "", Save_Tri & vbLf) & F.Key.Address & vbTab & F.Order & vbTab & F.SortOn
            Next
        Else ' on restaure les tris sauvegardés
            .SortFields.Clear
            Save_Tri = Split(Save_Tri, vbLf)
            For Each Elem In Save_Tri
                Elem = Split(Elem, vbTab)
                .SortFields.Add2 Key:=.Parent.Range(Elem(0)), Order:=Elem(1), SortOn:=Elem(2)
            Next
            .SetRange Feuil.Range("A1:C" & Feuil.Cells(Feuil.Rows.Count, "A").End(xlUp).Row)
            .Header = xlYes
            .MatchCase = False
            .Orientation = xlTopToBottom
            .SortMethod = xlPinYin
            .Apply
        End If
    End With
End Function
 
Dernière édition:

Discussions similaires

Réponses
6
Affichages
485
Les cookies sont requis pour utiliser ce site. Vous devez les accepter pour continuer à utiliser le site. En savoir plus…