他のトピックでデータ待ち行列 (*DTAQ) は読取ると同時に
データ待ち行列のデータそのものが消えてしまうことを紹介した。
確かにそのとおりであり、データ待ち行列 (*DTAQ) は
データを読取るとそのデータは消失してしまう。
では *DTAQ にデータが存在しているのか、確認する方法は
ないのだろうか?
ここで CHKDTAQCL という CLP を紹介しよう。
実は *DTAQ を読取るときの 11 番目の任意パラメータ : Remove Message (char(10))
というのがリリース・アップで追加されていて
| *YES : | The message is removed from the data queue. This is the default value if this parameter is not specified |
| *NO : | The message is not removed from the data queue. |
と追加されている。
このパラメータが指定されなければ省略値は *YES であり
メッセージはデータ待ち行列から削除される。
しかし *NO であれば「メッセージは *DTAQ から削除されない」とある。
API : QRCVDTAQ の機能が拡張されているのである。
それを利用したのが次に紹介するサンプル CL : CHKDTAQCL である。
CHKDTAQCL は 指定した *DTAQ にデータがあれば正常に終了するが、
データが何もなければ *ESCAPE メッセージを返す。
上位のプログラムは MONMSG CPF9800 によって結果を監視することができる。
【 サンプル・コマンド : CHKDTAQ 】
0001.00 CMD PROMPT(' データ待ち行列の検査 ')
0002.00 PARM KWD(DTAQ) TYPE(DTAQ) PROMPT(' データ待ち行列 ')
0003.00 DTAQ: QUAL TYPE(*NAME) LEN(10) MIN(1)
0004.00 QUAL TYPE(*NAME) LEN(10) DFT(*LIBL) +
0005.00 SPCVAL((*LIBL) (*CURLIB)) +
0006.00 PROMPT(' ライブラリー ')

