Accélération code VBA

Bonjour forum,

Je voudrais savoir s'il y a possibilité d'accélérer ce code VBA :

Dim i As Long
    Application.ScreenUpdating = False
            For i = 2 To [A65000].End(xlUp).Row
                If Cells(i, 1).Interior.ColorIndex = xlNone Then
                    Cells(i, 1).EntireRow.Hidden = True
                End If
            Next i

Merci d'avance pour votre aide.

Salut le forum

Essaye peut-être ceci

Dim Plage As Object
Dim Cellule As Range
Application.ScreenUpdating = False
Set Plage = Range("A2:A" & [A65000].End(xlUp).Row)
For Each Cellule In Plage
If Cellule.Interior.ColorIndex = xlNone Then Cellule.EntireRow.Hidden = True
Next Cellule
Set Plage = Nothing

Mais je ne suis pas certain pour la rapidité

Mytå

Edition : Ajout de Application.ScreenUpdating = False pour comparer des Pommes avec des Pommes.

Salut mytå, forum,

J'ai 2 centièmes de moins avec ton code (0.29 au lieu de 0.31 s)

C'est négligeable mais je garde quand même ton code.

J'attends un peu avant de mettre le post en résolu pour voir si quelqu'un d'autre peut me

faire gratter quelques centièmes.

Merci mytå

Merci également d'avance à ceux qui m'aideront (ou essaieront).

Bonjour,

Comme je l'avais déjà mentionné dans une autre fil pour Claude Dubois, évite les Crochets [ ] dans le code qui ralentissent l'exécution. Il vaut mieux mettre Range("A65000").

Amicalement

Dan

Edit Dan : code supprimé le 31/08/09.

Bonjour Dan, forum,

Merci pour le code, Dan.

Verdict pour le temps d'exécution : le mien et le tien sont équivalents. Celui de mytå est 2 centièmes plus rapide.

Je vais effectivement garder celui de mytå et garder le tien en commentaire.

Ton intervention m'a permis d'apprendre.

Merci encore à vous

bonjour,

Topikalakon !

Ce topic aurait aussi pu s'appeler se méfier des interprètations simplistes...

Je me suis livré à une petite étude sur la base des indications fournies dont vous trouverez le détail en pièce jointe.

Pour résumer, je me suis livré à trente tests sur la macro de Myta

trente test sur la macro de Nad-Dan

trente test sur ma propre macro

trente test sur ma probre macro version crochets [ ]

Pour que les tests soient significatifs dans la première colonne les 65000 premières lignes ont été remplies de "x"

Pour chacun, les dix premiers tests concernaient 1 ligne sur 2 à masquer

pour les dix suivants 9 lignes sur 10 étaient incolores (donc à msquer !)

pour les dix derniers 1 lignes sur 10 étaient incolore (...)

Si l'on considère la seule première batterie de test (1/2)

La macro de Myta met presque 43 secondes à s'exécuter et toutes les autres moins de 5 secondes...

And the winner is... ??? Galopin bien sur ! Je n'ai d'ailleurs pas grand mérite : j'ai juste repris et améliorées les macros des uns et des autres !

Tous les détails des résultats dans le fichier

A+

Bonsoir,

Testalakon......

Mettre une 2CV dans un grand prix de F1....

Facile, pour Ferrari....

Euh, Galopin, mets toutes les écuries sur le même pied d'égalité.....

Commence par mettre :

Application.ScreenUpdating = False

dans le code de Mytå....

Et recommence ton "Test".....

Pour moi,; le code de Mytå est le plus rapide.....

Désolé....

Bah, tu n'as pas à être désolé...

Le but n'était pas de modifier les macros des uns et des autres, mais de vérifier ce qui était dit et fait, de faire mieux si possible... et de vérifier l'assertion au sujet des crochets [ ].

Bien entendu il est possible de recommencer le test avec ScreenUpdating= False dans la macro de Myta et il est vrai que... c'est encore plus rapide dans tous les cas !

A+

re,

Assez bizarre tout de même cette histoire de crochets sachant que ces conseils sont donnés par Microsoft lui même dans ce lien : http://support.microsoft.com/kb/104502/fr

Mais aussi par J. Walkenbach :

Related to this is the shortcut method of refering to cells. VBA will allow you reference cells with [A1] rather than Range("A1"). While the [A1] syntax is easier to type, it is slower to execute than the Range("A1") syntax.

On se demanderait bien comment ils ont contrôlé cela.

Amicalement

Dan

