%TLOOKUP
Chercher dans une table
Cherche une valeur dans une table (un tableau dont le nom commence par TAB) et positionne l'élément courant, ce qui permet de lire au même endroit dans une table jumelle.
Syntaxe
%TLOOKUP(valeur : table {: table-jumelle})
%TLOOKUPLT(valeur : table {: table-jumelle})
%TLOOKUPLE(valeur : table {: table-jumelle})
%TLOOKUPGE(valeur : table {: table-jumelle})
%TLOOKUPGT(valeur : table {: table-jumelle})
valeur- Ce qu'on cherche, du même type que les éléments de la table.
table- La table où chercher. Son nom doit commencer par
TAB, sinon la compilation échoue (RNF0597). table-jumelle- Facultatif : une seconde table, déclarée avec
alt(table). Si la valeur est trouvée, son élément courant est positionné au même rang. - Résultat
- Un indicateur :
*onsi la valeur est trouvée,*offsinon. La table (et la table jumelle) désignée sans indice donne ensuite l'élément courant.
À quoi ça sert
Les tables sont l'ancienne façon de regrouper des données de référence chargées avec le programme : une ville et son forfait de port, un seuil et sa remise. On cherche dans la première table, et le taux correspondant est immédiatement lu dans la seconde, sans calculer de position.
Pour un tableau ordinaire, dont le nom ne commence pas par TAB, on utilise %LOOKUP, qui renvoie une position.
Exemple 1 : Forfait de port par ville
**free
// %TLOOKUP : chercher dans une table et lire l'element correspondant d'une table jumelle.
ctl-opt dftactgrp(*no) actgrp(*new);
// Le nom d'une table commence par TAB. Les donnees viennent de la fin du source.
dcl-s tabvill char(12) dim(3) ctdata perrcd(1);
dcl-s tabport packed(5:2) dim(3) alt(tabvill);
dcl-s trouve ind;
trouve = %tlookup('Lyon' : tabvill : tabport);
snd-msg 'Lyon trouve=' + %char(trouve) + ' port=' + %char(tabport);
trouve = %tlookup('Brest' : tabvill : tabport);
snd-msg 'Brest trouve=' + %char(trouve) + ' port=' + %char(tabport);
// Ville absente : rien n'est trouve, mais la table garde son element courant.
trouve = %tlookup('Paris' : tabvill : tabport);
snd-msg 'Paris trouve=' + %char(trouve) + ' port=' + %char(tabport) +
' ville=[' + tabvill + ']';
*inlr = *on;
**ctdata tabvill
Montpellier 01250
Lyon 01800
Brest 02450
Résultat réel, compilé et exécuté sur IBM i 7.5 :
Lyon trouve=1 port=18.00
Brest trouve=1 port=24.50
Paris trouve=0 port=24.50 ville=[Brest ]
La table tabvill est chargée depuis les données à la fin du source (**ctdata) ; tabport est sa jumelle (alt) et se lit dans la même ligne de données : 12 caractères pour la ville, puis 5 chiffres pour le forfait (01800 vaut 18,00). Après un %tlookup réussi, écrire tabport sans indice donne le forfait de la ville trouvée.
Regardez la dernière ligne : pour Paris, absente de la table, l'indicateur est à 0, mais tabport vaut toujours 24,50 et tabvill Brest. C'est le piège décrit plus bas.
Exemple 2 : Tranches de remise avec LE
**free
// %TLOOKUPLE : tranche de remise d'une table triee, lue dans la table jumelle.
ctl-opt dftactgrp(*no) actgrp(*new);
dcl-s tabseuil packed(7:0) dim(4) ctdata perrcd(1) ascend;
dcl-s tabrem packed(4:2) dim(4) alt(tabseuil);
dcl-s trouve ind;
dcl-s montant packed(9:2);
montant = 6500.00;
trouve = %tlookuple(montant : tabseuil : tabrem);
snd-msg 'Commande ' + %char(montant) + ' : trouve=' + %char(trouve) +
' seuil=' + %char(tabseuil) + ' remise=' + %char(tabrem) + ' %';
montant = 150.00;
trouve = %tlookuple(montant : tabseuil : tabrem);
snd-msg 'Commande ' + %char(montant) + ' : trouve=' + %char(trouve) +
' seuil=' + %char(tabseuil) + ' remise=' + %char(tabrem) + ' %';
montant = 98000.00;
trouve = %tlookuple(montant : tabseuil : tabrem);
snd-msg 'Commande ' + %char(montant) + ' : trouve=' + %char(trouve) +
' seuil=' + %char(tabseuil) + ' remise=' + %char(tabrem) + ' %';
// GE : premier seuil qui atteint ou depasse le montant.
trouve = %tlookupge(3000.00 : tabseuil);
snd-msg 'GE 3000 : trouve=' + %char(trouve) + ' seuil=' + %char(tabseuil);
*inlr = *on;
**ctdata tabseuil
00000000000
00010000250
00050000500
00200001000
Résultat réel, compilé et exécuté sur IBM i 7.5 :
Commande 6500.00 : trouve=1 seuil=5000 remise=5.00 %
Commande 150.00 : trouve=1 seuil=0 remise=.00 %
Commande 98000.00 : trouve=1 seuil=20000 remise=10.00 %
GE 3000 : trouve=1 seuil=5000
La table des seuils est triée et déclarée ascend. %tlookuple trouve le plus grand seuil inférieur ou égal au montant : 6 500 tombe dans la tranche 5 000 (remise 5 %), 150 dans la tranche 0, 98 000 dans la tranche 20 000 (10 %). Avec %tlookupge(3000 : …), on obtient au contraire le premier seuil qui atteint ou dépasse 3 000, soit 5 000.
Le piège
Quand la valeur n'est pas trouvée, la table garde son élément courant précédent. Le premier exemple le montre : après la recherche de Paris, tabport contient encore le forfait de Brest. Si on lit la table sans avoir testé le résultat, on utilise une valeur qui n'a rien à voir avec la recherche.
Il faut donc toujours écrire if %tlookup(…) avant d'utiliser la table. Le même comportement s'observe avec LE, GE, GT et LT quand rien ne convient.