Instruction RPG full free · IBM i (AS/400) · Mots-clés de déclaration
OVERLAY
Superposer des sous-zones
Place une sous-zone sur tout ou partie d'une autre sous-zone de la même structure ; POS fixe une position absolue.
Syntaxe
sous_zone type overlay(zone_base);
sous_zone type overlay(zone_base : position);
sous_zone type overlay(zone_base : *next);
sous_zone type pos(position);
zone_base- La sous-zone de la même structure sur laquelle on se pose. La nouvelle sous-zone partage ses octets.
position- Rang du premier caractère dans la zone de base (1 par défaut).
*NEXT- Se place juste après la sous-zone précédente qui superpose la même base : pratique pour découper un texte en tranches.
POS(n)- Position absolue, à partir de 1, dans la structure entière. Deux sous-zones qui se recouvrent partagent leurs octets.
- Effet
- Aucun indicateur. Les sous-zones superposées partagent les mêmes octets : écrire dans l'une modifie l'autre, sans copie.
À quoi ça sert
Cela sert à découper un enregistrement ou un texte à longueur fixe : une date de 8 caractères AAAAMMJJ en année, mois, jour ; un code article en famille et numéro ; une ligne de fichier plat en champs.
C'est la forme moderne des positions "début" et "fin" de la spécification D en colonnes : OVERLAY pour l'imbrication, POS à la place des colonnes From/To.
Exemple 1 : Découper un texte avec OVERLAY et POS
**free
// OVERLAY : des sous-zones posees sur une autre ; POS : position absolue dans la structure.
ctl-opt dftactgrp(*no) actgrp(*new);
dcl-ds ligne qualified;
tout char(16) inz('100Dupont SA ');
numero char(3) overlay(tout);
nom char(10) overlay(tout : 4);
end-ds;
dcl-ds date_ds qualified;
entier char(8) inz('20260930');
annee char(4) overlay(entier : 1);
mois char(2) overlay(entier : *next);
jour char(2) overlay(entier : *next);
end-ds;
dcl-ds zone qualified;
debut char(5);
milieu char(5) pos(3);
end-ds;
snd-msg 'Numero : [' + ligne.numero + ']';
snd-msg 'Nom : [' + ligne.nom + ']';
snd-msg 'Annee/mois/jour : ' + date_ds.annee + '/' + date_ds.mois + '/' + date_ds.jour;
date_ds.mois = '12';
snd-msg 'Apres modification du mois : ' + date_ds.entier;
zone.debut = 'ABCDE';
snd-msg 'POS(3) : [' + zone.milieu + ']';
*inlr = *on;
Résultat réel, compilé et exécuté sur IBM i 7.5 :
Numero : [100]
Nom : [Dupont SA ]
Annee/mois/jour : 2026/09/30
Apres modification du mois : 20261230
POS(3) : [CDE ]
numero couvre les 3 premiers caractères de tout, nom débute en position 4. Pour la date, *next enchaîne année, mois, jour sans calculer les positions. Écrire date_ds.mois = '12' modifie entier (20261230). pos(3) place milieu à partir du 3e octet de la structure, sur les octets de debut.
Exemple 2 : Sous-zone numérique sur du texte
**free
// Piege : une sous-zone numerique posee sur du texte lit les octets tels quels.
ctl-opt dftactgrp(*no) actgrp(*new);
dcl-ds saisie qualified;
texte char(5) inz('12 45');
qte zoned(5:0) overlay(texte);
end-ds;
dcl-ds correct qualified;
texte char(5) inz('00042');
qte zoned(5:0) overlay(texte);
end-ds;
snd-msg 'Texte bien forme : ' + %char(correct.qte);
snd-msg 'Texte avec un blanc : [' + saisie.texte + ']';
snd-msg 'Quantite : ' + %char(saisie.qte);
*inlr = *on;
Résultat réel, compilé et exécuté sur IBM i 7.5 :
Texte bien forme : 42
Texte avec un blanc : [12 45]
Quantite : 12045
Une zone zoned(5:0) posée sur '00042' lit bien 42. Posée sur '12 45' avec un blanc, elle ne signale rien : elle lit 12045.
Le piège
Une sous-zone numérique posée sur du texte lit les octets sans contrôler. Le blanc de '12 45' est interprété comme un zéro : le programme affiche 12045 sans aucune erreur. Avant de lire un numérique superposé à un texte saisi, validez le contenu (%CHECK).