Aller au contenu

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).