Loop For VBA dans excel : exemples concrets pour vos rapports

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 Long
For i = 2 To 50
With Cells(i, 5)
If .Value < 0 Then
.Font.Color = vbRed
.Font.Bold = True
.Interior.Color = RGB(255, 230, 230)
End If
End With
Next i
End 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.

Cadre masculin analysant des rapports Excel avec un script de boucle VBA sur un ordinateur portable en salle de réunion

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 Long
For i = Range("A" & Rows.Count).End(xlUp).Row To 2 Step -1
If Cells(i, 3).Value = "" Then
Rows(i).Delete
End If
Next i
End 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 Worksheet
Dim ligneSynthese As Long
ligneSynthese = 2
For Each ws In ThisWorkbook.Worksheets
If ws.Name <> "Synthese" Then
Sheets("Synthese").Cells(ligneSynthese, 1).Value = ws.Name
Sheets("Synthese").Cells(ligneSynthese, 2).Value = ws.Range("F2").Value
ligneSynthese = ligneSynthese + 1
End If
Next ws
End 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 ws est déclarée As Worksheet parce qu’on parcourt la collection Worksheets. Pour une plage, on utiliserait Dim 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 i et i+1, sauter une ligne sur deux), For...Next reste le bon choix. For Each ne donne pas de contrôle sur l’index.

Jeune développeur travaillant sur une boucle For en VBA Excel depuis son bureau à domicile avec un ordinateur portable

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.

Les immanquables