Instruction RPG full free · IBM i (AS/400) · Structures de contrôle
ITER
Passer au tour suivant
Abandonne le reste du tour de boucle en cours et reprend au test de la boucle (DOW, DOU, FOR, FOR-EACH) pour le tour suivant.
Syntaxe
ITER;
(aucun)ITERs'écrit seule, dans une boucle, souvent sous unIF.- Effet
- Aucun indicateur n'est positionné. Dans un
FOR, le compteur avance puis est comparé à la limite. Dans unDOWou unDOU, la condition est testée.
À quoi ça sert
Pour ignorer certains cas (soldes nuls, lignes vides) sans enfermer tout le reste du corps dans un grand IF. En colonnes, c'était l'opération ITER.
Exemple 1 : Ignorer les soldes nuls ou négatifs
**free
// ITER : passer au client suivant sans traiter ceux dont le solde est a zero ou negatif.
ctl-opt dftactgrp(*no) actgrp(*new) alwnull(*usrctl);
dcl-f client keyed extdesc('JOBIRPG/CLIENT') extfile(*extdesc);
dcl-s relances int(5);
read client;
dow not %eof(client);
if solde <= 0;
read client;
iter;
endif;
relances += 1;
snd-msg 'Relance ' + %char(numcli) + ' ' + %trim(nom) + ' : ' + %char(solde);
read client;
enddo;
snd-msg 'Relances : ' + %char(relances);
*inlr = *on;
Résultat réel, compilé et exécuté sur IBM i 7.5 :
Relance 100 Dupont SA : 1250.50
Relance 400 Bernard Transports : 98000.00
Relance 500 Petit Atelier : 45.10
Relances : 3
Les clients 200 (solde 0) et 300 (-320,00) sont sautés. Les trois autres sont relancés. Remarquez le read client; avant iter : il remplace la relecture de fin de corps, qui n'est pas atteinte.
Exemple 2 : ITER dans FOR et dans DOU
**free
// ITER dans FOR : le compteur avance quand meme. Dans DOU : la condition est testee.
ctl-opt dftactgrp(*no) actgrp(*new);
dcl-s i int(5);
dcl-s n int(5);
for i = 1 to 5;
if i = 3;
iter;
endif;
snd-msg 'FOR i = ' + %char(i);
endfor;
n = 0;
dou n >= 3;
n += 1;
if n = 3;
iter;
endif;
snd-msg 'DOU n = ' + %char(n);
enddo;
snd-msg 'Sortie du DOU avec n = ' + %char(n);
*inlr = *on;
Résultat réel, compilé et exécuté sur IBM i 7.5 :
FOR i = 1
FOR i = 2
FOR i = 4
FOR i = 5
DOU n = 1
DOU n = 2
Sortie du DOU avec n = 3
Dans le for, le tour 3 est sauté mais le compteur avance (4 puis 5). Dans le dou, à n = 3, iter saute l'affichage mais la condition de sortie n >= 3 est testée et arrête la boucle.
Exemple 3 : Oubli de la relecture
**free
// ITER oublie la relecture : le meme enregistrement revient. Garde-fou a 4 passages.
ctl-opt dftactgrp(*no) actgrp(*new) alwnull(*usrctl);
dcl-f client keyed extdesc('JOBIRPG/CLIENT') extfile(*extdesc);
dcl-s passes int(5);
read client;
dow not %eof(client);
passes += 1;
if passes > 4;
snd-msg 'Garde-fou : boucle sans fin evitee';
leave;
endif;
if solde <= 0;
iter;
endif;
snd-msg 'Relance ' + %char(numcli);
read client;
enddo;
snd-msg 'Passages : ' + %char(passes) + ', dernier client lu : ' + %char(numcli);
*inlr = *on;
Résultat réel, compilé et exécuté sur IBM i 7.5 :
Relance 100
Garde-fou : boucle sans fin evitee
Passages : 5, dernier client lu : 200
Ici iter est employé sans relire. Le client 200 (solde 0) revient à chaque tour : au cinquième passage le garde-fou arrête la boucle, qui serait sinon infinie.
Le piège
Dans une boucle de lecture DOW, ITER saute aussi la relecture. Si le read est en fin de corps, il faut relire avant iter (premier exemple), sinon on retombe sur le même enregistrement. Le troisième exemple montre le cas : le client 200 est examiné encore et encore, et seul le garde-fou à 4 passages évite la boucle sans fin. Dans un FOR, le problème n'existe pas, car le compteur avance tout seul.