VBA Boucles

Les boucles


Les boucles de répétition

Les boucles vous permettent d’exécuter un groupe d’instructions de manière répétée. Certaines boucles répètent les instructions jusqu’à ce qu’une condition obtienne la valeur False ; d’autres répètent les instructions jusqu’à ce qu’une condition à la valeur True.
On va utiliser ces boucles pour éviter de taper des lignes de code infiniment et surtout en fonction d'une condition, en écrivant la boucle on ne sait pas toujours le nombre de répétitions à prévoir.
Par exemple : Tant qu'il y a des points dans le jeu de sélection, insérer un bloc aux coordonnées du point.
On pourrait écrire une ligne qui insère le premier bloc, en écrire une deuxième pour insérer le deuxième bloc, en écrire une troisième... NON.
On va créer une boucle qui le fera à notre place.


L'instruction IF

C'est la première notion de boucle abordée, car c'est la plus simple, un test de condition et SI cette condition est vraie : Faire quelque chose.
Cette instruction va permettre de choisir la suite du traitement des données en fonction d'une comparaison. Le plus simple des cas de IF est celui ci :

If Condition Then
     'code si la condition est vraie
End IF

La syntaxe est IF [condition] Then, le Then est sur la même ligne que le IF, si la condition est avérée VBA passe à la ligne suivante et exécute le code soumis puis va rencontrer la ligne End If qui signifie qu'il est sorti de la boucle. On est d'accord que ce n'est pas une boucle stricto sensu puisqu'elle ne va tourner plusieurs fois, toutefois je pense que l'instruction IF a sa place dans cette page.

Un peu plus compliqué : SI la condition qui suit est vraie "faire ceci" et si elle est fausse "faire autre chose".
If Condition Then
     'code si la condition est vraie
Else
     'code si la condition est fausse
End IF

