Today's Special: Data Area Surprise!
Published: January 25, 2006
by Ted Holt
Data areas are as handy as pockets. Maybe that's because they are like pockets in that you can stuff things into them. RPG, like other iSeries programming languages, can read and modify data areas. In fact, RPG allows for two different data area I/O methods, and one of them has a "feature" that could give you a nasty surprise!
If you want an RPG program to read and/or change a data area, you have two options. You can let the RPG cycle handle the input and output operations, or you can control the I/O by hand. The easier method is to let the cycle do the work, so let's look at it first.
To tell the RPG cycle that you want it to control data area input and output, create a named data structure with the U option in the definition specs. Here's how to create a data structure for the data area named STATUS.
D Status uds
D Stat 1 8
Stat = 'BR-549';
The data structure must have a name. If you omit the name, the program will access the local data area.
If the data area's name is different from the data area name, use the DTAARA keyword to specify the object name. In this example, the data structure is named STATUS, but the object name is PGMSTAT.
D Status uds dtaara('PGMSTAT')
D Stat 1 8
Stat = 'BR-549';
When the program begins to run, it allocates the data area with a lock and brings its contents into storage. When the program ends, it updates the data area and releases the lock. Nothing to it.
The other method is the procedural method. Use the IN, OUT, and UNLOCK op codes to control data area I/O in calculations. The following example retrieves the current value of a data area, assigns a new value, and writes the changed value back to the data area object.
D Status ds 8 dtaara('STATUS')
in *lock Status;
Status = 'BR-549';
So which is the better method? I vote for the procedural method. For one reason, under the cycle method, the data area remains locked for the duration of the program run, even if the program does not change the data area's value. In some cases, such as when run time is short, locking the data area is of no importance. But when run time is longer and other programs may also need to access the data area, keeping the data area locked is out of the question.
But what concerns me more is that the cycle method includes a "feature" that I don't like. If the data area is not found at run time, the system takes it on itself to create a data area of the proper name in the QTEMP library. Surprise! If by some fluke the desired data area has been deleted, the program does not halt, as it does when data area I/O is handled with the IN and OUT op codes, but creates a temporary data area and keeps on truckin'. I do not like to take such risks.
Not only are there two ways to read and modify data areas, there are also two ways to define data areas--in calculation specifications and in definition specifications. The D-spec method is the "new and improved" one, so that is the definition method I use and the one I recommend others to use. One interesting feature of the D-spec method is you may specify DTAARA(*VAR) in a D spec in order to specify the name of a data area object at run time. The DEFINE op code, on the other hand, binds to the object name at compilation.
To learn more about the C-spec method, read about the DEFINE op code (DEFN in RPG III).