La boucle For en VBA Excel répète un bloc d’instructions un nombre défini de fois, contrôlé par un compteur. Elle existe sous deux formes principales : For...Next, qui travaille avec un indice numérique, et For Each...Next, qui parcourt les éléments d’une collection ou d’une plage. Savoir laquelle utiliser, et comment la structurer dans une macro de rapport, évite à la fois les erreurs de logique et les temps d’exécution excessifs.
Le bloc With dans une boucle For : accélérer la mise en forme d’un rapport
La plupart des tutoriels présentent la syntaxe de For...Next en boucle simple. Dans un contexte de rapport, chaque itération touche souvent plusieurs propriétés du même objet : valeur de la cellule, couleur de fond, police, bordure. Répéter la référence complète à chaque ligne alourdit le code et ralentit l’exécution.
Le bloc With…End With résout ce problème. Placé à l’intérieur de la boucle, il permet de qualifier l’objet une seule fois, puis d’enchaîner les propriétés avec un simple point.
Exemple concret : mettre en forme les lignes d’un tableau de suivi mensuel (colonnes A à E, lignes 2 à 50) en colorant en rouge les montants négatifs.
Sub FormatRapport()Dim i As LongFor i = 2 To 50With Cells(i, 5)If .Value < 0 Then.Font.Color = vbRed.Font.Bold = True.Interior.Color = RGB(255, 230, 230)End IfEnd WithNext iEnd Sub
Sans le bloc With, le code contiendrait trois fois Cells(i, 5) suivi de chaque propriété. Sur une plage de plusieurs centaines de lignes, la différence de lisibilité est nette, et la macro gagne en performance parce que VBA ne résout la référence objet qu’une fois par itération.

For Next avec Step : parcourir une plage VBA en sens inverse
La boucle For...Next incrémente son compteur de 1 par défaut. Le mot-clé Step modifie ce comportement, et c’est dans les rapports qu’il se révèle le plus utile.
Supprimer des lignes sans décalage d’index
Supprimer des lignes dans une boucle ascendante provoque un bug classique : après suppression de la ligne 10, l’ancienne ligne 11 prend l’index 10, mais le compteur passe à 11. Résultat : une ligne sur deux est ignorée.
La parade est de boucler de la dernière ligne vers la première avec un Step négatif :
Sub NettoyerRapport()Dim i As LongFor i = Range("A" & Rows.Count).End(xlUp).Row To 2 Step -1If Cells(i, 3).Value = "" ThenRows(i).DeleteEnd IfNext iEnd Sub
Cette macro supprime toutes les lignes dont la colonne C est vide, en partant du bas. L’index des lignes restantes n’est jamais perturbé.
Comparer deux lignes consécutives
Un rapport financier nécessite parfois de comparer la valeur d’une ligne avec celle qui la précède (écart mensuel, variation de stock). Avec For i = 3 To derniereLigne, on accède à Cells(i, 4).Value - Cells(i - 1, 4).Value pour calculer la différence. Démarrer à la ligne 3 (et non 2) évite une erreur de référence sur la première ligne de données.
For Each Next sur une collection Excel : traiter plusieurs feuilles d’un classeur
La boucle For Each...Next ne travaille pas avec un compteur numérique. Elle parcourt chaque élément d’une collection (feuilles, plages, classeurs ouverts). La variable de boucle doit être déclarée comme objet ou Variant, jamais comme type simple (Integer, String).
Cas de rapport fréquent : consolider un même indicateur depuis plusieurs onglets mensuels vers une feuille de synthèse.
Sub ConsoliderOnglets()Dim ws As WorksheetDim ligneSynthese As LongligneSynthese = 2For Each ws In ThisWorkbook.WorksheetsIf ws.Name <> "Synthese" ThenSheets("Synthese").Cells(ligneSynthese, 1).Value = ws.NameSheets("Synthese").Cells(ligneSynthese, 2).Value = ws.Range("F2").ValueligneSynthese = ligneSynthese + 1End IfNext wsEnd Sub
Chaque feuille (sauf « Synthese ») transmet la valeur de sa cellule F2 vers la feuille récapitulative. Ajouter un nouvel onglet mensuel au classeur suffit : la macro le prendra en compte automatiquement au prochain lancement.
- La variable
wsest déclaréeAs Worksheetparce qu’on parcourt la collectionWorksheets. Pour une plage, on utiliseraitDim cell As Range. - Modifier la collection pendant l’itération (supprimer une feuille dans la boucle, par exemple) provoque une erreur d’exécution. Stocker d’abord les noms à supprimer dans un tableau, puis traiter ce tableau dans une seconde boucle.
- Si l’ordre de parcours ou l’accès à un indice compte (comparer
ieti+1, sauter une ligne sur deux),For...Nextreste le bon choix.For Eachne donne pas de contrôle sur l’index.

Choisir entre For Next et For Each pour un rapport VBA Excel
Le choix dépend de ce que la macro doit faire avec les données, pas du volume à traiter.
| Critère | For…Next | For Each…Next |
|---|---|---|
| Accès par index (ligne i, colonne j) | Oui | Non |
| Parcours inverse (Step -1) | Oui | Non |
| Comparaison entre éléments adjacents | Oui | Non |
| Parcours d’une collection (Worksheets, Workbooks) | Possible mais inutilement verbeux | Oui, syntaxe native |
| Réécriture de valeurs dans un tableau VBA | Oui | Limité (la variable reçoit une copie) |
Pour un rapport qui consolide des onglets, For Each est plus lisible. Pour un rapport qui nettoie, trie ou compare des lignes dans une même feuille, For...Next avec un compteur Long donne plus de contrôle.
Un dernier point souvent négligé : déclarer le compteur en Long plutôt qu’en Integer. Une feuille Excel peut contenir plus d’un million de lignes, bien au-delà de la limite de 32 767 qu’impose le type Integer. Utiliser Long par défaut évite un dépassement silencieux qui corromprait les données du rapport sans message d’erreur explicite.