Dans l'exemple qui suit, une case de saisie apparait, si le nombre entier est pair on affiche un message, la condition est respectée et un autre à la suite du Else si cette condition n'est pas respectée.
(dans cet exemple il n'est pas vérifié si la valeur saisie est bien un nombre)

Sub testIF()
     Dim nombre As Integer
     nombre = InputBox("Entrez un nombre, je vous dirai s'il est pair ou impair ")
     If nombre Mod 2 = 0 Then
          MsgBox " C'est un nombre pair !"
     Else
     MsgBox " C'est un nombre impair !"
     End If
End Sub

Pour vérifier que le nombre est pair je compare le reste de la division par 2 à 0 (zéro), on est OK ?

Il est toléré de tout écrire sur une même ligne, pas forcément facile à lire, mais ça fonctionne donc j'en parle :

Sub salut1()
     Dim moment As String
     moment = "soir"
     If moment = "matin" Then MsgBox "Bonjour" Else MsgBox "Bonsoir"
End Sub

Il est possible de multiplier les Else, dans ce cas on utilisera ElseIf comme ceci :

Sub salut2()
     Dim moment As String
     moment = "je sais pas"
     If moment = "matin" Then
          MsgBox "Bonjour"
     ElseIf moment = "apres-midi" Then
          MsgBox "Bonne apres-midi"
     ElseIf moment = "soir" Then
          MsgBox "Bonsoir"
     ElseIf moment = "nuit" Then
     MsgBox "Bonne nuit"
     Else
          MsgBox "Moment de la journée inconnu..."
    End If
End Sub

Dans cet exemple les IF vont être testés un par un, comme la condition n'est pas respectée, VBA passe au suivant pour terminer sur le dernier Else qui sera exécuté, il sera plus tard question de SELECT CASE qui est plus approprié, mais le ElseIf fonctionne bel et bien.

Un autre exemple avec deux conditions reliées par un AND

Sub testIF2()
     Dim i As Integer
     i = 9
     If i < 10 And i > 5 Then
     MsgBox "la condition du IF est vraie"
End If
End Sub

Pour que la MsgBox s'affiche il faut que le contenu de la variable"i" soit plus petit que dix ET plus grand que cinq, les réponses recevables sont 6,7,8 et 9 puis qu'il est demandé des nombres entiers (integer).
5 et 10 sont exclus, car la comparaison se fait avec < et > strictement inférieur et strictement supérieur.

L'instruction WHILE

Structure classique qui signifie TANT QUE, la syntaxe est
While Condition
     'code à exécuter
Wend

Le mot de fin est Wend qui est la contraction While END
Exemple :
Apparition d'une case de saisie de valeur, puis comparaison de la valeur saisie avec l'addition des variables, et tant que le résultat saisi est faux on reste dans la boucle et la case revient. À la fin de la boucle une simple case de message apparaît.
(dans cet exemple il n'est pas vérifié si la valeur saisie est bien un nombre)

Sub testWhile()
     Dim a As Integer, b As Integer
     a = 5 : b = 3
     While InputBox ("Résultat de l'addition de " & a & " et " & b & " ?") <> a + b
          MsgBox "Faux, essaie encore ! ..."
     Wend
     MsgBox " Bien calculé !"
End Sub


L'instruction DO

Le principe est de lancer une action et suivant l'élément qui va suivre exécuter un certain nombre de fois cette action. Un nombre qui n'est pas connu au début de la boucle, c'est ce qu'on appelle une boucle indéfinie. Voir FOR pour un lancement de la boucle un nombre connu de fois.
Do peut être utilisé avec While ou Until qui ont à peu près le même sens, mais puisqu'il y a deux options, c'est qu'elles sont différentes.
En fait "while" c'est "tant que ..." et "until" c'est "jusqu'à ce que ..." C'est un choix à faire pour la clarté du code car in fine la boucle bouclera...

Do While

Syntaxe :

Do While Condition
     'code à exécuter tant que la condition est vraie
Loop

Dans cet exemple la boucle tournera tant que la condition est respectée :

Sub TestDoWhile1()
     Dim i As Integer
     Do While i < 5
          i = i + 1
          MsgBox "Tour numéro : " & i
     Loop
End Sub

À chaque "tour" la variable i augmente de 1 et quand elle passe supérieure à 5, la condition n'est plus vérifiée et VBA sort donc de la boucle.
Si au départ la variable avait eu 6 comme valeur, la boucle n'aurait même pas démarré.
Le test après Do n'est pas avéré donc on ne rentre pas dans la boucle.

Si on dépose le While après le Loop, la boucle démarrera au moins une fois comme ici :

Sub TestDoWhile2()
     Dim i As Integer
     i = 10
     Do
     i = i + 1
     MsgBox "La valeur de la variable i est de  : " & i
     Loop While i < 3
End Sub

Dans ce cas de figure, l'instruction va être lancée au moins une fois, puisque le test, la condition se trouve après ce premier lancement, dans notre cas l'apparition d'un MsgBox.
Et dans ce cas la condition est mal placée, car la boucle n'aurait jamais dû démarrer puisque i est supérieur à 3 dès le lancement.

Do Until

À l’inverse de la boucle Do While, il existe la boucle Do Until qui elle permet de répéter une partie de code tant qu’une condition n’est pas remplie !
Autrement dit : "Répéter l’opération JUSQU’À ce que … ". Ce qui revient quasiment au même c'est dans l'expression de la condition qu'il y a un changement.
Je reprends le premier exemple et je passe avec Until, donc il faut dire : répéter la boucle jusqu'à ce que le contenu de la variable reste strictement inférieur à 5.
Le souci dans ce cas, c'est que la boucle passe de 1 à 2 puis 3,4, et 5 et arrivé là elle devrait s'arrêter, mais elle continue encore un tour pour obtenir 6, et quand i est à 6 le prochain tour en passera pas la condition et s'arrêtera.

Sub TestDoUntil1()
     Dim i As Integer
     Do Until i > 5
     i = i + 1
     MsgBox "Tour numéro : " & i
    Loop
End Sub

Connaissant ces divers fonctionnements, vous êtes en mesure de faire vos choix de mot clé, While ou Until.
Je vous invite à faire des tests pour comprendre les différences, je n'ai pas assez de pages pour mettre tous les exemples...


Quitter le while

Il est possible de quitter prématurément une boucle Do While grâce à l’instruction Exit Do :

Sub TestDoWhile2()
     Dim i As Integer
     i = 10
     Do
          i = i - 1
          MsgBox "La valeur de la variable i est de  : " & i
          If MsgBox(" Voulez vous continuer ?", vbYesNo) = vbNo Then Exit Do
     Loop While i > 5

End Sub

Dans les faits ce qui se passe ici est le lancement de la MsgBox de résultat, tout de suite une autre s'ouvre pour affirmer la volonté de continuer, si l'utilisateur clique sur annuler, l'instruction Exit Do se lance et VBA saute après la ligne Loop While.
Pour quitter une boucle Until c'est exactement le même principe.


L'instruction FOR

Répète un groupe d’instructions un nombre de fois spécifié.

La syntaxe simple est :
For [Compteur] = début To fin (incrémentation)
     'code à effectuer
Next

En langage naturel cela signifie pour compteur de 1 à 10 faire ceci, et la boucle va au départ savoir qu'elle part de compteur à 1, exécuter le code qui suit, en rencontrant Next  le compteur s'incrémente et elle remonte à compteur tant que ce dernier n'est pas arrivé à la valeur "fin".
La valeur d'incrémentation est optionnelle si elle n'est pas précisée, c'est la valeur 1 qui est prise par défaut.
Le mot clé pour choisir l'incrémentation est Step.

Exemple :

Sub testFor1()
     Dim i As Integer
     For i = 1 To 5
     MsgBox i
Next
End Sub

Cette boucle va afficher cinq fois de suite la MsgBox avec la valeur de i qui s'incrémente de 1 à chaque tour et se termine toute seule une fois que la valeur de fin du For est atteinte.

Sub testFor2()
     Dim i As Integer
     For i = 1 To 5 Step 2
     MsgBox i
Next
End Sub

Cette boucle va aussi afficher cinq fois de suite la MsgBox avec la valeur de i, mais qui s'incrémente de 2 à chaque tour (valeur de step) et se termine aussi toute seule une fois la valeur de fin du For atteinte.
Notez qu'il est possible de mettre un Step négatif, voire de mettre un step qui n'est pas un nombre entier, c'est possible.

Exemple pour dessiner cent cercles concentriques avec un rayon incrémenté de un à chaque tour :

Sub Dess_Cercle_multiple()
    
Dim Mon_Cercle As AcadCircle ' Nom objet cercle
     Dim PtCentre As Variant ' variable definie en variant
     Dim i As Integer ' valeur du rayon qui va s'incrémenter
     PtCentre = ThisDrawing.Utility.GetPoint(, "Centre du cercle :")
     For i = 1 To 100
          Set Mon_Cercle = ThisDrawing.ModelSpace.AddCircle(PtCentre, i)
          Mon_Cercle.Update
     Next
End Sub

Aperçu boucle For 100 cercles

Imbrication de For

Il est possible d'imbriquer des boucles For, je m'explique :
Pour emplir un tableau à deux dimensions de 9 lignes et neuf colonnes mettant dans chaque colonne les chiffres de 1 à 9 et ce sur toutes les lignes (soit 81 cases) on va faire deux boucles imbriquées comme ceci :

Sub doubleFor()
     Dim tableau(9, 9)
     Dim i As Integer
     Dim j As Integer

     For i = 0 To 9
          For j = 0 To 9
          tableau(i, j) = j
          Next j
     j = i
     tableau(i, j) = i
    Next i
End Sub

Vous avez remarqué qu'après les Next j'ai mis le nom de la variable concernée, ce n'est pas obligatoire, car ça fonctionne sans mais ça simplifie bien la lecture du code par les humains.
Le premier For commence avec i à 0, le deuxième For commence avec le i à 0 et le j à 0
au premier tour de la boucle interne i vaut toujours 0, mais j vaut 1 et s'incrémente neuf fois en tout.
On passe donc au deuxième tour de i qui vaut 2 maintenant et on reprend la boucle imbriquée pour emplir la deuxième ligne du tableau et ainsi de suite. On est OK ?

J'arrête là pour l'instant et comme toujours je suis derrière le formulaire CONTACT pour tout genre d'explication ou de demande de mise à jour du site, si vous détectez une faute, de frappe ou plus grave faites-m'en part, je corrigerai.