Trier une sélection dynamique, macro VBA

Résolu
damiens1026 Messages postés 695 Statut Membre -  
damiens1026 Messages postés 695 Statut Membre -
Bonjour,

Sous EXCEL 2007 actuellement, je me démène pour créer une macro qui permettrait de trier une sélection dynamique (donc pas de B1:B16 mais plutôt Selection.xyz) mais je n'y arrive pas car à chaque fois il m'affiche une erreur 1004: Référence de tri non valide...

Voici le code que j'utilise:
    Range("B3").Select
    Range(Selection, Selection.End(xlDown)).Select
    Selection.Sort Key1:=Range("B3"), Order1:=xlAscending, Key2:=Range("C3") _
        , Order2:=xlAscending




Merci d'avance pour votre aide :)

--
Meilleures salutations
damiens1026

7 réponses

  1. damiens1026 Messages postés 695 Statut Membre 32
     
    Milles mercis michel_m, mais étant un peu débutant en VBA, pourrais-tu m'expliquer chaque ligne? :)
    3
    1. michel_m Messages postés 18903 Date d'inscription   Statut Contributeur Dernière intervention   3 320
       
      Sub xxx() 
      Dim col As Integer, lig As Long 'déclaration des variables voir l'aide (F1) 
      'cells(3,2)<==> range("B3") 
      
           
           col = Cells(3, 2).End(xlToRight).Column 'dernière colonne utilisée avant une cellule vide dans la ligne 3 
           lig = Cells(3, 2).End(xlDown).Row ' m^me chose mais verticalement (dernière ligne)
           
          Range(Cells(3, 2), Cells(lig, col)).Sort Key1:=Range("B3"), Key2:=Range("C3") 
          'Range(Cells(3, 2), Cells(lig, col)) on aurait pu écrire Range($B$3: & cells(Lig,col).address) 
          'le param^tre xlascending est le param^tre par défaut il n'est donc pas obligatoire de l'écrire a condition _ 
          que les affectations aux autres param^tres soient précédées de ":=" 
       End Sub

      Quant à select-selection, cela encombre la mémoire et ralentit grandement la sélection; de plus dans les boucles cela fait clignoter l'écran...

      si tu veux apprendre vBa
      https://bidou.developpez.com/article/VBA/
      ca se lit pas comme un roman policier mais c'est assez complet pour 50 à 60 % des ap^llis en VBA
      0
    2. damiens1026 Messages postés 695 Statut Membre 32
       
      Merci pour cette claire réponse. Mais pour mes connaissances personnelles, cela aurait pu être possible fait avec une selection à partir de mon exemple? :)
      0
    3. michel_m Messages postés 18903 Date d'inscription   Statut Contributeur Dernière intervention   3 320
       
      oui
      0
    4. damiens1026 Messages postés 695 Statut Membre 32
       
      Okay, merci :)
      0
  2. michel_m Messages postés 18903 Date d'inscription   Statut Contributeur Dernière intervention   3 320
     
    Bonjour

    essaies ceci (nota: en VBA, on évite au maximum les select-sélection)

    Sub xxx() 
    Dim col As Integer, lig As Long 
    
         col = Cells(3, 2).End(xlToRight).Column 
         lig = Cells(3, 2).End(xlDown).Row 
        Range(Cells(3, 2), Cells(lig, col)).Sort Key1:=Range("B3"),  Key2:=Range("C3")  
            
    End Sub


    Michel
    1
    1. damiens1026 Messages postés 695 Statut Membre 32
       
      Salut,

      Je reviens sur ce post mais il me reste néanmoins une question, lorsque je dois trier une plage de cellules de plusieurs colonnes, est-ce faisable avec cela?
      0
  3. PHILOU10120 Messages postés 6463 Date d'inscription   Statut Contributeur Dernière intervention   835
     
    Sub trier3()
    '
    ' trier3 Macro
    '

    '
    Range("B3").Select
    Range(Selection, Selection.End(xlToRight)).Select
    Range(Selection, Selection.End(xlDown)).Select
    ActiveWorkbook.Worksheets("Feuil1").Sort.SortFields.Clear
    ActiveWorkbook.Worksheets("Feuil1").Sort.SortFields.Add Key:=Range("C4:C162") _
    , SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
    ActiveWorkbook.Worksheets("Feuil1").Sort.SortFields.Add Key:=Range("B4:B162") _
    , SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
    With ActiveWorkbook.Worksheets("Feuil1").Sort
    .SetRange Range("B3:G162")
    .Header = xlYes
    .MatchCase = False
    .Orientation = xlTopToBottom
    .SortMethod = xlPinYin
    .Apply
    End With
    Range("B3").Select
    End Sub

    Il y a quand même un problème le champ sélectioné quand on met le filtre est défini exemple C4:G162 donc à la prochaine éxécution c'est ce champ qui sera traité.

    Pour ma part j'ai pris l'habitude de définir un champ nommé exemple "base" avec la ligne de libellé et de longueur supérieur aux informations à traités et comme ça je n'ai pas de problème (je mets 50 ou 100 lignes de plus que mes données

    Exemple avec des nom de champ

    Sub trier_base2()
    '
    ' trier_base2 Macro
    '

    '
    Range("base").Select
    ActiveWorkbook.Worksheets("Feuil1").Sort.SortFields.Clear
    ActiveWorkbook.Worksheets("Feuil1").Sort.SortFields.Add Key:=Range("clé1") _
    , SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
    ActiveWorkbook.Worksheets("Feuil1").Sort.SortFields.Add Key:=Range("clé2") _
    , SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
    With ActiveWorkbook.Worksheets("Feuil1").Sort
    .SetRange Range("base")
    .Header = xlYes
    .MatchCase = False
    .Orientation = xlTopToBottom
    .SortMethod = xlPinYin
    .Apply
    End With
    Range("ancre1").Select
    End Sub

    Donc j'ai défini un champ "base" qui va de B3 à G250
    un champ clé1 qui va de B4:B250
    un champ cle2 qui va de C4:C250
    un champ ancre1 qui est la cellule B3
    0
  4. damiens1026 Messages postés 695 Statut Membre 32
     
    Salut,

    Merci pour ton aide et réponse, donc si j'ai bien compris, il n'existe pas de moyen de trier une plage de cellules via une sélection?
    Meilleures salutations
    damiens1026
    0
  5. Vous n’avez pas trouvé la réponse que vous recherchez ?

    Posez votre question
  6. PHILOU10120 Messages postés 6463 Date d'inscription   Statut Contributeur Dernière intervention   835
     
    Merci Michel
    0
  7. damiens1026 Messages postés 695 Statut Membre 32
     
    Merci à vous 2 de m'avoir éclairé, aidé et fait progresser dans le domaine. Bonne suite à vous :)
    0
  8. damiens1026 Messages postés 695 Statut Membre 32
     
    Et comme définit-on ces champs?
    J'ai essayé avec
    base = Range([B4], [E4].End(xlDown))
    ou
    base = Range("B4:E4") 
    Range("base").Select
    mais sans succès non plus...
    0
    1. michel_m Messages postés 18903 Date d'inscription   Statut Contributeur Dernière intervention   3 320
       
      bonjour
      [B4] est l'écriture fainéante de range("B4").value (je l'utilise souvent)

      donc range([B4],.... te renvoie la valeur dans B4 d'où protestation de tonton VBA....

      pour définir une zone

      dernière ligne utilisée
      derlig=columns("B").find("*",,,,,xlprevious).row
      ou si tu préfères
      derlig=range("B4").End(xlDown).Row ' attention : s'arrête à la première cellule vide dans la col B

      Base=Range("B4:E" & derlig)
      0
    2. damiens1026 Messages postés 695 Statut Membre 32
       
      Salut,
      Merci pour ta réponse. Cependant, j'ai trouvé une solution "alternative" mais boiteuse puisqu'elle ne fonctionne qu'à moitié et me semble également un peu "grailleuse":

      Dim plage As Range 
      Set plage = Range("A1:C1") 
      plage.Select 
      Dim plage2 As Range 
      Set plage2 = Range(Selection, Selection.End(xlDown)) 
      plage2.Select 
      
          ActiveCell.Range("plage2").Select 
          ActiveWorkbook.Worksheets("Feuil2").Sort.SortFields.Clear 
          ActiveWorkbook.Worksheets("Feuil2").Sort.SortFields.Add Key:=ActiveCell.Range _ 
              ("A1:A3"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _ 
              xlSortNormal 
          With ActiveWorkbook.Worksheets("Feuil2").Sort 
              .SetRange ActiveCell.Range("plage2") 
              .Header = xlGuess 
              .MatchCase = False 
              .Orientation = xlTopToBottom 
              .SortMethod = xlPinYin 
              .Apply 
          End With 
      
      
      End Sub


      En résumé, ce code sert à définir une liste d'une plage à 2 dimensions dont une des dimensions est changeante (en taille). Il se met râler dès que je lui demande d'effectuer une sélection d'une plage définie tel que
      ActiveCell.Range("plage2").Select

      Merci pour le coup de pouce... ;)
      0
    3. michel_m Messages postés 18903 Date d'inscription   Statut Contributeur Dernière intervention   3 320
       
      Il y a quelque temps je 't'avais dit d'éviter les "select" ,"selection"; voir lien #6 et t'avais proposé un tri simple sans lignes parasites liées à l'enregistreur de macros

      Tu fais comme tu veux...
      0
    4. damiens1026 Messages postés 695 Statut Membre 32
       
      Oui, c'est juste. Je vais essayer avec ta méthode et chercher un peu comme un grand. Merci ;)
      0
    5. damiens1026 Messages postés 695 Statut Membre 32
       
      Merci beaucoup, tout fonctionne à merveille!! :D
      0