Sending Escape Messages From RPG, Take 2
May 10, 2016 Hey, Ted
In Sending Escape Messages from RPG, your program defines the message data parameter as 80 bytes, but the IBM manual (Send Program Message (QMHSNDPM)) defines the parameter as char(*), with notes saying it can be up to 32767. I would like a variable longer than 80, but instead of coding 100 today, 120 next project, and so on, I’m wondering how I could code it better to take full advantage of the API.
The short answer is that you don’t have to code the length. Let the compiler figure it out for you. Here’s an illustration that may help.
Let’s suppose you use message USR1001 as a general escape message in an application. This message tells which program canceled, tells where it canceled, and gives some idea of what went wrong.
ADDMSGD MSGID(USR1001) MSGF(USRMSG) + MSG('Program &1 canceled. Statement=&2, status=&3.') + SECLVL('See previous messages in the job log for more + information.') SEV(40) + FMT((*CHAR 10) (*UBIN 2) (*CHAR 5))
Notice the FMT parameter in the Add Message Description (ADDMSGD) command. It defines three fields. The first step in using this message is to create a data structure that defines those same fields. You might want to put it in a copybook.
dcl-ds USR1001 qualified inz; Program char(10); Statement uns(5); Status char(5); end-ds;
Create another copybook for a QMHSNDPM prototype.
dcl-pr QMHSNDPM extpgm('QMHSNDPM'); MsgID char(7) const; MsgFile char(20) const; MsgDta char(32767) const options(*varsize); MsgDtaLen int(10) const; MsgType char(10) const; MsgQ char(10) const; MsgQNbr int(10) const; MsgKey char(4); ErrorDs likeds(ErrorDS); end-pr;
As you pointed out, the message data parameter can be up to 32,767 bytes long. Adding OPTIONS(*VARSIZE) allows you to pass character variables of other sizes. This is part of the answer to your question.
Now, to address the rest of your question, here’s a fragmented program with a call to QMHSNDPM.
ctl-opt actgrp(*caller) option(*srcstmt: *nodebugio); /copy copybooks,psds /copy copybooks,qmhsndpm /copy copybooks,errords /copy copybooks,usr1001 dcl-s MsgKey char(4); *inlr = *on; monitor; Msg01RMain (); on-error; USR1001.Statement = 99; USR1001.Status = '99999'; ErrorDS.BytesProvided = *zero; endmon; if USR1001.Statement <> *zero; USR1001.Program = psds.procedure; ErrorDS.BytesProvided = *zero; qmhsndpm ('USR1001': 'USRMSG *LIBL': USR1001: %size(USR1001): '*ESCAPE': '*PGMBDY': 1: MsgKey: ErrorDS ); endif; return; dcl-proc Msg01RMain; dcl-c EOD_SQL const('02000'); // some sql statement here if SQLState > EOD_SQL; USR1001.Statement = 10; USR1001.Status = SqlState; endif; end-proc;
Notice the fourth argument supplied to QMHSNDPM: %SIZE(USR1001). Never do anything the compiler can do for you.
So, to sum it up:
If you do these things, you should have no problem sending escape messages from RPG programs, and your concern about the size of the message data parameter becomes a non-issue.
It’s great that you’re looking for an effective way to use QMHSNDPM. Messaging is a fundamental that every developer should work to master.