QUSLOBJ
も使用頻度の高い API であり、オブジェクトの一覧をユーザー・スペースに
出力して、それを検索して解析したり別の一覧表に出力するような目的のために使用される。
API の結果の出力方法は QUSROBJD
で紹介したレシーバー変数に出力する場合と
結果の項目が複数個ある場合は、この QUSLOBJ
のようにユーザー・スペースに
出力する方法に分かれる。
必須パラメータ・グループ:
1. | ユーザー・スペース修飾名 | 入力 | Char(20) |
2. | 形式名 | 入力 | Char(8) |
3. | オブジェクト修飾名 | 入力 | Binary(4) |
4. | オブジェクト・タイプ | 入力 | Char(10) の配列(*) |
任意選択パラメータ:
5. | エラー・コード | 入出力 | Char(*) |
任意選択パラメータ:
6. | 権限制御 | 入力 | Char(*) |
7. | 選択制御 | 入力 | Char(*) |
結果の内容を受け取るためのユーザー・スペース ( *USRSPC
) は QUSLOBJ
を実行する前には
予め作成して準備しておかなければならない。
後で示すサンプル・ソースには、この作業も含めてある。
形式名 は、
OBJL0100 形式 | ・・・・・・ | オブジェクト名(最高速) |
OBJL0200 形式 | ・・・・・・ | テキスト記述および拡張属性 |
OBJL0300 形式 | ・・・・・・ | 基本オブジェクト情報 |
OBJL0400 形式 | ・・・・・・ | 作成情報 |
OBJL0500 形式 | ・・・・・・ | 保管および復元情報 |
OBJL0600 形式 | ・・・・・・ | 使用状況情報 |
OBJL0700 形式 | ・・・・・・ | すべてのオブジェクト情報(最低速) |
形式によって受け取る情報の詳細は後述する。
オブジェクト修飾名 は ( オブジェクト名 ) + ( ライブラリー名 ) であるが、次の特殊値を
指定することができる。
*ALL | ・・・・・・ | すべてのライブラリー |
*ALLUSR | ・・・・・・ | すべてのユーザー・ライブラリー ( ユーザー・ライブラリーとは 名前が Q で始まっていないライブラリーであり、 #CGULIB, #RPGLIB, #COBLIB, #SDALIB, #DFULIB, #SEULIB, #DSULIB を除く。) |
*CURLIB | ・・・・・・ | ジョブの現行ライブラリー |
*LIBL | ・・・・・・ | ライブラリー・リスト |
*USRLIBL | ・・・・・・ | ジョブのライブラリー・リストのユーザー部分だけ |
オブジェクト・タイプ は、特定のオブジェクト・タイプ または *ALL
を指定する。
権限制御 と 選択制御 はあまり指定することがないので必要があれば IBM API 解説書を参照のこと。
最初にユーザー・スペースを作成するために ユーザー・スペースの作成 API である QUSCRTUS
を紹介する。
必須パラメータ・グループ:
1. | ユーザー・スペース修飾名 | 入力 | Char(20) |
2. | 拡張属性 | 入力 | Char(10) |
3. | 初期サイズ | 入力 | Binary(4) |
4. | 初期値 | 入力 | Char(1) |
5. | 共通権限 | 入力 | Char(10) |
6. | テキスト記述 | 入力 | Char(20) |
任意選択パラメータ:
7. | 置換 | 入力 | Char(10) |
8. | エラー・コード | 入出力 | Char(*) |
ユーザー・スペース修飾名 は例えば、「 USRSPC QTEMP
」 などのように任意の名前をつけて
QTEMP に作成することが多い。
拡張属性 は、ユーザー・スペースの拡張属性であり使用するユーザーが識別できるものでよい。
例えば、PF
, LF
, DSPF
または SAVF
などでよい。
初期サイズは最初にユーザー・スペースを作成するサイズ ( バイト数 ) であるが 1000 バイトあたりに
定義しておけば不測の場合は自動的に OS によって拡張される。
初期値 は最初にユーザー・スペースに埋め込む 1 バイトの Char である。NULL かまたはブランクでよい。
共通権限 は AUT
であるので通常は *ALL
として作成しておけばよい。
テキスト記述 は文字通りこのユーザー・スペースのテキストである。
置換 は任意選択とはなっているが必須であろう。
*YES
として指定しておけば QUSCRTUS
は、作成するユーザー・スペースが存在していても
エラーを発生することなく上書きで作成してくれる便利な機能である。
従って置換には必ず *YES
を指定して作成することが肝要である。
QUSCRTUS
の実行例は次のとおりである。
/*( ユーザー・スペースの作成 )*/ CALL PGM(QUSCRTUS) PARM('LIBSPC QTEMP ' + 'PF ' 1000 ' ' '*ALL ' + 'QUSLOBJ 用ユーザー・スペース ' + '*YES ' &APIERR) IF COND(%SST(&APIERR 5 4) *NE &NULL4) THEN(DO) GOTO APIERR ENDDO
次に API : QUSLOBJ
によって *ALLUSR
のライブラリー一覧を ユーザー・スペースに出力する。
QUSLOBJ
の実行自体は次のように簡単である。
/*( QUSLOBJ の実行 )*/ CALL PGM(QUSLOBJ) PARM('LIBSPC QTEMP ' + 'OBJL0100' '*ALLUSR *ALL ' + '*LIB ' &APIERR) IF COND(%SST(&APIERR 5 4) *NE &NULL4) THEN(DO) GOTO APIERR ENDDO
結果の ユーザー・スペースの読み取りは API : QUSRTVUS
によって検索する。
API : QUSRTVUS
もユーザー・スペースを検索するために良く使う API であり
使用方法はどのような場合でも全く同じである。
必須パラメータ・グループ:
1. | ユーザー・スペース修飾名 | 入力 | Char(20) |
2. | 開始位置 | 入力 | Birary(4) |
3. | データの長さ | 入力 | Binary(4) |
4. | レシーバー変数 | 出力 | Char(*) |
任意選択パラメータ:
5. | エラー・コード | 入出力 | Char(*) |
ユーザー・スペースの構造はすべて同じであり、最初のヘッダー部分にレコード数と 1 レコードの長さが
登録されている。従って 最初にヘッダー部分を読んで最初のデータの開始位置と
レコードの長さを取得してから 項目数の分だけ LOOP してデータを読み取ればよい。
/*(3) QUSRTVUS によるユーザー・スペースの検索 */ /*( リストデータ・セクションのオフセット値を検索 )*/ CALL PGM(QUSRTVUS) PARM('LIBSPC QTEMP ' + &STRPOS &LENDTA &RCVVAR) CHGVAR VAR(&OFFSET) VALUE(%SST(&RCVVAR 1 4)) CHGVAR VAR(&NOENTR) VALUE(%SST(&RCVVAR 9 4)) CHGVAR VAR(&LSTSIZ) VALUE(%SST(&RCVVAR 13 4)) /*( RCVVAR によって OFFSET,LSTSIZ を受取った )*/ CHGVAR VAR(&STRPOS) VALUE(&OFFSET) CHGVAR VAR(&DEC08) VALUE(%BIN(&STRPOS)) CHGVAR VAR(&DEC08) VALUE(&DEC08 + 1) CHGVAR VAR(%BIN(&STRPOS)) VALUE(&DEC08) CHGVAR VAR(&LENDTA) VALUE(&LSTSIZ) CHGVAR VAR(&ADDLEN) VALUE(%BIN(&LENDTA)) CHGVAR VAR(&NOENT) VALUE(%BIN(&NOENTR)) NXTRTV: CALL PGM(QUSRTVUS) PARM('LIBSPC QTEMP ' + &STRPOS &LENDTA &RCVDTA) /*( 処理の開始 )*/ : : /*( 処理の終了 )*/ IF COND(&N < &NOENT) THEN(DO) CHGVAR VAR(&N) VALUE(&N + 1) CHGVAR VAR(&DEC08) VALUE(%BIN(&STRPOS)) CHGVAR VAR(&DEC08) VALUE(&DEC08 + &ADDLEN) CHGVAR VAR(%BIN(&STRPOS)) VALUE(&DEC08) GOTO NXTRTV ENDDO
ユーザー・スペースの読み取りは ( 処理の開始 ) 〜 ( 処理の終了 ) が変わるだけで
ヘッダー構造もつねに同じである。
以上の処理をひとつのソースにまとめると次のようになる。
0001.00 PGM 0002.00 /*---------------------------------------------------------*/ 0003.00 /* TESTUSLCL : ライブラリー一覧表 */ 0004.00 /* */ 0005.00 /* QUSLOBJ のサンプル */ 0006.00 /* */ 0007.00 /*---------------------------------------------------------*/ 0008.00 DCL VAR(&TYPE) TYPE(*CHAR) LEN(1) 0009.00 DCL VAR(&MSG) 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(&MSGDTA) TYPE(*CHAR) LEN(132) 0014.00 DCL VAR(&APIERR) TYPE(*CHAR) LEN(116) + 0015.00 VALUE(X'000074') /* 2 進数 */ 0016.00 DCL VAR(&STRPOS) TYPE(*CHAR) LEN(4) + 0017.00 VALUE(X'0000007D') /* 2 進数開始位置 : + 0018.00 125 */ 0019.00 DCL VAR(&LENDTA) TYPE(*CHAR) LEN(4) + 0020.00 VALUE(X'00000010') /* 2 進数受取長さ : 16 */ 0021.00 DCL VAR(&RCVVAR) TYPE(*CHAR) LEN(16) + 0022.00 VALUE(X'0000000000000000') 0023.00 DCL VAR(&OFFSET) TYPE(*CHAR) LEN(4) /* + 0023.00 DCL VAR(&OFFSET) TYPE(*CHAR) LEN(4) /* + 0024.00 2 進数 オフセット */ 0025.00 DCL VAR(&NOENTR) TYPE(*CHAR) LEN(4) /* + 0026.00 2 進数項目数 */ 0027.00 DCL VAR(&LSTSIZ) TYPE(*CHAR) LEN(4) /* + 0028.00 2 進数リストサイズ */ 0029.00 DCL VAR(&DEC08) TYPE(*DEC) LEN(8 0) /* WORK */ 0030.00 DCL VAR(&ADDLEN) TYPE(*DEC) LEN(8 0) /* WORK */ 0031.00 DCL VAR(&NOENT) TYPE(*DEC) LEN(8 0) /* WORK */ 0032.00 DCL VAR(&N) TYPE(*DEC) LEN(8 0) VALUE(1) /* WORK */ 0033.00 DCL VAR(&RCVDTA) TYPE(*CHAR) LEN(256) /* + 0034.00 受取データ */ 0035.00 DCL VAR(&NULL4) TYPE(*CHAR) LEN(4) + 0036.00 VALUE(X'00000000') 0037.00 MONMSG MSGID(CPF0000) EXEC(GOTO CMDLBL(ERROR)) 0038.00 0039.00 RTVJOBA TYPE(&TYPE) 0040.00 /*( ユーザー・スペースの作成 )*/ 0041.00 CALL PGM(QUSCRTUS) PARM('LIBSPC QTEMP ' + 0042.00 'PF ' 1000 ' ' '*ALL ' + 0043.00 'QUSLOBJ 用ユーザー・スペース ' + 0044.00 '*YES ' &APIERR) 0045.00 IF COND(%SST(&APIERR 5 4) *NE &NULL4) THEN(DO) 0046.00 GOTO APIERR 0047.00 ENDDO 0048.00 0049.00 /*( QUSLOBJ の実行 )*/ 0050.00 CALL PGM(QUSLOBJ) PARM('LIBSPC QTEMP ' + 0051.00 'OBJL0100' '*ALLUSR *ALL ' + 0052.00 '*LIB ' &APIERR) 0053.00 IF COND(%SST(&APIERR 5 4) *NE &NULL4) THEN(DO) 0054.00 GOTO APIERR 0055.00 ENDDO 0056.00 0057.00 /*( リストデータ・セクションのオフセット値を検索 )*/ 0058.00 CALL PGM(QUSRTVUS) PARM('LIBSPC QTEMP ' + 0059.00 &STRPOS &LENDTA &RCVVAR) 0060.00 CHGVAR VAR(&OFFSET) VALUE(%SST(&RCVVAR 1 4)) 0061.00 CHGVAR VAR(&NOENTR) VALUE(%SST(&RCVVAR 9 4)) 0062.00 CHGVAR VAR(&LSTSIZ) VALUE(%SST(&RCVVAR 13 4)) 0063.00 0064.00 /*( RCVVAR によって OFFSET,LSTSIZ を受取った )*/ 0065.00 CHGVAR VAR(&STRPOS) VALUE(&OFFSET) 0066.00 CHGVAR VAR(&DEC08) VALUE(%BIN(&STRPOS)) 0067.00 CHGVAR VAR(&DEC08) VALUE(&DEC08 + 1) 0068.00 CHGVAR VAR(%BIN(&STRPOS)) VALUE(&DEC08) 0069.00 CHGVAR VAR(&LENDTA) VALUE(&LSTSIZ) 0070.00 CHGVAR VAR(&ADDLEN) VALUE(%BIN(&LENDTA)) 0071.00 CHGVAR VAR(&NOENT) VALUE(%BIN(&NOENTR)) 0072.00 NXTRTV: 0073.00 CALL PGM(QUSRTVUS) PARM('LIBSPC QTEMP ' + 0074.00 &STRPOS &LENDTA &RCVDTA) 0075.00 /*( 処理の開始 )*/ 0076.00 SNDPGMMSG MSG('LIB=' *CAT %SST(&RCVDTA 1 10)) + 0077.00 MSGTYPE(*DIAG) 0078.00 0079.00 /*( 処理の終了 )*/ 0080.00 IF COND(&N < &NOENT) THEN(DO) 0081.00 CHGVAR VAR(&N) VALUE(&N + 1) 0082.00 CHGVAR VAR(&DEC08) VALUE(%BIN(&STRPOS)) 0083.00 CHGVAR VAR(&DEC08) VALUE(&DEC08 + &ADDLEN) 0084.00 CHGVAR VAR(%BIN(&STRPOS)) VALUE(&DEC08) 0085.00 GOTO NXTRTV 0086.00 ENDDO 0087.00 RETURN 0088.00 0089.00 APIERR: 0090.00 CHGVAR VAR(&MSGID) VALUE(%SST(&APIERR 9 7)) 0091.00 CHGVAR VAR(&MSGF) VALUE('QCPFMSG ') 0092.00 CHGVAR VAR(&MSGDTA) VALUE(%SST(&APIERR 17 100)) 0093.00 RTVMSG MSGID(&MSGID) MSGF(QCPFMSG) MSGDTA(&MSGDTA) + 0094.00 MSG(&MSG) 0095.00 GOTO SNDMSG 0096.00 ERROR: RCVMSG MSGTYPE(*LAST) RMV(*NO) MSG(&MSG) + 0097.00 MSGDTA(&MSGDTA) MSGID(&MSGID) MSGF(&MSGF) + 0098.00 MSGFLIB(&MSGFLIB) 0099.00 SNDMSG: 0100.00 IF COND(&TYPE *EQ '0') THEN(DO) /* バッチ */ 0101.00 IF COND(&MSGID *EQ ' ') THEN(DO) 0102.00 SNDPGMMSG MSG(&MSG) TOMSGQ(*SYSOPR) MSGTYPE(*COMP) 0103.00 ENDDO 0104.00 ELSE CMD(DO) 0105.00 SNDPGMMSG MSGID(&MSGID) MSGF(&MSGFLIB/&MSGF) + 0106.00 MSGDTA(&MSGDTA) TOMSGQ(*SYSOPR) + 0107.00 MSGTYPE(*COMP) 0108.00 ENDDO 0109.00 ENDDO /* バッチ */ 0110.00 ELSE CMD(DO) /* 対話型 */ 0111.00 IF COND(&MSGID *EQ ' ') THEN(DO) 0112.00 SNDPGMMSG MSGID(CPF9897) MSGF(QCPFMSG) MSGDTA(&MSG) + 0113.00 TOMSGQ(*TOPGMQ) MSGTYPE(*ESCAPE) 0114.00 ENDDO 0115.00 ELSE CMD(DO) 0116.00 SNDPGMMSG MSGID(&MSGID) MSGF(&MSGFLIB/&MSGF) + 0117.00 MSGDTA(&MSGDTA) TOMSGQ(*TOPGMQ) + 0118.00 MSGTYPE(*ESCAPE) 0119.00 ENDDO 0120.00 ENDDO /* 対話型 */ 0121.00 ENDPGM
QUSLOBJ
以外の別の ユーザー・スペースに出力する API の場合も
0049.00 /*( QUSLOBJ の実行 )*/ 0050.00 CALL PGM(QUSLOBJ) PARM('LIBSPC QTEMP ' + 0051.00 'OBJL0100' '*ALLUSR *ALL ' + 0052.00 '*LIB ' &APIERR)
と、
0075.00 /*( 処理の開始 )*/ 0076.00 SNDPGMMSG MSG('LIB=' *CAT %SST(&RCVDTA 1 10)) + 0077.00 MSGTYPE(*DIAG) 0078.00 0079.00 /*( 処理の終了 )*/
が変わるだけでありその他は同じソースとなるはずである。
従ってこの例はコピーして繰り返し参照して使用することになるだろう。