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
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 SubMerci 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").SelectAmicalement
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 WithMerci 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 SubSub 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 SubLe 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
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 Withremplacé 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 WithUn 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 = FalseSe traduit par :
fa.Range("A2:C" & derligne).Copy
fb.Range("B" & derln).PasteSpecial xlPasteValuesLa 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