c'est tout à fait vrai.

Sur la base de mon test de ce matin, j'ai refait un test sur 2 macros srictement identiques dont l'une fait appel à range et l'autre utilise des crochets.

Sub TestRange()
Dim i&
Application.ScreenUpdating = False
    For i = 2 To Range("A65536").End(xlUp).Row
        If Cells(i, 1).Interior.ColorIndex = xlNone Then Rows(i).Hidden = True
    Next i
End Sub

Sub TestCrochets()
Dim i&
Application.ScreenUpdating = False
    For i = 2 To [A65536].End(xlUp).Row
        If Cells(i, 1).Interior.ColorIndex = xlNone Then Rows(i).Hidden = True
    Next i
End Sub

Le nombre de boucles est de 65000 et les tests ont été réalisés 10 fois par macros

sur une batterie de tests les moyennes des résultats respectifs sont les suivants :

5.203125 et 5.2046875

La méthode Timer donne des temps avec une précision de l'ordre du millième. Ont peut donc dire que sur cet exemple l'avantage est de 15/1000 pour laméthode Range.

Sur d'autres séries de tests identiques j'ai mesuré des écarts moyens avec une différence jusqu'à 160/1000 !

C'est négligeable sans doute car dans cette démo le nombre d'appels est relativement limité.

On peut donc en déduire que pour un appel unique à :

i=[A65536].End(xlUp).Row 

La notation par crochet ne pose alors aucun problème.

Mais on imagine sans peine que certaines boucles peuvent évaluer des crochets plusieurs centaines de milliers de fois et dans ce cas le gain est réel...

Le

A+

Bonjour à tous, merci pour votre implication,

Nad-Dan a écrit :

re,

Assez bizarre tout de même cette histoire de crochets sachant que ces conseils sont donnés par Microsoft lui même dans ce lien : http://support.microsoft.com/kb/104502/fr

Mais aussi par J. Walkenbach :

Related to this is the shortcut method of refering to cells. VBA will allow you reference cells with [A1] rather than Range("A1"). While the [A1] syntax is easier to type, it is slower to execute than the Range("A1") syntax.

On se demanderait bien comment ils ont contrôlé cela.

Amicalement

Dan

En fait ils ont (surement) raison Dan, j'avais fait attention à dire que ton code et le mien

étaient "équivalents" et non identiques. Il y a une petite nuance (pour moi en tout cas).

J'avais testé ton code et le mien et je trouvais un temps de l'ordre de 29 centièmes et

des poussières. Je n'ai pas fait attention à ces poussières. D'où l'emploi du terme

"équivalent". De plus, le nombre de lignes à traiter est de seulement 1813 au total.

Encore une raison qui montre le gain infinitésimal entre les crochets et le range.

Par contre galopin, avec ton fichier test, en incorporant le code de Mytå, j'ai les résultats suivants :

Range : 4,43125 s

Crochets : 4,42421875 s

Mytå : 4,0140625 s

C'est un peu surprenant car le test avec range est plus long que celui avec crochets.

On peut en déduire que les conditions dans lesquelles je teste ne sont pas optimales. Contrairement à Microsoft je suppose. De plus, même John Walkenbach le dit.

Par conséquent, je suis d'accord avec Dan : "On se demanderait bien comment ils ont contrôlé cela."

Une (quasi?) certitude néanmoins, le code de Mytå est plus rapide.

D'ailleurs, comment cela se fait-il? Quelqu'un a-t-il une explication?

PS : J'enlève pour un temps le résolu. Pour voir où nous mènera ce post.

Bonjour,

Pour ma part, je pense que le fait de travailler dans un tableau VBA, comme le fait Mytå (Set Plage....) donne un gain significatif...

D'une part, un calcul dans un tableau VBA est nettement plus rapide

Et ensuite, le calcul de la dernière ligne n'est fait qu'une seule fois :

[A65000].End(xlUp).Row

Maintenant, le code de Dan utilisait également un tableau, tu me diras...

Oui, mais le contrôle de la couleur se fait quand même sur l'onglet, il incrémente toutes les cellules, une à une (comme le font tous les autres codes, d'ailleurs...)

avec le code de Mytå, on incrémente dans le tableau VBA...

Peut-être une explication???

Bbonjour,

Je n'avais pas envie de répondre à cette question sur laquelle je me suis déjà suffisament exprimé, mais je vais quand même m'y coller.

Quand on fait des tests de ce genre et qu'on les rend publique, ça veut dire qu'on a un minimum de rigueur scientifique. et un maximum d'objectivité dans l'analyse de ces résultats.