【 サンプル CLP : CHKDTAQCL 】
0001.00 PGM PARM(&DTAQQLIB)
0002.00 /*-------------------------------------------------------------------*/
0003.00 /* CHKDTAQCL : *DTAQ のデータの検査 */
0004.00 /* */
0005.00 /* 2017/07/17 作成 */
0006.00 /*-------------------------------------------------------------------*/
0007.00 DCL VAR(&DTAQQLIB) TYPE(*CHAR) LEN(20)
0008.00 DCL VAR(&DTAQ) TYPE(*CHAR) LEN(10)
0009.00 DCL VAR(&DTAQLIB) TYPE(*CHAR) LEN(10)
0010.00 DCL VAR(&MSG) TYPE(*CHAR) LEN(132)
0011.00 DCL VAR(&MSGID) TYPE(*CHAR) LEN(7)
0012.00 DCL VAR(&MSGF) TYPE(*CHAR) LEN(10)
0013.00 DCL VAR(&MSGFLIB) TYPE(*CHAR) LEN(10)
0014.00 DCL VAR(&MSGDTA) TYPE(*CHAR) LEN(132)
0015.00 DCL VAR(&TYPE) TYPE(*CHAR) LEN(1)
0016.00 DCL VAR(&TOPGMQ) TYPE(*CHAR) LEN(10)
0017.00 DCL VAR(&MSGTYPE) TYPE(*CHAR) LEN(10) +
0018.00 VALUE('*ESCAPE ')
0019.00 DCL VAR(&APIERR) TYPE(*CHAR) LEN(116) +
0020.00 VALUE(X'000074') /* 2 進数 */
0021.00 DCL VAR(&NULL4) TYPE(*CHAR) LEN(4) +
0022.00 VALUE(X'00000000')
0023.00 DCL VAR(&WAIT) TYPE(*DEC) LEN(5 0) VALUE(0)
0024.00 DCL VAR(&MSGBUF) TYPE(*CHAR) LEN(4096)
0025.00 DCL VAR(&MSGLEN) TYPE(*DEC) LEN(8 0)
0026.00 DCL VAR(&KEYLEN) TYPE(*DEC) LEN(3 0)
0027.00 DCL VAR(&SENDER) TYPE(*DEC) LEN(3 0)
0028.00 DCL VAR(&DTA_REC) TYPE(*DEC) LEN(5 0)
0029.00 MONMSG MSGID(CPF0000) EXEC(GOTO CMDLBL(ERROR))
0030.00
0031.00 /*( 環境の取得 )*/
0032.00 RTVJOBA TYPE(&TYPE)
0033.00 IF COND(&TYPE *EQ '0') THEN(DO) /* バッチ */
0034.00 CHGVAR VAR(&TOPGMQ) VALUE('*SYSOPR ')
0035.00 ENDDO /* バッチ */
0036.00 ELSE CMD(DO) /* 対話式 */
0037.00 CHGVAR VAR(&TOPGMQ) VALUE('*TOPGMQ ')
0038.00 ENDDO /* 対話式 */
0039.00
0040.00 /*( パラメータの読取り )*/
0041.00 CHGVAR VAR(&DTAQ) VALUE(%SST(&DTAQQLIB 01 10))
0042.00 CHGVAR VAR(&DTAQLIB) VALUE(%SST(&DTAQQLIB 11 10))
0043.00
0044.00 /*( *DTAQ の読取り )*/
0045.00 CHGVAR VAR(&WAIT) VALUE(0) /* 即時読取り */
0046.00 CALL PGM(QRCVDTAQ) PARM(&DTAQ &DTAQLIB &MSGLEN +
0047.00 &MSGBUF &WAIT ' ' &KEYLEN '' &SENDER '' +
0048.00 '*NO ' &DTA_REC &APIERR)
0049.00 IF COND(%SST(&APIERR 5 4) *NE &NULL4) THEN(DO)
0050.00 SNDPGMMSG +
0051.00 MSG('API: QRCVDTAQ の実行で次のエラーが発生 +
0052.00 しました。 ') MSGTYPE(*DIAG)
0053.00 GOTO APIERR
0054.00 ENDDO
0055.00 IF COND(&MSGLEN > 0) THEN(RETURN)
0056.00 ELSE CMD(DO)
0057.00 CHGVAR VAR(&MSGDTA) +
0058.00 VALUE(' データ待ち行列にはデータはありませ +
0059.00 ん。 ')
0060.00 GOTO SNDMSG
0061.00 ENDDO
0062.00 RETURN
0063.00
0064.00 APIERR:
0065.00 CHGVAR VAR(&MSGID) VALUE(%SST(&APIERR 9 7))
0066.00 CHGVAR VAR(&MSGDTA) VALUE(%SST(&APIERR 17 100))
0067.00 CHGVAR VAR(&MSGF) VALUE('QCPFMSG ')
0068.00 CHGVAR VAR(&MSGFLIB) VALUE('QSYS ')
0069.00 GOTO SNDMSG
0070.00
0071.00 ERROR: RCVMSG MSGTYPE(*LAST) RMV(*NO) MSG(&MSG) +
0072.00 MSGDTA(&MSGDTA) MSGID(&MSGID) MSGF(&MSGF) +
0073.00 MSGFLIB(&MSGFLIB)
0074.00 SNDMSG: IF COND(&MSGID *EQ ' ') THEN(DO)
0075.00 SNDPGMMSG MSGID(CPF9897) MSGF(QCPFMSG) MSGDTA(&MSG) +
0076.00 TOMSGQ(&TOPGMQ) MSGTYPE(&MSGTYPE)
0077.00 ENDDO
0078.00 ELSE CMD(DO)
0079.00 SNDPGMMSG MSGID(&MSGID) MSGF(&MSGFLIB/&MSGF) +
0080.00 MSGDTA(&MSGDTA) TOMSGQ(&TOPGMQ) +
0081.00 MSGTYPE(&MSGTYPE)
0082.00 ENDDO
0083.00 ENDPGM

【 解説 】
ポイントは
0046.00 CALL PGM(QRCVDTAQ) PARM(&DTAQ &DTAQLIB &MSGLEN + 0047.00 &MSGBUF &WAIT ' ' &KEYLEN '' &SENDER '' + 0048.00 '*NO ' &DTA_REC &APIERR)
で示されている 11 番目のパラメータに *NO が明示的に指定されていることである。
*DTAQ にデータがあれば MSGLEN は > 0 として返ってくるがメッセージの除去が
*NO として指定されているのでデータが *DTAQ から除去されることはない。
データがない場合は MSGLEN = 0 で戻るので CPF9887 の *ESCAPE メッセージが
呼び出し元のプログラムに戻る。
