Aller au contenu

Instruction RPG full free · IBM i (AS/400) · Mots-clés de déclaration

LIKE

Copier le type d'une autre déclaration

Déclare une zone, une structure ou un enregistrement avec le même type qu'une déclaration existante : LIKE pour une zone, LIKEDS pour une structure, LIKEREC pour un format de fichier.

Syntaxe

dcl-s zone like(autre_zone);
dcl-s zone like(autre_zone : +5);
dcl-ds nom likeds(modele);
dcl-ds nom likerec(format : *all);
LIKE(zone)
Prend le type, la longueur et le nombre de décimales de la zone indiquée, y compris une zone de fichier. Si la zone source est un tableau, la nouvelle zone a le type d'un seul élément.
LIKE(zone : +n)
Même type, allongé de n positions.
LIKEDS(modele)
Crée une structure de même forme qu'une autre structure (de préférence un modèle template). Les sous-zones se lisent nom.sous_zone.
LIKEREC(format : *ALL)
Crée une structure dont les sous-zones sont celles d'un format d'enregistrement de fichier. *ALL reprend toutes les zones du format.
Effet
Aucun indicateur. Seul le type est repris : ni la valeur, ni le mot-clé INZ de la zone d'origine ne sont copiés.

À quoi ça sert

Quand une zone doit toujours avoir le même type qu'une autre, par exemple le numéro de client d'un fichier, LIKE évite d'écrire packed(5:0) à vingt endroits. Le jour où le fichier change, il suffit de recompiler : tout suit.

LIKEDS est l'outil des paramètres et des retours de procédure de type structure. LIKEREC permet de lire un enregistrement entier dans une structure (chain (clé) fichier structure) sans collision de noms avec les zones du fichier. C'est l'équivalent moderne de LIKE et DEFINE en colonnes.

Exemple 1 : LIKE, LIKEDS et LIKEREC

**free
// LIKE : une zone prend le type d'une autre ; LIKEDS : une structure copie un modele ;
// LIKEREC : une structure prend les zones d'un format de fichier.
ctl-opt dftactgrp(*no) actgrp(*new);

dcl-f client keyed;

dcl-s numprec like(numcli);
dcl-s soldes  like(solde) dim(2);

dcl-ds adresse_t qualified template;
  rue   varchar(30);
  ville char(20);
end-ds;

dcl-ds livraison likeds(adresse_t);
dcl-ds facturation likeds(adresse_t);
dcl-ds enrcli likerec(clientr : *all);

numprec = 100;
chain (numprec) client;
snd-msg 'Solde de ' + %char(numprec) + ' : ' + %char(solde);

soldes(1) = solde;
soldes(2) = 20000.99;
snd-msg 'Tableau : ' + %char(soldes(1)) + ' / ' + %char(soldes(2));

livraison.rue = '12 rue des Lilas';
livraison.ville = 'Montpellier';
facturation = livraison;
facturation.ville = 'Lyon';
snd-msg 'Livraison : ' + %trimr(livraison.ville) + ' / Facturation : ' + %trimr(facturation.ville);

chain (200) client enrcli;
snd-msg 'Format lu : ' + %trimr(enrcli.nom) + ' ' + %char(enrcli.numcli);

*inlr = *on;

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

Solde de 100 : 1250.50
Tableau : 1250.50 / 20000.99
Livraison : Montpellier / Facturation : Lyon
Format lu : Martin et fils 200

numprec prend le type du numéro de client du fichier ; soldes est un tableau de deux éléments du type du solde. livraison et facturation sont deux structures indépendantes, copiées d'un modèle : l'affectation d'une structure à l'autre copie tout, on change ensuite la ville de la seconde. enrcli reçoit un enregistrement complet du fichier par chain ... enrcli.

Exemple 2 : LIKE ne copie pas la valeur

**free
// Piege : LIKE copie le type, jamais la valeur ni INZ ; et LIKE(tableau) donne un element seul.
ctl-opt dftactgrp(*no) actgrp(*new);

dcl-s base   packed(7:2) inz(99.50);
dcl-s autre  like(base);
dcl-s liste  packed(7:2) dim(3) inz(5);
dcl-s un     like(liste);
dcl-s court  packed(3:0) inz(999);
dcl-s copie  like(court);

snd-msg 'base : ' + %char(base) + ' / autre : ' + %char(autre);
un = 12.34;
snd-msg 'un : ' + %char(un) + ' (liste a ' + %char(%elem(liste)) + ' elements)';

copie = court;
copie += 1;
snd-msg 'copie : ' + %char(copie);

*inlr = *on;

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

base : 99.50 / autre : .00
un : 12.34 (liste a 3 elements)
Erreur : RNQ0103 - (C G D F) Cible pour opération numérique trop petite pour contenir résultat.

La zone autre a le type de base mais pas sa valeur : elle vaut zéro. un, déclaré sur le tableau liste, est une zone simple et non un tableau. Enfin copie reprend la précision exacte de court : voir le piège.

Le piège

LIKE copie le type, pas la valeur, et le type copié est exact. autre like(base) ne reprend pas le inz(99.50) de base (elle vaut .00). Et la précision est celle de la source : une zone like(court) d'un packed(3:0) contenant 999 n'accepte pas d'ajouter 1, le programme s'arrête sur RNQ0103 (cible trop petite). Si la nouvelle zone doit être plus grande, utilisez like(court : +2).