Aller au contenu

Instruction RPG full free · IBM i (AS/400) · Structures de contrôle

DOU

Répéter jusqu'à ce que la condition soit vraie

Répète un bloc d'instructions au moins une fois, jusqu'à ce qu'une condition de sortie devienne vraie, la condition étant testée après chaque passage.

Syntaxe

DOU condition;
  instructions;
ENDDO;
condition
Condition de sortie, évaluée après chaque passage. Tant qu'elle est fausse, le bloc recommence ; dès qu'elle est vraie, le programme reprend après ENDDO.
Effet
Aucun indicateur n'est positionné. Le bloc s'exécute au moins une fois. On en sort par la condition, ou plus tôt avec LEAVE.

À quoi ça sert

DOU (« do until ») convient quand l'action doit avoir lieu avant de pouvoir juger : lire un enregistrement, saisir une valeur, tenter une opération puis contrôler son résultat. On évite ainsi la lecture d'amorçage avant la boucle.

En colonnes, c'était DOUxx (par exemple DOUGT) avec ENDDO.

Exemple 1 : Au moins un passage

**free
// DOU : le corps passe au moins une fois, puis on teste la condition de SORTIE.
ctl-opt dftactgrp(*no) actgrp(*new);

dcl-s reste  packed(7:2) inz(0);
dcl-s passes int(5) inz(0);

dou reste <= 0;
  passes += 1;
  reste -= 100;
enddo;
snd-msg 'DOU, reste = 0 : ' + %char(passes) + ' passage, reste = ' + %char(reste);

reste = 250;
passes = 0;
dou reste <= 0;
  passes += 1;
  reste -= 100;
enddo;
snd-msg 'DOU, reste = 250 : ' + %char(passes) + ' passages, reste = ' + %char(reste);

*inlr = *on;

Résultat réel, compilé et exécuté sur IBM i 7.5 :

DOU, reste = 0 : 1 passage, reste = -100.00
DOU, reste = 250 : 3 passages, reste = -50.00

Avec un reste de 0, le corps s'exécute quand même une fois (le reste devient -100,00) avant que la condition de sortie ne soit vérifiée. Avec 250, on a trois passages, comme avec le DOW équivalent.

Exemple 2 : Lire jusqu'à une condition ou la fin du fichier

**free
// DOU : lire jusqu'a trouver un client debiteur de plus de 50000, sinon fin de fichier.
ctl-opt dftactgrp(*no) actgrp(*new) alwnull(*usrctl);

dcl-f client keyed extdesc('JOBIRPG/CLIENT') extfile(*extdesc);

setll *start client;
dou %eof(client) or solde > 50000;
  read client;
  if not %eof(client);
    snd-msg 'Lu : ' + %char(numcli) + ' solde ' + %char(solde);
  endif;
enddo;

if %eof(client);
  snd-msg 'Aucun solde superieur a 50000';
else;
  snd-msg 'Trouve : ' + %trim(nom);
endif;

*inlr = *on;

Résultat réel, compilé et exécuté sur IBM i 7.5 :

Lu : 100 solde 1250.50
Lu : 200 solde .00
Lu : 300 solde -320.00
Lu : 400 solde 98000.00
Trouve : Bernard Transports

On lit jusqu'à trouver un solde supérieur à 50 000 ou la fin du fichier. Le client 400 (98 000,00) arrête la boucle. Le if not %eof évite d'afficher un enregistrement qui n'existe pas quand la lecture atteint la fin.

Le piège

La condition de DOU est la condition de sortie, l'inverse de celle d'un DOW. Convertir un DOW reste > 0 en DOU impose d'écrire reste <= 0. Et le corps passe toujours au moins une fois : avec un reste de 0, il est tout de même passé une fois et le reste est devenu -100,00 (premier exemple).