1

I'm a beginner learning RPGLE and display files on IBM i. I’ve created a program that displays a message using a message subfile (SFLMSG) when calling a CL program (MSGSFLCL) via a subroutine, and it works fine.

However, when I refactor that subroutine into a procedure, the message no longer shows up in the subfile, even though everything else remains the same.

Here's what I'm doing:

Display File DDS:

A          R MSGSFL                    SFL
A                                      SFLMSGRCD(24)
A            MSGKEY                    SFLMSGKEY
A            PGMQ                      SFLPGMQ

A          R MSGCTL                    SFLCTL(MSGSFL)
A                                      OVERLAY
A                                      SFLDSP
A                                      SFLDSPCTL
A                                      SFLINZ
A N99                                  SFLEND
A                                      SFLSIZ(0010)
A                                      SFLPAG(0001)
A            PGMQ                      SFLPGMQ

CL Program (MSGSFLCL):

PGM        PARM(&MSGID &MSGF &MSGOPT)
DCL        VAR(&MSGID) TYPE(*CHAR) LEN(7)
DCL        VAR(&MSGF) TYPE(*CHAR) LEN(10)
DCL        VAR(&MSGOPT) TYPE(*CHAR) LEN(1)

IF         COND(&MSGOPT *EQ 'I') THEN(SNDPGMMSG +
             MSGID(&MSGID) MSGF(&MSGF) TOPGMQ(*PRV) +
             MSGTYPE(*INFO))

IF         COND(&MSGOPT *EQ 'C') THEN(RMVMSG PGMQ(*PRV (*)) CLEAR(*ALL))
ENDPGM

RPGLE Program:

**free
ctl-opt dftactgrp(*no) actgrp(*new) option(*srcstmt:*nodebugio);

exec sql
    set option commit = *none;

dcl-f Employee Usage(*input) Keyed;
dcl-s RRN packed(4: 0);
dcl-f EMPSFL WorkStn SFILE(SFLDATA: RRN) INFDS(DSPFDS);

dcl-ds MyDs ExtName('EMPLOYEE');
end-ds;

dcl-ds DSPFDS qualified;
  MIN_RRN int(5) pos(378);
end-ds;

dcl-ds  psds  psds;
   PgmName   char(10);
end-ds;

dcl-s MSGID char(7);
dcl-s MSGF char(10) inz('AF_MSGF'); // Message File
dcl-s MSGOPT char(1);

dcl-pr MSGSFLCL extpgm;
    MessageID char(7) const;
    MsgF char(10) const;
    MsgOpt char(1) const;
end-pr;

RCDNBR = 1;
PGMQ = PgmName;
loadPage();

Dou *In03;
    write MSGCTL;
    ExFMT SFLCTL;
    RCDNBR = DSPFDS.MIN_RRN;

    MSGID = 'MSG0001';
    exsr sendMessage;

    if (*IN05 = *ON);
        MSGID = 'MSG0001';
        Exsr clearMsg;
    EndIf;
EndDo;

*INLR = *ON;

begsr sendMessage;
    exsr clearMsg;
    MSGOPT = 'I';
    MSGF = 'AF_MSGF';
    MSGSFLCL(MSGID: MSGF: MSGOPT);
endsr;

dcl-proc loadPage;
    clearPr();
    loadPr();
    write Footer;
end-proc;

dcl-proc clearPr;
    *IN50 = *OFF;
    Write SFLCTL;
    *IN50 = *ON;
    RRN = 0;
End-proc;

dcl-proc loadPr;
    Exec sql
        declare c1 cursor for
        select EMPID, NAME, DEPT, SALARY from employee;

    Exec sql
        open c1;
        
    Exec sql
        fetch c1 into :MyDs;

    Dow (sqlcode = 0);
        RRN = RRN + 1;
        Write SFLDATA;
        Exec sql
            fetch c1 into :MyDs;
    EndDo;
End-proc;

In my RPGLE Program, calling this from a subroutine like this works:

begsr sendMessage;
    exsr clearMsg;
    MSGOPT = 'I';
    MSGF = 'AF_MSGF';
    MSGSFLCL(MSGID: MSGF: MSGOPT);
endsr;

SFL Message Successfully displayed

But calling it from a procedure like this does not display the message:

dcl-proc sendMessage;
    MSGID = 'MSG0001';
    MSGOPT = 'I';
    MSGF = 'AF_MSGF';
    MSGSFLCL(MSGID: MSGF: MSGOPT);
end-proc;

Message is not displayed

I’m calling write MSGCTL; before exfmt SFLCTL, and I’ve also set PGMQ = PgmName; to match the program name.

What could be the reason that the message subfile only works when I use a subroutine but not a procedure?

Any insights are appreciated — thank you!

2 Answers 2

2

Subroutine calls aren't true calls. In other words, when you are in them you're still at the call stack level of the program.

Sub-procedures on the other hand, have their own call stack level.

`SNDPGMMSG TOPGMQ(*PRV)` send to the PGM when the CL is called from the subroutine but to the sub-procedure when the CL is called from the sub-procedure.

You're going to need to adjust TOPGMQ.

See the IBM docs for identifying call stack entry

You might also consider calling the Send Program Message API
You'll have the same issue, but in addition to the Call Stack Entry parameter, there's a Call Stack Counter parameter available for use.

Sign up to request clarification or add additional context in comments.

1 Comment

On your CL program, you could also explicitly state the program queue to send the message to so that no matter how deep you are in the call stack, you can get to the correct program queue. Use TOPGMQ(*SAME program name). But I do use the Send Program Message API when I do this. RPG also has an op code to do this now! I have never used it myself, but it would be easier than using the API.
-1

Already implied but…

Switch to using the 276 byte PGMQ layout. Then you can ensure your messages go to the right procedure MSGQ and your message subfile population will gets it messages from there also.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.