Tri Multi Colonne Tableau VBA Le sujet est résolu

Y compris Power BI, Power Query et toute autre question en lien avec Excel
Avatar du membre
pmfontaine
Membre habitué
Membre habitué
Messages : 67
Inscrit le : 4 juillet 2016
Version d'Excel : 2013

Message par pmfontaine » 21 décembre 2019, 10:51

Bonjour,
Avec le code si dessous (trouvé sur le NET, Je ne sais plus où, désolé pour l'auteur),
je fais un tri d'un tableau VBA mais toujours de A à Z
Mais sur une des colonne je voudrais faire un tri inversé (de Z à A)
Est-ce que l'un d'entre vous peut m'aider ou m'orienter vers un sujet qui m'aiderai (Rien trouvé dans mes recherche)
Merci d'avance pour votre aide.
Patrick
Option Explicit
Dim tabloBDD
Sub TriBDD2Critère()
With FSourceTaxref
tabloBDD = .Cells(2, 1).Resize(.Cells(Rows.Count, 1).End(xlUp).Row - 1, 4)
End With
TriTabMult tabloBDD, 1, 3, 2
FSourceTaxref.[F1].Resize(UBound(tabloBDD), 4) = tabloBDD
End Sub
Option Compare Text
Sub TriTabMult(Tbl, Optional ColTri1, Optional Coltri2, Optional Coltri3)
 If IsMissing(ColTri1) Then ColTri1 = 1
 Dim clé() As String: ReDim clé(LBound(Tbl) To UBound(Tbl))
 Dim idx() As Long: ReDim idx(LBound(Tbl) To UBound(Tbl))
 Dim b(): ReDim b(LBound(Tbl) To UBound(Tbl), LBound(Tbl, 2) To UBound(Tbl, 2))
 If IsNumeric(Tbl(1, ColTri1)) Or IsDate(Tbl(1, ColTri1)) Then Tri1 = "num"
 If Not IsMissing(Coltri2) Then If IsNumeric(Tbl(1, Coltri2)) Or IsDate(Tbl(1, Coltri2)) Then Tri2 = "num"
 If Not IsMissing(Coltri3) Then If IsNumeric(Tbl(1, Coltri3)) Or IsDate(Tbl(1, Coltri3)) Then Tri2 = "num"

 For i = LBound(Tbl) To UBound(Tbl)
    If Tri1 = "num" Then col1 = Format(Tbl(i, ColTri1), "0000000") Else col1 = Tbl(i, ColTri1)
    If Not IsMissing(Coltri2) Then
      If Tri2 = "num" Then col2 = Format(Tbl(i, Coltri2), "0000000") Else col2 = Tbl(i, Coltri2)
    Else
      col2 = ""
    End If
    If Not IsMissing(Coltri3) Then
      If tri3 = "num" Then col3 = Format(Tbl(i, Coltri3), "0000000") Else col3 = Tbl(i, Coltri3)
    Else
      col3 = ""
    End If
    clé(i) = col1 & "_" & col2 & "_" & col3
    idx(i) = i
 Next i
 Call QuickI(clé(), idx(), LBound(clé), UBound(clé))
 For lig = LBound(clé) To UBound(clé)
   For Col = LBound(Tbl, 2) To UBound(Tbl, 2): b(lig, Col) = Tbl(idx(lig), Col): Next Col
 Next lig
 For lig = LBound(clé) To UBound(clé)
    For Col = LBound(Tbl, 2) To UBound(Tbl, 2): Tbl(lig, Col) = b(lig, Col): Next Col
 Next lig
End Sub

Sub QuickI(clé() As String, index() As Long, gauc, droi) ' Quick sort
  ref = clé((gauc + droi) \ 2)
  g = gauc: d = droi
  Do
    Do While clé(g) < ref: g = g + 1: Loop
    Do While ref < clé(d): d = d - 1: Loop
    If g <= d Then
      temp = clé(g): clé(g) = clé(d): clé(d) = temp
      temp = index(g): index(g) = index(d): index(d) = temp
      g = g + 1: d = d - 1
    End If
  Loop While g <= d
  If g < droi Then Call QuickI(clé, index, g, droi)
  If gauc < d Then Call QuickI(clé, index, gauc, d)
End Sub
TriTableauVBAPlusieursColonnes.xlsm
(644.04 Kio) Téléchargé 157 fois
h
h2so4
Passionné d'Excel
Passionné d'Excel
Messages : 9'464
Appréciations reçues : 428
Inscrit le : 16 juin 2013
Version d'Excel : 365 UK Windows 10

Message par h2so4 » 21 décembre 2019, 11:29

Bonjour,

solution en utilisant la méthode sort de l'objet range
Sub aargh()
    dl = Cells(Rows.Count, 1).End(xlUp).Row
    Range("A1").Resize(dl, 4).Copy Range("F1") 'copie du tableau en colonne F,G,H,I
    Range("F1").Resize(dl, 4).Sort key1:=Range("F1"), order1:=xlAscending, key2:=Range("H1"), order2:=xlDescending, key3:=Range("I1"), order3:=xlAscending, Header:=xlYes 'tri du tableau
End Sub
Avatar du membre
pmfontaine
Membre habitué
Membre habitué
Messages : 67
Inscrit le : 4 juillet 2016
Version d'Excel : 2013

Message par pmfontaine » 21 décembre 2019, 18:47

Bonsoir H2So4
Merci pour ton aide et pour ta solution qui marche très bien si on passe par une feuille Excel.
Mais j'aurais souhaité avoir une adaptation de mon code existant ou une autre solution me permettant de trié le tableau VBA obtenu avec :
With FSourceTaxref
tabloBDD = .Cells(2, 1).Resize(.Cells(Rows.Count, 1).End(xlUp).Row - 1, 4)
End With
D’où ma question avec "Tableau VBA"
et utiliser ce tableau dans mon code sans mettre le tableau trié sur une feuille.
(Mon vrai tableau comporte plus de 40 000 ligne et 32 colonnes)
Merci
Patrick
Modifié en dernier par pmfontaine le 21 décembre 2019, 19:09, modifié 1 fois.
B
Boisgontierjacques
Membre fidèle
Membre fidèle
Messages : 470
Appréciations reçues : 109
Inscrit le : 5 octobre 2018
Version d'Excel : 2016

Message par Boisgontierjacques » 21 décembre 2019, 18:47

Bonsoir,

Cf pgm joint (non testé)

Boisgontier
TriTableau2DIndex3CritAscDesc.xls
(51.5 Kio) Téléchargé 155 fois
Avatar du membre
pmfontaine
Membre habitué
Membre habitué
Messages : 67
Inscrit le : 4 juillet 2016
Version d'Excel : 2013

Message par pmfontaine » 21 décembre 2019, 20:06

Bonsoir Jacques,
Voila ce qui correspond mieux a ma recherche.
Le code original vient probablement de ton site sur lequel je trouve beaucoup de solutions, merci beaucoup pour tous ce travail.

Pour le code que tu me propose, sauf erreur de ma part, çà marche si la colonne descendant est un chiffre (Du plus grand au plus petit), mais ne marche pas si c'est du texte. (FEUILLE2 Colonne 3 (Les prénoms reste dans l'ordre alphabétique)
Voir fichier joint (FEUILLE1 et FEUILLE2)
Merci
TriTableau2DIndex3CritAscDescV2.xls
(65.5 Kio) Téléchargé 147 fois
h
h2so4
Passionné d'Excel
Passionné d'Excel
Messages : 9'464
Appréciations reçues : 428
Inscrit le : 16 juin 2013
Version d'Excel : 365 UK Windows 10

