Code opération RPG III / RPG/400 · IBM i (AS/400) · Tableaux, structures et bits
LOKUP
Chercher une valeur dans un tableau
Cherche le facteur 1 dans un tableau ou une table et allume l'indicateur égal, plus grand ou plus petit selon le résultat de la recherche.
Syntaxe
C argum LOKUPtab HILOEQ
C argum LOKUPtab,idx HILOEQ
- Facteur 1 (18-27)
- La valeur cherchée : une zone ou un littéral. Elle doit avoir le même type et la même longueur que les éléments du tableau.
- Facteur 2 (33-42)
- Le tableau, ou
tableau,indexavec une zone numérique sans décimale comme index. Avec l'index, la recherche commence à cet élément et, si elle réussit, la zone reçoit le rang trouvé. - Indicateurs (54-55)
- HI : s'allume si le tableau contient un élément plus grand que la valeur ; l'index désigne alors l'élément le plus proche au-dessus. Il faut que le tableau soit déclaré trié (colonne 45 de la spécification E).
- Indicateurs (56-57)
- LO : s'allume si le tableau contient un élément plus petit ; l'index désigne l'élément le plus proche en dessous. Même condition de tri que HI. On ne peut pas coder HI et LO sur la même ligne.
- Indicateurs (58-59)
- EQ : s'allume si un élément est égal à la valeur.
- Effet
Avec EQ, l'indicateur s'allume et l'index reçoit le rang de l'élément égal. Avec HI ou LO seul (sur un tableau trié), l'index reçoit le rang de l'élément le plus proche au-dessus ou en dessous. Quand rien n'est trouvé, l'index est remis à 1 et les indicateurs restent éteints.
À quoi ça sert
LOKUP remplace la boucle qui compare une valeur à chaque élément d'un tableau. On l'utilise pour valider un code (ville, taux, famille d'articles) contre une liste chargée à la compilation, ou, sur un tableau trié, pour trouver la tranche d'un barème (montant 250 : première tranche supérieure ou inférieure).
Le tableau se déclare en spécification E. Pour HI et LO, la colonne 45 porte A (croissant) ou D (décroissant) ; les données chargées après ** doivent alors déjà être dans cet ordre.
Exemple 1 : Rang d'une ville dans un tableau
H* LOKUP : chercher une valeur dans un tableau, rang dans l'index
E VIL 1 4 8
C*
C MOVEL'LYON' RECH 8
C Z-ADD1 IDX 30
C RECH LOKUPVIL,IDX 50
C *IN50 IFEQ '1'
C IDX DSPLY
C VIL,IDX DSPLY
C END
C*
C* Valeur absente : 50 reste eteint
C MOVEL'PARIS' RECH
C RECH LOKUPVIL,IDX 50
C *IN50 IFEQ '0'
C 'Absent' DSPLY
C END
C*
C SETON LR
**
BREST
LYON
MONTPEL
NANTES
Résultat réel, compilé par CRTRPGPGM et exécuté sur IBM i 7.5 :
2
LYON
Absent
Le tableau VIL compte quatre villes de 8 caractères. LYON est au rang 2 : l'indicateur 50 (colonnes 58-59, égal) s'allume et IDX vaut 2. La zone de recherche RECH fait 8 caractères comme les éléments. Pour PARIS, le 50 reste éteint.
Exemple 2 : Tableau trié : plus grand, plus petit, égal
H* LOKUP : tableau trie, plus grand (HI), plus petit (LO), egal (EQ)
E PAL 1 4 5 0A
C*
C* 250 n'existe pas : HI donne l'entree juste au-dessus
C Z-ADD250 MONT 50
C Z-ADD1 IDX 30
C MONT LOKUPPAL,IDX 71 73
C *IN71 IFEQ '1'
C 'Plus gd' DSPLY
C IDX DSPLY
C END
C* Meme recherche avec LO : l'entree juste en dessous
C Z-ADD1 IDX 30
C MONT LOKUPPAL,IDX 7273
C *IN72 IFEQ '1'
C 'Plus pt' DSPLY
C IDX DSPLY
C END
C* 300 existe : EQ s'allume
C Z-ADD300 MONT
C Z-ADD1 IDX
C MONT LOKUPPAL,IDX 71 73
C *IN73 IFEQ '1'
C 'Egal' DSPLY
C IDX DSPLY
C END
C* 900 depasse tout : HI reste eteint
C Z-ADD900 MONT
C Z-ADD1 IDX
C MONT LOKUPPAL,IDX 71 73
C *IN71 IFEQ '0'
C 'Aucun' DSPLY
C END
C SETON LR
**
00100
00200
00300
00400
Résultat réel, compilé par CRTRPGPGM et exécuté sur IBM i 7.5 :
Plus gd
3
Plus pt
2
Egal
3
Aucun
Le barème PAL est trié croissant (A en colonne 45). Pour 250, qui n'existe pas, HI (indicateur 71) donne le rang 3 (300) et LO (indicateur 72) le rang 2 (200). Pour 300, EQ s'allume avec le rang 3. Pour 900, rien n'est plus grand : HI reste éteint.
Exemple 3 : L'index est le point de départ
H* LOKUP : l'index est le point de depart de la recherche
E VIL 1 4 8
C*
C MOVEL'NANTES' RECH 8
C Z-ADD1 IDX 30
C RECH LOKUPVIL,IDX 50
C IDX DSPLY
C* Sans remettre IDX a 1, BREST (rang 1) est cherche a partir du rang 4
C MOVEL'BREST' RECH
C RECH LOKUPVIL,IDX 50
C *IN50 IFEQ '0'
C 'Perdu' DSPLY
C IDX DSPLY
C END
C* Avec IDX remis a 1, la recherche reussit
C Z-ADD1 IDX
C RECH LOKUPVIL,IDX 50
C *IN50 IFEQ '1'
C 'Trouve' DSPLY
C IDX DSPLY
C END
C SETON LR
**
BREST
LYON
MONTPEL
NANTES
Résultat réel, compilé par CRTRPGPGM et exécuté sur IBM i 7.5 :
4
Perdu
1
Après la recherche de NANTES (rang 4), l'index vaut 4. Chercher BREST (rang 1) sans remettre l'index à 1 échoue : la recherche part du rang 4. Après Z-ADD 1 IDX, elle réussit.
Le piège
Remettez l'index à 1 avant chaque recherche : VIL,IDX démarre à l'élément IDX (troisième exemple), et un échec le remet à 1. Un index resté à 4 fait « perdre » les éléments précédents.
Facteur 1 et éléments doivent avoir la même longueur. Avec le littéral 'LYON' (4 caractères) contre un tableau de 8, le compilateur refuse : QRG7021, « Les zones définies en Facteur 1 et Facteur 2 sont de longueurs ou de types différents. La spécification n'est pas prise en compte. » Passez par une zone de 8 caractères.
HI et LO exigent un tableau trié et ne se combinent pas. Sur un tableau sans séquence, un indicateur en 54-55 donne QRG5058 (« Un indicateur supérieur ou inférieur est défini pour LOKUP alors que le tableau ou la table n'a pas de séquence définie »). HI et LO ensemble donnent QRG5055 (« Définition simultanée des indicateurs résultants sup et inf incorrecte pour une opération LOKUP. Indicateur inf ignoré. »).
En RPG ILE full free
En RPG ILE, %LOOKUP renvoie directement le rang (0 si absent) ; %LOOKUPGE, %LOOKUPGT, %LOOKUPLE et %LOOKUPLT remplacent les indicateurs HI et LO. Le troisième argument est le point de départ.
idx = %lookup(rech : vil);
if idx > 0;
dsply vil(idx);
endif;
idx = %lookupgt(250 : pal);