Temps d'execution de ma macro très long
Bonjour à tous !
Je vous agresse de si bon matin (un lundi un plus ! :p) car j'aimerai réduire le temps d'exécution de ma macro.
DernLigne = Range("A" & Rows.Count).End(xlUp).Row 'permet de connaitre le nombre exact de ligne remplies
For i = 2 To DernLigne
Do Until Cells(i, 9).Value = 0
Cells(i, 9).EntireRow.Delete
Loop
NextJ'ai un fichier excel d'une longueur de 60.000 lignes à peu près, et cette étape peut prendre jusque 10-15 minutes à être traitée. Le fichier étant mis à jour assez régulièrement, je dois réutiliser cette portion de code souvent et celà me fait perdre un temps fou ...
J'aimerai donc savoir s'il y a une autre méthode plus rapide pour connaitre la valeur d'une cellule, et supprimer la ligne entière si jamais la valeur ne me convient pas ?
Je suis évidemment disponible pour toute demande de renseignements supplémentaires, et je vous remercie d'avance pour l'attention que vous porterez à mon problème !
Cordialement
Thibault
Bonjour,
à première vu je pense qu'un If dans la boucle suffit :
For i = 2 to derligne
If Cells(i,9)<>0 Then
Cells(i,9).EntireRow.Delete
Next i
End ifDis nous ce que cela donne ou si tu as déjà essayé.
(J'avais lu rapidement ton code, je viens juste de me rendre compte que tu veux supprimer les lignes qui ne sont pas égales à 0, remplace le = par <>)
Bonjour, merci de ta réponse !
Alors en effet j'ai déjà essayé cette solution, mais cela ne donne pas le résultat souhaité.
En effet, lorsque excel supprime la ligne, toutes les autres remontent d'un cran ... Je veux dire par là, que si on supprime la ligne 1, l'ancienne ligne 2 devient la nouvelle ligne 1.
Or l'incrémentation sur le i fait que je vais traiter la nouvelle ligne 2 ( donc l'ancienne ligne 3
Je ne sais pas si je me suis très bien exprimé là, mais j'espère que vous comprenez le problème du if !
C'est pour ça que je suis passé par le DO UNTIL, ce qui me permet de bien vérifier que toutes les nouvelles lignes 1 (ou plus ...) sont traitées.
Une autre idée peut être de stopper la mise à jour visuelle à l'écran pour réduire le ralentissement :
Application.ScreenUpdating = False
Ensuite le réactiver à la fin de la boucle
Application.ScreenUpdating = True
Tu l'as déjà fait ?
Sinon, tricher un peu ça marche ^^
lastRow = Range("A" & Rows.Count).End(xlUp).Row
For i = 2 To lastRow
If Cells(i, 9) <> 0 Then
Cells(i, 9).EntireRow.Delete
i = i - 1
End If
NextTu annules le décallage en remontant d'un i
J'avais en effet déjà stoppé le ScreenUpdating, sachant que cela ralentissait l'execution des macros
Je vais tester la métode alors, si celà fonctionne je reviens très vite te remercier !
Sinon ... à dans 15 minutes
(C'est vrai que je n'avais pas pensé du tout à désincrémenter le i, l'idée est très bonne en tous cas !)
Bonjour,
Pour éviter le problème de décalage, il suffit de partir de la dernière ligne et remonter la colonne
Sub supprimerLignes()
Dim DerLigne As Long, i As Long
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
DerLigne = Range("A" & Rows.Count).End(xlUp).Row
For i = DerLigne To 2 Step -1
If Cells(i, 9).Value <> 0 Then Cells(i, 9).EntireRow.Delete
Next
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End SubA+
J'ai fait le test avec Timer, le temps d'éxécution est plus long avec la boucle If vu qu'il à une condition de plus qu'avec loop, donc pas vraiment intéressant, je me suis souvenu de la fonction Timer qu'ensuite ... (cela permet de voir le temps de fonctionnement de la macro)
Sub test()
start = Timer
DernLigne = Range("A" & Rows.Count).End(xlUp).Row 'permet de connaitre le nombre exact de ligne remplies
For i = 2 To DernLigne
Do Until Cells(i, 9).Value = 0
Cells(i, 9).EntireRow.Delete
Loop
Next
MsgBox "durée du traitement: " & Timer - start & " secondes"
End SubEn faisant la méthode de Frangy, on se débarasse du code superflu et on a un temps d'éxecution 3 fois moindre aux deux autre qui sont sensiblement les mêmes sur un test de 500 lignes
Timothe :
Bon, celà vient de se terminer, 10 minutes de traitement, c'est donc pas vraiment plus rapide en effet ! A part cette portion de code, je ne fais que des suppressions de colonnes (une dizaine en tout) et 3 renommage de colonnes. Ce n'est donc que cette partie de code qui est très longue à traiter.
En effet, elle travaille sur 60.000 lignes et doit en supprimer environ 55.000 ... je ne sais pas ce que cela represente pour un ordinateur, mais je me dit qu'il y a du boulot !
Frangy :
Bonjour !
Etant débutant à VBA je ne savais pas que l'on pouvait également faire des steps à l'envers. Je vais donc tester votre méthode immédiatement, et je vous tiens au courant
(mais en effet, j'avais le même problème avec mes suppressions de colonnes, et j'ai donc pensé à le faire à l'envers. Mais les lignes ... ça ne m'était pas venu à l'esprit hihi)
EDIT : Pour info, si jamais quelqu'un regarde ton code, tu as oublié un
End If. Rien de grave, mais si ce poste interesse un débutant, qu'il comprenne pourquoi ça ne marche pas
Application.Calculation = xlCalculationManual
Application.Calculation = xlCalculationAutomaticD'ailleurs, étant débutant à excel, pourrais je savoir que font concrètement ces deux lignes ? Est-il important que je les écrive ? Je prefère comprendre tout ce que je fais afin de progresser.
Merci Beaucoup !
Si je ne dis pas de bétises, Excel recalcule pas mal de choses en mode automatique en plus du code. En le passant en mode manuel tu le forces à se concentrer uniquement sur le code qu'il effectue (donc gain de temps). Il faut juste penser à remettre le mode auto à la fin.
Bonjour,
Supprimer 55.000 lignes sur un total de 60.000 lignes, soit 92%, tu devrais plutôt envisager l'utilisation d'un filtre avancé.
Le résultat serait quasiment instantané.
Cdlt.
Jean-Eric :
Bonjour ! Le problème est qu'une fois que j'ai supprimé ces 55.000 lignes, je crée de nouvelles colonnes et fait des calculs avec macros sur les colonnes restantes. Or je ne sais pas si on peut faire fonctionner une macro sans qu'elle ne prenne en compte les lignes cachées par le filtre ?
De plus j'avais cru remarquer que je ne peut pas copier et coller uniquement les cellules visibles. En effet, j'exporte les résultats obtenus dans un autre fichier excel ensuite, afin de remplir des graphiques ... je ne peux me trimbaler 60.000 lignes même cachées, cela rend vraiment toutes les opérations très lentes.
Timothé :
Ok, merci pour l'info alors, c'est assez interessant du coup !
Aide Microsoft pour copier/coller uniquement les valeurs filtrées :
2.
Sélectionnez la cellule supérieure gauche de la zone de collage.
En enregistrant une macro cela donne ça :
Selection.SpecialCells(xlCellTypeVisible).Select
Selection.Copy
Sheets("Feuil3").Select
Range("A1").Select
ActiveSheet.PasteOn copie les cellules visibles, changement de feuille ("Feuil3"), on colle le tout à partir de la cellule A1 .
Bonjour,
Je tenais à vous remercier pour votre aide à tous, tout particulièrement frangy qui a permis de diviser mon temps de traitement par 2 environ, et Timothé qui a proposé des idées pas si bêtes que ça.
Je met le sujet en résolu, mais si l'un de vous à l'idée miracle du traitement rapide, ou veux m'offrir un PC plus performant, je suis preneur
Je vous souhaite à tous une excellente journée !
Cordialement,
Thibault
(Mon problème est surtout sur l'utilisation des macros sur les cellules uniquement visible, et sans rajouter si possible des conditions qui doubleraient mon temps de traitement ... je préfère encore perdre un peu de temps au début, et déjà bien moins grâce à vous tous ! qu'avoir que des formules loooongues à executer ^^)