Instruction RPG full free · IBM i (AS/400) · Lecture de fichiers
CHAIN
Lire un enregistrement par sa clé
Cherche dans un fichier l'enregistrement dont la clé correspond à la valeur donnée et le lit, ou signale qu'il n'existe pas.
Syntaxe
CHAIN clé fichier;
CHAIN clé format;
clé- La valeur cherchée : une zone, ou un littéral entre parenthèses comme
(100). Son type doit correspondre à celui de la clé du fichier. fichier ou format- Le fichier déclaré par
dcl-favec le mot-clékeyed, ou le nom d'un de ses formats d'enregistrement. - Effet
- Positionne
%FOUND(fichier)à vrai si l'enregistrement existe, à faux sinon. Quand il existe, les zones du format sont chargées. L'enregistrement lu devient la position courante : unREADPqui suit donne l'enregistrement précédent.
À quoi ça sert
CHAIN est l'accès direct : on connaît la clé, on veut l'enregistrement, sans parcourir le fichier. C'est l'opération de tous les programmes qui affichent un client à partir de son numéro ou qui retrouvent un article avant de le mettre à jour.
En RPG IV en colonnes, la clé s'écrivait en facteur 1 et le résultat s'obtenait par un indicateur en colonnes 71-72. En full free, la clé est dans l'instruction et le test se fait par %FOUND, bien plus lisible.
Exemple 1 : Clé en zone ou en littéral
**free
// CHAIN : lire un enregistrement par sa cle, puis tester %FOUND.
ctl-opt dftactgrp(*no) actgrp(*new) alwnull(*inputonly);
dcl-f client keyed extdesc('JOBIRPG/CLIENT') extfile(*extdesc);
dcl-s numero packed(5:0);
// Cle donnee par une zone
numero = 200;
chain numero client;
if %found(client);
snd-msg 'Trouve : [' + %char(numcli) + '] [' + %trim(nom) + '] [' + %trim(ville) + ']';
else;
snd-msg 'Client ' + %char(numero) + ' inconnu';
endif;
// Cle litterale, test sur un client absent
chain (999) client;
if not %found(client);
snd-msg 'Absent : le client 999 n existe pas';
endif;
*inlr = *on;
Résultat réel, compilé et exécuté sur IBM i 7.5 :
Trouve : [200] [Martin et fils] [Lyon]
Absent : le client 999 n existe pas
La première lecture utilise une zone, la seconde un littéral entre parenthèses. Le test %FOUND(client) sépare le cas normal du cas « inconnu » : on le fait toujours juste après le CHAIN, avant toute autre opération sur le fichier.
Exemple 2 : Après un échec, les zones ne bougent pas
**free
// CHAIN : apres un echec, les zones gardent les valeurs de la lecture precedente.
ctl-opt dftactgrp(*no) actgrp(*new) alwnull(*inputonly);
dcl-f client keyed extdesc('JOBIRPG/CLIENT') extfile(*extdesc);
chain (100) client;
snd-msg 'Lecture 100 : [' + %trim(nom) + '] trouve=' + %char(%found(client));
chain (999) client;
snd-msg 'Lecture 999 : [' + %trim(nom) + '] trouve=' + %char(%found(client));
snd-msg 'NUMCLI apres l echec : [' + %char(numcli) + ']';
*inlr = *on;
Résultat réel, compilé et exécuté sur IBM i 7.5 :
Lecture 100 : [Dupont SA] trouve=1
Lecture 999 : [Dupont SA] trouve=0
NUMCLI apres l echec : [100]
Le second CHAIN échoue : %FOUND vaut 0, mais NOM contient toujours « Dupont SA » et NUMCLI toujours 100. Un programme qui afficherait la zone sans tester %FOUND montrerait le client précédent.
Le piège
Un CHAIN raté ne vide pas les zones. Elles gardent les valeurs de la dernière lecture réussie (voir le deuxième exemple : après la recherche du client 999, NOM vaut encore « Dupont SA »). Testez toujours %FOUND avant d'utiliser les zones, et remettez-les à blanc vous-même si votre écran ou votre état doit montrer « client inconnu ».