XL 2010 Trier une Variable Tableau en VBA

Nicodemius

XLDnaute Nouveau
Bonjour,
Je tente désespérément de créer une fonction pour Trier une variable Tableau.
Pour le moment elle fonctionne mais seulement en ordre croissant.
J'utilise le module de classe [Sorted List] de Jacques BOISGONTIER que j'ai trouvé sur un fil :
Fonction de tri d'une variable tableau en VBA (Sparrow, Décembre 2013)

Vu que le sujet date un peu, j'ai préféré créer une nouvelle discussion.

Si quelqu'un a une idée, surtout qu'il n'hésite pas. :rolleyes:

Bonne soirée à tous.
 

Pièces jointes

  • Public Function TrierCol.txt
    889 bytes · Affichages: 28
Solution
Classe Tris réduite


VB:
Sub TriCroissant()
   Tbl = [a3:D8].Value
   Set montab = New Tris       ' instanciation de la classe Tris
   montab.Tri Tbl, 2               ' tri col 2
   [a3:D8].Value2 = Tbl
End Sub

Sub TriDéCroissant()
   Tbl = [a3:D8].Value
   Set montab = New Tris        ' instanciation de la classe Tris
   montab.TriInv Tbl, 2            ' tri col 2
   [a3:D8].Value2 = Tbl
End Sub


Boisgontier

Dranreb

XLDnaute Barbatruc
Bonsoir.
J'ai un processus très légèrement plus rapide que le Qick-sort si ça vous intéresse, pour indexer un tableau de Variant. Il ne change pas l'ordre des éléments du tableau, mais produit dans un tableau de Long les numéros de lignes dans l'ordre nécessaire pour y accéder en ordre croissant ou décroissant d'une ou plusieurs colonnes.
 

cp4

XLDnaute Barbatruc
Salut :),
Une autre de Boisgontier que j'ai utilisé dernièrement.
VB:
Private Sub UserForm_Initialize()
'je l'ai utilisé dans userform
Quick TbStc(), LBound(TbStc), UBound(TbStc), 5, True   'on trie TbStc par rapport à la colonne 5
End Sub

Sub Quick(A(), gauc, droi, col, ordre)   ' Quick sort
    Dim ref, g, d, i As Long, temp
    ref = A((gauc + droi) \ 2, col)
    g = gauc: d = droi
    Do
        If ordre Then
            Do While A(g, col) < ref: g = g + 1: Loop
            Do While ref < A(d, col): d = d - 1: Loop
        Else
            Do While A(g, col) > ref: g = g + 1: Loop
            Do While ref > A(d, col): d = d - 1: Loop
        End If
        If g <= d Then
            For i = LBound(A, 2) To UBound(A, 2)
                temp = A(g, i): A(g, i) = A(d, i): A(d, i) = temp
            Next i
            g = g + 1: d = d - 1
        End If
    Loop While g <= d
    If g < droi Then Call Quick(A, g, droi, col, ordre)
    If gauc < d Then Call Quick(A, gauc, d, col, ordre)
End Sub
 

Dranreb

XLDnaute Barbatruc
Bonjour Dranred je veux bien cela m’intéresse aussi
C'est qu'il est intégré à un module de service plus général, compte tenu de ce que si on souhaite classer un tableau sans utiliser de tri Excel, c'est en général en vue d'en faire quelque chose derrière. Alors la fonction Gigogne regroupe tout ça en collections imbriquées.

Attention c'est un précurseur de complément xlam.
 

Pièces jointes

  • GigIdx.xlsm
    90.3 KB · Affichages: 16

jmfmarques

XLDnaute Accro
Bonjour
Je n'ouvre jamais les classeurs tiers et n'en ai donc ouvert aucun de ceux ici déposés.

Juste une observation :
- Excel dispose et offre de manière native de quoi trier facilement et comme on l'entend toute plage de données
- toute matrice (tableau) peut alimenter toute plage, alors facilement triable par Excel/VBA

Je ne m'embêterais dans ces conditions personnellement pas et utiliserais une feuille tremplin à cet effet.
 

jmfmarques

XLDnaute Accro
Merci Laurent
Voilà qui me conforte dans le choix du mécanisme évoqué :
-- alimenter une feuille "tremplin" avec ce tableau
- utiliser Exel/VBA pour trier la plage ainsi construite
- affecter les valeurs de cette plage ainsi triée à un tableau résultat.
Ce devrait être plutôt confortable, me paraît-il.
 

