Macro suppression de lignes trop longue
Bonjour,
J'utilise ce code pour supprimer les lignes dont la colonne A sont vide.
J'ai rarement plus de 100 lignes sauvées à la fin de la macro, et les lignes totales dépassent rarement 500 lignes
Ma macro partant d'en bas et en remontant, c'est hyper long.
Question donc !
Y a t'il moyen de gagner du temps, peu être en allant chercher la dernière ligne de la colonne A pleine, et supprimer d'entrée tout ce qui a derrière ?!
Merci par avance
Bien à vous
Sub SupprimerLignesVidesColonneA()
Dim ws As Worksheet
Dim i As Long
'Application.ScreenUpdating = False
' Définir la feuille de calcul
Set ws = ThisWorkbook.Worksheets("Masque1")
' Parcourir les lignes de bas en haut pour éviter les problèmes de décalage
For i = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row To 1 Step -1
' Vérifier si la cellule de la colonne A est numérique
If Not IsNumeric(ws.Cells(i, 1).Value) Then
' Supprimer la ligne de A à S
ws.Range(ws.Cells(i, 1), ws.Cells(i, 19)).Delete
Application.Goto [A2], True
'ActiveWindow.ScrollRow = 1
'ActiveWindow.ScrollColumn = 1
'Range("A2").Select
MsgBox "Les lignes ont été supprimées"
'Application.ScreenUpdating = True
End If
Next i
End SubBonjour
Pourquoi ne pas filtrer les lignes vides, supprimer les lignes visibles puis dé filtrer
Si pas de trou, le plus simple est l'équivalent du Ctrl bas pour se placer sur la dernière ligne rempli...
Hello,
je valide la proposition de @78chris
Sub Supprimer_Lignes_Vides_Colonne_A_Via_Filtre()
Dim Feuille As Worksheet
Dim Der_Lig As Long
Dim Plage_Donnees As Range
Set Feuille = ThisWorkbook.Worksheets("Masque1")
' Dernière ligne utilisée
Der_Lig = Feuille.Cells(Feuille.RoFeuille.Count, "A").End(xlUp).Row
If Der_Lig < 2 Then Exit Sub ' pas de ligne à supprimer
Application.ScreenUpdating = False
' désactive les éventuels filtres existants
If Feuille.AutoFilterMode Then Feuille.AutoFilterMode = False
Set Plage_Donnees = Feuille.Range("A1:S" & Der_Lig)
' filtre sur la colonne A les cellules vides
Plage_Donnees.AutoFilter Field:=1, Criteria1:="="
' supprime les lignes visibles (hors en-tête)
On Error Resume Next
Feuille.Range("A2:S" & Der_Lig).SpecialCells(xlCellTypeVisible).Delete Shift:=xlUp
On Error GoTo 0
Feuille.AutoFilterMode = False
Application.ScreenUpdating = True
MsgBox "Les lignes ont été supprimées via le filtre."
End Subre,
une autre méthode
Sub M_Supprimer()
Dim C, rw, cl, T
T = Timer
With ActiveSheet
On Error Resume Next
.AutoFilter.Range.AutoFilter 'désactiver filter
On Error GoTo 0
.Columns(1).Insert 'insérer nouvelle colonne temporaire A
With .UsedRange
rw = .Row + .Rows.Count - 1 'N° dernière ligne
cl = .Column + .Columns.Count - 1 'N° dernière colonne
End With
With .Columns(1).Resize(rw) 'plage jusqu'à la dernière ligne
.FormulaR1C1 = "=if(len(rc[1])>0,row(),"""")" 'montrer ligne si l'ancienne cellule A n'est pas vide (oubien autre condition était numérique)
.Value = .Value 'remplacer formule par sa valeur
.Cells(1).Resize(4) = 1 'éventuellement certainement conserver les 4 premières lignes
.Resize(, cl).Sort .Range("A1"), xlAscending, Header:=xlNo 'trier tout avec la colonne A
End With
Set C = .Columns(1).SpecialCells(xlBlanks)(1) 'première cellule vide de la colonne A
If rw >= C.Row Then C.Resize(rw - C.Row+1).EntireRow.Delete 'supprimer éventuellement ces lignes vides
.Columns(1).Delete 'supprimer la nouvelle colonne temporaire A
End With
MsgBox "prêt en " & Format(Timer - T, "0.0\s")
End Subsalut, sauf si j'ai mal lu ton code y'a un truc que personne a relevé : ton Application.Goto et surtout ton MsgBox sont DANS la boucle, pas apres. du coup a chaque ligne supprimé excel repositionne l'affichage et t'ouvre une boite de dialogue. sur 400 lignes ça fait 400 aller retour, c'est pas le volume qui est lent la c'est ça.
rien qu'en sortant ces deux lignes du For, et en decommentant le ScreenUpdating = False que t'as deja ecrit en commentaire, tu devrais voir une difference enorme avant meme de changer de methode
apres la solution par filtre au dessus reste plus propre si un jour tu passes sur des vrai gros volumes, ça je dis pas. mais sur 500 lignes ta boucle d'origine devrait tourner en une fraction de seconde une fois nettoyé, y'a pas de raison
Bonjour à tous.
dasaquit si votre demande précédente a été résolue, clôturez le fil (https://forum.excel-pratique.com/excel/ameliorer-l-enregistreur-de-macros-sur-filtre-202441) : cela permettra à d'autres de le savoir et éventuellement récupérer la solution. Merci
Cordialement.
@Tom & BsAlv
Merci beaucoup c'est très sympa de votre part je test cela dans un moment et vous fais un retour.
Bonne journée
A toute
David
Bonjour dasaquit, à tous,
Quand on a que quelques lignes à tester et à supprimer, la méthode de test et de suppression des lignes une par une est généralement rapide.
il faut cependant mettre les bons paramètres (écran, calcul), veiller à bien repérer la dernière ligne des données et connaitre les particularités des fonctions VBA et Excel. Le principe est d'en faire le moins possible au sein de la boucle de suppression : pas de manipulation d'écran, de défilement de lignes, de sélection, de lecture une à une des données, etc.
Limiter la plage :
Le END(xlUP) ne prend pas en compte les lignes masquées soit par un filtre soit manuellement. Il faut s'assurer que toutes les lignes soient visibles.
Si des lignes non vides en fin de plage ont cependant leur cellule de la première colonne vide alors END(xlUp) "sautera" ces lignes. End(xlUP) ira à la première cellule non vide en partant du bas et "oubliera" ces dernières lignes. On pourra parcourir les colonnes de la plage et chercher le numéro maximum des données de chaque plage au sein de toutes les colonnes de la plage.
Utiliser un tableau en mémoire (array) pour les valeurs de la première colonne:
En transférant en mémoire vive le tableau des valeurs de la première colonnes, on évite les lectures successives au sein de la feuille Excel de ces valeurs qui sont plus lentes que l'accès au tableau en mémoire.
Différence entre des fonctions similaires entre VBA et Excel:
La fonction ESTNUM() d'Excel a un comportement différent de la fonction VBA IsNumeric(). Si la cellule (A1 par exemple) est vide ESTNUM(A1) renverra FAUX alors que IsNumeric(Range("A1").value) renverra TRUE. En VBA, on peut tester si la valeur d'une variable X est vide avec Len(X)=0.
Bien d'autres méthodes que la mienne sont bien sûr possibles et tout aussi efficientes
Dans la macro de suppression fournie, la constante SupprimerVide indique si on supprime (=True) les lignes avec la cellule de la première colonne vide ou bien si on conserve ces lignes (=False). Dans le fichier joint, la constante SupprimerVide est à True.
Le bouton Initialisation de Masque1 réinitialise les données de la Feuille de travail "Masque1". Le bouton Suppression des lignes lance la suppression des lignes.
Le code est commenté à ma sauce...
Hey !
Merci @Mafraise pour ce complément d'information, qui aidera, je n'en doute pas, la communauté.
Bonne soirée, mais aussi très bon week-end
Bien à toi
David