Passing File Names to RPG IV

Article ID: 57094

Passing the name of a file to be used by your RPG program has been around for decades. The typical approach has been to create a parameter (see Qualified Parameters in Tuesday Tips video) to the program and then issue either an OVRDBF command in CL or via QCMDEXC in RPG itself. But since V5R1 of i5/OS (now IBM "i"), IBM has included the EXTFILE keyword. This keyword eliminates most but certainly not all of the reasons we use overrides.

The four most popular reasons to use overrides are:

  • Overriding to a different library name
  • Overriding to a different member name
  • Changing the Sequential Only Processing to SEQONLY(*YES) with a number of records
  • And sadly, setting the level-check to LVLCHK(*NO)

Of these four, the first two no longer require an override. So if you only need to override the library or member name or even the file name itself, you are no longer required to issue an override; RPG IV can handle redirection ("overriding") for you, here's how.

By now you may have read my article on using the EXTFILE and EXTMBR keywords on the File Description specification and know that you can add this keyword to your files to identify, at runtime, the file you want to open. But there's more to it. You can also pass the file name to the program as a parameter and then process that file instead of the one you have declared.

For example, if you have a user-written CL command that accepts a qualified file name, it would contain the following Command Definition statements and probably a few others as well.

 DSPFILE:    CMD        PROMPT('Example QUAL Parm Command')  
             /*  Command processing program is: DSPFILE  */        
             PARM       KWD(FILE) TYPE(MYQUAL) PROMPT('File')     
 MYQUAL:     QUAL       TYPE(*NAME) EXPR(*YES)                    
             QUAL       TYPE(*NAME) DFT(*LIBL) EXPR(*YES) +       
                          PROMPT('Library')                       

This CL command allows the user (who might be an end user or a CL programmer) to specify the file to be used by the associated program. This file is passed to the Command Processing Program (CPP) as a 20-position field. The first 10 bytes contain the file name, and the second 10 bytes contain the library name.

To get this file into your RPG IV program and pass it to the EXTFILE keyword involves a little bit of effort. First you have to set up the parameter in your program. I prefer to use the contemporary style of input parameters over the legacy *ENTRY/PLIST syntax, but either one works. Here's the declaration of the input parameter:

     D DSPFile         PR                  EXTPGM('DSPFILE')
     D  file                         20A
     
     D DSPFile         PI
     D  file                         20A

These statements effectively replace the *ENTRY/PLIST statement of traditional RPG code. Yes, in RPG IV, you have to include both a prototype and the parameter interface statements. I've chosen the simplified declaration here, a 20-position character value. Normally I would be a bit more normalized and use the LIKEDS keyword with a data structure that already has the file and library subfields defined, but I want to simply things as much as possible for this example.

The value from the DSPFILE command is passed in the following format:

Pos-> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
Value f i l e n a m e     l i b r a r y      

Positions 1 to 10 contain the file name; positions 11 to 20 contain the library name. Herein lies the problem --the EXTFILE keyword accepts only 21-position values in a CL-style qualified syntax, for example:

      library/file

The extra byte holds the forward slash qualifier.

To convert this to what the EXTFILE expects, we have to use simple RPG IV manipulation. One way to do this conversion is as follows:

     D myFile          S             21A   

      /free
          myFile = %trimR(%subst(file:11:10)) + '/' +
                   %trimR(%subst(file:1:10));

Now that we have the file back in the format that the end user originally type it in as, we can pass it on to the EXTFILE keyword.

     FCUSTMAST  IF   E           K DISK    EXTFILE(myFile) 

     D DSPFile         PR                  EXTPGM('DSPFILE')
     D  file                         20A
     
     D DSPFile         PI
     D  file                         20A
     
     D myFile          S             21A   

      /free
          myFile = %trimR(%subst(file:11:10)) + '/' +
                   %trimR(%subst(file:1:10));

In this example, I've added the File spec and included the EXTFILE(myFile) keyword. MYFILE is the 21-position character field I've declared down on the D- specs to hold the actual file I want to open.

There's a big problem with this, however. The file CUSTMAST is going to be opened by the RPG cycle before your Calc specs are performed. Consequently, the MYFILE field is going to contain blanks when CUSTMAST is open. Yes this creates a problem.

RPG TnT: 101 Dynamic Tips 'n Techniques with RPG IV  by Bob Cozzi
Bob Cozzi's latest book contains 300 pages with 101 example RPG IV Tips and Techniques for everyday programming, from date calculations, to regular expression searches, to using APIs. Cozzi wrote down every cool technique he's found over the years, updated them, and consolidated them into this great desktop companion -- and it includes full example source code. Order your copy today.

The Solution

To avoid having the CUSTMAST file's open cause a runtime error, you have to include the USROPN (User Controlled Open) keyword. This keyword causes the RPG cycle to skip your file when it goes into its Open-All-Files routine. But it also does what it says, puts the burden of opening the file on you.

So now we have to include the OPEN opcode to open the file. We open the file name specified on the File spec, not the file we've passed to the program, so the following operation will do just fine:

          open CUSTMAST;

The OPEN must occur after you populate the MYFILE field and before you attempt to use the file, so a good place for it would be right after our concatenation routine, as follows:

     FCUSTMAST  IF   E           K DISK    EXTFILE(myFile) 

     D DSPFile         PR                  EXTPGM('DSPFILE')
     D  file                         20A
     
     D DSPFile         PI
     D  file                         20A
     
     D myFile          S             21A   

      /free
          myFile = %trimR(%subst(file:11:10)) + '/' +
                   %trimR(%subst(file:1:10));
          open custmast;
          if %open(custmast);  // Everything worked!!!
             // we are happy.
          endif;

Alternatively, a lot of programmers (myself included) prefer to put these routines inside the *INZSR subroutine. Of course, that doesn't work in the secondary modules of a multi-module program; however, for the main module it works just fine.

A couple of final thoughts on EXTFILE:

  • The field used by EXTFILE must contain a valid qualified file name before the file is open by the program.
  • The file open with EXTFILE is rerouted not overridden. This means the file is open directly and a "hidden override" is not applied. I'm surprised to hear a number of seasoned programmers state that EXTFILE overrides the file -- it does not. To prove this, start a program that opens a file with the EXTFILE keyword. Then interrupt the job and use DSPJOB or WRKJOB and select the Display Overrides menu option. You will not see the file name declared on the File spec's listed in the files that have overrides unless, of course, you also overrode that file for other reasons.
  • Remember to consider the EXTMBR keyword, which does the same thing except for member names. In fact, you can even close your file, change the member name on EXTMBR, and then re-open it to the new member to do multi-member processing. Great for those utility-style applications. One more thing, EXTMBR also accepts *ALL, *FIRST, and *LAST.

 

Bob Cozzi is the author of the popular "RPG TnT: 101 Dynamic Tips 'n Techniques with RPG IV" and is host of RPG World Live, a live 2-hours video podcast for System i Developers and Managers. It is aired live on Friday's from 10:00 AM to Noon central time (15:00 GMT) on ustream.tv and on RPGWorld.com. Bob also produces RPG World, the most popular RPG IV developer conference of the year. Visit RPGWorld.com for details on the dates and location of the 2009 RPG World Conference.

ProVIP Sponsors

ProVIP Sponsors