Problème de tri

Bonjour à tous, voici mon problème :

J'ai une feuille("Donnees_planning") sur laquelle il y a un TDC avec entête (A1:F1).

J'essaie de faire en sorte que lorsque j'active ma feuille("OJO") un tri se fasse de A à Z sur la colonne B de la feuille ("Donnees_planning"), sans toucher à la ligne d'entête.

J'ai essayé avec l'enregistreur de macro mais j'ai ce problème:(image 1) Merci

erreur tri

Bonjour,

Private Sub Worksheet_Activate()
    Me.Range("C7").Value = Sheets("PARAM").Range("B8").Value
    Me.Range("M7").Value = Me.Range("C7").Value
    With [Tableau1]
        .Sort key1:=.Cells(1, 2), order1:=xlAscending, Header:=xlYes
    End With
End Sub

Merci MFerrand, ça fonctionne. Le problème c'est que ça me fait beuguer une autre macro:

Sheets("Donnees_planning").Select
    ActiveWorkbook.Worksheets("Donnees_planning").ListObjects("Tableau1").Sort. _
        SortFields.Clear
    ActiveWorkbook.Worksheets("Donnees_planning").ListObjects("Tableau1").Sort. _
        SortFields.Add Key:=Range("Tableau1[[#All],[Colonne1]]"), SortOn:= _
        xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal
    With ActiveWorkbook.Worksheets("Donnees_planning").ListObjects("Tableau1").Sort
        .Header = xlYes
        .MatchCase = False
        .Orientation = xlTopToBottom
        .SortMethod = xlPinYin
        .Apply
    End With
    ActiveSheet.Range("A2:E" & derligne).RemoveDuplicates Columns:=1, Header:= _
        xlYes
    Sheets("Attente_planning").Select
    Rows("2:" & derligne).Select
    Selection.Delete shift:=xlUp
    Sheets("Planning").Select

Amicalement

Benoist


Je viens de le remplacer par ce code (copier du tiens), ça a l'air de fonctionner.

With [Tableau1]
        .Sort key1:=.Cells(1, 1), order1:=xlDescending, Header:=xlYes
    End With

Merci pour ton aide.

Amicalement

Benoist

Bonjour,

Je considère qu'il n'y a jamais lieu de s'étonner qu'une macro enregistrée remplisse mal son rôle ou puisse provoquer des anomalies... tant qu'on ne l'a pas entièrement réécrite en l'épurant et en en vérifiant toutes les commandes.

J'ai répondu à ta demande concernant une macro évènementielle, en réécrivant le code à partir des éléments qu'elle contenait, en substituant à la partie de code enregistrée un code qui ne l'est pas, et en éliminant quelques instructions (non enregistrées) également superflues dans le contexte. Le résultat en est nettement plus simple, facile à lire, et tu confirmes qu'il fonctionne.

Tu soulèves maintenant un bogue, sans aucune précision, sans la macro censée boguer, avec un fragment de code dont on ne voit pas de relation avec la procédure précédente. Il s'agit donc jusqu'à preuve du contraire d'un autre problème, distinct, lequel demeure insuffisamment explicité pour que l'on puisse s'y pencher !

C'est vrai MFerrand, voici tout le code

Sub Rectangle22_Cliquer()
Application.ScreenUpdating = False
If Not Intersect(ActiveCell, Range("C11:AU" & Range("B" & Rows.Count).End(xlUp).Row)) Is Nothing Then
v = "MIS"
Call ranger_donnees
End If
Application.ScreenUpdating = True
End Sub
Sub ranger_donnees()
Set fa = Sheets("Attente_planning")
Set fb = Sheets("Donnees_planning")
    For Each cell In Selection
        If Not Intersect(cell, Range("C9:AV" & Range("B" & Rows.Count).End(xlUp).Row)) Is Nothing Then

            lgn = fa.Range("A" & Rows.Count).End(xlUp)(2).Row
            fa.Range("A" & lgn) = Range("B" & cell.Row)
            fa.Range("B" & lgn) = Cells(9, cell.Column)
            fa.Range("B" & lgn).NumberFormat = "m/d/yyyy"

            fa.Range("C" & lgn) = v
        End If
    Next cell

    derln = fb.Range("B" & Rows.Count).End(xlUp).Row + 1
    derligne = fa.Range("A" & Rows.Count).End(xlUp).Row
    Sheets("Attente_planning").Select

 If Range("A3").Value = "" Then
    Range("A2:C2").Select
    Selection.Copy
    Sheets("Donnees_planning").Select
    Range("B" & derln).Select
    Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
        :=False, Transpose:=False
    Application.CutCopyMode = False
 Else
    Range("A2:C2").Select
    Range(Selection, Selection.End(xlDown)).Select
    Selection.Copy
    Sheets("Donnees_planning").Select
    Range("B" & derln).Select
    Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
        :=False, Transpose:=False
    Application.CutCopyMode = False
End If
'On supprime les doublons en ne gardant que les dernières entrées

