Aller au contenu

Instruction RPG full free · IBM i (AS/400) · Déclarations

DCL-DS

Déclarer une structure de données

Regroupe plusieurs zones (les sous-champs) sous un seul nom, pour les manipuler ensemble : copie d'un bloc, passage en paramètre, découpage d'une zone.

Syntaxe

dcl-ds nom [qualified] [inz] [likeds(autre)];
  sous-champ type(longueur);
  …
end-ds;
dcl-ds copie likeds(modele) inz;
qualified
Les sous-champs s'écrivent nom.sousChamp. À préférer : deux structures peuvent avoir les mêmes noms de sous-champs, et le code dit d'où vient chaque valeur.
inz
Met toute la structure à sa valeur de départ : blancs pour le texte, zéro pour les nombres.
likeds(modele)
Copie la forme d'une autre structure.
overlay(sousChamp [: position])
Place un sous-champ par-dessus un autre, pour découper une zone.
Effet
Aucun indicateur ni %FOUND. La structure occupe une zone mémoire d'un seul tenant. Sans inz, ses sous-champs numériques ne contiennent pas de nombre valide (voir le piège). %size(structure) donne sa taille totale en octets.

À quoi ça sert

Une structure de données représente un objet de gestion : un client, une ligne de facture, une adresse. On la remplit, on la passe à une procédure, on la copie d'une seule affectation (copie = client;). C'est la base de tout programme un peu organisé, et le moyen le plus propre de passer plusieurs valeurs à une procédure.

Elle sert aussi à découper une zone : une date AAAAMMJJ en trois sous-champs avec overlay, un code sur 10 caractères dont les 3 premiers sont un préfixe… En RPG IV en colonnes, c'est la spécification D avec le code DS.

Exemple 1 : Un client, sa copie et un découpage de date

**free
// DCL-DS : regrouper les zones d'un meme objet, et le copier d'un bloc.
ctl-opt dftactgrp(*no) actgrp(*new);

dcl-ds client qualified inz;
  numero  packed(5:0);
  nom     char(20);
  ville   char(15);
  solde   packed(9:2);
end-ds;

dcl-ds copie likeds(client) inz;

dcl-ds dateInfo;
  dateTexte char(8);
  annee     char(4) overlay(dateTexte);
  mois      char(2) overlay(dateTexte : 5);
  jour      char(2) overlay(dateTexte : 7);
end-ds;

client.numero = 100;
client.nom = 'Dupont SA';
client.ville = 'Montpellier';
client.solde = 1250.50;
copie = client;
copie.numero = 200;

snd-msg 'Client  : ' + %char(client.numero) + ' [' + %trim(client.nom) + ']';
snd-msg 'Copie   : ' + %char(copie.numero) + ' [' + %trim(copie.nom) + ']';
snd-msg 'Taille  : ' + %char(%size(client));

dateTexte = '20260930';
snd-msg 'Annee ' + annee + ' mois ' + mois + ' jour ' + jour;

*inlr = *on;

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

Client  : 100 [Dupont SA]
Copie   : 200 [Dupont SA]
Taille  : 43
Annee 2026 mois 09 jour 30

La structure client est qualifiée : client.nom. likeds(client) crée copie de même forme ; l'affectation copie = client copie tout d'un coup, puis on change le numéro de la copie sans toucher à l'original. La taille est la somme des sous-champs (3 + 20 + 15 + 5 = 43). La structure dateInfo découpe le texte 20260930 en année, mois et jour grâce à overlay.

Exemple 2 : Sans INZ, le nombre est invalide

**free
// DCL-DS : sans INZ, un sous-champ numerique est rempli de blancs et plante a la premiere lecture.
ctl-opt dftactgrp(*no) actgrp(*new);

dcl-ds avecInz qualified inz;
  numero packed(5:0);
  nom    char(10);
end-ds;

dcl-ds sansInz qualified;
  numero packed(5:0);
  nom    char(10);
end-ds;

snd-msg 'Avec INZ : ' + %char(avecInz.numero) + ' [' + avecInz.nom + ']';
snd-msg 'Sans INZ, texte : [' + sansInz.nom + ']';
snd-msg 'Sans INZ, nombre : ' + %char(sansInz.numero);

*inlr = *on;

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

Avec INZ : 0 [          ]
Sans INZ, texte : [          ]
Erreur : RNQ0907 - (C G D F) Erreur de données décimales.

Avec inz, le numéro vaut 0 et le nom est blanc. Sans inz, le texte est blanc, mais le sous-champ numérique contient des blancs, pas un nombre valide : le %char arrête le programme avec RNQ0907 (MCH1202, erreur de données décimales).

Le piège

Sans inz, un sous-champ numérique est invalide. Dans l'exemple 2, la structure sansInz contient des blancs à la place du packed : le programme s'arrête dès qu'on lit le sous-champ (RNQ0907, erreur de données décimales). Une zone autonome dcl-s ne pose pas ce problème, elle commence à zéro. Pour une structure, ajoutez toujours inz.

La structure lue depuis un fichier est, elle, remplie par la lecture. Le piège vient des structures qu'on remplit à la main.