Aller au contenu

Instruction RPG full free · IBM i (AS/400) · Lecture de fichiers

SETLL

Se placer avant une clé

Positionne le fichier sur le premier enregistrement dont la clé est supérieure ou égale à celle donnée, sans lire d'enregistrement.

Syntaxe

SETLL clé fichier;
SETLL clé format;
SETLL *LOVAL fichier;
SETLL *HIVAL fichier;
clé
La valeur cherchée : une zone, un littéral entre parenthèses, ou une clé partielle. *LOVAL désigne la plus petite clé possible (début du fichier) et *HIVAL la plus grande (fin du fichier).
fichier ou format
Le fichier déclaré avec keyed, ou un de ses formats.
Effet
Ne lit aucun enregistrement. Positionne %EQUAL(fichier) à vrai si une clé exactement égale existe. %FOUND(fichier) vaut vrai si un enregistrement de clé supérieure ou égale existe, faux si la clé dépasse toutes celles du fichier.

À quoi ça sert

SETLL prépare une lecture séquentielle (READ ou READE) à partir d'un endroit précis, ou teste l'existence d'une clé sans charger de zones : pour savoir si un client existe, il suffit de regarder %EQUAL.

En RPG IV en colonnes, ces résultats étaient lus par des indicateurs ; en full free on les lit par %EQUAL et %FOUND.

Exemple 1 : Tester l'existence et se positionner

**free
// SETLL : tester l existence d une cle, puis se positionner avant la premiere cle voulue.
ctl-opt dftactgrp(*no) actgrp(*new) alwnull(*inputonly);

dcl-f client keyed extdesc('JOBIRPG/CLIENT') extfile(*extdesc);

setll (300) client;
snd-msg 'Cle 300 : existe=' + %char(%equal(client)) + ' found=' + %char(%found(client));

setll (350) client;
snd-msg 'Cle 350 : existe=' + %char(%equal(client)) + ' found=' + %char(%found(client));

// La lecture suivante donne le premier enregistrement dont la cle est >= 350
read client;
snd-msg 'READ suivant : [' + %char(numcli) + '] [' + %trim(nom) + ']';

*inlr = *on;

Résultat réel, compilé et exécuté sur IBM i 7.5 :

Cle 300 : existe=1 found=1
Cle 350 : existe=0 found=1
READ suivant : [400] [Bernard Transports]

La clé 300 existe : %EQUAL vaut 1. La clé 350 n'existe pas : %EQUAL vaut 0, mais %FOUND vaut 1 car il y a un enregistrement après (le 400), et le READ suivant le lit.

Exemple 2 : *LOVAL et clé trop grande

**free
// SETLL : *LOVAL, *HIVAL et cle superieure a toutes les cles.
ctl-opt dftactgrp(*no) actgrp(*new) alwnull(*inputonly);

dcl-f client keyed extdesc('JOBIRPG/CLIENT') extfile(*extdesc);

setll *loval client;
read client;
snd-msg 'Apres *LOVAL : [' + %char(numcli) + '] eof=' + %char(%eof(client));

setll (999) client;
snd-msg 'Cle 999 : %found=' + %char(%found(client)) + ' %equal=' + %char(%equal(client));
read client;
snd-msg 'READ apres cle 999 : eof=' + %char(%eof(client));

*inlr = *on;

Résultat réel, compilé et exécuté sur IBM i 7.5 :

Apres *LOVAL : [100] eof=0
Cle 999 : %found=0 %equal=0
READ apres cle 999 : eof=1

SETLL *LOVAL renvoie au début du fichier : le READ donne le 100. Avec la clé 999, supérieure à toutes, %FOUND et %EQUAL valent 0 et le READ suivant arrive en fin de fichier.

Le piège

%FOUND après SETLL ne dit pas « cette clé existe ». Pour la clé 350, absente du fichier, %FOUND vaut 1 (premier exemple), parce qu'un enregistrement de clé supérieure existe. Le test d'existence exacte est %EQUAL. Prendre %FOUND comme test d'existence fait croire qu'un client inconnu est connu.