Supported RPG Features

A standalone field is bound to a data area with the DTAARA('name') keyword. IN reads the data area into the field (optionally locking it for update with *LOCK); OUT writes the field back and releases the lock; UNLOCK releases the lock without writing back.

OUT requires a prior IN *LOCK on the same data area - issuing OUT without it raises program status 412 ("Data area not locked for output"). After a successful OUT, the lock is released automatically, so a second OUT requires a new IN *LOCK:

DCL-S daNextRcpt PACKED(7:0) DTAARA('NEXTRCPT');

IN *LOCK daNextRcpt;              // lock and read
daNextRcpt = daNextRcpt + 1;
OUT daNextRcpt;                   // write back, release lock

UNLOCK releases the data-area lock without persisting the local value. The data area retains whatever was last written via OUT. IN, OUT and UNLOCK all support the (E) operation extender for error handling:

IN *LOCK daNextRcpt;              // lock and read
daNextRcpt = 0;                   // local change
UNLOCK daNextRcpt;                // release lock - 0 is NOT written back
IN daNextRcpt;                    // re-read: still holds the prior value

UNLOCK can also be used with a file name (instead of a data area field) to release the record lock held from the most recent read-for-update without performing an UPDATE. This allows other jobs to access the record:

     FCUSTMAST  UF   E           K DISK
     C                   READ      CUSTMAST
     C                   UNLOCK    CUSTMAST

Record-level UNLOCK releases the database row lock the read acquired, making the record available to other jobs again, and leaves the file's position untouched. It applies whether or not the file is under commitment control. After an UNLOCK no record is held for update, so an UPDATE or DELETE issued without reading again fails with status 1221 - see Disk File I/O.

The DTAARA argument names the external data area; the field is a view onto it. Two fields bound to the same external name therefore refer to the same data area, so an OUT from one is visible to an IN on the other:

DCL-S writer PACKED(7:0) DTAARA('SHARED');
DCL-S reader PACKED(7:0) DTAARA('SHARED');

IN *LOCK writer;
writer = 1234567;
OUT writer;                      // writes 1234567 and releases the lock
IN reader;                       // reader now holds 1234567

When DTAARA is written without an explicit name, the data-area name defaults to the field's own name.

Data-area data structures

A data structure can be bound to a data area as well. Two forms bind it, and they differ in when the area is read and written:

A data structure and another data structure bound to the same area alias its bytes, just as two scalar fields do.

Not supported (each is rejected with a diagnostic rather than silently ignored, so nothing binds to local memory by mistake): an unnamed data-area data structure (DCL-DS *N DTAARA(...)); DTAARA(*VAR:name) and other special words beyond *LDA / *AUTO; and an auto (UDS / DTAARA(*AUTO)) data structure in a cycle program (one with a primary file) - a plain DTAARA(name) binding with explicit IN/OUT still works there.