Instruction RPG full free · IBM i (AS/400) · Structures de contrôle
SELECT
Choisir entre plusieurs cas
Examine une suite de conditions (WHEN) dans l'ordre, exécute le bloc de la première qui est vraie, et sinon celui du cas par défaut (OTHER).
Syntaxe
SELECT;
WHEN condition;
instructions;
OTHER;
instructions;
ENDSL;
SELECT valeur;
WHEN-IS valeur;
WHEN-IN liste;
OTHER;
ENDSL;
WHEN condition- Cas testé : une expression logique complète, comme pour
IF. LesWHENsont évalués du premier au dernier. valeur- Forme
SELECT valeur;: une zone ou une expression comparée à chaqueWHEN-IS(une valeur) ouWHEN-IN(une liste, par exemple%LIST(2 : 3 : 4)). OTHER- Cas par défaut, exécuté si aucun
WHENn'est vrai. Facultatif, mais à placer en dernier. ENDSL- Ferme la structure.
- Effet
- Aucun indicateur n'est positionné. Un seul bloc est exécuté au maximum : celui du premier
WHENvrai. Il n'y a pas de passage au cas suivant.
À quoi ça sert
SELECT remplace avantageusement une cascade de IF/ELSEIF quand on classe un code, une ville ou une tranche de montant. Les cas sont alignés, faciles à relire et à compléter. En colonnes, c'étaient les opérations SELECT, WHEN, OTHER et ENDSL.
Les formes WHEN-IS et WHEN-IN, plus récentes, évitent de répéter la zone testée à chaque ligne. Elles sont acceptées par le compilateur de la machine d'essai (IBM i 7.5).
Exemple 1 : Une région par ville
**free
// SELECT / WHEN / OTHER : un libelle par ville, sur tous les clients.
ctl-opt dftactgrp(*no) actgrp(*new) alwnull(*usrctl);
dcl-f client keyed extdesc('JOBIRPG/CLIENT') extfile(*extdesc);
dcl-s region char(10);
read client;
dow not %eof(client);
select;
when %trim(ville) = 'Montpellier';
region = 'Sud';
when %trim(ville) = 'Lyon';
region = 'Centre-Est';
other;
region = 'Autre';
endsl;
snd-msg %char(numcli) + ' ' + %trim(ville) + ' : [' + %trim(region) + ']';
read client;
enddo;
*inlr = *on;
Résultat réel, compilé et exécuté sur IBM i 7.5 :
100 Montpellier : [Sud]
200 Lyon : [Centre-Est]
300 Montpellier : [Sud]
400 Brest : [Autre]
500 Lyon : [Centre-Est]
Chaque client est classé selon sa ville : Montpellier au Sud, Lyon au Centre-Est, tout le reste dans OTHER (Brest). Les conditions portent sur %trim(ville) car la zone fait 20 caractères.
Exemple 2 : WHEN-IS, WHEN-IN et premier cas vrai
**free
// SELECT avec valeur (WHEN-IS, WHEN-IN) et piege : seul le premier WHEN vrai s'execute.
ctl-opt dftactgrp(*no) actgrp(*new);
dcl-s code int(5) inz(2);
dcl-s ville char(15) inz('Brest');
dcl-s note int(5) inz(15);
select code;
when-is 1;
snd-msg 'Code 1 : creation';
when-in %list(2 : 3 : 4);
snd-msg 'Code 2 a 4 : modification';
other;
snd-msg 'Code inconnu';
endsl;
// Deux WHEN vrais : le second est ignore.
select;
when note >= 10;
snd-msg 'Note >= 10 : admis';
when note >= 14;
snd-msg 'Note >= 14 : mention bien';
endsl;
// Aucun WHEN vrai, pas de OTHER : rien ne se passe, sans erreur.
select;
when ville = 'Lyon';
snd-msg 'Lyon';
endsl;
snd-msg 'Fin, aucune erreur';
*inlr = *on;
Résultat réel, compilé et exécuté sur IBM i 7.5 :
Code 2 a 4 : modification
Note >= 10 : admis
Fin, aucune erreur
Avec select code; le code 2 est reconnu par when-in %list(2 : 3 : 4). Dans le deuxième select, la note 15 vérifie les deux when mais seul le premier s'exécute. Le troisième select n'a aucun cas vrai et pas de other : le programme continue sans erreur.
Le piège
Seul le premier WHEN vrai est exécuté, et l'absence de OTHER ne signale rien. Avec une note de 15, le cas « note >= 10 » masque « note >= 14 » placé après lui (deuxième exemple) : il faut classer les cas du plus précis au plus général. Et si aucun cas ne convient, le programme poursuit sans message, ce qui cache un code inattendu. Ajoutez un OTHER qui signale l'anomalie.