Wednesday, July 12, 2023

Use new RPG BiFs to see if input parameter was passed

I cannot remember how long ago it was when IBM introduced the %PARMS RPG Built in Function, BiF, that would return the number of parameters were passed to the program. This has been "refined" in IBM i 7.5 TR2 and 7.2 TR8 with two new BiFs:

  • %PASSED:  Returns logical true if the parameter was passed
  • %OMITTED:  Returns logical true if the parameter was omitted

To show how these BiFs work I created a procedure, that contains the new, and a RPG program to call the procedure.

Let me start showing by showing the procedure, Procedure:

01  **free
02  ctl-opt nomain ;

03  dcl-proc Procedure export reqproto(*no) ;
04    dcl-pi *n ;
05      Parm1 char(1) options(*nopass : *omit) ;
06      Parm2 char(1) const options(*nopass : *omit) ;
07      Parm3 char(1) const options(*nopass : *omit) ;
08    end-pi ;

09    if (%parms = 3) ;
10      dsply 'Three parms passed' ;
11    elseif (%parms = 2) ;
12      dsply 'Two parms passed' ;
13    elseif (%parms = 1) ;
14      dsply 'One parm passed' ;
15    else ;
16      dsply 'Zero or too many parms passed' ;
17    endif ;

18    if %passed(Parm1) ;
19      dsply 'Parm1 passed' ;
20    else ;
21      dsply 'Parm1 not passed' ;
22    endif ;

23    if %passed(Parm2) ;
24      dsply 'Parm2 passed' ;
25    else ;
26      dsply 'Parm2 not passed' ;
27    endif ;

28    if %passed(Parm3) ;
29      dsply 'Parm3 passed' ;
30    else ;
31      dsply 'Parm3 not passed' ;
32    endif ;

33    if %omitted(Parm1) ;
34      dsply '*OMIT was passed as Parm1' ;
35    endif ;

36    if %omitted(Parm2) ;
37      dsply '*OMIT was passed as Parm2' ;
38    endif ;

39    if %omitted(Parm3) ;
40      dsply '*OMIT was passed as Parm3' ;
41    endif ;
42  end-proc ;

Line 1: In 2023 it has to be totally free RPG.

Line 2: As this is a member does not contain a main procedure I can use this control option, NOMAIN. I use it in all the members I create "external" procedures in.

Line 3: As I have the REQPROTO(*NO) keyword for this procedure I do not have to give a procedure prototype for it.

Lines 4 – 8: I do need a procedure interface as I am passing parameters to this procedure. Notice that the three parameters have the *OMIT keyword.

Lines 9 – 17: I am using the %PARMS BiF to return the number of parameters passed to the procedure when it was called. I use the RPG Display operation code, DSPLY to display a message about how many parameters were passed.

Lines 18 – 32: I am testing if a parameter was passed using the new %PASSED BiF. If the parameter was passed the Bif returns a logical true (or indicator *on). I have three If statements checking each of the passed parameters and use DSPLY to display a message informing me if it was passed or not.

Lines 33 – 41: In these If statements I am checking if the parameter was omitted using the %OMITTED BiF. If the parameter contains "*OMIT" then it is omitted and the BiF returns a logical true.

I told you that the procedure was simple despite its length.

This source member was compiled to create a module, that will be bound to the RPG program.

The RPG program that calls the procedure is a lot shorter:

01  **free
02  ctl-opt dftactgrp(*no) bnddir('MYBNDDIR') ;

03  dcl-pr Procedure ;
04    *n char(1) options(*nopass : *omit) ;
05    *n char(1) const options(*nopass : *omit) ;
06    *n char(1) const options(*nopass : *omit) ;
07  end-pr ;

08  dcl-s P1 char(10) inz('1') ;

09  dsply 'Test 1' ;
10  Procedure(P1:'2':'3') ;

11  dsply 'Test 2' ;
12  Procedure(P1) ;

13  dsply 'Test 3' ;
14  Procedure(P1:*omit:'3') ;

Line 2: The control option line contains the BNDDIR keyword. This gives the name of the binding directory that will be used to bind service programs and modules to this program when it is created. The binding directory contains just one entry, the module I created above.

Lines 3 – 7: I do need a procedure definition in this program.

Line 8: Here I am defining a variable that will be passed to the procedure. I didn't need to use a variable to call the procedure I just wanted to show that it was possible.

Lines 9 and 10: In the first test I am passing three parameters to the procedure. The procedure displays the following messages:

DSPLY  Test 1
DSPLY  Three parms passed
DSPLY  Parm1 passed
DSPLY  Parm2 passed
DSPLY  Parm3 passed

The first message was from the program.

The second is the result from the %PARM BiF.

The next three messages are from the If statements that used the %PASSED to check if the individual parameters were passed.

Lines 11 and 12: The second test only passed the first parameter. The following messages are displayed:

DSPLY  Test 2
DSPLY  One parm passed
DSPLY  Parm1 passed
DSPLY  Parm2 not passed
DSPLY  Parm3 not passed

The second line shows that %PARMS determined only one parameter was passed.

Checking the parameters with %PASSED confirms that only the first parameter was passed.

Lines 13 and 14: In the third and final test the first and third parameters were passed, and second was omitted by using "*OMIT". Messages returned are:

DSPLY  Test 3
DSPLY  Three parms passed
DSPLY  Parm1 passed
DSPLY  Parm2 not passed
DSPLY  Parm3 passed
DSPLY  *OMIT was passed as Parm2

%PARMS determines that three passed.

%PASSED says the first and third parameters were passed. The second was not passed as it was "*OMIT".

The %OMITTED BiF determined that the second parameter was omitited.

I could give more examples, but the results above are enough to show you how to use these new BiFs. I will be using the %PASSED in my future work.


You can learn more about this from the IBM website:


This article was written for IBM i 7.5 TR2 and 7.4 TR8.

No comments:

Post a Comment

To prevent "comment spam" all comments are moderated.
Learn about this website's comments policy here.

Some people have reported that they cannot post a comment using certain computers and browsers. If this is you feel free to use the Contact Form to send me the comment and I will post it for you, please include the title of the post so I know which one to post the comment to.