Perhaps you felt cheated the last time you looked at a job log. One program produced incorrect results, so you decided to look at the job log. At one point, a CL program called another program. You hoped to catch the value of an important parameter, but all you got from the job log was something like Figure 1.
Thats not very helpful, is it? The job log does not reveal any of the parameters. By the same token, the job log doesnt show the values of variables in CHGVARs or IFs; in fact, the job log doesnt record such statements at all. The only way to force a variable to appear in a job log is to run a command that uses the variableany command other than CALL, CHGVAR, or IF. And CL comments dont show up either.
Thats why I decided to create a command that, to put it bluntly, does nothing. Its main purpose is to force the job log to display variable data. As youll see in Figure 2, however, this nothing is highly valuable. What I did was code a COMMENT command immediately before the CALL. The COMMENT command looked like this: When the system reaches the COMMENT command, it evaluates the variable and resolves the TEXT parameter by concatenating its components.
The COMMENT Command
COMMENT (Figure 3) has two parameters. The first parameter, TEXT, is where you enter whatever you want to write into the job log. You can enter up to 512 characters of text, and you can use any combination of literals, variables, %SST expressions, and concatenations you want. The only limitation is imposed by the maximum length of 512 characters.
The second parameter tells COMMENT what to do with the resulting text. By default, it does nothing with it besides writing it to the job log. But you can force COMMENT to send that text as a message: *STATUS so it appears as a status message,
COMMENT TEXT(Parameter = *BCAT &DATA) MSGOPT(*NONE)
*USER to send the text as a message to the user running the job, *WRKSTN to send it to
the workstation, or *SYSOPR to send it to the system operator, QSYSOPR.
At first, I wrote COMMENT with only one parameter, TEXT. It was simple, and the command processing program (CPP) was simple indeed (Figure 4) because it contained no executable statements. In fact, it had only the PGM and ENDPGM statements and a DCL for the TEXT parameter. To accommodate the MSGOPT parameter, however, I had to insert code, which you can see in Figure 4.
If you select MSGOPT(*STATUS), the program sends the text as a *STATUS message to *EXT (the jobs external program message queue). If the job is running interactively, that message appears at the bottom of the screen, in high intensity.
If you select *USER, the program gets the name of the current user by running the Retrieve Job Attributes (RTVJOBA) command and then runs the Send Message (SNDMSG) command to send the message to the current users message queue. The user can then look at the message with the Display Message (DSPMSG) command.
The value *WRKSTN works a bit differently. RTVJOBA gets the name of the current workstation as the job name and then uses SNDMSG to send the message to that particular message queue. Batch jobs, however, have no workstation attached, so SNDMSG fails; in that case, the message is sent to QSYSOPR.
*SYSOPR directs the message straight to QSYSOPR. Of course, if you selected *NONE, none of the conditions in the IF statements are satisfied, so no messages are sent anywhere.
Other Uses
Using COMMENT is very safe because you can write anything you want to the job log without executing any commands that do anything at all. But writing to the job log is not the only purpose of COMMENT, although it is an important one. You can also use it to alert users when a program reaches an important part of your program, taking advantage of the various do something options of the MSGOPT parameter. Finally, you can also use COMMENT instead of the normal comments you use in your CL programs, so you dont have to mess with /* and */ symbols.
Display All Messages
System: MCRISC
Job . . : QPADEV0008 User . . : MALAGA Number . . . : 043011
> call x
600 - CALL PGM(XXX) /* The CALL command contains parameters */
- RETURN /* RETURN due to end of CL program */
- RETURN /* RETURN due to end of CL program */
> dspjoblog
Bottom
Press Enter to continue.
F3= Exit F5=Refresh F12=Cancel F17=Top F18=Bottom
Display All Messages
System: MCRISC
Job . . : QPADEV0008 User . . : MALAGA Number . . . : 043011
> call x
500 - COMMENT TEXT(Parameter = HERVE) MSGOPT(*NONE)
Figure 1: Typical, unhelpful job log
5700 - RETURN
600 - CALL PGM(XXX) /* The CALL command contains parameters */
- RETURN /* RETURN due to end of CL program */
- RETURN /* RETURN due to end of CL program */
> dspjoblog
Bottom
Press Enter to continue.
F3= Exit F5=Refresh F12=Cancel F17=Top F18=Bottom /*===================================================================*/
/* To compile: */
/* */
/* CRTCMD CMD(XXX/COMMENT) PGM(XXX/COM001CL) + */
/* SRCFILE(XXX/QCMDSRC) TEXT(CL Program + */
/* Comment) */
/* */
/*===================================================================*/
CMD PROMPT(CL Program Comment)
PARM KWD(TEXT) TYPE(*CHAR) LEN(512) EXPR(*YES) +
PROMPT(Comment text)
PARM KWD(MSGOPT) TYPE(*CHAR) LEN(7) RSTD(*YES) +
DFT(*NONE) VALUES(*NONE *STATUS *USER +
*WRKSTN *SYSOPR) PROMPT(Message option) /*===================================================================*/
/* To compile: */
/* */
/* CRTCLPGM PGM(XXX/COM001CL) SRCFILE(XXX/QCLSRC) + */
/* TEXT(CPP for COMMENT command) */
/* */
/* Prerequisite: */
/* */
/* Utility command FWDPGMMSG. */
/* */
/*===================================================================*/
PGM PARM(&TEXT &MSGOPT)
DCL VAR(&MSGOPT) TYPE(*CHAR) LEN(7)
DCL VAR(&TEXT) TYPE(*CHAR) LEN(512)
DCL VAR(&USER) TYPE(*CHAR) LEN(10)
DCL VAR(&WRKSTN) TYPE(*CHAR) LEN(10)
MONMSG MSGID(CPF0000 MCH0000) EXEC(GOTO CMDLBL(ERROR))
/* Send as a status message */
IF COND(&MSGOPT *EQ *STATUS) THEN(DO)
SNDPGMMSG MSGID(CPF9897) MSGF(QCPFMSG) MSGDTA(&TEXT) +
TOPGMQ(*EXT) MSGTYPE(*STATUS)
ENDDO
/* Send message to user profile */
ELSE CMD(IF COND(&MSGOPT *EQ *USER) THEN(DO))
RTVJOBA USER(&USER)
SNDMSG MSG(&TEXT) TOUSR(&USER) MSGTYPE(*INFO)
ENDDO
/* Send message to workstation */
ELSE CMD(IF COND(&MSGOPT *EQ *WRKSTN) THEN(DO))
RTVJOBA JOB(&WRKSTN)
SNDMSG MSG(&TEXT) TOMSGQ(&WRKSTN) MSGTYPE(*INFO)
/* If message queue not found, send to QSYSOPR */
MONMSG MSGID(CPF0000) EXEC(DO)
SNDMSG MSG(&TEXT) TOUSR(*SYSOPR) MSGTYPE(*INFO)
ENDDO
ENDDO
/* Send message to QSYSOPR */
ELSE CMD(IF COND(&MSGOPT *EQ *SYSOPR) THEN(DO))
Figure 2: Job log augmented with a COMMENT
Figure 3: Command COMMENT
SNDMSG MSG(&TEXT) TOUSR(*SYSOPR) MSGTYPE(*INFO)
ENDDO
RETURN
ERROR:
FWDPGMMSG
MONMSG MSGID(CPF0000)
ENDPGM
LATEST COMMENTS
MC Press Online