Sheets("Donnees_planning").Select
    ActiveWorkbook.Worksheets("Donnees_planning").ListObjects("Tableau1").Sort. _
        SortFields.Clear
        With [Tableau1]
        .Sort key1:=.Cells(1, 1), order1:=xlDescending, Header:=xlYes
    End With
    ActiveSheet.Range("A2:E" & derligne).RemoveDuplicates Columns:=1, Header:= _
        xlYes
    Sheets("Attente_planning").Select
    Rows("2:" & derligne).Select
    Selection.Delete shift:=xlUp
    Sheets("Planning").Select

End Sub

Le problème maintenant c'est que si doublon ce sont les nouveaux qui sont supprimés et non les anciens.

Amicalement

Benoist

Avec tous ces Select, c'est quelque peu pénible !

Sauf erreur, RemoveDuplicates supprime les doublons, en conservant donc le 1er item trouvé. Tu définis les doublons sur la colonne 1. Et le tri se fait également sur cette colonne. Il faudrait sans doute compléter le tri par la colonne contenant la date (par ordre décroissant) pour obtenir le résultat souhaité.

Désolé pour les select.

La colonne date ne correspond pas à la date d'ajout de la ligne , elle concerne un planning (voir image)

En fait, les nouvelles entrées se copie à la suite dans les colonnes (B:D), donc se que j'essaie de faire c'est que si doublon effacer celui que se trouve au plus près de la ligne 1.

Amicalement

Benoist

planning

Mais c'est le plus éloigné qui se trouve supprimé par la méthode.

Il faut donc trier en conséquence...

C'est bon, j'ai réussi. En fait le tri se faisait sur la colonne 1 alors qu'il devait se faire sur la 5.

Sheets("Donnees_planning").Select
    ActiveWorkbook.Worksheets("Donnees_planning").ListObjects("Tableau1").Sort. _
        SortFields.Clear
        With [Tableau1]
        .Sort key1:=.Cells(1, 1), order1:=xlDescending, Header:=xlYes
    End With

remplacé par

Sheets("Donnees_planning").Select
    ActiveWorkbook.Worksheets("Donnees_planning").ListObjects("Tableau1").Sort. _
        SortFields.Clear
        With [Tableau1]
        .Sort key1:=.Cells(1, 5), order1:=xlDescending, Header:=xlYes
    End With

Un grand merci à toi pour ton aide et ta patience MFerrand.

PS: comment faire pour remplacer les "Select" ? Merci.

PS: comment faire pour remplacer les "Select" ? Merci.

Un exemple pris dans ton code :

    Range("A2:C2").Select
    Range(Selection, Selection.End(xlDown)).Select
    Selection.Copy
    Sheets("Donnees_planning").Select
    Range("B" & derln).Select
    Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
        :=False, Transpose:=False
    Application.CutCopyMode = False

Se traduit par :

    fa.Range("A2:C" & derligne).Copy
    fb.Range("B" & derln).PasteSpecial xlPasteValues

La majeure partie disparaissent en raccordant les morceaux sélectionnés successifs. Il faut quand même vérifier que l'on a bien pour chaque commande tous les qualificateurs d'objets des expressions (et on qualifie systématiquement en évitant de se reposer sur l'élément actif implicite, on évite ainsi toute surprise ultérieure et l'exécution sera plus rapide).

Ici en plus on utilise tes variables initialisées en début de procédure et que tu as perdu de vue chemin faisant...

Pour la commande PasteSpecial, passage des arguments par position (c'est plus court que par nom...) et élimination de tous ceux laissés à leur valeur par défaut (que l'enregistreur reprend inutilement).

Enfin le fameux CutCopyMode = False : cette commande vide le presse-papier. Si l'enregistreur te le met, c'est que dans une de tes commandes enregistrées, l'une d'elles a eu cet effet, elle continuera de l'avoir et tu peux donc la supprimer de ton code à coup sûr.

Cette commande est rarement utile mais les rares cas où elle l'est tu peux être assuré que l'enregistreur ne te l'aura pas mise (parce qu'aucune commande n'a eu cet effet et qu'il faut donc le programmer : pour éliminer le scintillement d'une plage copiée restant affichée devant l'utilisateur ou pour éviter le message demandant si tu veux ou non conserver le contenu du presse-papier lors d'une fermeture qui suit immédiatement un copier-coller.

Voilà quelques éléments de révision des macros enregistrées. Il faut également y ajouter le tri : l'enregistreur ne connait plus que la méthode Worksheet.Sort qui occupe pas mal de lignes et ne fait rien de plus (sauf cas très rare) que la méthode Range.Sort qui s'écrit en un ligne...

J'ajouterai aussi que lorsqu'on reproduit des plages de valeurs, on peut le plus souvent éviter le copier-coller (c'est à dire le transit par le presse-papier) et affecter directement les valeurs d'une plage à une autre : soit sous la forme PlageA.Value = PlageB.Value, soit en utilisant une variable tableau intermédiaire.

Cordialement.

Un grand merci pour tes explications MFerrand, je vais m'appliquer à mettre en oeuvre tes explications.

Amicalement

Benoist

Rechercher des sujets similaires à "probleme tri"