


IF COND(&MSGID = ‘CPF3390′) THEN(GOTO +
CMDLBL(STARTPRT))
Start by changing this statement to:
ChkMsg: IF COND(&MSGID = ‘ ′) THEN( return )
When your message handler finds that there is no message ID returned from the RCVMSG command, then your program is done and it can RETURN.
But if your program does get a non-blank message ID, it needs to see if it is CPF3390. Now it can make that test:
IF COND(&MSGID = ‘CPF3390′) THEN(GOTO +
CMDLBL(STARTPRT))
Right after that IF statement, you need to decide what to do about the message that you received. It's not CPF3390 and it wasn't a blank message ID. So what will you do about it? Well, mostly you are probably just going to skip it. That's a perfectly valid thing to do.
But if you skip it, you can't RETURN yet. You haven't received a blank message ID yet, so you haven't run out of messages. There are still other messages on the queue that you need to look at. To do that, you need to run RCVMSG again.
But you can't use the same one that you used before. The first RCVMSG had a message mark that was passed in by the system. You can't use the same message mark because you already received that message. You need to run a RCVMSG command that will get the message after the one that you just got:
NextMsg: Qsys/rcvmsg msgq( &MsgQLib/&MsgQ ) +
msgtype( *NEXT ) +
msgkey( &MsgMrk ) +
wait( &MsgWait ) +
rmv( *NO ) +
keyvar( &NxtKey ) +
msg( &MsgTxt ) +
msgdta( &MsgDta ) +
msgid( &MsgId ) +
sender( &MsgSnd ) +
senderfmt( *SHORT ) +
rtntype( &MsgRtnTyp )
chgvar &MsgMrk &NxtKey
goto ChkMsg
This RCVMSG says to get the msgtype( *NEXT ) message from the queue, i.e., the next one after msgkey( &MsgMrk ). And after you get it, you'll set &MsgMrk to the message key of this next message and go back up to check this next message. You need to replace the message mark in order to keep moving forward through the message queue.
Now, down at STARTPRT is where you will do your work:
STARTPRT: chgvar &JOBDEV %sst( &MsgDta 1 10)
STRPRTWTR DEV(&JOBDEV)
goto NextMsg
You extract the device from the message data, use the device to start your printer writer, then go back up to see if any more messages are on the message queue.
This program runs in a small loop looking at each message until there are no more messages to receive. When it runs out of messages, that's when it returns. After it returns, it won't do anything until a new message arrives on the queue. Then it will get called again and it'll start over.
If it runs out of messages, it RETURNS.
If it gets CPF3390, it starts the writer and then loops to get the next message.
If it gets any message other than CPF3390, it falls through and loops to get the next message.
But the logic is getting a little messy. See if you can put these statements into your existing program and post the changed version. There are a couple minor details that you will probably want to add, and they will make a lot more sense if the whole program is available.
Tom


I’m not really sure what you’re trying to do. But it looks to me like your STRPRTWTR command does not like what you’re giving it for the DEV parameter.
It looks like you’re passing a HEX value? (X’000015E0000000000000′)
I know where I work, we have 10(or less) character names for our writers (I.E. “USERPRT1″)
I’d look into what’s getting passed in the &JOBDEV parameter to your second program.
Dave
Hi Dave, thanks for your help.
I don´t know, the parameters was passed after the job received the new message CPF3390.
When I receive the new message CPF3390 I nedd to get the name of device printer to start a command STRPRTWTR
Is this the PGM statement from program TEST/PRT_GET? If so, where did you see that those should be the parameters? I suspect that they came from looking at the CPF3390 message description.
A break-handling program receives three parameters.
But you have the parameters named &JOBNUM, &JOBNAME and &JOBDEV. The values that will be in those parameters won’t be job number, job name and device.
As you can see in the joblog message, you put a value into &JOBDEV that resulted in DEV(X’000015E0000000000000′). The first four bytes came from the message mark that the system passed into your program — X’000015E0′. The remaining six bytes came from whatever was in memory after that, possibly random values.
If you need the device name, you need to receive the message that caused the break by using the message mark. Something like this:
Qsys/rcvmsg msgq( &MsgQLib/&MsgQ ) + msgkey( &MsgMrk ) + wait( &MsgWait ) + rmv( *NO ) + msg( &MsgTxt ) + msglen( &MSGLEN ) + msgdta( &MsgDta ) + msgdtalen( &MSGDTALEN ) + msgid( &MsgId ) + sender( &MsgSnd ) + senderfmt( *SHORT ) + msgf( &MSGF ) + msgflib( &MSGFLIB ) + rtntype( &MsgRtnTyp )You probably don’t need to receive all of those parameters, but you should familiarize yourself with each of them. If you will be writing message handling programs, you’re going to use them eventually if not in this program.
After receiving the message, you would test &MsgId to see if it was a ‘CPF3390′ message. If it was, you could probably get the device name from the &MsgDta by taking the substring %SST(&MSGDTA 1 10).
You can tell that those are the likely positions by looking at the message description for CPF3390. It shows three fields. The first field is *CHAR (10), and the message text shows that it is used as the ‘job name’ portion of the qualified job name. You could also simply have your test program dump the &MsgDta field so you could study it to figure out where the pieces are.
There may be more to it that you will want to do. You need to decide if you want to remove the message from the queue when you receive it or after you are done with or if you’re going to leave it on the queue. If you don’t remove it, you need to decide what your program might do when it starts the next time and runs across the message again. And you need to decide what to do when a second message shows up on the message queue when you break-handling program is already busy handling a message. And what will you do with messages that aren’t CPF3390?
But first things first — get your parameters defined appropriately and get the device name from the message data. And remove those four CHGVAR statements at the beginning that put values into your &MSGDTA and &MSGID variables. Let the RCVMSG command do that work.
Tom
Check out the STRWCH command. We use it to handle a similar situation in our shop.
Bruce Vining published a good article about STRWCH and included a sample program. Wish I could remember where it is.
Here is the first part of the help text:
The Start Watch (STRWCH) command starts the watch for event
function, which notifies the user by calling a user specified
program when the specified event (a message, a LIC log entry or PAL
entry) occurs. PAL stands for Product Activity Log which shows
errors that have occurred (such as in disk and tape units,
communications, and work stations).
Thanks Wood, but my version is V5R3, I don´t know cause this CL not works. IF COND(&MSGID = 'CPF3390') THEN(GOTO + CMDLBL(STARTPRT)) STARTPRT: STRPRTWTR DEV(PRT_1) MONMSG MSGID(CPF3310 CPA3387) STRPRTWTR DEV(PRT_2) MONMSG MSGID(CPF3310 CPA3387) STRPRTWTR DEV(PRT_3) MONMSG MSGID(CPF3310 CPA3387)IF COND(&MSGID = ‘CPF3390′) THEN(GOTO + CMDLBL(STARTPRT)) STARTPRT: STRPRTWTR DEV(PRT_1)A specific problem with that is that there is no ELSE statement after the IF statement. If it doesn’t GOTO STARTPRT, then it will fall through to STARTPRT. No matter what, when this program receives any message, it’s going to run through STARTPRT.
If there is a problem that happens when the program runs or if the program doesn’t run at all, we need to know what happens. If we don’t know what the problem is, we don’t know how to answer.
Tom
It helps when those asking the original questions show their code and are also willing to clarify when asked. Many problems need a dialog from both sides to work towards a solution. If there is willingness for a dialog, it’s easier to stay with the question until it’s solved. If there are no responses or the responses come days or weeks later, it eventually gets forgotten and lost.
You’re welcome.
Tom