How do you define frustration? I'm sure you could think of several definitions, but maybe one definition is, "having to run System/36 RPG on an AS/400." No external file definitions. No WRITE and UPDAT op codes. Endless lines of input and output specs. And, converting all those data files to native isn't something that can be accomplished overnight.
In this article, we'll look at another way to do I/O--using data structures. Not only will you learn some ways to spice up your S/36-style RPG code, you'll discover that this technique has some usefulness in native mode.
External Described and Program-Described Files
There are two ways to define file record layouts to the AS/400. The traditional method--defining the fields within program source code--still works as it did on earlier machines. In AS/400 terminology, such files are called program-described files.
You can also use DDS specifications to describe file layouts. Files built with DDS are called externally described files. HLL programs do not require that the fields be defined within program source code, if the externally described file is referenced with an 'E' in column 19 of the F-spec.
IBM has added a new wrinkle to program-described files that combines the best of both worlds. The result field of most I/O operations (CHAIN, WRITE, UPDAT, and various forms of READ) may contain a data structure name if factor 2 contains the name of a program-described file. Input operations place data from the file into the data structure. Output operations write data to the file from the data structure.
Look at the fragment of an RPG program in 1a. The program writes to a program-described file called SEQFL (sequential file), which will contain data of various formats. Factor 2 of the WRITE statements contains the name of the program-described file. The result fields are all data structures. The traditional way of writing this program would be to code the three record formats in output specs, and use EXCPT or the RPG cycle to output them.
Look at the fragment of an RPG program in Figure 1a. The program writes to a program-described file called SEQFL (sequential file), which will contain data of various formats. Factor 2 of the WRITE statements contains the name of the program-described file. The result fields are all data structures. The traditional way of writing this program would be to code the three record formats in output specs, and use EXCPT or the RPG cycle to output them.
Suppose SEQFL requires a header record at the top of the file and a trailer record at the end. We could add the output specs in 1b to the code in 1a. In other words, you can mix and match the two methods--via data structures and via output specs--to write to a program-described file. Putting the header and trailer in data structures is OK, but not necessary.
Suppose SEQFL requires a header record at the top of the file and a trailer record at the end. We could add the output specs in Figure 1b to the code in Figure 1a. In other words, you can mix and match the two methods--via data structures and via output specs--to write to a program-described file. Putting the header and trailer in data structures is OK, but not necessary.
In the first example, data structures eliminated output specs only. Let's look at an example that shows greater savings.
2a contains fragments of an interactive RPG program that does maintenance to a vendor master file. Data structure VNDREC is used to define the record layout of file VNDMAST, which has no input or output specifications in this program. The CHAIN operation puts the data into VNDREC. After the data has been changed and verified, the WRITE and UPDAT statements store it to disk. In this example, the number of input specs is the same, whether we use data structures or the traditional approach. But 12 lines of output specs have been eliminated. One nice thing about this is that program maintenance is reduced in the event that the record layout of VNDMAST changes. Rather than changing both input and output specs, you only change the data structure.
Figure 2a contains fragments of an interactive RPG program that does maintenance to a vendor master file. Data structure VNDREC is used to define the record layout of file VNDMAST, which has no input or output specifications in this program. The CHAIN operation puts the data into VNDREC. After the data has been changed and verified, the WRITE and UPDAT statements store it to disk. In this example, the number of input specs is the same, whether we use data structures or the traditional approach. But 12 lines of output specs have been eliminated. One nice thing about this is that program maintenance is reduced in the event that the record layout of VNDMAST changes. Rather than changing both input and output specs, you only change the data structure.
This example also shows that the DELET op code can be used with program- described files. No data structure name is needed in the result field, since data is not being written, but erased.
Externally Described Data Structures
You can make your S/36-type RPG programs more like native programs by describing file I/O data structures externally. 2b shows the DDS needed to define file VNDMASTDES (vendor master description), a file with the same record layout as VNDMAST. VNDMASTDES will not contain data. In fact, it doesn't have a member. When it is created you should use MBR(*NONE).
You can make your S/36-type RPG programs more like native programs by describing file I/O data structures externally. Figure 2b shows the DDS needed to define file VNDMASTDES (vendor master description), a file with the same record layout as VNDMAST. VNDMASTDES will not contain data. In fact, it doesn't have a member. When it is created you should use MBR(*NONE).
To instruct the RPG compiler to use the record layout of VNDMASTDES to describe VNDREC, you need to change the program as shown in 2c. The "E" in column 17 means that the data structure is externally described by the first record format of the file named in columns 21 through 30. This isn't RPG III coding, but it is more like RPG III than RPG II.
To instruct the RPG compiler to use the record layout of VNDMASTDES to describe VNDREC, you need to change the program as shown in Figure 2c. The "E" in column 17 means that the data structure is externally described by the first record format of the file named in columns 21 through 30. This isn't RPG III coding, but it is more like RPG III than RPG II.
Overcoming Limitations Of Externally Described Files
Externally described files are wonderful, but they have a couple of limitations. One is that you can't rename a field in output specs. The other is that you can't doubly define fields in input. Using data structures is one way to work around them.
The DDS for file WORKFL (work file) is given in 3a. 3b shows how that file would normally be used as an output-only file. But suppose we want to rename AMOUNT to AMT. One way to do that is shown in 3c. Even though WORKFL is defined by DDS, we can treat it as a program-described file and use WORKFL to describe the data structure used for I/O. Although WORKFL is an output-only file, it is defined in input specs, allowing fields to be renamed.
The DDS for file WORKFL (work file) is given in Figure 3a. Figure 3b shows how that file would normally be used as an output-only file. But suppose we want to rename AMOUNT to AMT. One way to do that is shown in Figure 3c. Even though WORKFL is defined by DDS, we can treat it as a program-described file and use WORKFL to describe the data structure used for I/O. Although WORKFL is an output-only file, it is defined in input specs, allowing fields to be renamed.
This is one method of renaming fields in output-only files. For another method, see the sidebar.
You may also add new fields to external definitions. In 3d, field TERR (territory) is defined as the first two characters in the data structure. As a rule I don't recommend this, since it could present a problem if the record layout of WORKFL were ever changed. It does, however, give a way to doubly define fields, as is often done in RPG II input specs.
You may also add new fields to external definitions. In Figure 3d, field TERR (territory) is defined as the first two characters in the data structure. As a rule I don't recommend this, since it could present a problem if the record layout of WORKFL were ever changed. It does, however, give a way to doubly define fields, as is often done in RPG II input specs.
A Few Requirements
We should mention a few other points before ending this treatment of file I/O through data structures. First, the record length coded in the F spec must equal the data structure length. They do not have to equal the actual record length, but they should not be shorter.
Second, these examples all deal with disk files. This technique will also work with files of other device types.
Third, don't forget that a field can appear in only one data structure. This is easy to forget, especially if you're used to coding the same field name in multiple record formats in the input and output specs.
Your Turn
I believe this technique will be of most benefit to those converting to the AS/400 from the S/34 or S/36. I use it in native mode from time to time to build multi-format files which I transmit to our corporate office or feed into a PC-based EDI package.
I've illustrated a few ways this technique can be put to work, but I suspect there are other ways I haven't thought of. Let me challenge you to give this technique a try. Find some effective ways to do I/O through data structures. Then write a follow-up article to this one to share what you've learned with the rest of us.
Sidebar:
Renaming a Field in an Externally Described Output File
RPG III/400 provides a way to rename fields of input and update files, but not of output files. Of course, you could build a logical file which renames fields and writes to that logical, but that's not necessary. Here's a simple way to rename a field in an externally defined, output-only file.
Assume file WORKFL has fields called CUSNBR, CUSNAM, AMOUNT and DUEDAT, and that we wish to rename AMOUNT to AMT. Even though WORKFL is to be treated as an output file, code it as input ("I" in column 15) with file addition allowed ("A" in column 66). Because WORKFL is an input file, you may rename AMOUNT in the input specs.
To make the program compile properly, code a dummy read. That's all there is to it.
FWRKFILE IF E DISK A FWRKREC I AMOUNTIN AMT ... C Z-ADDXAMT AMT C WRITEWRKREC ... CLRNLR READ WRKREC LR
Ted Holt is a programmer/analyst at Dana Corporation, a manufacturer of hydraulic pumps and motors in Corinth, MS. Ted can be reached via the Midrange Computing BBS or at (601) 287-1481.
File I/O Through Data Structures
Figure 1A Writing multiple record formats
Figure 1a: Writing Multiple Record Formats FINVHDR IF E K DISK FINVDTL IF E K DISK FSEQFL O F 80 DISK ISEQFT1 DS 80 I I '01' 1 2 RECID1 I 3 70CUSNR I 8 120INVNR ISEQFT2 DS 80 I I '02' 1 2 RECID2 I 3 11 PARTNR I 12 160QTY I 17 232UPRICE ISEQFT3 DS 80 I I '03' 1 2 RECID3 I 3 142INVTTL ... C WRITESEQFL SEQFT1 ... C WRITESEQFL SEQFT2 C WRITESEQFL SEQFT3 ...
File I/O Through Data Structures
Figure 1B Additional output defined in Output Specs
Figure 1b: Additional Output Defined in Output Specs OSEQFL D 1P O 'BEGIN INVOICE' O T LR O 'END INVOICE'
File I/O Through Data Structures
Figure 2A File maintenance using data structure I/O
Figure 2a: File Maintenance Using Data Structure I/O F* VENDOR FILE MAINTENANCE THROUGH DATA STRUCTURE F* FVNDMAST UF F 44 3PI 1 DISK A FVND100D etc. WORKSTN IVNDREC DS I P 1 30VNDNBR I 4 18 VNDNAM I 19 32 VNDCTY I 33 34 VNDSTT I 35 44 VNDZIP ... C VNDNBR CHAINVNDMAST VNDREC 91 ... C WRITEVNDMAST VNDREC ... C UPDATVNDMAST VNDREC ... C DELETVNDMAST
File I/O Through Data Structures
Figure 2B DDS for file VNDMASTDES
Figure 2b: DDS For File VNDMASTDES A* VENDOR MASTER FILE -- FIELD DESCRIPTION A R VNDMASTDES TEXT('VENDOR MASTER') A VNDNBR 5 0 TEXT('VENDOR NUMBER') A VNDNAM 15 TEXT('VENDOR NAME') A VNDCTY 14 TEXT('CITY') A VNDSTT 2 TEXT('STATE') A VNDZIP 10 TEXT('ZIP CODE')
File I/O Through Data Structures
Figure 2C Externally defining VNDMAST
Figure 2c: Externally Defining VNDMAST F* VENDOR FILE MAINTENANCE THROUGH DATA STRUCTURE F* FVNDMAST UF F 44 3PI 1 DISK A FVND100D etc WORKSTN IVNDREC E DSVNDMASTDES ... C VNDNBR CHAINVNDMAST VNDREC 91 ... C WRITEVNDMAST VNDREC ... C UPDATVNDMAST VNDREC ... C DELETVNDMAST ...
File I/O Through Data Structures
Figure 3A DDS for file WORKFL
Figure 3a: DDS For File WORKFL A R WORKFLR TEXT('WORK FILE') A CUSNBR 5S 0 TEXT('CUSTOMER NBR') A CUSNAM 6 TEXT('CUSTOMER NAME') A AMOUNT 9 2 TEXT('DOLLAR AMOUNT') A DUEDAT 6 0 TEXT('DUE DATE -- YYMMDD') A K CUSNAM
File I/O Through Data Structures
Figure 3B Fragment of RPG program
Figure 3b: Fragment of RPG Program FWORKFL O E DISK ... C Z-ADDXTAMT AMOUNT C WRITEWORKFLR ...
File I/O Through Data Structures
Figure 3C Renaming AMOUNT field
Figure 3c: Renaming Amount Field FWORKFL O F 128 DISK IWORKDS E DSWORKFL 128 I AMOUNT AMT ... C Z-ADDXTAMT AMT C WRITEWORKFL WORKDS ...
File I/O Through Data Structures
Figure 3D Adding a field to an external file definition
Figure 3d: Adding a Field to an External File Definition IWORKDS E DSWORKFL 128 I 1 2 TERR
LATEST COMMENTS
MC Press Online