Message par h2so4 » 22 décembre 2019, 00:50

Bonsoir,

une adaptation du code de Jacques pour inclure le tri descendant alphabétique.

Pas sûr que cette correction soit plus efficace que le tri via les fonctions tri d'excel, d'autant plus que tu mets le résultat final sur une feuille.
TriTableau2DIndex3CritAscDescrev1.xls
(52.5 Kio) Téléchargé 151 fois
Avatar du membre
pmfontaine
Membre habitué
Membre habitué
Messages : 67
Inscrit le : 4 juillet 2016
Version d'Excel : 2013

Message par pmfontaine » 22 décembre 2019, 11:18

Merci H2So4 pour ta réponse.
Je vais tester ta prosition;
h2so4 a écrit :
22 décembre 2019, 00:50
d'autant plus que tu mets le résultat final sur une feuille.
Oui dans mon exemple de fichier, pour faire simple (enfin je croyais) mais dans mon application, je ne mets pas le résultat final sur une feuille je récupère uniquement certaines valeurs avec plusieurs conditions.

P.S.
Lorsque j'écris sur les forum ou dans mes recherche sur le Net, Je nome "Tableau VBA" un tableau créé en VBA avec
With FSourceTaxref
tabloBDD = .Cells(2, 1).Resize(.Cells(Rows.Count, 1).End(xlUp).Row - 1, 4)
End With
Est-ce que cette désignation est correcte ?
Avatar du membre
pmfontaine
Membre habitué
Membre habitué
Messages : 67
Inscrit le : 4 juillet 2016
Version d'Excel : 2013

Message par pmfontaine » 22 décembre 2019, 12:05

Re Bonjour
Je viens de tester la solution de H2So4.
Mais j'ai un autre problème !
En effet, le tri alphabétique ascendant ou descendant me fonctionne pas avec les accents.
en effet sur des noms d'oiseaux j'obtiens :
Accenteur mouchet
Bruant fou
Bruant zizi
Buse variable
Bécasse des bois
Chardonneret élégant
Moineau domestique
Mésange charbonnière
Mésange à longue queue

Troglodyte mignon
Verdier d'Europe
Épervier d'Europe
Étourneau sansonnet
Les nom soulignés, ne sont pas à la bonne place ?
Voir fichier joint
Merci
TriTableau2DIndex3CritAscDescV3.xlsm
(22.69 Kio) Téléchargé 150 fois
B
Boisgontierjacques
Membre fidèle
Membre fidèle
Messages : 470
Appréciations reçues : 109
Inscrit le : 5 octobre 2018
Version d'Excel : 2016

Message par Boisgontierjacques » 22 décembre 2019, 12:21

Bonjour,

Il faut utiliser une fonction SansAccent() avant le tri mais qui ralentira.
Function sansAccent(chaine)
   codeA = "ÉÈÊËÔéèêëàçùôûïî"
   codeB = "EEEEOeeeeacuouii"
   temp = chaine
   For i = 1 To Len(temp)
    p = InStr(codeA, Mid(temp, i, 1))
    If p > 0 Then Mid(temp, i, 1) = Mid(codeB, p, 1)
   Next
   sansAccent = temp
End Function
Boisgontier
Avatar du membre
pmfontaine
Membre habitué
Membre habitué
Messages : 67
Inscrit le : 4 juillet 2016
Version d'Excel : 2013

Message par pmfontaine » 22 décembre 2019, 15:45

Bonjour
Merci Jacques,
Ça marche et la différence de temps d’exécution est de 0.42 s (pour BDD de 37434 lignes et 27 colonnes)
Donc c'est parfait pour moi.
Bonnes fêtes de fin d'année à tous
Patrick
Répondre
  • Sujets similaires
    Réponses
    Vues
    Dernier message