Fonction de tri d'un range de cellules

Fermé
mockup Messages postés 4 Date d'inscription jeudi 20 juin 2013 Statut Membre Dernière intervention 21 juin 2013 - Modifié par mockup le 20/06/2013 à 11:28
eriiic Messages postés 24603 Date d'inscription mardi 11 septembre 2007 Statut Contributeur Dernière intervention 15 décembre 2024 - 21 juin 2013 à 11:21
Bonjour,

Je suis novice en VBA et je bute sur un problème basique: Trier une plage de cellules passée en paramètre à une fonction. La liste triée est renvoyée sous forme d'une chaine concaténée.

Function TrierPlage(plage As Range) As String
    Dim rep As String, c As Range
    
    plage.Sort Key1:=plage, Order1:=xlAscending, Header:=xlNo
    
'    For i = 1 To plage.Count
'        MsgBox plage(i)
'    Next i
    
    For Each c In plage
         rep = rep & " " & c.Value
    Next c
    TrierPlage = rep
End Function

En l'état, en appliquant cette fonction sur 3 cellules ayant pour valeur 1, 3, 2, j'obtiens la chaine "1 3 2". La fonction de tri est donc ici inopérante. Bien sûr je m'attendais à avoir "1 2 3".

Merci d'avance pour vos conseils et remarques,
Bonne journée,
Mockup
A voir également:

7 réponses

f894009 Messages postés 17206 Date d'inscription dimanche 25 novembre 2007 Statut Membre Dernière intervention 22 novembre 2024 1 711
20 juin 2013 à 20:37
Re,

en attendant, vous pouvez utilisez ceci, appelle d'une cellule ou autre

'
' Tri de Shell - Shell Sort adapté pour tri plage de cellules
'
Function TrierPlage(plage As Range, Optional ByVal loBound As Long = -1, Optional ByVal upBound As Long = -1) As String
    Dim i As Long, j As Long, h As Long, v As Long, t()
    Dim rep As String
    
    'mise en tableau de la plage de cellules
    t = Application.Transpose(plage)
    'debut de tableau
    If loBound = -1 Then
        loBound = LBound(t())
    End If
    'fin de tableau
    If upBound = -1 Then
        upBound = UBound(t())
    End If

    h = loBound
    Do
        h = 3 * h + 1
    Loop Until h > upBound
      
    Do
        h = h / 3
        For i = h + 1 To upBound
            v = t(i): j = i
            Do While t(j - h) > v
                t(j) = t(j - h): j = j - h
                If j <= h Then
                    Exit Do
                End If
            Loop
            t(j) = v
        Next i
    Loop Until h = loBound
    'ecriture de la chaine de valeurs triées
    For i = 1 To upBound
        rep = rep & " " & t(i)
    Next
    
    TrierPlage = rep
End Function


A+
1
f894009 Messages postés 17206 Date d'inscription dimanche 25 novembre 2007 Statut Membre Dernière intervention 22 novembre 2024 1 711
21 juin 2013 à 07:40
Bonjour ronmubar,

Il n'y a peut-être pas besoin d'une macro pour effectuer cette opération dans le contexte voulu par mockup: oui, il faut passer par du VBA
1
f894009 Messages postés 17206 Date d'inscription dimanche 25 novembre 2007 Statut Membre Dernière intervention 22 novembre 2024 1 711
Modifié par f894009 le 20/06/2013 à 12:05
Bonjour,

J'ai teste votre code et le tri se fait correctement !!!!!!!

rectification, marche pas a tout coup si appel d'une cellule, si vba pas de probleme??

comment appelez-vous cette fonction ??
0
mockup Messages postés 4 Date d'inscription jeudi 20 juin 2013 Statut Membre Dernière intervention 21 juin 2013
20 juin 2013 à 12:10
Bonjour,

J'appelle effectivement cette fonction d'une cellule et je n'ai jamais réussi à voir un résultat correct.

Merci pour votre test.
Cordialement.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
eriiic Messages postés 24603 Date d'inscription mardi 11 septembre 2007 Statut Contributeur Dernière intervention 15 décembre 2024 7 247
20 juin 2013 à 20:44
Bonjour,

Une fonction personnalisée ne peut pas modifier son environnement sur une feuille, elle retourne une valeur c'est tout.
plage.Sort n'a aucune chance d'être réalisé.
Il faut faire faire le tri par la macro, comme proposé par f894009.

eric
0
mockup Messages postés 4 Date d'inscription jeudi 20 juin 2013 Statut Membre Dernière intervention 21 juin 2013
21 juin 2013 à 10:45
Bonjour et merci à tous pour vos réponses :).

Sur la remarque d'Eric, je voudrais préciser que mon besoin n'est pas de modifier les cellules sources mais de les utiliser pour générer une valeur affichée dans autre cellule (chaine retournée). Dans mon contexte, plage.Sort n'est peut-être pas appropriée mais je suis étonné qu'il n'y ait pas une solution équivalente, quitte à copier les valeurs de la plage source dans un objet temporaire qui supporterait nativement la fonctionnalité de tri.

À défaut, l'algo de tri de f894009 est un pis-aller (qui fonctionne avec des entiers). À terme, il me faudra une solution qui supporte le tri de tout type de donnée (date, texte, décimal...).

Si quelqu'un dispose d'une solution générique, je suis preneur !

Merci d'avance et bonne journée à tous,
Mockup
0
eriiic Messages postés 24603 Date d'inscription mardi 11 septembre 2007 Statut Contributeur Dernière intervention 15 décembre 2024 7 247
21 juin 2013 à 11:21
Bonjour,

mon besoin n'est pas de modifier les cellules sources mais de les utiliser
Ce qui revient à modifier le contenu de cellules différentes de la cellule d'appel, ce que tu ne peux pas faire avec une fonction personnalisée.

Sur le très bon site de J. Boisgontier tu trouveras des algorithme de tri : http://boisgontierjacques.free.fr/pages_site/Tris.htm

eric
0
ronmubar Messages postés 5 Date d'inscription jeudi 20 juin 2013 Statut Membre Dernière intervention 20 juin 2013
20 juin 2013 à 22:06
Il n'y a peut-être pas besoin d'une macro pour effectuer cette opération, la fonction tri est capable de trier une plage sur plusieurs champs : onglet Données > Trier. Et dans la fenêtre il faut choisir la liste des champs sur lesquels baser le tri.
-5