version 6.0
La syntaxe de la structure répétitive Boucle...Fin de boucle est la suivante :
Boucle (Variable_Compteur; Expression_Début; Expression_Fin {; Expression_Incrément}) instructions(s) Fin de boucle
La structure Boucle...Fin de boucle est une boucle contrôlée par un compteur :
La variable compteur Variable_Compteur est une variable numérique (Réel, Entier ou Entier long) initialisée par Boucle...Fin de boucle à la valeur spécifiée par Expression_Début.
La variable Variable_Compteur est incrémentée de la valeur spécifiée par le paramètre optionnel Expression_Incrément à chaque fois que la boucle est exécutée. Si vous ne passez pas de valeur dans Expression_Incrément, la variable compteur est incrémentée par défaut de un (1).
Lorsque le compteur atteint la valeur définie par Expression_Fin, la boucle s'arrête.
Important : Les expressions numériques Expression_Début, Expression_Fin et Expression_Incrément sont évaluées une seule fois, au début de la boucle. Si ces expressions sont des variables, leur modification depuis l'intérieur de la boucle n'affectera pas l'exécution de la boucle.
Astuce : En revanche, vous pouvez, si vous le souhaitez, modifier la valeur de la variable Variable_Compteur depuis l'intérieur de la boucle et cela affectera l'exécution de la boucle.
Généralement, Expression_Début est inférieure à Expression_Fin.
Si les deux expressions sont égales, la boucle ne sera exécutée qu'une fois.
Si Expression_Début est supérieure à Expression_Fin, la boucle ne s'exécutera pas du tout, à moins que vous ne spécifiiez une Expression_Incrément négative. Reportez-vous ci-dessous au paragraphe décrivant ce point.
Exemples élémentaires
(1) La boucle suivante s'exécute 100 fois :
Boucle (vCompteur;1;100) ` Faire quelque chose Fin de boucle
(2) L'exemple suivant permet de traiter tous les éléments du tableau unTableau :
Boucle ($vlElem;1;Taille tableau(unTableau)) ` Faire quelque chose avec l'élément unTableau{$vlElem}:=... Fin de boucle
(3) L'exemple suivant permet d'examiner chaque caractère du texte vtDuTexte :
Boucle ($vlCar;1;Longueur(vtDuTexte)) ` Faire quelque chose avec le caractère si c'est une tabulation Si (Code de caractere(vtDuTexte[[$vlCar]])=Caractere(Tab)) ` ... Fin de si Fin de boucle
(4) L'exemple suivant permet de traiter tous les enregistrements de la sélection de la table [uneTable]:
DEBUT SELECTION([uneTable]) Boucle ($vlEnrg;1;Enregistrements trouves([uneTable])) ` Faire quelque chose avec chaque enregistrement ENVOYER ENREGISTREMENT([uneTable]) ` ... ` Passer à l'enregistrement suivant ENREGISTREMENT SUIVANT([uneTable]) Fin de boucle
La plupart des structures Boucle...Fin de boucle que vous écrirez dans vos bases ressembleront à celles présentées ci-dessus.
Décrémenter la variable Compteur
Dans certains cas, vous pouvez souhaiter disposer d'une boucle dont la valeur de la variable compteur décroît au lieu de croître. Pour cela, Expression_Début doit être supérieure à Expression_Fin et Expression_Increment doit être négative. Les exemples suivants effectuent les mêmes tâches que les précédents, mais en sens inverse :
(5) La boucle suivante s'exécute 100 fois :
Boucle (vCompteur;100;1;-1) ` Faire quelque chose Fin de boucle
(6) L'exemple suivant permet de traiter tous les éléments du tableau unTableau :
Boucle ($vlElem;Taille tableau(unTableau);1;-1) ` Faire quelque chose avec l'élément unTableau{$vlElem}:=... Fin de boucle
(7) L'exemple suivant permet d'examiner chaque caractère du texte vtDuTexte :
Boucle ($vlCar;Longueur(vtDuTexte);1;-1) ` Faire quelque chose avec le caractère si c'est une tabulation Si (Code de caractere(vtDuTexte[[$vlCar]])=Caractere(Tab)) ` ... Fin de si Fin de boucle
(8) L'exemple suivant permet de traiter tous les enregistrements de la sélection de la table [uneTable]:
ALLER A DERNIER ENREGISTREMENT([uneTable]) Boucle ($vlEnrg;Enregistrements trouves([uneTable]);1;-1) ` Faire quelque chose avec chaque enregistrement ENVOYER ENREGISTREMENT([uneTable]) ` ... ` Passer à l'enregistrement précédent ENREGISTREMENT PRECEDENT([uneTable]) Fin de boucle
Incrementer la variable compteur de plus de 1
Si vous le souhaitez, vous pouvez passer dans Expression_Incrément une valeur (positive ou négative) dont la valeur absolue est supérieure à un.
(9) La boucle suivante ne traite que les éléments pairs du tableau unTableau :
Boucle ($vlElem;2;Taille tableau(unTableau);2) ` Faire quelque chose avec l'élément 2,4...2n unTableau{$vlElem}:=... Fin de boucle
Sortir d'une boucle en modifiant la variable compteur
Dans certains cas, vous voudrez exécuter une boucle un certain nombre de fois, mais également pouvoir sortir si une autre condition devient Vraie.
Pour cela, il vous suffit de tester cette condition à l'intérieur de la boucle et, si elle devient Vraie, de "forcer" la valeur de la variable compteur, de manière à ce qu'elle soit supérieure à celle de Expression_Fin.
(10) Dans l'exemple suivant, vous effectuez une boucle parmi les enregistrements d'une sélection jusqu'à ce que la fin de la sélection soit atteinte, ou bien jusqu'à ce que la variable interprocess <>vbStop, initialement fixée à Faux, prenne la valeur Vrai. Cette variable est gérée par une méthode projet APPELER SUR EVENEMENT utilisée pour interrompre l'opération :
<>vbStop:=Faux APPELER SUR EVENEMENT ("GESTION STOP") ` GESTION STOP définit <>vbStop à Vrai si les touches Ctrl+point (Windows) ou Commande+point (Mac OS) sont enfoncées $vlNbEnrgs:=Enregistrements trouves([aTable]) DEBUT SELECTION([aTable]) Boucle ($vlEnrgs;1;$vlNbEnrgs) ` Faire quelque chose avec l'enregistrement ENVOYER ENREGISTREMENT([aTable]) ` ... ` Aller à l'enregistrement suivant Si (<>vbStop) $vlEnrgs:=$vlNbEnrgs+1 ` Forcer la variable compteur à stopper la boucle Sinon ENREGISTREMENT SUIVANT([aTable]) Fin de si Fin de boucle APPELER SUR EVENEMENT("") Si (<>vbStop) ALERTE("L'opération a été interrompue.") Sinon ALERTE("L'opération s'est terminée avec succès.") Fin de si
Comparaison des structures répétitives
Reprenons le premier exemple employé pour la structure Boucle...Fin de boucle :
(1) La boucle suivante s'exécute 100 fois :
Boucle (vCompteur;1;100) ` Faire quelque chose Fin de boucle
Il est intéressant d'examiner la manière dont les boucles Tant que...Fin tant que et Repeter...Jusque effectuent la même action :
Voici la boucle Tant que...Fin tant que équivalente :
$i := 1 ` Initialisation du compteur Tant que ($i<=100) ` Boucle 100 fois ` Faire quelque chose $i := $i + 1 ` Il faut incrémenter le compteur Fin tant que
Voici la boucle Repeter...Jusque équivalente :
$i := 1 ` Initialisation du compteur Repeter ` Faire quelque chose $i := $i + 1 ` Il faut incrémenter le compteur Jusque ($i=100) ` Boucle 100 fois
Astuce : La boucle Boucle...Fin de boucle est généralement plus rapide que les boucles Tant que...Fin tant que et Repeter...Jusque car 4D teste la condition en interne pour chaque cycle de la boucle et incrémente lui-même le compteur. Par conséquent, nous vous conseillons de préférer à chaque fois que c'est possible la structure Boucle...Fin de boucle.
Optimiser l'exécution de Boucle...Fin de boucle
Vous pouvez utiliser comme compteur une variable interprocess, process ou locale, et lui attribuer le type Réel, Entier ou Entier long. Pour des boucles longues, et particulièrement en mode compilé, nous vous conseillons d'employer des variables locales de type Entier long.
(11) Voici un exemple :
C_ENTIER LONG($vlCompteur) ` Utilisons une variable locale de type Entier long Boucle ($vlCompteur;1;10000) ` Faire quelque chose Fin de boucle
Structures Boucle...Fin de boucle emboîtées
Vous pouvez emboîter autant de structures répétitives que vous voulez (dans les limites du raisonnable). Cela s'applique aux structures de type Boucle...Fin de boucle. Il y a dans ce cas une erreur courante à éviter : assurez-vous d'utiliser une variable compteur différente par structure de boucle. Voici deux exemples :
(12) L'exemple suivant permet de traiter tous les éléments d'un tableau à deux dimensions :
Boucle ($vlElem;1;Taille tableau(unTableau)) ` ... ` Faire quelque chose avec la ligne ` ... Boucle ($vlSousElem;1;Taille tableau(unTableau{$vlElem})) ` Faire quelque chose avec l'élément unTableau{$vlElem}{$vlSousElem}:=... Fin de boucle Fin de boucle
(13) L'exemple suivant construit un tableau de pointeurs vers tous les champs de type Date présents dans la base :
TABLEAU POINTEUR($apChampsDate;0) $vlElem:=0 Boucle ($vlTable;1;Lire numero derniere table) Si(Est un numero de table valide($vlTable)) Boucle($vlChamp;1;Lire numero dernier champ($vlTable)) Si(Est un numero de champ valide($vlTable;$vlChamp)) $vpChamp:=Champ($vlTable;$vlChamp) Si (Type($vpChamp>)=Est une date) $vlElem:=$vlElem+1 INSERER DANS TABLEAU($apChampsDate;$vlElem) $apChampsDate{$vlElem}:=$vpChamp Fin de si Fin de si Fin de boucle Fin de si Fin de boucle
Référence
Au cas ou...Sinon...Fin de cas, Conditions et boucles, Repeter...Jusque, Si...Sinon...Fin de si, Tant que...Fin tant que.