Aller au contenu

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,index avec 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);