Comment présenter les instructions de boucle
Exemple 1: boucle de collection
Exemple 2: boucle avec compteur et accumulateur
Les instructions d'un programme sont normalement exécutées les unes à la suite
des autres, séquentiellement.
Les instructions de boucle, de
test et de
branchement permettent de
modifier cet ordre naturel.
On utilise les instructions de boucle pour que le programme exécute un bloc d'instructions plusieurs fois.
For Each objet In collection Où:
Le bloc d'instructions est exécuté autant de fois qu'il y a d'objets dans la collection. À chaque itération, l'objet suivant de la collection collection est assigné à la variable objet. La boucle est terminée lorsque chaque objet a été traité, ou lorsque l'instruction Exit For est exécutée. Le programme se poursuit à l'instruction suivant le Next. |
Cette première version de l'instruction For ... Next est la
plus utilisée pour manipuler les plages de cellules Excel. Elle permet de
traiter simplement toutes les cellules d'une plage, sans se soucier de leur
adresse absolue ou relative.
Elle manipule aussi, mais plus difficilement, les
tableaux VBA.
Une plus ancienne version de l'instruction For ... Next est plus générale, mais requiert l'utilisation d'un compteur:
For compteur = début To fin[Step
valeur] [instructions] [Exit For] [instructions] Next [compteur] Où:
En principe, les instructions entre For et Next sont exécutées (fin - début + 1) fois, en ajoutant valeur à compteur à chaque itération. Bien noter que les bornes fin et début sont inclues. L'instruction Exit For peut être utilisée pour une sortie exceptionnelle de la boucle. À la fin de l'exécution de la boucle (après le Next), compteur vaut fin + valeur, et non fin. DANGER: ne jamais assigner de valeur à compteur à l'intérieur
des instructions. |
Cette 2e version de For...Next est plus ancienne que la précédente, et
est plus complexe à utiliser pour des collections d'objet.
Par contre, elle est plus adaptée à la manipulation de
tableaux VBA.
Elle correspond au code VBA suivant:
compteur = début
Do Until compteur > fin
[instructions]
[Exit Do]
[instructions]
compteur = compteur + valeur
Loop
Ce qui nous amène aux instructions de répétition plus générales:
Do While condition [instructions] [Exit Do] [instructions] Loop Do Until condition Do Do Où
Ces quatre instructions implantent en VBA les structures de boucle structurées. Elles sont peu utilisées, sauf pour les boucles de lecture. |
En VBA, il est convenu de présenter en retrait les instructions à l'intérieur d'une boucle.
Exemples à éviter:
Présentez cette boucle ainsi:
For Each Cellule in Plage
MsgBox Cellule.Value
'Mettre les instructions répétées en retrait
Next
Supposons une plage de cellules Excel nommée ListeProvinces:
On peut écrire une fonction VBA qui retourne le nom associé au sigle:
Function fnNomProvince4(SigleProvince) 'Auteur: Michel Berthiaume 'Retourner le nom d'une province Dim sSigleProvince As String Dim rCellule As Range On Error GoTo erreur: 'au cas où fnNomProvince4 = "sigle inconnu" 'Réponse par défaut 'D'abord tester la validité du paramètre If TypeName(SigleProvince) = "Range" Then sSigleProvince = UCase (SigleProvince.Value) ElseIf TypeName(SigleProvince) = "String" Then sSigleProvince = UCase(SigleProvince) Else Exit Function End If 'Rendu ici, sSigleProvince contient une version en majuscules du sigle 'Pour chaque cellule de colonne 1 de la plage nommée ListeProvinces For Each rCellule In Range("ListeProvinces").Columns(1).Cells If sSigleProvince = UCase(rCellule.Value) Then 'Valeur trouvée fnNomProvince4 = rCellule.Offset(0, 1).Value 'Valeur de la cellule à droite Exit For 'inutile de continuer: on sort de la boucle. End If Next Exit Function 'Pour éviter l'exécution des instructions de gestion d'erreur erreur: fnNomProvince4 = "Erreur inattendue, contacter le programmeur." & Err.Description End Function |
La même, en utilisant un compteur de lignes:
Function fnNomProvince5(SigleProvince) 'Auteur: Michel Berthiaume 'Retourner le nom d'une province Dim sSigleProvince As String Dim lLigne as Long On Error GoTo erreur: 'au cas où fnNomProvince5 = "sigle inconnu" 'Réponse par défaut
Exit Function 'Pour éviter
l'exécution des instructions de gestion d'erreur |
On veut une fonction fnMoyennePlus qui calcule la moyenne des valeurs positives d'une plage.
Function fnMoyennePlus(Plage) 'Auteur: Michel Berthiaume 'Calculer la moyenne des valeurs positives d'une plage Dim cSomme as Currency Dim cCompteur as Currency Dim rCellule as Range On Error GoTo erreur: 'au cas où 'D'abord tester la validité du paramètre
Exit Function 'Pour éviter
l'exécution des instructions de gestion d'erreur |
Une variante de la même fonction:
Function fnMoyennePlus1(Plage) 'Auteur: Michel Berthiaume 'Calculer la moyenne des valeurs positives d'une plage Dim lNoCellule As Long Dim cSomme as Currency Dim cCompteur as Currency Dim rCellule as Range On Error GoTo erreur: 'au cas où 'D'abord tester la validité du paramètre
Exit Function 'Pour éviter
l'exécution des instructions de gestion d'erreur |
Finalement, une variante plus classique de cette solution, utilisant un compteur de lignes et un compteur de colonnes:
Function fnMoyennePlus2(Plage) 'Auteur: Michel Berthiaume 'Calculer la moyenne des valeurs positives d'une plage Dim lNoLigne As Long
Dim lNoColonne As
Long
'D'abord tester la validité du paramètre End Function |
Dans une boucle de lecture, le nombre d'itérations n'est pas connu au départ. L'utilisation de For...Next n'est donc pas approprié.
Ici, on veut saisir une série de nombres qui seront inscrits dans la feuille Excel.
Sub SaisirNombres() 'Auteur: Michel Berthiaume 'Saisir des nombres et les inscrire dans une feuille Excel Dim sSaisie As String Dim lNoLigne As Long On
Error GoTo erreur: 'au cas où 'Dans la boucle de lecture "standard", la première valeur est lue AVANT d'entrer dans la boucle sSaisie = InputBox("Entrer une valeur", "Inscription de valeurs dans une feuille") Do Until sSaisie = "" 'Le bouton Annuler de InputBox renvoie la chaîne nulle If IsNumeric(sSaisie) Then lNoLigne = lNoLigne + 1 'Prochaine ligne de la feuille Excel Range("A1").Offset(lNoLigne, 0).Value = sSaisie End If sSaisie = InputBox("Entrer une valeur", "Inscription de valeurs dans une feuille") Loop Exit Sub 'Pour éviter l'exécution des instructions de gestion d'erreur erreur: MsgBox "Erreur inattendue, contacter le programmeur." & Err.Description End Sub |
Ce type de boucle est utilisé pour lire des données venant de requêtes SQL,
de fichiers conventionnels, etc.
Notez qu'il y a lecture AVANT d'entrer dans la boucle, puis une autre
immédiatement avant la fin, et que le test de fin de lecture est en début de
boucle.
La première instruction de lecture est automatique (implicite) dans l'ouverture
d'une requête SQL.
Une autre façon d'arriver au même résultat:
Sub SaisirNombres1() 'Auteur: Michel Berthiaume 'Saisir des nombres et les inscrire dans une feuille Excel Dim sSaisie As String Dim lNoLigne As Long On
Error GoTo erreur: 'au cas où Do sSaisie = InputBox("Entrer une valeur", "Inscription de valeurs dans une feuille") Loop Until IsNumeric(sSaisie) Or Len(sSaisie) = 0 If Len(sSaisie) = 0 Then lNoLigne = lNoLigne + 1 'Prochaine ligne de la feuille Excel Range("A1").Offset(lNoLigne, 0).Value = sSaisie End If Loop Until sSaisie = "" 'Le bouton Annuler de InputBox renvoie la chaîne nulle Exit Sub 'Pour éviter l'exécution des instructions de gestion d'erreur erreur: MsgBox "Erreur inattendue, contacter le programmeur." & Err.Description End Sub |
VBA offre plusieurs structures contrôlant l'ordre d'exécution des instructions.
Le fichier Excel Tutoriel Exemples Boucles.xlsm contient les exemples présentés dans la présente section.