Loop For VBA expliqué simplement pour automatiser vos macros Excel

La boucle For…Next en VBA reste la structure itérative la plus utilisée dans les macros Excel. Nous partons du principe que vous maîtrisez l’éditeur VBE et la notion de variable typée, pour nous concentrer sur ce qui fait réellement la différence entre une macro qui tourne et une macro qui gèle un classeur de plusieurs dizaines de milliers de lignes.

Goulot d’étranglement COM : pourquoi votre boucle For fige Excel

Le problème numéro un des boucles For en VBA ne se situe pas dans la boucle elle-même. Chaque appel à Range.Cells ou Cells(i, j) déclenche un aller-retour via la couche COM d’Excel, un rafraîchissement d’écran et, selon le contexte, un recalcul complet des formules volatiles.

Sur un classeur de quelques centaines de lignes, l’impact est imperceptible. Sur plusieurs dizaines de milliers de lignes, ces micro-accès s’accumulent et provoquent le gel caractéristique de la fenêtre Excel, même si la logique à l’intérieur de la boucle est triviale.

Nous recommandons de poser systématiquement trois verrous avant toute boucle qui touche la feuille :

  • Application.ScreenUpdating = False pour couper le rafraîchissement visuel pendant l’exécution de la macro, ce qui réduit drastiquement le temps de traitement
  • Application.Calculation = xlCalculationManual pour empêcher Excel de recalculer les formules à chaque écriture dans une cellule
  • Application.EnableEvents = False pour désactiver les événements (Worksheet_Change, etc.) qui se déclenchent à chaque modification et ajoutent des appels supplémentaires

Pensez à rétablir ces trois propriétés dans un bloc de fin, y compris en cas d’erreur, sous peine de laisser Excel dans un état instable.

Développeur analysant une boucle For en VBA Excel sur double écran dans un bureau en open space

Boucle For VBA sur tableau en mémoire : la méthode performante

Les guides d’optimisation récents sont explicites : remplacer les boucles sur Range.Cells par des boucles sur des tableaux VBA en mémoire supprime la majorité des accès lents au modèle objet. Le principe tient en trois temps.

On charge la plage entière dans un tableau Variant en une seule opération :

Dim arr As Variant
arr = Range("A1:D50000").Value

On parcourt ensuite ce tableau avec une boucle For classique. Ici, chaque itération ne traverse plus la couche COM puisque les données résident en mémoire VBA :

Dim i As Long
For i = LBound(arr, 1) To UBound(arr, 1)
    arr(i, 2) = arr(i, 1) * 1.2
Next i

On réécrit le résultat d’un bloc sur la feuille :

Range("A1:D50000").Value = arr

Cette approche élimine les allers-retours unitaires. Sur des volumes conséquents, le gain de temps est souvent de l’ordre de plusieurs dizaines de fois par rapport à une boucle cellule par cellule.

Step et décrémentation dans une boucle For Next Excel

Le mot-clé Step modifie l’incrément du compteur. L’usage le plus courant est l’incrémentation par pas de 2 ou plus (pour traiter une ligne sur deux, par exemple), mais c’est la décrémentation qui pose le plus de pièges.

Quand vous supprimez des lignes dans une boucle For, itérer du haut vers le bas décale les index à chaque suppression. La macro saute alors des lignes ou génère une erreur d’exécution. La solution consiste à parcourir la plage du bas vers le haut :

For i = derniereLigne To 1 Step -1
    If Cells(i, 3).Value = "" Then Rows(i).Delete
Next i

Toute suppression de lignes dans une boucle For doit utiliser Step -1, sans exception. Nous observons régulièrement des macros en production qui tournent pendant des minutes et produisent des résultats incohérents simplement parce que la boucle itère dans le mauvais sens.

For Each VBA : quand préférer l’itération sur collection

For Each itère sur les éléments d’une collection ou d’un objet sans compteur explicite. Cette syntaxe est plus lisible quand vous parcourez des objets comme des feuilles, des classeurs ou des formes :

Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
    ws.Protect Password:="abc"
Next ws

En revanche, For Each ne garantit pas l’ordre de parcours sur un Range. Si votre logique dépend de l’index de ligne ou de colonne, restez sur For…Next avec un compteur Long. For Each reste le bon choix pour les collections d’objets, les dictionnaires ou les tableaux unidimensionnels où l’ordre n’a pas d’importance.

Déléguer l’itération aux fonctions de feuille via WorksheetFunction

Avant d’écrire une boucle For, posez-vous la question : Excel sait-il déjà faire ce calcul nativement ? Les fonctions de feuille (WorksheetFunction.SumIf, WorksheetFunction.CountIf, WorksheetFunction.Match) exécutent leurs itérations en code compilé C++, bien plus rapide que le runtime VBA interprété.

Exemple concret : compter les cellules non vides dans une colonne de plusieurs dizaines de milliers de lignes avec une boucle For prend un temps notable. Un simple appel à WorksheetFunction.CountA(Range("A:A")) retourne le résultat quasi instantanément.

Nous recommandons de réserver la boucle For aux traitements qui nécessitent une logique conditionnelle complexe ou des écritures séquentielles. Pour les agrégations, les recherches et les comparaisons simples, WorksheetFunction remplace avantageusement toute boucle.

Vue de dessus d'un bureau de développeur avec code VBA For Loop visible sur écran laptop et notes manuscrites

Le choix entre boucle For, For Each et appel direct à une fonction de feuille dépend du type d’opération et du volume de données. Sur les classeurs volumineux, la combinaison tableau en mémoire plus verrous d’application reste la configuration la plus fiable pour éviter les gels. Gardez la boucle cellule par cellule pour le prototypage rapide, passez aux arrays dès que le code entre en production.

Articles populaires