ジョブの一覧表を出力するには
(1)ユーザー・スペースをQTEMPに作成
(2)API: QUSLJOBによってジョブの一覧をユーザー・スペースに出力する
(3)ユーザー・スペースを読んでジョブの一覧を取得すると
というような手段で行うのがこれまで一般的であった。
例えば月次のバッチ・ジョブが活動中であるかどうかを
調べるにはこの方法しかなかった。
しかしこれでは常に数百個以上のジョブが活動している
大規模ユーザーでは結果が出てくるにはかなりの
時間がかかってしまう。
そこでオープン・リストAPI: QGYOJOBL が使えれば
かなりのパフォーマンス良く実行できるのだが
IBM API のKnowledgCenter(マニュアル)はもちろんのこと
海外のサンプル・ソースを見ても意味不明というのが多い。
海外のIBM開発者はAPIのサンプル・ソースを作成したり
紹介するのにどういうわけかRPGでの使用を
紹介したがる傾向にある。
しかも長々としたソース・リストであり
やさしいことを難しく表現するのが大好きなようである。
どうだ、長いステップですごいだろう! と言わんばかりである。
言語と言えばRPGしか知らないのではないかと思える。
CLPソースで紹介すればRPG開発者だけでなくCOBOL開発者でも
理解することができるしAPIの使用はCLP上のほうが
はるかに使用頻度が高い。
日本のユーザーにはCLPで簡単なCLPソースとして
紹介したい。非常に貴重な公開である。
[ジョブ一覧を検索するAPI: QGYOJOBL のサンプルCLPソース ]
ソースはこちらから
0001.00 PGM 0002.00 /*---------------------------------------------------------------------------*/ 0003.00 /* TESTGYOJOB : QGYOLJOB のテスト */ 0004.00 /* */ 0005.00 /* 2022/02/18 作成 */ 0006.00 /* HTTPS://WWW.IBM.COM/DOCS/API/V1/CONTENT/SSW_IBM_I_74/APIS/QGYOLJOB.HTM */ 0007.00 /*---------------------------------------------------------------------------*/ 0008.00 DCL VAR(&MSG) TYPE(*CHAR) LEN(132) 0009.00 DCL VAR(&STMMSG) TYPE(*CHAR) LEN(132) 0010.00 DCL VAR(&MSGID) TYPE(*CHAR) LEN(7) 0011.00 DCL VAR(&MSGF) TYPE(*CHAR) LEN(10) 0012.00 DCL VAR(&MSGFLIB) TYPE(*CHAR) LEN(10) 0013.00 DCL VAR(&MSGKEY) TYPE(*CHAR) LEN(4) 0014.00 DCL VAR(&MSGDTA) TYPE(*CHAR) LEN(132) 0015.00 DCL VAR(&ERRDTA) TYPE(*CHAR) LEN(132) 0016.00 DCL VAR(&TYPE) TYPE(*CHAR) LEN(1) 0017.00 DCL VAR(&TOPGMQ) TYPE(*CHAR) LEN(10) 0018.00 DCL VAR(&MSGTYPE) TYPE(*CHAR) LEN(10) + 0019.00 VALUE('*ESCAPE ') 0020.00 DCL VAR(&APIERR) TYPE(*CHAR) LEN(116) + 0021.00 VALUE(X'000074') /* 2 進数 */ 0022.00 DCL VAR(&ERR) TYPE(*CHAR) LEN(1) 0023.00 DCL VAR(&NULL4) TYPE(*CHAR) LEN(4) + 0024.00 VALUE(X'00000000') 0025.00 /*( QGYOJOBL に必要な変数 )*/ 0026.00 DCL VAR(&JOBL0100) TYPE(*CHAR) LEN(512) 0027.00 DCL VAR(&JBLLEN) TYPE(*CHAR) LEN(4) + 0028.00 VALUE(X'00000200') 0029.00 DCL VAR(&JOBID) TYPE(*CHAR) LEN(16) 0030.00 DCL VAR(&JOBVAR) TYPE(*CHAR) LEN(1024) 0031.00 DCL VAR(&JOBLEN) TYPE(*CHAR) LEN(4) + 0032.00 VALUE(X'00000400') 0033.00 DCL VAR(&NBRRCD) TYPE(*CHAR) LEN(4) + 0034.00 VALUE(X'FFFFFFFF') 0035.00 DCL VAR(&LISTINFO) TYPE(*CHAR) LEN(80) 0036.00 DCL VAR(&LISTSU) TYPE(*CHAR) LEN(4) + 0037.00 VALUE(X'0000000A') 0038.00 DCL VAR(&SORTINF) TYPE(*CHAR) LEN(16) 0039.00 DCL VAR(&SORT) TYPE(*CHAR) LEN(4) + 0040.00 VALUE(X'00000001') 0041.00 DCL VAR(&SELECT) TYPE(*CHAR) LEN(128) 0042.00 DCL VAR(&SELSIZ) TYPE(*CHAR) LEN(4) + 0043.00 VALUE(X'00000080') 0044.00 DCL VAR(&KEYSU) TYPE(*CHAR) LEN(4) + 0045.00 VALUE(X'00000001') 0046.00 DCL VAR(&KEYARY) TYPE(*CHAR) LEN(4) + 0047.00 VALUE(X'000000CA') 0048.00 DCL VAR(&BIN0) TYPE(*CHAR) LEN(4) + 0049.00 VALUE(X'00000000') 0050.00 DCL VAR(&BIN1) TYPE(*CHAR) LEN(4) + 0051.00 VALUE(X'00000001') 0052.00 /*( QGYGTLE に必要な変数 )*/ 0053.00 DCL VAR(&JOB) TYPE(*CHAR) LEN(10) 0054.00 DCL VAR(&USER) TYPE(*CHAR) LEN(10) 0055.00 DCL VAR(&JOBNBR) TYPE(*CHAR) LEN(6) 0056.00 DCL VAR(&N) TYPE(*DEC) LEN(7 0) 0057.00 DCL VAR(&RCVDTA) TYPE(*CHAR) LEN(1024) /* + 0058.00 受取データ */ 0059.00 DCL VAR(&NBRRCDS) TYPE(*CHAR) LEN(4) + 0060.00 VALUE(X'0000000A') /* + 0061.00 受入れレコード数 =1024 */ 0062.00 DCL VAR(&BIN4) TYPE(*CHAR) LEN(4) 0063.00 DCL VAR(&RTNSU) TYPE(*DEC) LEN(5 0) 0064.00 DCL VAR(&RTNSUC) TYPE(*CHAR) LEN(5) 0065.00 DCL VAR(&OBJD) TYPE(*CHAR) LEN(10) 0066.00 DCL VAR(&OBJLIB) TYPE(*CHAR) LEN(10) 0067.00 DCL VAR(&OBJTYP) TYPE(*CHAR) LEN(10) 0068.00 DCL VAR(>EHND) TYPE(*CHAR) LEN(4) 0069.00 DCL VAR(&VARLEN) TYPE(*CHAR) LEN(4) + 0070.00 VALUE(X'00000400') 0071.00 DCL VAR(&STRCNV) TYPE(*CHAR) LEN(4) 0072.00 DCL VAR(&TEXT) TYPE(*CHAR) LEN(50) 0073.00 DCL VAR(&STSBIN) TYPE(*CHAR) LEN(4) 0074.00 DCL VAR(&COUNT) TYPE(*DEC) LEN(5 0) 0075.00 DCL VAR(&COUNTC) TYPE(*CHAR) LEN(5) 0076.00 DCL VAR(&DEVD) TYPE(*CHAR) LEN(10) 0077.00 DCL VAR(&OBJATR) TYPE(*CHAR) LEN(10) 0078.00 MONMSG MSGID(CPF9999) EXEC(GOTO CMDLBL(ERROR)) 0079.00 0080.00 /*( 環境の取得 )*/ 0081.00 RTVJOBA TYPE(&TYPE) 0082.00 IF COND(&TYPE *EQ '0') THEN(DO) /* バッチ */ 0083.00 CHGVAR VAR(&TOPGMQ) VALUE('*SYSOPR ') 0084.00 ENDDO /* バッチ */ 0085.00 ELSE CMD(DO) /* 対話式 */ 0086.00 CHGVAR VAR(&TOPGMQ) VALUE('*TOPGMQ ') 0087.00 ENDDO /* 対話式 */ 0088.00 0089.00 /******************************/ 0090.00 /* すべての JOB の一覧 */ 0091.00 /******************************/ 0092.00 CHGVAR VAR(%SST(&JOBVAR 1 4)) VALUE(&BIN0) 0093.00 CHGVAR VAR(%SST(&LISTINFO 1 4)) VALUE(&LISTSU) 0094.00 CHGVAR VAR(%SST(&SORTINF 1 4)) VALUE(&BIN0) 0095.00 CHGVAR VAR(%SST(&SELECT 1 10)) VALUE('*ALL') 0096.00 CHGVAR VAR(%SST(&SELECT 11 10)) VALUE('*ALL') 0097.00 CHGVAR VAR(%SST(&SELECT 21 6)) VALUE('*ALL') 0098.00 CHGVAR VAR(%SST(&SELECT 27 1)) VALUE('*') 0099.00 /* PRIMARY JOB STATUS */ 0100.00 CHGVAR VAR(%SST(&SELECT 29 4)) VALUE(X'0000003C') 0101.00 CHGVAR VAR(%SST(&SELECT 33 4)) VALUE(X'00000001') 0102.00 CHGVAR VAR(%SST(&SELECT 61 10)) VALUE('*ACTIVE') 0103.00 /* ACTIVE JOB STATUS */ 0104.00 CHGVAR VAR(%SST(&SELECT 37 4)) VALUE(X'00000047') 0105.00 CHGVAR VAR(%SST(&SELECT 41 4)) VALUE(X'00000000') 0106.00 /* JOBS ON JOB QUEUE STATUS */ 0107.00 CHGVAR VAR(%SST(&SELECT 45 4)) VALUE(X'00000047') 0108.00 CHGVAR VAR(%SST(&SELECT 49 4)) VALUE(X'00000000') 0109.00 /* JOBS QUEUE NAME */ 0110.00 CHGVAR VAR(%SST(&SELECT 53 4)) VALUE(X'00000047') 0111.00 CHGVAR VAR(%SST(&SELECT 57 4)) VALUE(X'00000000') 0112.00 CALL PGM(QGYOLJOB) PARM(&JOBL0100 &JBLLEN + 0113.00 'OLJB0100' &JOBVAR &JOBLEN &LISTINFO + 0114.00 &NBRRCD &SORTINF &SELECT &SELSIZ &KEYSU + 0115.00 &KEYARY &APIERR) 0116.00 IF COND(%SST(&APIERR 5 4) *NE &NULL4) THEN(DO) 0117.00 SNDPGMMSG + 0118.00 MSG('API: QGYOJOBL の実行で次のエラーが発生 + 0119.00 しました。 ') MSGTYPE(*DIAG) 0120.00 GOTO APIERR 0121.00 ENDDO 0122.00 IF COND(%SST(&APIERR 5 4) *NE &NULL4) THEN(DO) 0123.00 SNDPGMMSG + 0124.00 MSG('API: QUIDSPH の実行で次のエラーが発生 + 0125.00 しました。 ') MSGTYPE(*DIAG) 0126.00 GOTO APIERR 0127.00 ENDDO 0128.00 0129.00 /*( リスト検索の開始 )*/ 0130.00 CHGVAR VAR(&BIN4) VALUE(%SST(&LISTINFO 1 4)) 0131.00 CHGVAR VAR(&RTNSU) VALUE(%BIN(&BIN4)) 0132.00 IF COND(&RTNSU *EQ 0) THEN(DO) /* + 0133.00 戻り数がない */ 0134.00 SNDPGMMSG MSG(' 活動ジョブがありません。 ') + 0135.00 MSGTYPE(*DIAG) 0136.00 GOTO ENDLIST 0137.00 ENDDO /* 戻り数がない */ 0138.00 0139.00 CHGVAR VAR(&N) VALUE(1) 0140.00 CHGVAR VAR(%BIN(&STRCNV)) VALUE(1) 0141.00 CHGVAR VAR(%BIN(&NBRRCDS)) VALUE(1) 0142.00 CHGVAR VAR(>EHND) VALUE(%SST(&LISTINFO 9 4)) 0143.00 LOOP: CALL PGM(QGYGTLE) PARM(&RCVDTA &VARLEN >EHND + 0144.00 &LISTINFO &NBRRCDS &STRCNV &APIERR) 0145.00 IF COND(%SST(&APIERR 5 4) *NE &NULL4) THEN(DO) 0146.00 SNDPGMMSG + 0147.00 MSG('API: QGYGTLE の実行で次のエラーが発生 + 0148.00 しました。 ') MSGTYPE(*DIAG) 0149.00 GOTO APIERR 0150.00 ENDDO 0151.00 /*( 処理の開始 )*/ 0152.00 CHGVAR VAR(&JOB) VALUE(%SST(&RCVDTA 1 10)) 0153.00 CHGVAR VAR(&USER) VALUE(%SST(&RCVDTA 11 10)) 0154.00 CHGVAR VAR(&JOBNBR) VALUE(%SST(&RCVDTA 21 6)) 0155.00 CHGVAR VAR(&JOBID) VALUE(%SST(&RCVDTA 27 16)) 0156.00 SNDPGMMSG MSG(&JOB *TCAT '/' *CAT &USER *TCAT '/' + 0157.00 *CAT &JOBNBR) MSGTYPE(*DIAG) 0158.00 /*( 処理の終了 )*/ 0159.00 BYPAS: IF COND(&N < &RTNSU) THEN(DO) 0160.00 CHGVAR VAR(&N) VALUE(&N + 1) 0161.00 CHGVAR VAR(%BIN(&STRCNV)) VALUE(%BIN(&STRCNV) + 1) 0162.00 GOTO LOOP 0163.00 ENDDO 0164.00 /*( リストのクローズ )*/ 0165.00 ENDLIST: CALL PGM(QGYCLST) PARM(>EHND &APIERR) 0166.00 RETURN 0167.00 0168.00 APIERR: 0169.00 CHGVAR VAR(&MSGID) VALUE(%SST(&APIERR 9 7)) 0170.00 CHGVAR VAR(&MSGDTA) VALUE(%SST(&APIERR 17 100)) 0171.00 CHGVAR VAR(&MSGF) VALUE('Q' *CAT %SST(&MSGID 1 + 0172.00 3) *CAT 'MSG') 0173.00 CHGVAR VAR(&MSGFLIB) VALUE('QSYS ') 0174.00 GOTO SNDMSG 0175.00 0176.00 ERROR: RCVMSG MSGTYPE(*LAST) RMV(*NO) KEYVAR(&MSGKEY) + 0177.00 MSGDTA(&MSGDTA) MSGID(&MSGID) MSGF(&MSGF) + 0178.00 MSGFLIB(&MSGFLIB) 0179.00 IF COND(&MSGID *EQ 'CPF9999') THEN(DO) 0180.00 CHGVAR VAR(&ERRDTA) VALUE(&MSGDTA) 0181.00 RCVMSG MSGTYPE(*PRV) MSGKEY(&MSGKEY) RMV(*NO) + 0182.00 MSG(&MSG) MSGDTA(&MSGDTA) MSGID(&MSGID) + 0183.00 MSGF(&MSGF) MSGFLIB(&MSGFLIB) 0184.00 CHGVAR VAR(&STMMSG) VALUE(' プログラム ' *CAT + 0185.00 %SST(&ERRDTA 8 10) *TCAT + 0186.00 ' のステートメント ' *CAT %SST(&ERRDTA + 0187.00 24 4) *CAT ' で次のエラーが発生しました。 ') 0188.00 SNDPGMMSG MSGID(CPF9897) MSGF(QCPFMSG) MSGDTA(&STMMSG) + 0189.00 TOMSGQ(&TOPGMQ) MSGTYPE(*DIAG) 0190.00 ENDDO 0191.00 SNDMSG: IF COND(&MSGID *EQ ' ') THEN(DO) 0192.00 SNDPGMMSG MSGID(CPF9897) MSGF(QCPFMSG) MSGDTA(&MSG) + 0193.00 TOMSGQ(&TOPGMQ) MSGTYPE(&MSGTYPE) 0194.00 MONMSG MSGID(CPF2400) EXEC(RETURN) 0195.00 ENDDO 0196.00 ELSE CMD(DO) 0197.00 SNDPGMMSG MSGID(&MSGID) MSGF(&MSGFLIB/&MSGF) + 0198.00 MSGDTA(&MSGDTA) TOMSGQ(&TOPGMQ) + 0199.00 MSGTYPE(&MSGTYPE) 0200.00 MONMSG MSGID(CPF2400) EXEC(RETURN) 0201.00 ENDDO 0202.00 ENDPGM
>h3>[解説]
このわずか202ステップのCLPはジョブの一覧表を超高速で出力するのに優れた
最も最先端の技術である。
0112.00 CALL PGM(QGYOLJOB) PARM(&JOBL0100 &JBLLEN + 0113.00 'OLJB0100' &JOBVAR &JOBLEN &LISTINFO + 0114.00 &NBRRCD &SORTINF &SELECT &SELSIZ &KEYSU + 0115.00 &KEYARY &APIERR)
の部分でCPUメモリー内にジョブ一覧表が作成されて
0142.00 CHGVAR VAR(>EHND) VALUE(%SST(&LISTINFO 9 4))
によってメモリーのハンドルが取得されて
0143.00 LOOP: CALL PGM(QGYGTLE) PARM(&RCVDTA &VARLEN >EHND + 0144.00 &LISTINFO &NBRRCDS &STRCNV &APIERR)
によってすべてのジョブ情報を短時間で読取ることができる。
0155.00 CHGVAR VAR(&JOBID) VALUE(%SST(&RCVDTA 27 16))
によってジョブIDも取得しているのでこのJOBIDによってジョブ情報に高速で
アクセスすることができるようになる。
API: QGYOJOBL の使い方を示す世界で初めてのCLPソースであるはずである。