Donc on ne peut pas dire que -tel quel- le code de Myta est plus rapide alors qu'il est 10 fois plus lent... La faute en est qu'il a oublié le ScreenUpdating mais la moindre des choses est de dire que tu as forcément corrigé ce "détail" avant d'affirmer qu'il est plus rapide...

cousinhub a donné une partie des précisions qui manquaient : Une fois corrigé le code de myta est plus rapide car il travaille sur une instance et non pas sur le tableau lui même, Ce qui s'apparente à un travail sur Array et est toujours au minimum 10 fois plus rapide qu'un travail sur Sheet. (car une instance d'un tableau restreint est entièrement chargée en mémoire) et ne comporte aucun des attributs du classeur ou du tableau d'origine. Un véritable Array ne comporte que des données brutes pas de couleur, pas de format, pas de bordures, pas de liens hypertextes, pas d'images... donc l'accès et les calculs sont forcement plus simples.

Ici Myta ne travaille pas sur un Array mais sur une instance de plage et qui conserve encore quelques attributs. Le principal intéret me semble être le travail sur une zone mémoire restreinte, ce qui lui confère encore un net avantage. Cette zone mémoire est forcément plus réduite car elle n'a pas à explorer tout le territoire d'un classeur... ni même d'une feuille. Rien que des données Range. Le gain est donc du même ordre

Au moins dans des conditions significatives : J'entend par là qu'il faut travailler sur un nombre significatif de lignes pour obtenir un résultat significatif.

Parlons en. Il me parait curieux qu'un code sur 1800 lignes mette autant de temps à s'éxécuter qu'un autre sur 65000 lignes mébon...

De plus il manque une précision importante dans l'exposé de vba-new : c'est le nombre de lignes réellement explorées :

La méthode ...End(xlUp).Row) ne retient que les lignes contenant des données pas des couleurs en d'autre terme si ton tableau contient 65000 lignes dont seulement les 25 premières sont remplies la méthode ne renvoie qu'une plage de 25 lignes...

Le code de Dan : Bien qu'il comporte le mots Tablo en fait celui-ci ne sert à rien, je l'ai d'ailleurs discrètement supprimé de mon test car il ne faisait que ralentir le code. Ce tableau n'était pas chargé avec la plage de référence juste dimensionné à la valeur de j (End(xlUp).Row)... mais parfaitement inutile.

La mesure des différences entre Range et crochets : Pour être rigoureux, il faut utiliser ma deuxième démo qui ne comporte aucune autre différence que ces fameux crochets et travailler sur un minimum de boucles et faire plusieurs tests... En dessous de 50 000 boucles et une dizaines de tests la mesure parait insuffisante pour un gain aussi infinitésimal : Sur cette batterie de tests et sur 25 000 lignes seulement on arrive à des résultats parfois contradictoires.

En pratique on ne se soucie guère de tels détails sur des macros qui durent moins d'une dizaine de secondes. Les sources de gains les plus significatives sont ailleurs... On commence la plupart du temps à s'y intéresser sur des macros qui durent plusieurs minutes, voire plusieurs heures.

C'est toutes ces imprécisions que j'ai sanctionné par un "topikalakon" qui se voulait plus humoristique que qualitatif : Quand on veut parler mesure et évaluation, il faut être rigoureux et prouver ce qu'on affirme.

Ce que j'ai essayé de préciser ici.

A+

Bonjour les experts,

Je ne sais pas le faire, mais en cherchant du coté:

SpecialCells(Type, Valeur)

Exemple d'un code qui fonctionne

Sub SupprimeLigne()
'Supprime lignes dont colonne A est en texte
Dim Lg As Long, Plg As Range
    Lg = Range("A65536").End(xlUp).Row
On Error Resume Next
    Set Plg = Range("a1:a" & Lg).SpecialCells(xlTextValues, 2)
    Plg.EntireRow.Delete
End Sub

en adaptant le Type xl

   Set Plg = Range("a1:a" & Lg).SpecialCells(xlTextValues, 2)

avec

Interior.ColorIndex = xlNone

On ne traite que les cellules concernées

Votre avis sur la faisabilité ?

Bonne journée

Claude.

Bonsoir,

Galopin.....

mais la moindre des choses est de dire que tu as forcément corrigé ce "détail" avant d'affirmer qu'il est plus rapide...

Ce qui a été fait, il me semble....

PS, toi-même, tu t'es empressé de le mettre, à ce que je vois....

