Les zones de données, une valeur partagée entre programmes
Ce qu'est une DTAARA, ses trois types et la *LDA de chaque travail, puis trois exemples : un compteur de factures verrouillé, une zone de paramètres découpée en morceaux, et la *LDA transmise à un travail soumis. En CL, en RPG IV colonné, en full free et en SQL, tout exécuté sur un IBM i 7.5.
En une phrase
Une zone de données (*DTAARA) est un objet qui
contient une seule valeur, texte, nombre ou indicateur, que des programmes et des
travaux différents lisent et modifient : un compteur, un paramètre, un état.
Une zone de données, c'est quoi
Un objet d'une bibliothèque, comme un programme ou un fichier, mais qui ne contient qu'une valeur, sans enregistrements ni clé. IBM le décrit comme un moyen de « communiquer et stocker les données utilisées par différents programmes à l'intérieur d'un travail ou entre les travaux ». La valeur est écrite sur disque à chaque modification : elle survit à l'arrêt du programme et du système.
| Type | Contenu | Longueur maximale | Par défaut | Valeur initiale |
|---|---|---|---|---|
*CHAR | Caractère | 2 000 caractères | 32, ou la longueur de la valeur initiale | Blancs |
*DEC | Numérique condensé | 24 chiffres, dont 9 décimales | 15 chiffres, dont 5 décimales | 0 |
*LGL | Logique | 1 | 1 | 0 |
Pour qu'un programme CL puisse lire une zone *DEC, sa longueur totale ne doit pas dépasser
15 chiffres. Un quatrième type, *DDM, désigne une zone d'un autre système.
Les zones spéciales
Trois zones existent sans qu'on les crée. Elles n'ont pas de bibliothèque et ne demandent aucun droit :
| Nom | Zone | Caractères | Portée |
|---|---|---|---|
*LDA | Zone de données locale | 1 024 | Une par travail ; aucun autre travail ne la voit. Un travail soumis par SBMJOB en reçoit une copie (démonstration plus bas). |
*GDA | Zone de données de groupe | 512 | Une par groupe de travaux (travaux de groupe), invisible hors du groupe. |
*PDA | Paramètres d'initialisation de programme | 2 000 | Seulement dans un travail à démarrage anticipé. |
Créer et afficher une zone de données
Les zones des exemples, dans la bibliothèque JOBIDTA : un compteur numérique, une zone de paramètres de 50 caractères, et une zone qui recevra la *LDA d'un travail soumis.
CRTDTAARA DTAARA(JOBIDTA/COMPTEUR) TYPE(*DEC) LEN(7 0) VALUE(1000) TEXT('Dernier numero de facture')
CRTDTAARA DTAARA(JOBIDTA/PARAMS) TYPE(*CHAR) LEN(50) VALUE('ACMRECETTE 20261031N') TEXT('Parametres de l''application')
CRTDTAARA DTAARA(JOBIDTA/RESLDA) TYPE(*CHAR) LEN(10) TEXT('*LDA vue par le travail soumis')

