%FOUND
Savoir si l'enregistrement a été trouvé
Renvoie *ON si la dernière opération de recherche (CHAIN, SETLL, SETGT) a trouvé un enregistrement, et *OFF sinon.
Syntaxe
%FOUND(nom-fichier)
%FOUND
nom-fichier- Le fichier concerné. Il peut être omis pour désigner la dernière opération de recherche.
- Résultat
- Un indicateur : *ON si l'enregistrement demandé existe, *OFF sinon.
À quoi ça sert
C'est le test qui suit presque tous les CHAIN : if %found(client); remplace l'indicateur de non-trouvé de l'ancien RPG. Il sert aussi après SETLL pour savoir s'il existe au moins un enregistrement de clé supérieure ou égale à celle demandée.
Exemple 1 : Tester un CHAIN
**free
// %FOUND : savoir si un CHAIN a trouve l'enregistrement.
ctl-opt dftactgrp(*no) actgrp(*new) alwnull(*usrctl);
dcl-f client keyed;
dcl-s recherche packed(5:0);
recherche = 400;
chain (recherche) client;
if %found(client);
snd-msg 'Client ' + %char(recherche) + ' : ' + %trim(nom) + ' (' + %trim(ville) + ')';
else;
snd-msg 'Client ' + %char(recherche) + ' : inconnu';
endif;
recherche = 250;
chain (recherche) client;
if %found(client);
snd-msg 'Client ' + %char(recherche) + ' : ' + %trim(nom) + ' (' + %trim(ville) + ')';
else;
snd-msg 'Client ' + %char(recherche) + ' : inconnu';
// Piege : les zones du fichier n'ont pas ete videes par le CHAIN rate
snd-msg 'NOM contient encore : [' + %trim(nom) + ']';
endif;
*inlr = *on;
Résultat réel, compilé et exécuté sur IBM i 7.5 :
Client 400 : Bernard Transports (Brest)
Client 250 : inconnu
NOM contient encore : [Bernard Transports]
Le client 400 est trouvé, le client 250 ne l'est pas. Regardez la dernière ligne : après le CHAIN raté, la zone NOM contient toujours « Bernard Transports », celui du CHAIN précédent.
Exemple 2 : Après SETLL, et ce que READ ne change pas
**free
// %FOUND apres SETLL, et ce que READ ne change pas.
ctl-opt dftactgrp(*no) actgrp(*new) alwnull(*usrctl);
dcl-f client keyed;
// SETLL : %FOUND vaut 1 s'il existe un enregistrement de cle >= a celle demandee
setll (150) client;
snd-msg 'SETLL 150 : %FOUND = [' + %char(%found(client)) + ']';
setll (500) client;
snd-msg 'SETLL 500 : %FOUND = [' + %char(%found(client)) + ']';
setll (999) client;
snd-msg 'SETLL 999 : %FOUND = [' + %char(%found(client)) + ']';
// Une lecture reussie ne touche pas a %FOUND : il garde la valeur du SETLL
setll (999) client;
readp client;
snd-msg 'READP apres SETLL 999 : lu ' + %char(numcli) + ', %FOUND = [' +
%char(%found(client)) + ']';
*inlr = *on;
Résultat réel, compilé et exécuté sur IBM i 7.5 :
SETLL 150 : %FOUND = [1]
SETLL 500 : %FOUND = [1]
SETLL 999 : %FOUND = [0]
READP apres SETLL 999 : lu 500, %FOUND = [0]
Après SETLL, %FOUND est à 1 dès qu'un enregistrement de clé supérieure ou égale existe : c'est vrai pour 150 (qui n'existe pas, mais 200 oui) et pour 500 (dernier client). Il est à 0 pour 999. Enfin, une lecture réussie ne change pas %FOUND : après SETLL 999, un READP lit bien le client 500 et %FOUND reste à 0.
Le piège
Après un CHAIN raté, les zones du fichier ne sont pas vidées. Le premier exemple le montre : le nom du client précédent est toujours là. Si on oublie le test %FOUND, le programme travaille sans erreur sur des données périmées.
Un SETLL trouve « au moins » la clé. %FOUND vaut 1 pour 150 alors que ce client n'existe pas. Pour tester l'égalité exacte, il faut %EQUAL.