Boucles Excel VBA – For Each, For Next, Do While, Imbriquées et Autres
In this Article
Pour travailler efficacement en VBA, vous devez comprendre les boucles.
Les boucles vous permettent de répéter un bloc de code un nombre déterminé de fois ou de répéter un bloc de code sur chaque objet d’un ensemble d’objets.
Nous allons d’abord présenter quelques exemples pour vous montrer ce que boucles peuvent accomplir. Ensuite, nous vous apprendrons tout sur les boucles.
Exemples Rapides de Boucles VBA
Boucles For Each
Les boucles For Each parcourent chaque objet d’une collection, par exemple chaque feuille de calcul du classeur ou chaque cellule d’une plage.
Boucle sur Toutes les Feuilles de Calcul du Classeur
Ce code parcourt en boucle toutes les feuilles de calcul du classeur, en affichant chaque feuille:
Sub BoucleChaqueFeuille()
Dim fc As Worksheet
For Each fc In Worksheets
fc.Visible = True
Next fc
End Sub
Boucler sur Toutes les Cellules d’une Plage
Ce code parcourt en boucle une plage de cellules, en vérifiant si la valeur de la cellule est négative, positive ou nulle :
Sub BoucleInstructionIf()
Dim Cell As Range
For Each Cell In Range("A2:A6")
If Cell.Value < 0 Then
Cell.Offset(0, 1).Value = "Positif"
ElseIf Cell.Value < 0 Then
Cell.Offset(0, 1).Value = "Négatif"
Else
Cell.Offset(0, 1).Value = "Zéro"
End If
Next Cell
End Sub
Boucles For Next
Un autre type de boucle « For » est la boucle « For Next ». La boucle For Next vous permet de parcourir des nombres entiers en boucle.
Ce code passe en boucle les nombres entiers de 1 à 10, en affichant chacun d’eux dans une boîte de message :
Sub BoucleForNext()
Dim i As Integer
For i = 1 To 10
MsgBox i
Next i
End Sub
Boucles Do While
Les boucles Do While bouclent pendant qu’une condition est remplie. Ce code va également parcourir en boucle les nombres entiers de 1 à 10, en affichant chacun d’eux dans une boîte de message.
Sub BoucleDoWhile()
Dim n As Integer
n = 1
Do While n < 11
MsgBox n
n = n + 1
Loop
End Sub
Boucles Do Until
À l’inverse, les boucles Do Until bouclent jusqu’à ce qu’ une condition soit remplie. Ce code fait la même chose que les deux exemples précédents.
Sub BoucleDoUntil()
Dim n As Integer
n = 1
Do Until n >= 10
MsgBox n
n = n + 1
Loop
End Sub
Nous en parlerons plus loin, mais vous devez être extrêmement prudent lorsque vous créez des boucles Do While ou Do Until afin de ne pas créer une boucle sans fin.
Créateur de Boucles VBA
Voici une capture d’écran du « Loop Builder » de notre VBA Add-in : AutoMacro Premium. Le créateur de boucle vous permet de construire rapidement et facilement des boucles pour passer en revue différents objets ou nombres. Vous pouvez effectuer des actions sur chaque objet et/ou sélectionner uniquement les objets qui répondent à certains critères.
Le module complémentaire contient également de nombreux autres créateurs de code, une vaste bibliothèque de code VBA et un assortiment d’outils de programmation. Il s’agit d’un outil indispensable pour tout développeur VBA.
Nous allons maintenant aborder en profondeur les différents types de boucles.
Boucle For Next en VBA
Syntaxe de la Boucle For
La boucle For Next vous permet de répéter un bloc de code un nombre de fois déterminé. La syntaxe est la suivante :
[Dim Compteur as Integer]
For Compteur = Début to Fin [Valeur des incréments]
[Votre code à boucler ici]
Next [Compteur]
Les éléments entre crochets sont facultatifs.
- [Dim Compteur as Long] – Déclare la variable compteur. Requis si l’option Explicit est déclarée en haut de votre module.
- Compteur – Une variable entière utilisée pour compter
- Début – La valeur de départ (Ex. 1)
- Fin – La valeur de fin (Ex. 10)
- [Valeur des Incréments] – Vous permet de compter tous les n entiers au lieu de tous les 1 entiers. Vous pouvez également faire l’inverse avec une valeur négative (ex. Step -1)
- [Do Something] – Le code qui sera répété
- Next [Counter] – Instruction de clôture de la boucle For Next. Vous pouvez inclure le compteur ou non. Cependant, je recommande fortement d’inclure le compteur car il rend votre code plus facile à lire.
Si cela vous semble confus, ne vous inquiétez pas. Nous allons passer en revue quelques exemples :
Compter Jusqu’à 10
Ce code va compter jusqu’à 10 en utilisant une boucle For-Next :
Sub ForEach_Compte10()
Dim n As Integer
For n = 1 à 10
MsgBox n
Next n
End Sub
Etape de la Boucle For
Compter jusqu’à 10 – Uniquement les Nombres Pairs
Ce code permet de compter jusqu’à 10 en ne comptant que les nombres pairs :
Sub ForEach_Compte10_Pairs()
Dim n As Integer
For n = 2 To 10 Step 2
MsgBox n
Next n
End Sub
Remarquez que nous avons ajouté « Step 2 ». Nous pouvons également utiliser une valeur de pas négative pour effectuer incréments décroissants :
For Loop Step – Inverse
Compte à Rebours à Partir de 10
Ce code effectue un compte à rebours à partir de 10 :
Sub ForEach_CompteRebours()
Dim n As Integer
For n = 10 To 1 Step -1
MsgBox n
Next n
MsgBox "Décollage"
End Sub
Suppression des Lignes si la Cellule est Vide
J’ai le plus souvent utilisé un For-Loop à pas négatif pour parcourir en boucle des plages de cellules, en supprimant les lignes qui répondent à certains critères. Si vous bouclez à partir des rangées supérieures vers les rangées inférieures, lorsque vous supprimez des rangées, le compteur pourrait ne plus être correctement synchronisé à vos actions.
Cet exemple supprimera les lignes contenant des cellules vides (en commençant par la ligne inférieure) :
Sub ForEach_Suppression_CellulesVides()
Dim n As Integer
For n = 10 To 1 Step -1
If Range("a" & n).Value = "" Then
Range("a" & n).EntireRow.Delete
End If
Next n
End Sub
Boucle For Imbriquée
Vous pouvez « imbriquer » un For Loop dans un autre For Loop. Nous allons utiliser des boucles For imbriquées pour créer une table de multiplication :
Sub ForEach_Imbriquée_TableMultiplication()
Dim ligne As Integer, col As Integer
For ligne = 1 To 9
For col = 1 To 9
Cells(ligne + 1, col + 1).Value = ligne * col
Next col
Next ligne
End Sub
Exit For
L’instruction Exit For vous permet de quitter immédiatement une boucle For Next.
Vous utilisez généralement Exit For avec une instruction If, pour sortir de la boucle For Next si une certaine condition est remplie.
Par exemple, vous pouvez utiliser une boucle For pour trouver une cellule. Une fois la cellule trouvée, vous pouvez quitter la boucle pour accélérer votre code.
Ce code parcourt en boucle les lignes 1 à 1000, à la recherche du mot « erreur » dans la colonne A. S’il est trouvé, le code sélectionne la cellule, vous avertit de l’erreur trouvée et quitte la boucle :
Sub ExitFor_Boucle()
Dim i As Integer
Pour i = 1 à 1000
If Range("A" & i).Value = "erreur" Then
Range("A" & i).Select
MsgBox "Erreur trouvée"
Exit For
End If
Next i
End Sub
Important : Dans le cas de boucles For imbriquées, Exit For ne quitte que la boucle For actuelle, et non toutes les boucles actives.
Continue For
VBA ne dispose pas de la commande « Continue » que l’on trouve dans Visual Basic. Vous devez plutôt utiliser « Exit ».
Boucle For Each de VBA
La boucle VBA For Each parcourt en boucle tous les objets d’une collection :
- Toutes les cellules d’une plage
- Toutes les feuilles de calcul d’un classeur
- Toutes les formes d’une feuille de calcul
- Tous les classeurs ouverts
Vous pouvez également utiliser des boucles For Each imbriquées pour :
- Toutes les cellules d’une plage sur toutes les feuilles de calcul
- Tous les objets de toutes les feuilles de calcul
- Toutes les feuilles de tous les classeurs ouverts
- et ainsi de suite…
La syntaxe est la suivante :
For Each Objet in collection
[Votre code ici]
Next [Objet]
Où :
- Objet – Variable représentant une plage, une feuille de calcul, un classeur, une forme, etc. (ex. rng)
- Collection – Collection d’objets (ex. Range(« a1:a10 »))
- [Votre code ici] – Bloc de code à exécuter pour chaque objet
- Next [Objet] – Déclaration finale. L’option [Objet] est facultative, mais fortement recommandée.
Pour Chaque Cellule de la Plage
Ce code permet de parcourir en boucle chaque cellule d’une plage:
Sub ForEach_CelluleDansUnePlage()
Dim cell As Range
For Each cell In Range("a1:a10")
cell.Value = cell.Offset(0,1).Value
Next cell
End Sub
Pour Chaque Feuille de Travail dans le Classeur
Ce code parcourt en boucle toutes les feuilles de calcul d’un classeur et enlève la protection sur chaque feuille :
Sub ForEach_FeuileDansLeClasseur()
Dim fc As Worksheet
For Each fc In Worksheets
fc.Unprotect "MotDePasse"
Next fc
End Sub
Pour Chaque Classeur Ouvert
Ce code va enregistrer et fermer tous les classeurs ouverts :
Sub ForEach_ClasseurDansCollectionWorkbooks()
Dim cl As Workbook
For Each cl In Workbooks
cl.Close SaveChanges:=True
Next cl
End Sub
Pour Chaque Forme dans la Feuille de Calcul
Ce code va supprimer toutes les formes dans la feuille active.
Sub ForEachForme()
Dim forme As Shape
For Each forme In ActiveSheet.Shapes
forme.Delete
Next forme
End Sub
Pour Chaque Forme dans Chaque Feuille de Calcul du Classeur
Vous pouvez également imbriquer les boucles For Each. Ici, nous allons parcourir en boucle toutes les formes de toutes les feuilles de calcul du classeur actif :
Sub ForEachForme_DansToutesLesFeuilles()
Dim forme As Shape, fc As Worksheet
For Each fc In Worksheets
For Each forme In fc.Shapes
forme.Delete
Next forme
Next fc
End Sub
For Each – Boucle IF
Comme nous l’avons déjà mentionné, vous pouvez utiliser une instruction If dans une boucle, pour n’effectuer des actions que si certains critères sont remplis.
Ce code permet de masquer toutes les lignes vides d’une plage :
Sub ForEachCellule_DansLaPlage()
Dim cell As Range
For Each cell In Range("a1:a10")
If cell.Value = "" Then _
cell.EntireRow.Hidden = True
Next cell
End Sub
Boucle Do While en VBA
Les boucles VBA Do While et Do Until (voir section suivante) sont très similaires. Elles répètent une boucle pendant (ou jusqu’à) ce qu’une condition soit remplie.
La boucle Do While répète une boucle tant et aussi longtemps qu’une condition est remplie.
Voici la syntaxe Do While :
Do While Condition
[Votre Code Ici]
Loop
Où :
- Condition – La condition à tester
- [Votre Code Ici] – Le bloc de code à répéter
Vous pouvez également configurer une boucle Do While avec la condition à la fin de la boucle :
Do
[Votre Code Ici]
Loop While Condition
Nous allons faire une démonstration de chacune d’entre elles et montrer en quoi elles diffèrent :
Do While
Voici un exemple de boucle Do While que nous avons démontré précédemment :
Sub DoWhileLoop()
Dim n As Integer
n = 1
Do While n < 11
MsgBox n
n = n + 1
Loop
End Sub
Loop While
Maintenant, exécutons la même procédure, sauf que nous allons déplacer la condition à la fin de la boucle :
Sub DoLoopWhile()
Dim n As Integer
n = 1
Do
MsgBox n
n = n + 1
Loop While n < 11
End Sub
Boucle Do Until en VBA
Les boucles Do Until répètent une boucle jusqu’à ce qu’ une certaine condition soit remplie. La syntaxe est essentiellement la même que celle des boucles Do While :
Do Until Condition
[Votre Code Ici]
Loop
de même, la condition peut être placée au début ou à la fin de la boucle :
Do
[Votre Code Ici]
Loop Until Condition
Do Until
Cette boucle Do Until va compter jusqu’à 10, comme nos exemples précédents
Sub DoUntilLoop()
Dim n As Integer
n = 1
Do Until n > 10
MsgBox n
n = n + 1
Loop
End Sub
Boucle Jusqu’à
Cette boucle Loop Until va compter jusqu’à 10 :
Sub DoLoopUntil()
Dim n As Integer
n = 1
Do
MsgBox n
n = n + 1
Loop Until n > 10
End Sub
Sortie de la Boucle Do
De la même façon que vous utilisez Exit For pour sortir d’une boucle For, vous utilisez la commande Exit Do pour sortir immédiatement d’une boucle Do
Exit Do
Voici un exemple de la commande Exit Do :
Sub ExitDo_Boucle()
Dim i As Integer
i = 1
Do Until i > 1000
If Range("A" & i).Value = "erreur" Then
Range("A" & i).Select
MsgBox "erreur trouvée"
Exit Do
End If
i = i + 1
Loop
End Sub
Terminer ou Interrompre une Boucle
Comme nous l’avons mentionné ci-dessus, vous pouvez utiliser les fonctions Exit For ou Exit Do pour sortir des boucles :
Exit For
Exit Do
Cependant, ces commandes doivent être ajoutées à votre code avant d’exécuter votre boucle.
Si vous essayez de « casser » une boucle en cours d’exécution, vous pouvez essayer d’appuyer sur ESC ou CTRL + Pause Break sur le clavier. Cependant, il est possible que cela ne fonctionne pas. Si cela ne fonctionne pas, vous devrez attendre que votre boucle se termine ou, dans le cas d’une boucle sans fin, utiliser CTRL + ALT + Suppr pour forcer la fermeture d’Excel.
C’est pourquoi j’essaie d’éviter les boucles Do, il est plus facile de créer accidentellement une boucle sans fin vous obligeant à redémarrer Excel, ce qui peut entraîner la perte de votre travail.
Autres Exemples de Boucles
Boucle au Travers des Lignes
Cette fonction permet de parcourir toutes les lignes d’une colonne :
Public Sub ParcourirLesRangées()
Dim cell As Range
For Each cell In Range("A:A")
If cell.Value <> "" Then MsgBox cell.Address & ": " & cell.Value
Next cell
End Sub
Boucle au Travers des Colonnes
Cette fonction permet de parcourir en boucle toutes les colonnes d’une ligne :
Public Sub ParcourirLesColonnes()
Dim cell As Range
For Each cell In Range("1:1")
If cell.Value <> "" Then MsgBox cell.Address & ": " & cell.Value
Next cell
End Sub
Parcourir en Boucle les Fichiers d’un Dossier
Ce code permet de parcourir en boucle tous les fichiers d’un dossier, en créant une liste:
Sub ParcourirLesFichiers()
Dim oFSO As Object
Dim oDossier As Object
Dim oFichier As Object
Dim i As Integer
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set oDossier = oFSO.GetFolder("C:\Demo")
i = 2
For Each oFichier In oDossier.Files
Range("A" & i).Value = oFichier.Name
i = i + 1
Next oFichier
End Sub
Boucle dans un Tableau
Ce code va parcourir en boucle le tableau ‘arrListe’ :
For i = LBound(arrListe) To UBound(arrListe)
MsgBox arrListe(i)
Next i
La fonction LBound obtient la « limite inférieure » du tableau et UBound la « limite supérieure ».
Boucles dans Access VBA
La plupart des exemples ci-dessus fonctionnent également dans Access VBA. Cependant, dans Access, nous bouclons à travers l’objet Recordset plutôt que l’objet Range.
Sub ParcourirLaBaseDeDonnées()
On Error Resume Next
Dim dbs As Database
Dim rst As Recordset
Set dbs = CurrentDb
Set rst = dbs.OpenRecordset("tblClients", dbOpenDynaset)
Avec rst
.MoveLast
.MoveFirst
Do Until .EOF = True
MsgBox (rst.Fields("NomClient"))
.MoveNext
loop
End With
rst.Close
Set rst = Nothing
Set dbs = Nothing
End Sub