DSPDTAARA DTAARA(JOBIDTA/COMPTEUR) : une zone *DEC de 7 chiffres, valeur 1000 (haut de l'écran).
DSPDTAARA sur PARAMS : une règle de positions au-dessus de la valeur.La zone PARAMS est découpée par convention : la société en positions 1 à 3 (ACM), l'environnement en 4 à 13 (RECETTE), la date de clôture en 14 à 21, un indicateur de blocage en 22. Les autres commandes : CHGDTAARA (modifier), RTVDTAARA (lire dans un CL), WRKDTAARA (gérer), DLTDTAARA (supprimer).
Exemple 1 Un compteur partagé
Le numéro de facture suivant
Chaque programme qui crée une facture prend le numéro suivant dans COMPTEUR. Lire, ajouter 1, réécrire : entre la lecture et l'écriture, aucun autre travail ne doit pouvoir faire de même, sinon deux factures auraient le même numéro. D'où le verrou.
RPG IV colonné NUMFAC4
H* NUMFAC4 : prend le numero de facture suivant dans COMPTEUR
DCOMPTEUR S 7P 0 DTAARA
DTEXTE S 52A
C* IN *LOCK : lire et verrouiller ; OUT : ecrire et liberer
C *LOCK IN COMPTEUR
C EVAL COMPTEUR = COMPTEUR + 1
C OUT COMPTEUR
C EVAL TEXTE = 'Facture numero ' + %CHAR(COMPTEUR)
C TEXTE DSPLY
C EVAL *INLR = *ON Full free NUMFACF
**FREE
// NUMFACF : prend le numero de facture suivant dans COMPTEUR
dcl-s compteur packed(7:0) dtaara;
// IN *LOCK : lire et verrouiller ; OUT : ecrire et liberer
in *lock compteur;
compteur += 1;
out compteur;
dsply ('Facture numero ' + %char(compteur));
*inlr = *on; dcl-s compteur packed(7:0) dtaara;- Le mot-clé
DTAARAsans paramètre lie la variable à la zone du même nom, cherchée dans la liste des bibliothèques (*LIBL). La variable doit avoir le type et la longueur de la zone :packed(7:0)pour une zone*DECde 7 0. in *lock compteur;- Lit la zone et la verrouille. En colonné :
*LOCKen facteur 1,INen code opération, la zone en facteur 2. out compteur;- Écrit la nouvelle valeur et libère le verrou. Sans OUT ni UNLOCK, le verrou tombe à la fin du programme.
CL NUMCL
/* NUMCL : prend le numéro de facture suivant dans COMPTEUR */
PGM
DCL VAR(&NUM) TYPE(*DEC) LEN(7 0)
/* Lire puis réécrire, ce sont deux commandes : on alloue la zone */
/* pour qu'aucun autre travail ne la change entre les deux. */
ALCOBJ OBJ((COMPTEUR *DTAARA *EXCL)) WAIT(10)
RTVDTAARA DTAARA(COMPTEUR) RTNVAR(&NUM)
CHGVAR VAR(&NUM) VALUE(&NUM + 1)
CHGDTAARA DTAARA(COMPTEUR) VALUE(&NUM)
DLCOBJ OBJ((COMPTEUR *DTAARA *EXCL))
SNDPGMMSG MSG('Facture numéro' *BCAT %CHAR(&NUM))
ENDPGM En CL, lire puis écrire demande deux commandes. CHGDTAARA et RTVDTAARA verrouillent la zone chacune pendant leur seule exécution : pour une mise à jour en plusieurs commandes, IBM demande d'allouer la zone par ALCOBJ, et de la libérer par DLCOBJ.
CALL QCMD
ADDLIBLE JOBIDTA
CALL NUMFAC4
CALL NUMFACF
CALL NUMCL

Le verrou, vu d'un autre travail
Pour voir le verrou, un programme le garde le temps qu'on réponde à un message :
**FREE
// VERROUF : garde COMPTEUR verrouille jusqu'a la reponse
dcl-s compteur packed(7:0) dtaara;
dcl-s reponse char(1);
in *lock compteur;
dsply 'COMPTEUR verrouille, Entree pour liberer' '' reponse;
unlock compteur;
*inlr = *on; 
Pendant l'attente, depuis un autre travail, le service QSYS2.OBJECT_LOCK_INFO montre le verrou :
SELECT LOCK_STATE, LOCK_STATUS, LOCK_SCOPE, JOB_NAME
FROM QSYS2.OBJECT_LOCK_INFO
WHERE OBJECT_SCHEMA = 'JOBIDTA' AND OBJECT_NAME = 'COMPTEUR' LOCK_STATE | LOCK_STATUS | LOCK_SCOPE | JOB_NAME |
|---|---|---|---|
*EXCLRD | HELD | JOB | 013920/SAKADM/QPADEV0001 |
*EXCLRD : exclusif, mais la lecture reste permise. Pendant le verrou, une
lecture par DATA_AREA_INFO rend bien 1003. En revanche, la modification attend :
CHGDTAARA DTAARA(JOBIDTA/COMPTEUR) VALUE(5000)
(30 secondes d'attente)
CPF1063 : Impossible d'allouer la zone de données COMPTEUR dans JOBIDTA.
Le compteur n'a pas bougé : il valait toujours 1003. Une fois la réponse donnée, UNLOCK libère la zone et OBJECT_LOCK_INFO ne rend plus aucune ligne.
Exemple 2 Une zone découpée
Une zone de paramètres vue comme une structure
En RPG, une structure de données (DS) liée à la zone découpe PARAMS en sous-zones, en une seule lecture.
RPG IV colonné PARAM4
H* PARAM4 : la zone PARAMS vue comme une structure de donnees
DPARAMS DS 50 DTAARA
D SOCIETE 1 3
D ENVIRON 4 13
D CLOTURE 14 21
D BLOQUE 22 22
DTEXTE S 52A
C IN PARAMS
C EVAL TEXTE = 'Societe ' + SOCIETE
C TEXTE DSPLY
C EVAL TEXTE = 'Environnement ' + ENVIRON
C TEXTE DSPLY
C EVAL TEXTE = 'Cloture ' + CLOTURE
C TEXTE DSPLY
C EVAL TEXTE = 'Bloque ' + BLOQUE
C TEXTE DSPLY
C EVAL *INLR = *ON Full free PARAMF
**FREE
// PARAMF : la zone PARAMS vue comme une structure de donnees
dcl-ds params len(50) dtaara;
societe char(3);
environ char(10);
cloture char(8);
bloque char(1);
end-ds;
in params;
dsply ('Societe ' + societe);
dsply ('Environnement ' + environ);
dsply ('Cloture ' + cloture);
dsply ('Bloque ' + bloque);
*inlr = *on; dcl-ds params len(50) dtaara;- La structure prend la zone PARAMS ;
len(50)lui donne la longueur de la zone. En colonné,DSen 24-25, la longueur 50 en 33-39, et chaque sous-zone avec ses positions de début et de fin. in params;- Sans
*LOCK: une simple lecture, sans verrou.

En CL, pas de structure : on lit et on modifie une sous-chaîne, donnée par sa position de début et sa longueur. CHGDTAARA ne change alors que ces positions :
/* PARAMCL : lit et modifie une partie de la zone PARAMS */
PGM
DCL VAR(&SOCIETE) TYPE(*CHAR) LEN(3)
DCL VAR(&ENV) TYPE(*CHAR) LEN(10)
/* Une sous-chaîne : (position de début, longueur) */
RTVDTAARA DTAARA(PARAMS (1 3)) RTNVAR(&SOCIETE)
RTVDTAARA DTAARA(PARAMS (4 10)) RTNVAR(&ENV)
SNDPGMMSG MSG('Société' *BCAT &SOCIETE *CAT +
', environnement' *BCAT &ENV)
/* On ne change que les positions 4 à 13 : le reste est conservé */
CHGDTAARA DTAARA(PARAMS (4 10)) VALUE('PROD')
RTVDTAARA DTAARA(PARAMS (4 10)) RTNVAR(&ENV)
SNDPGMMSG MSG('Nouvel environnement :' *BCAT &ENV)
ENDPGM 
Exemple 3 La zone de données locale
La *LDA, propre à chaque travail
La *LDA sert à faire passer une valeur d'un programme à l'autre dans le même travail, sans paramètre. LDACL l'écrit, appelle un programme RPG qui la lit, puis soumet un travail :
CL LDACL
/* LDACL : remplit la *LDA, la lit en RPG, puis soumet un travail */
PGM
CHGDTAARA DTAARA(*LDA (1 10)) VALUE('LOT-2026-A')
CALL PGM(LDAF)
/* Le travail soumis reçoit une copie de la *LDA */
SBMJOB CMD(CALL PGM(LDACOP)) JOB(LDACOP)
ENDPGM RPG IV colonné LDA4
H* LDA4 : lit la zone de donnees locale (*LDA) du travail
D* U en 23 et pas de nom : structure liee a la *LDA
D UDS
D LOT 1 10
DTEXTE S 52A
C EVAL TEXTE = 'Lot lu dans la *LDA : ' + LOT
C TEXTE DSPLY
C EVAL *INLR = *ON Full free LDAF
**FREE
// LDAF : lit la zone de donnees locale (*LDA) du travail
// Sans nom de structure ni de zone : DTAARA(*AUTO) designe la *LDA
dcl-ds *n dtaara(*auto);
lot char(10);
end-ds;
dsply ('Lot lu dans la *LDA : ' + lot);
*inlr = *on; D UDS- En colonné, un
Uen position 23 fait de la DS une structure liée à une zone, lue au démarrage du programme et écrite à la fin. Sans nom, c'est la *LDA. dcl-ds *n dtaara(*auto);- L'équivalent full free :
*AUTOpour la lecture et l'écriture automatiques, et sans nom ni de structure ni de zone, la *LDA.

Le travail soumis, lui, recopie sa propre *LDA dans la zone RESLDA, puis modifie sa *LDA :
/* LDACOP : en batch, recopie sa *LDA dans la zone RESLDA */
PGM
DCL VAR(&LOT) TYPE(*CHAR) LEN(10)
RTVDTAARA DTAARA(*LDA (1 10)) RTNVAR(&LOT)
CHGDTAARA DTAARA(RESLDA) VALUE(&LOT)
/* Modifier sa *LDA ne change pas celle du travail qui a soumis */
CHGDTAARA DTAARA(*LDA (1 10)) VALUE('MODIFIE')
ENDPGM 

DSPDTAARA DTAARA(*LDA) dans le travail interactif : toujours LOT-2026-A, pas MODIFIE. Le travail soumis n'avait changé que sa copie.La *LDA ne se verrouille pas : IN *LOCK sur elle est refusé à la compilation (RNF7090).
Le piège du full free : les apostrophes
En colonné, DTAARA(COMPTEUR) désigne la zone COMPTEUR. En full free, sans
apostrophes, c'est le nom d'une variable (ou d'une constante) qui contient le nom de la zone.
Le même mot-clé, recopié du colonné vers le free :
dcl-s numero packed(7:0) dtaara(COMPTEUR); RNF7030 sev 30 : Le nom ou l'indicateur COMPTEUR n'est pas défini.
En full free, on écrit le nom entre apostrophes, éventuellement avec la bibliothèque, en majuscules :
dtaara('JOBIDTA/COMPTEUR') compile sans erreur. Sans parenthèses, c'est le nom de la
variable qui sert, comme dans NUMFACF. En colonné, DNUMERO S 7P 0 DTAARA(COMPTEUR)
compile aussi : COMPTEUR y est bien le nom de la zone.
Lire une zone de données en SQL
Le service QSYS2.DATA_AREA_INFO existe en vue, pour toutes les zones, et en fonction de table, pour une zone précise. Résultats obtenus après les exemples ci-dessus :
SELECT DATA_AREA_NAME, DATA_AREA_TYPE, LENGTH, DECIMAL_POSITIONS, DATA_AREA_VALUE
FROM QSYS2.DATA_AREA_INFO
WHERE DATA_AREA_LIBRARY = 'JOBIDTA'
ORDER BY DATA_AREA_NAME DATA_AREA_NAME | DATA_AREA_TYPE | LENGTH | DECIMAL_POSITIONS | DATA_AREA_VALUE |
|---|---|---|---|---|
COMPTEUR | *DEC | 7 | 0 | 1003 |
PARAMS | *CHAR | 50 | - | ACMPROD 20261031N |
RESLDA | *CHAR | 10 | - | LOT-2026-A |
La fonction de table, avec SUBSTR pour retrouver les sous-zones :
SELECT SUBSTR(DATA_AREA_VALUE, 4, 10) AS ENVIRONNEMENT,
SUBSTR(DATA_AREA_VALUE, 22, 1) AS BLOQUE
FROM TABLE(QSYS2.DATA_AREA_INFO(DATA_AREA_NAME => 'PARAMS',
DATA_AREA_LIBRARY => 'JOBIDTA')) ENVIRONNEMENT | BLOQUE |
|---|---|
PROD | N |
Pour modifier une zone depuis SQL, on passe la commande CL à QSYS2.QCMDEXC :
CALL QSYS2.QCMDEXC('CHGDTAARA DTAARA(JOBIDTA/PARAMS (22 1)) VALUE(''O'')') ENVIRONNEMENT | BLOQUE |
|---|---|
PROD | O |
Le résultat est celui de la fonction de table relancée après l'appel : BLOQUE vaut maintenant O.
Les erreurs, et ce qu'elles veulent dire
| Message | Quand | Texte | Cause |
|---|---|---|---|
CPF1063 | à l'exécution, autre travail | Impossible d'allouer la zone de données COMPTEUR dans JOBIDTA. | La zone est verrouillée par un autre travail (IN *LOCK, ALCOBJ) : CHGDTAARA a attendu 30 secondes, puis abandonné. |
RNF7030 | à la compilation, full free | Le nom ou l'indicateur COMPTEUR n'est pas défini. | DTAARA(COMPTEUR) sans apostrophes : en full free, c'est le nom d'une variable qui contient le nom de la zone. |
RNF7090 | à la compilation | *LOCK utilisé en Facteur 1 avec LDA ou PDA comme Facteur 2. | IN *LOCK sur la *LDA : elle n'appartient qu'au travail, il n'y a rien à verrouiller. |
Sources
Les exemples ont été exécutés sur un IBM i 7.5 (voir la méthode). Les règles viennent de ces sources, consultées le 23 octobre 2026 :
- Create Data Area (CRTDTAARA), IBM, IBM i 7.5 CL commands. Types *DEC, *CHAR, *LGL et *DDM ; longueurs maximales (24 chiffres dont 9 décimales, 2 000 caractères, 1) et par défaut (15 5, 32, 1) ; 15 chiffres au plus pour un usage en CL ; zone écrite sur disque à chaque modification.
- Change Data Area (CHGDTAARA), IBM, IBM i 7.5 CL commands. *LDA de 1 024 caractères, *GDA de 512, *PDA de 2 000 ; sous-chaîne (début, longueur) ; zone partagée mise à jour en plusieurs commandes : l'allouer par ALCOBJ.
- Retrieve Data Area (RTVDTAARA), IBM, IBM i 7.5 CL commands. Lecture de tout ou partie d'une zone dans une variable CL, dans un programme CL seulement.
- ILE RPG Reference (SC09-2508-12), IBM, IBM i 7.5 (PDF). Mot-clé DTAARA en full free (nom entre apostrophes, sinon variable ou constante qui le contient) et en colonné ; *AUTO et *USRCTL ; U en position 23 ; *LDA pour une structure sans nom ; IN, OUT, UNLOCK et *LOCK, interdit sur la *LDA ; même type et même longueur que la zone.
Questions fréquentes
Qu'est-ce qu'une zone de données (DTAARA) sur IBM i ?
Un objet de type *DTAARA qui contient une seule valeur : du texte (*CHAR, 2 000 caractères au plus), un nombre (*DEC, 24 chiffres dont 9 décimales au plus) ou un indicateur (*LGL). Elle sert à garder et à partager une valeur entre programmes ou entre travaux : un compteur, un paramètre, un état.
Quelle différence entre une zone de données et la *LDA ?
Une zone de données est un objet d'une bibliothèque, visible de tous les travaux qui ont le droit de la lire. La *LDA (zone de données locale) est une zone de 1 024 caractères propre à chaque travail : aucun autre travail ne la voit. Un travail soumis par SBMJOB en reçoit une copie.
Comment lire une zone de données en CL ?
Avec RTVDTAARA, dans un programme CL : RTVDTAARA DTAARA(PARAMS (4 10)) RTNVAR(&ENV) lit 10 caractères à partir de la position 4. CHGDTAARA la modifie, DSPDTAARA l'affiche.
Comment lire et modifier une zone de données en RPG ?
On la déclare avec le mot-clé DTAARA sur une variable ou une structure de données, puis IN la lit et OUT l'écrit. IN *LOCK la verrouille jusqu'à OUT, UNLOCK ou la fin du programme : c'est ce qu'il faut pour un compteur partagé.
Que se passe-t-il si un autre travail a verrouillé la zone ?
IN *LOCK pose un verrou *EXCLRD : les autres travaux peuvent encore la lire, mais pas la modifier. Sur IBM i 7.5, un CHGDTAARA lancé depuis un autre travail a attendu 30 secondes, puis a échoué avec CPF1063, « Impossible d'allouer la zone de données ».
Peut-on lire une zone de données en SQL ?
Oui, avec QSYS2.DATA_AREA_INFO, en vue pour toutes les zones ou en fonction de table pour une zone précise. Pour la modifier depuis SQL, on peut appeler CHGDTAARA par QSYS2.QCMDEXC.