CLP に組み込むメッセージ送信は SNDPGMMSG であるが
メッセージのタイプには *INFO, *DIAG, *ESCAPE, ... など
種類があるが、どのように使い分ければよいのだろうか?
| *INFO |
通知メッセージ。 主に QSYSOPR(*SYSOPR) などに通知するために使用される。自分自身へのメッセージを *INFO で送信してもDSPMSG で表示しないとメッセージは表示されない。SNDMSG でメッセージ送信したのと同じことである。従って CLP で QSYSOPR に送信するときは *INFO でもよいが自分自身(実行したジョブ)へのメッセージ送信には使用しない。 |
|---|---|
| *DIAG |
*DIAG とは DIALOG, つまり直訳すると「日記」の意味であり結果の通知となりメッセージが表示として残ることになる。 メニューやプログラムの実行直後に「XXXを実行しました」などの メッセージが最後に出力されているのは *DIAG メッセージである。従って自分自身への結果の報告のために出力するメッセージ・タイプ として最も多く利用されている。 |
| *ESCAPE |
ESCAPE とは直訳すると「脱出」や「非難」、「抜け出す」などの 意味であるがエラーが発生して実行中の処理から抜け出すのに 利用される。 上位のプログラムは *ESCAPE メッセージを受け取ると MONMSG していないと異常終了となる。従って CLP の中でもエラーを報告するのであれば *DIAG や*INFO ではなく、*ESCAPE で出力するようにしておくべきである。逆に何かチェックする CLP プログラムを作って *ESCAPE で結果を出力するようにしておくと上位のプログラムは MONMSG で *ESCAPE を判断することができる。 |
次は弊社で CLP を作成するときのテンプレートとしている CLP ソースであり
基本的に CLP は、この CLP ソースを元に開発されている。
CLP はバッチ環境で実行されれば結果のメッセージは
QSYSOPR に報告されるように作成されており、
対話式環境であれば自分自身 (*TOPGMQ) に報告されるように設計されている。
0001.00 PGM
0002.00 /*-------------------------------------------------------------------*/
0003.00 /* AA_SAMPLE : テンプレート・サンプル CLP */
0004.00 /* */
0005.00 /* 2017/02/01 作成 */
0006.00 /*-------------------------------------------------------------------*/
0007.00 DCL VAR(&MSG) TYPE(*CHAR) LEN(132)
0008.00 DCL VAR(&MSGID) TYPE(*CHAR) LEN(7)
0009.00 DCL VAR(&MSGF) TYPE(*CHAR) LEN(10)
0010.00 DCL VAR(&MSGFLIB) TYPE(*CHAR) LEN(10)
0011.00 DCL VAR(&MSGDTA) TYPE(*CHAR) LEN(132)
0012.00 DCL VAR(&TYPE) TYPE(*CHAR) LEN(1)
0013.00 DCL VAR(&TOPGMQ) TYPE(*CHAR) LEN(10)
0014.00 DCL VAR(&MSGTYPE) TYPE(*CHAR) LEN(10) +
0015.00 VALUE('*ESCAPE ')
0016.00 DCL VAR(&APIERR) TYPE(*CHAR) LEN(116) +
0017.00 VALUE(X'000074') /* 2 進数 */
0018.00 DCL VAR(&NULL4) TYPE(*CHAR) LEN(4) +
0019.00 VALUE(X'00000000')
0020.00 MONMSG MSGID(CPF0000) EXEC(GOTO CMDLBL(ERROR))
0021.00
0022.00 /*( 環境の取得 )*/
0023.00 RTVJOBA TYPE(&TYPE)
0024.00 IF COND(&TYPE *EQ '0') THEN(DO) /* バッチ */
0025.00 CHGVAR VAR(&TOPGMQ) VALUE('*SYSOPR ')
0026.00 ENDDO /* バッチ */
0027.00 ELSE CMD(DO) /* 対話式 */
0028.00 CHGVAR VAR(&TOPGMQ) VALUE('*TOPGMQ ')
0029.00 ENDDO /* 対話式 */
0030.00
0031.00 IF COND(%SST(&APIERR 5 4) *NE &NULL4) THEN(DO)
0032.00 SNDPGMMSG +
0033.00 MSG('API: QUHDSPH の実行で次のエラーが発生 +
0034.00 しました。 ') MSGTYPE(*DIAG)
0035.00 GOTO APIERR
0036.00 ENDDO
0037.00 RETURN
0038.00
0039.00 APIERR:
0040.00 CHGVAR VAR(&MSGID) VALUE(%SST(&APIERR 9 7))
0041.00 CHGVAR VAR(&MSGDTA) VALUE(%SST(&APIERR 17 100))
0042.00 CHGVAR VAR(&MSGF) VALUE('QCPFMSG ')
0043.00 CHGVAR VAR(&MSGFLIB) VALUE('QSYS ')
0044.00 GOTO SNDMSG
0045.00
0046.00 ERROR: RCVMSG MSGTYPE(*LAST) RMV(*NO) MSG(&MSG) +
0047.00 MSGDTA(&MSGDTA) MSGID(&MSGID) MSGF(&MSGF) +
0048.00 MSGFLIB(&MSGFLIB)
0049.00 SNDMSG: IF COND(&MSGID *EQ ' ') THEN(DO)
0050.00 SNDPGMMSG MSGID(CPF9897) MSGF(QCPFMSG) MSGDTA(&MSG) +
0051.00 TOMSGQ(&TOPGMQ) MSGTYPE(&MSGTYPE)
0052.00 ENDDO
0053.00 ELSE CMD(DO)
0054.00 SNDPGMMSG MSGID(&MSGID) MSGF(&MSGFLIB/&MSGF) +
0055.00 MSGDTA(&MSGDTA) TOMSGQ(&TOPGMQ) +
0056.00 MSGTYPE(&MSGTYPE)
0057.00 ENDDO
0058.00 ENDPGM
この CLP はテンプレートなので、これをそのまま動作させることはできない。
「環境の取得」では、このCLPが対話式環境で実行されているのか、
それともバッチ式環境で実行されているのかを検出して
&TOPGMQ : どこにメッセージ報告すべきかを決定している。
メッセージ・タイプは、始めは
0014.00 DCL VAR(&MSGTYPE) TYPE(*CHAR) LEN(10) +
0015.00 VALUE('*ESCAPE ')
として *ESCAPE として設定されているが、
内部で RPG/COBOL などを実行して &MSG を
完了メッセージとして受け取ったのであれば
CHGVAR &MSGTYPE VALUE('*DIAG ')
GOTO SNDMSG
とすればメッセージ &MSG を報告メッセージとして出力することができる。
APIERR の部分は
DCL VAR(&APIERR) TYPE(*CHAR) LEN(116) +
VALUE(X'000074') /* 2 進数 */
:
CALL PGM(QSYSETPT) PARM(&PROFTOKN &APIERR)
IF COND(%SST(&APIERR 5 4) *NE &NULL4) THEN(DO) +
/* APIERR */
SNDPGMMSG +
MSG('API:QSYSETPT の実行でエラーが発生しま +
した。 ') TOMSGQ(&TOPGMQ) MSGTYPE(*DIAG)
GOTO APIERR
ENDDO /* APIERR */
のようにして何かの API を実行したときに APIERR に飛ばせば
APIERR の内容を取り出して報告してくれる仕組みとなっている。
この CLP: AA_SAMPLE は、いつか読者に紹介しようと思っていたが
CLP のベースとしてあらゆる条件が加味されているので是非活用されたい。