Quand on veut parler mesure et évaluation, il faut être rigoureux et prouver ce qu'on affirme.

Pas de soucis, tu as sans doute testé avec le "détail".....

Euh, je ne ne pense pas qu'il y avait de la place, pour ce type d'embrouille, et comme tu le précises toi-même, on ne joue que sur des dixièmes, voire centièmes de secondes...

Donc, inutile de se prendre la tête...

Au plaisir, de te croiser sur un autre fil

@ Claude, le Type des cellules "Spéciales" est défini...

Pour les valeurs :

XlSpecialCellsValue peut être l'une de ces constantes XlSpecialCellsValue.

xlErrors

xlLogical

xlNumbers

xlTextValues

et pour les Types :

XlCellType peut être l'une de ces constantes XlCellType.

xlCellTypeAllFormatConditions. Cellules de n'importe quel format

xlCellTypeAllValidation. Cellules présentant des critères de validation

xlCellTypeBlanks. Cellules vides

xlCellTypeComments. Cellules contenant des commentaires

xlCellTypeConstants. Cellules contenant des constantes

xlCellTypeFormulas. Cellules contenant des formules

xlCellTypeLastCell. Dernière cellule dans la plage utilisée

xlCellTypeSameFormatConditions. Cellules de même format

xlCellTypeSameValidation. Cellules présentant les mêmes critères de validation

xlCellTypeVisible. Toutes les cellules visibles

De plus, selon le nombre de lignes, cette méthode n'est pas forcément la plus rapide....

Bonne soirée à Tous

Bonjour à tous,

Tout d'abord merci pour les explications.

Ensuite :

galopin01 a écrit :

La faute en est qu'il a oublié le ScreenUpdating mais la moindre des choses est de dire que tu as forcément corrigé ce "détail" avant d'affirmer qu'il est plus rapide...

En effet, toutes mes excuses pour avoir omis ce détail.

galopin01 a écrit :

Il me parait curieux qu'un code sur 1800 lignes mette autant de temps à s'éxécuter qu'un autre sur 65000 lignes mébon

Je n'ai jamais dit ça

Les temps que j'avais mis dans mon précédent post étaient avec TON fichier test et TES données galopin.

Dans mon fichier, le temps d'exécution est de moins de 30 centièmes.

galopin01 a écrit :

De plus il manque une précision importante dans l'exposé de vba-new : c'est le nombre de lignes réellement explorées :

Comme dit précédemment c'est bien environ 1800 lignes.

galopin01 a écrit :

En pratique on ne se soucie guère de tels détails sur des macros qui durent moins d'une dizaine de secondes. Les sources de gains les plus significatives sont ailleurs... On commence la plupart du temps à s'y intéresser sur des macros qui durent plusieurs minutes, voire plusieurs heures.

Je suis tout à fait d'accord avec toi. Mais au-delà de ça, je suis relativement nouveau dans le monde du VBA, je suis donc encore en phase d'apprentissage (et je suis sûr que même les plus aguerris peuvent en apprendre davantage).

Donc derrière tout ça, il y a également une volonté d'apprendre.

Merci encore à tous.

Le topic est clos (normalement )

Re,

galopin01 a écrit :

...Le code de Dan : Bien qu'il comporte le mots Tablo en fait celui-ci ne sert à rien, je l'ai d'ailleurs discrètement supprimé de mon test car il ne faisait que ralentir le code. Ce tableau n'était pas chargé avec la plage de référence juste dimensionné à la valeur de j (End(xlUp).Row)... mais parfaitement inutile....

Vu le "topikalakon" et "interprétations simplistes", le code n'apporte rien au forum et à ce qui est dit ici. Je l'ai donc supprimé de mon post du jeudi 27/08.

Dan

bon, on va arrêter là.

J'ai bien intégré qu'on est sur un forum de débutant et je n'ai pas l'habitude de pinailler sur des queues de cerises , Seulement si on laisse toujours dire et faire n'importe quoi, à la longue ça n'a plus ni queue ni tête. C'est pourquoi j'ai cru bon faire remarquer que ce topic marqué résolu était un peu... léger.

C'est un Forum sur Excel, pas sur la dialectique et ma remarque ne se voulait pas aussi désobligeante que ramenée aux seuls mots qui fâchent. A ceux qui se sont senti inutilement agressés qu'ils veulent bien m'en excuser.

Pour ma part la question est close et je n'y reviendrai pas.

A+

Rechercher des sujets similaires à "acceleration code vba"