Staple1600

XLDnaute Barbatruc
Bonsoir le fil, Nicodemius, cp4, Laurent950, sylvanu, Dranreb, jmfmarques

Autre piste (pour ceux qui sont sous Windows)
(A tester sur une feuille vierge)
VB:
Sub test()
Dim c, tablo, tabloo 'déclarations variables
'Ne fonctionne que sur PC (pas sur MAC)
'A tester sur une feuille vide
[A1:A1600] = "=1600-MOD(ROW()-1,7)" '1) Insertion formule
'pour avoir des données en doublons
'et 1600 pour la blague, rapport à mon pseudo.
[A1:A1600] = [A1:A1600].Value '2) on transforme en valeur
    With CreateObject("System.Collections.ArrayList")
        For Each c In Range("A1", Cells(Rows.Count, 1).End(3)).Value
            If Not .Contains(c) Then .Add c 'sans doublons
        Next
    .Sort 'tri croissant
    tablo = (.ToArray)
    .Reverse ' tri décroissant
    tabloo = (.ToArray)
    'NB: voir limitation de Transpose (erreur si plus 65536 lignes)
'restitution en colonne (d'où utilisation de Transpose)
    Cells(1).Offset(, 2).Resize(.Count).Value = Application.Transpose(tablo)
'restitution en ligne
    Cells(1).Offset(, 4).Resize(, .Count).Value = tabloo
    End With
    'PS:Ce code n'était qu'un test illustratif
End Sub
EDITION: ajouts commentaires pour répondre aux interrogations de laurent950.
 
Dernière édition:

Nicodemius

XLDnaute Nouveau
Bonjour à tous. A peine une heure après mon premier post, tant de réponses !!
Inespéré. o_O

Merci Dranreb, laurent950, cp4 et même au schtroumpf grognon.
J'avoue que je n'en espérais pas tant.

@Dranreb
Oui, avec plaisir. Je suis ouvert à toute suggestion et toutes sources d'inspiration.
Mais comme le disait à juste titre jmfmarques, je préfère les fichiers sources sous formes de fichier texte afin de les étudier avant de les intégrer. Quoi qu'il en soit j'ai récupéré ton exemple et je m'en vais de ce pas le triturer.

@laurent950
Merci pour ta confiance. J'ai pour habitude de joindre des fichiers texte comme format d'échange. Ils ne présentent aucun danger en tant que tel. Le module de classe est dispo sur le premier fil.

@cp4
Merci pour le bout de code. Je l'avais déjà trouvé sur le net mais malheureusement, mes compétences limitées en Excel ne me permettent pas d'en saisir tout le sens. Si tu avais quelques explications quant à son utilisation, je suis preneur.

@jmfmarques
Ton excès de prudence t'honore. Il est souvent utile de rappeler certaines règles de bon sens que l'on a parfois tendance à oublier. Seulement, Personne ne t'oblige à ouvrir quoi que ce soit.

Merci Staple1600, je testerai cela dés que possible.

Pour Rappel, je cherche à écrire une fonction qui appele un tableau et qui renvoi un tableau.
Mes premières tentatives m'ont donné bon espoir, malheureusement je ne sais pas comment faire pour faire un tre en ordre décroissant. Cerise sur le gateau, je ne suis pas sous Excel 2010 mais 2007.

Encore merci à tous pour votre soutien.
 

Staple1600

XLDnaute Barbatruc
Bonjour à toi aussi Laurent950...:rolleyes:

>•Laurent950
Il ne s'agit pas d'un module de classe mais d'un module.
(Voir le lien du premier message) Ce que je viens de faire
Pour m'apercevoir que JB évoquait déjà en 2013 : System.Collections.ArrayList
(comme je le fais en 2020 dans le message#11)
NB: C'est Dranreb qui évoquait un module de classe dans ce même fil de 2013.
 

Dranreb

XLDnaute Barbatruc
Bonjour @Staple1600 .
J'ai depuis pratiquement abandonné l'emploi de l'objet TableIndex, qui fonctionnait en quick-sort, principalement parce que j'ai constaté une supériorité du tri par fusions. J'ai donc remplacé ça par deux procédures internes, une IndexerFus1Col dans mon MSujetCBx et cette IndexerParFusions pour mon module MGigogne.
Elles sont toutefois Public, donc aussi utilisables indépendamment des fonctions principales de ces modules de service.
 
Dernière édition:

Discussions similaires