Aller au contenu

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. Les WHEN sont évalués du premier au dernier.
valeur
Forme SELECT valeur; : une zone ou une expression comparée à chaque WHEN-IS (une valeur) ou WHEN-IN (une liste, par exemple %LIST(2 : 3 : 4)).
OTHER
Cas par défaut, exécuté si aucun WHEN n'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 WHEN vrai. 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.