Boucle...Fin de boucle

4D - Documentation   Français   English   German   4e Dimension, Commandes par thèmes   4e Dimension, Liste alphabétique des commandes   4e Dimension, Constantes par thèmes   Retour   Précédent   Suivant

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 ascii(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 ascii(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)+1)\2)*2;2)
         ` Faire quelque chose avec l'élément 2,4...2n
      unTableau{$vlElem}:=...
   Fin de boucle

Notez l'expression ((Taille tableau(unTableau)+1)\2)*2 qui permet de traiter indifféremment les tableaux de taille paire et impaire.

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 4e Dimension 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;Nombre de tables)
      Boucle($vlChamp;1;Nombre de champs($vlTable))
         $vpChamp:=Champ($vlTable;$vlChamp)
         Si (Type($vpChamp>)=Est une date)
            $vlElem:=$vlElem+1
            INSERER LIGNES($apChampsDate;$vlElem)
            $apChampsDate{$vlElem}:=$vpChamp
         Fin de si
      Fin de boucle
   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.


4D - Documentation   Français   English   German   4e Dimension, Commandes par thèmes   4e Dimension, Liste alphabétique des commandes   4e Dimension, Constantes par thèmes   Retour   Précédent   Suivant