Aller au contenu

%LIST

Liste de valeurs

Écrit une liste de valeurs directement dans une instruction, pour tester si une valeur en fait partie ou pour les parcourir avec for-each.

Syntaxe

valeur IN %LIST(valeur1 : valeur2 {: …})
for-each variable IN %LIST(valeur1 : valeur2 {: …})
valeur1, valeur2…
Les valeurs de la liste : constantes ou zones, de même nature que la valeur testée (ou que la variable de for-each).
Résultat
Une liste, utilisable à droite d'un in (test d'appartenance, vrai ou faux) ou d'un for-each (parcours des valeurs dans l'ordre écrit).

À quoi ça sert

Sans %list, tester un statut contre plusieurs valeurs donne statut = 'A' or statut = 'B' or statut = 'C'. Avec la liste, la ligne se lit d'un coup : statut in %list('A' : 'B' : 'C'). La négation se fait avec not (… in …), la forme not in n'existe pas.

Dans un for-each, elle évite de déclarer un tableau juste pour parcourir quelques valeurs connues d'avance.

Exemple 1 : Appartenance avec IN

**free
// %LIST avec IN : une valeur est-elle parmi plusieurs ?
ctl-opt dftactgrp(*no) actgrp(*new);

dcl-s ville  char(12) inz('Lyon');
dcl-s statut char(1)  inz('X');

if ville in %list('Brest' : 'Lyon' : 'Rennes');
  snd-msg 'Lyon est une ville de livraison';
endif;

if not (ville in %list('Nantes' : 'Paris'));
  snd-msg 'Lyon n''est pas dans la seconde liste';
endif;

// Remplace une suite de "statut = 'A' or statut = 'B' or ...".
if statut in %list('A' : 'B' : 'C');
  snd-msg 'Statut actif';
else;
  snd-msg 'Statut ' + statut + ' hors liste';
endif;

// La comparaison tient compte de la casse.
ville = 'lyon';
if ville in %list('Lyon' : 'Brest');
  snd-msg 'lyon en minuscules trouve';
else;
  snd-msg 'lyon en minuscules : non trouve';
endif;
if %upper(ville) in %list('LYON' : 'BREST');
  snd-msg 'apres %upper : trouve';
endif;

*inlr = *on;

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

Lyon est une ville de livraison
Lyon n'est pas dans la seconde liste
Statut X hors liste
lyon en minuscules : non trouve
apres %upper : trouve

Lyon est dans la première liste, pas dans la seconde. Le statut « X » n'est pas dans A, B, C : c'est la branche else. Les blancs de fin de la zone char(12) ne gênent pas la comparaison.

Regardez les deux dernières comparaisons : « lyon » en minuscules n'est pas trouvé dans une liste qui contient « Lyon ». Avec %upper des deux côtés, il l'est.

Exemple 2 : Parcourir une liste avec for-each

**free
// %LIST avec FOR-EACH : parcourir une liste de valeurs ecrites dans le source.
ctl-opt dftactgrp(*no) actgrp(*new);

dcl-s ville varchar(12);
dcl-s seuil packed(7:0);
dcl-s total packed(9:0);

for-each ville in %list('Montpellier' : 'Lyon' : 'Brest');
  snd-msg 'Agence : [' + ville + ']';
endfor;

for-each seuil in %list(1000 : 5000 : 20000);
  total += seuil;
endfor;
snd-msg 'Somme des seuils : ' + %char(total);

*inlr = *on;

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

Agence : [Montpellier]
Agence : [Lyon]
Agence : [Brest]
Somme des seuils : 26000

Le for-each lit les trois agences dans l'ordre écrit, dans une variable varchar. Avec une variable numérique et une liste de nombres, on additionne ici les seuils : 1 000 + 5 000 + 20 000.

Le piège

La comparaison est exacte, majuscules et minuscules comprises. 'lyon' in %list('Lyon' : 'Brest') est faux : la valeur venue d'un écran ou d'un fichier n'a pas forcément la casse du programme. On met les deux côtés en majuscules avec %upper avant de comparer, comme à la fin du premier exemple.