4

I have a PGMA(RPGLE) which is called from PGMB(CL) and PGMC(CL). PGMB calls PGMA with 2 parms while PGMC calls PGMA with 3 parms.

How do I deal with this in PGMA. I tried options(*Nopass) for the third parm(which is optional) but that is only for procedures I guess. I cannot put this option in PLIST of *entry in PGMA.

AS400 User
  • 187
  • 2
  • 14

2 Answers2

4

Options(*nopass) works for both programs and procedures. I tend to replace *ENTRY PLIST with dcl-pi, but You can make parameters optional even when using PLIST.

So best way:

ctl-opt Main(MyProgram);

...

dcl-proc MyProgram;
  dcl-pi *n ExtPgm('MYPROGRAM');
    parm1     Char(10);
    parm2     Char(10);
    optparm   Char(10) options(*nopass);
  end-pi;

  ...

  // to process optional parm
  if %parms() >= %parmnum(optparm);
    // do something with optparm;
  endif;

end-proc;

Without linear main spec you would just add the PI to the main body of the program like this:

dcl-pi MyProgram ExtPgm('MYPROGRAM');
  parm1     Char(10);
  parm2     Char(10);
  optparm   Char(10) options(*nopass);
end-pi;

  ...

// to process optional parm
if %parms() >= %parmnum(optparm);
  // do something with optparm;
endif;

Here is a v5 version

 d MyProgram       pr                  ExtPgm('MYPROGRAM')
 d  parm1                        10a        
 d  parm2                        10a   
 d  optparm                      10a   options(*nopass)
 d
 d MyProgram       pi                 
 d  parm1                        10a        
 d  parm2                        10a   
 d  optparm                      10a   options(*nopass)
  *
  /free
   if %parms() >= 3;
     // do something with optparm
   endif;

But it even works if you are using PLIST, but in that case you cannot include entries in factor 1 or 2. This is only allowed in fixed format programs, and I typically do not write new fixed format code without extenuating circumstances, so I would classify this as a last resort option.

 C     *Entry        PLIST
 C     input1        PARM                    parm1
 C     input2        PARM                    parm2
 C                   PARM                    optparm
 C*
 C                   if        %parms() >= 3
 C*        do something with optparm
 C                   endif

Note: I did not add any prototypes to my free format procedure interface examples as they are no longer required. However, if your program could be called by another RPG IV program or procedure, it is best to create a copy book to contain that prototype, and include it in the original program, and any calling program. This ensures that the prototype matches the caller.

In all these cases, it is important to understand that you cannot use a parameter that is not passed. Thus at the beginning of a program I will test all optional parms with the if %parms() >= ... structure and if the parm has been passed, I move it into a variable that I have defined in the program. If it does not exist, I default a value. The fixed format example above works for all versions of RPG IV since v3r2/v3r6. If your version of RPG does not have the %parms() built-in, you can use the field in the Program Status Data Structure to determine the number of parameters. This is really going back to the past as %parms() was introduced in the second release of RPG IV in the mid 1990's.

jmarkmurphy
  • 11,030
  • 31
  • 59
  • optional parms generate a mch error when not passed. You can pass wilth plist if you handle the error. – danny117 May 04 '17 at 16:25
  • @danny117 That is only true if you try to do something with the parm that wasn't passed. This is the reason for `if %parms() >= %parmnum(optparm)` – jmarkmurphy May 04 '17 at 16:39
  • Code that in a CLP. On version 5 ? – danny117 May 04 '17 at 16:41
  • Yes, this works when called from a CLP in v5. There are some caveats though, v5 only supports free form C specs, so you either have to use the `*ENTRY PLIST` or define the prototype and procedure interface in D specs. – jmarkmurphy May 04 '17 at 16:54
2

All parameters are automatically optional when using *ENTRY PLIST.

Barbara Morris
  • 3,195
  • 8
  • 10