Wednesday, July 16, 2014

How to cope with missing parameters in CL

clp clle parm missing parameter

When programming in RPGLE it is possible not to pass all the parameters between programs or procedures, using *OMIT in the calling code and %PARMS in the called code. The same functionality is not available in CL.

I needed to make a modification to an existing CL program, which is called from many other programs. If it was called from one program I needed to pass a parameter to it, if it was called by the others I did not need to use the parameter as a default value is used. I needed to make this quickly, before today’s night run. It would take too long to:

  • Identify all the programs that call the program I need to modify.
  • Change all the programs.
  • Have all the programs tested by the IT tester.
  • Prepare and stage them all for the move into production.
  • Find an authorized person to move them all into production.

Was there a way I could just modify the two programs, the one calling program with the parameter and the called program, in a way that if the called program was called without the parameter it would not error? That way only two objects would need to be modified, tested, staged, and deployed, and I could be done in time.

The error MCH3601 occurs if you call a program passing no or too few parameters. Therefore, if I could monitor for that message I could know if the parameter was passed. I also found that you cannot use the "passed" variable unless it was used when the program was called.

With this in mind I can create a program that looks like:

01  PGM        PARM(&P_FLD)
 
02  DCL        VAR(&P_FLD) TYPE(*CHAR) LEN(10)
03  DCL        VAR(&FLD) TYPE(*CHAR) LEN(10)

04  CHGVAR     VAR(&FLD) VALUE(&P_FLD)
05  MONMSG     MSGID(MCH3601) +
                 EXEC(CHGVAR VAR(&FLD) VALUE('Default'))

I have defined two variables, &P_FLD and &FLD, which are defined identically. &P_FLD is the passed parameter. On line 4 I try to move the value in &P_FLD to &FLD. If a value was passed this line executes without error. If no value was passed the line errors, which is caught by the monitor message on line 5, and the default value is moved to &FLD.

 

This article was written for IBM i 7.1, and it should work with earlier releases too.

7 comments:

  1. you could compare the pointer of parm with NULL

    ReplyDelete
    Replies
    1. I created the following CL program just like the one in the post, but with a check for null in place of the MONMSG.
      (I know the comments section is going to mess up the formatting)

      PGM PARM(&P_FLD)

      DCL VAR(&P_FLD) TYPE(*CHAR) LEN(10)
      DCL VAR(&FLD) TYPE(*CHAR) LEN(10)

      IF COND(&P_FLD = *NULL) +
      THEN(CHGVAR VAR(&FLD) VALUE('Default'))
      ELSE CMD(CHGVAR VAR(&FLD) VALUE(&P_FLD))

      ENDPGM

      Alas, when called without a parameter I receive a MCH3601 message for the line where I check if it is null.

      Delete
    2. You should learn how to use pointers look for OPTIONS(*NOPASS/*STRING/*OMIT) on PROTOTYPES RPGLE to get basics

      PGM (&C1)

      dcl &c1 *char 10
      dcl &c2 *char 10 'EMPTY'
      IF (%ADDRESS(&C1) *NE *NULL) +
      chgvar &c2 c1

      sndusrmsg &c2

      ENDPGM

      Delete
    3. Thanks Markus that works.

      PGM PARM(&P_FLD)

      DCL VAR(&P_FLD) TYPE(*CHAR) LEN(10)
      DCL VAR(&FLD) TYPE(*CHAR) LEN(10)

      IF COND(%ADDRESS(&P_FLD) = *NULL) +
      THEN(CHGVAR VAR(&FLD) VALUE('Default'))
      ELSE CMD(CHGVAR VAR(&FLD) VALUE(&P_FLD))

      ENDPGM

      Delete
  2. Jorge Julio Agüero BenaventeJuly 16, 2014 at 11:28 AM

    mandalo en blanco el parametro.

    ReplyDelete
    Replies
    1. Pero yo habría tenido que cambiar todos los programas que llaman a este programa. De esta manera no tenía que hacerlo.

      Delete
  3. I achieved this another way which was to create an RPG pro to accept one optional parameter and return a Boolean if the parameter was passed. That way my cl program can call the RPG program to determine if the pointer to the parameter is null. The cl doesn't seem to crash if it's just passing the parameter on to another program. It's more work the first time but once you have the RPG program you can use it in more than one cl program. It doesn't matter if the variable is the same type if you are only checking the %addr

    ReplyDelete

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.