Aller au contenu

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-f avec 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 : un READP qui 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 ».