API には
- 結果の値を直接、受け取る
- 結果をユーザー・スペースに書き込む
の 2 種類の結果の戻し方がある。
ここでは最初に結果の値を直接、受け取る API として QUSROBJD : オブジェクトの属性の検索を紹介しよう。
QUSROBJD は API の中でもかなり使用頻度が高い API であり、CLP 開発者が最初に使うAPI かも
知れないと思うほどポピュラーな API である。
QUSROBJD は DSPOBJD コマンドとほぼ同じ情報を提供する。
もちろん API であるので DSPOBJD より詳しい情報を高速で得ることができる。
今回のサンプルはライブラリー SPOOLWTR の 最終変更日 と 時刻 を QUSROBJD によって
取得するというものである。
オブジェクト記述の検索(QUSROBJD)API
必須パラメータ・グループ:
1. | レシーバー変数 | 出力 | Char(*) |
2. | レシーバー変数長 | 入力 | Binary(4) |
3. | 形式名 | 入力 | Binary(4) |
4. | オブジェクト修飾名 | 入力 | Char(10) の配列(*) |
5. | オブジェクト・タイプ | 入出力 | Char(*) |
任意選択パラメータ:
6. | エラー・コード | 入出力 | Char(*) |
【解説】
レシーバー変数 と レシーバー変数長 は形式名によって異なる。
形式名 は、
OBJD0100 形式 |
・・・・・・ | 基本情報(最高速) |
OBJD0200 形式 |
・・・・・・ | PDM によって表示される情報に良く似た情報 |
OBJD0300 形式 |
・・・・・・ | 保守情報 |
OBJD0400 形式 |
・・・・・・ | 全情報(最低速) |
レシーバー変数の構造
[参照メンバー] QSYSINC/H(QUSROBJD)
■ OBJD0100 形式
オフセット | タイプ | フィールド | |
---|---|---|---|
10進数 | 16進数 | ||
0 |
0 |
BINARY(4) |
返されるバイト数 |
4 |
4 |
BINARY(4) |
使用可能なバイト数 |
8 |
8 |
CHAR(10) |
オブジェクト名 |
18 |
12 |
CHAR(10) |
オブジェクト・ライブラリー名 |
28 |
1C |
CHAR(10) |
オブジェクト・タイプ |
38 |
26 |
CHAR(10) |
戻りライブラリー |
48 |
30 |
BINARY(4) |
補助記憶域プール |
52 |
34 |
CHAR(10) |
オブジェクト所有者 |
62 |
3E |
CHAR(2) |
オブドェクト・ドメイン |
64 |
40 |
CHAR(13) |
作成日時 |
77 |
40 |
CHAR(13) |
オブジェクト変更日時 |
■ OBJD0200 形式
オフセット | タイプ | フィールド | |
---|---|---|---|
10進数 | 16進数 | ||
0 |
0 |
OBJD0100 形式からのすべての情報 |
|
90 |
5A |
CHAR(10) |
オブジェクトの拡張属性 |
100 |
64 |
CHAR(50) |
テキスト記述 |
150 |
96 |
CHAR(10) |
ソース・ファイル名 |
160 |
A0 |
CHAR(10) |
ソース・ファイル・ライブラリー名 |
170 |
AA |
CHAR(10) |
ソース・ファイル・メンバー名 |
■ OBJD0300 形式
オフセット | タイプ | フィールド | |
---|---|---|---|
10進数 | 16進数 | ||
0 |
0 |
OBJD0200 形式からのすべての情報 |
|
180 |
B4 |
CHAR(13) |
ソース・ファイルの更新日時 |
193 |
C1 |
CHAR(13) |
オブジェクト保管日時 |
206 |
CE |
CHAR(13) |
オブジェクト復元日時 |
219 |
DB |
CHAR(10) |
作成者のユーザー・プロフィール |
229 |
E5 |
CHAR(8) |
オブジェクトが作成されたシステム |
237 |
ED |
CHAR(7) |
リセット日付 |
244 |
F4 |
BINARY(4) |
保管サイズ |
248 |
F8 |
BINARY(4) |
保管順序番号 |
252 |
FC |
CHAR(10) |
記憶域 |
262 |
106 |
CHAR(10) |
保管コマンド |
272 |
110 |
CHAR(71) |
保管ボリュームID |
343 |
157 |
CHAR(10) |
保管装置 |
353 |
161 |
CHAR(10) |
保管ファイル名 |
363 |
16B |
CHAR(10) |
保管ファイル・ライブラリー名 |
373 |
175 |
CHAR(17) |
保管ラベル |
390 |
186 |
CHAR(9) |
システム・レベル |
399 |
18F |
CHAR(16) |
コンパイラー |
415 |
19F |
CHAR(8) |
オブジェクト・レベル |
423 |
1A7 |
CHAR(1) |
ユーザーの変更 |
424 |
1A8 |
CHAR(16) |
ライセンス・プログラム |
440 |
1B8 |
CHAR(10) |
プログラム一時修正(PTF) |
450 |
1C2 |
CHAR(10) |
プログラム診断依頼書(APAR) |
■ OBJD0400 形式
オフセット | タイプ | フィールド | |
---|---|---|---|
10進数 | 16進数 | ||
0 |
0 |
OBJD0300 形式からのすべての情報 |
|
460 |
1CC |
CHAR(7) |
最終使用日付 |
467 |
1D3 |
CHAR(1) |
使用状況の更新 |
468 |
1D4 |
BINARY(4) |
使用日数カウント |
472 |
1D8 |
BINARY(4) |
オブジェクト・サイズ |
476 |
1DC |
BINARY(4) |
オブジェクト・サイズの乗数 |
480 |
1E0 |
CHAR(1) |
オブジェクト圧縮状況 |
481 |
1E1 |
CHAR(1) |
プログラムによる変更許可< |
482 |
1E2 |
CHAR(1) |
プログラムによる変更 |
483 |
1E3 |
CHAR(10) |
ユーザー定義属性 |
493 |
1ED |
CHAR(1) |
オブジェクト ASP オーバーフロー標識 |
494 |
1EE |
CHAR(13) |
SAVACT 保管日時 |
507 |
1FB |
CHAR(10) |
オブジェクト監査値 |
517 |
205 |
CHAR(10) |
1次グループ |
0001.00 PGM 0002.00 /*---------------------------------------------------------*/ 0003.00 /* TESTLIBCL : 最終更新日付の検索 */ 0004.00 /*---------------------------------------------------------*/ 0005.00 DCL VAR(&TYPE) TYPE(*CHAR) LEN(1) 0006.00 DCL VAR(&MSG) TYPE(*CHAR) LEN(132) 0007.00 DCL VAR(&MSGID) TYPE(*CHAR) LEN(7) 0008.00 DCL VAR(&MSGF) TYPE(*CHAR) LEN(10) 0009.00 DCL VAR(&MSGFLIB) TYPE(*CHAR) LEN(10) 0010.00 DCL VAR(&MSGDTA) TYPE(*CHAR) LEN(132) 0011.00 DCL VAR(&APIERR) TYPE(*CHAR) LEN(116) + 0012.00 VALUE(X'000074') /* 2 進数 */ 0013.00 DCL VAR(&NULL4) TYPE(*CHAR) LEN(4) + 0014.00 VALUE(X'00000000') 0015.00 DCL VAR(&RCVVAR) TYPE(*CHAR) LEN(256) 0016.00 DCL VAR(&RCVLEN) TYPE(*CHAR) LEN(4) + 0017.00 VALUE(X'00000100') 0018.00 DCL VAR(&CHG_DATE) TYPE(*CHAR) LEN(13) 0019.00 DCL VAR(&DATE) TYPE(*CHAR) LEN(8) 0020.00 DCL VAR(&TIME) TYPE(*CHAR) LEN(6) 0021.00 MONMSG MSGID(CPF0000) EXEC(GOTO CMDLBL(ERROR)) 0022.00 0023.00 RTVJOBA TYPE(&TYPE) 0024.00 CALL PGM(QUSROBJD) PARM(&RCVVAR &RCVLEN + 0025.00 'OBJD0100' 'SPOOLWTR *LIBL ' + 0026.00 '*LIB ' &APIERR) 0027.00 IF COND(%SST(&APIERR 5 4) *NE &NULL4) THEN(DO) 0028.00 GOTO APIERR 0029.00 ENDDO 0030.00 CHGVAR VAR(&CHG_DATE) VALUE(%SST(&RCVVAR 78 13)) 0031.00 CHGVAR VAR(&DATE) VALUE('20' *CAT %SST(&CHG_DATE + 0032.00 2 4)) 0033.00 SNDPGMMSG MSG('DATE = ' *CAT &DATE) MSGTYPE(*DIAG) 0034.00 CHGVAR VAR(&TIME) VALUE(%SST(&CHG_DATE 8 6)) 0035.00 SNDPGMMSG MSG('TIME = ' *CAT &TIME) MSGTYPE(*DIAG) 0036.00 RETURN 0037.00 0038.00 APIERR: 0039.00 CHGVAR VAR(&MSGID) VALUE(%SST(&APIERR 9 7)) 0040.00 CHGVAR VAR(&MSGF) VALUE('QCPFMSG ') 0041.00 CHGVAR VAR(&MSGDTA) VALUE(%SST(&APIERR 17 100)) 0042.00 RTVMSG MSGID(&MSGID) MSGF(QCPFMSG) MSGDTA(&MSGDTA) + 0043.00 MSG(&MSG) 0044.00 GOTO SNDMSG 0045.00 ERROR: RCVMSG MSGTYPE(*LAST) RMV(*NO) MSG(&MSG) + 0046.00 MSGDTA(&MSGDTA) MSGID(&MSGID) MSGF(&MSGF) + 0047.00 MSGFLIB(&MSGFLIB) 0048.00 SNDMSG: 0049.00 IF COND(&TYPE *EQ '0') THEN(DO) /* バッチ */ 0050.00 IF COND(&MSGID *EQ ' ') THEN(DO) 0051.00 SNDPGMMSG MSG(&MSG) TOMSGQ(*SYSOPR) MSGTYPE(*COMP) 0052.00 ENDDO 0053.00 ELSE CMD(DO) 0054.00 SNDPGMMSG MSGID(&MSGID) MSGF(&MSGFLIB/&MSGF) + 0055.00 MSGDTA(&MSGDTA) TOMSGQ(*SYSOPR) + 0056.00 MSGTYPE(*COMP) 0057.00 ENDDO 0058.00 ENDDO /* バッチ */ 0059.00 ELSE CMD(DO) /* 対話型 */ 0060.00 IF COND(&MSGID *EQ ' ') THEN(DO) 0061.00 SNDPGMMSG MSGID(CPF9897) MSGF(QCPFMSG) MSGDTA(&MSG) + 0062.00 TOMSGQ(*TOPGMQ) MSGTYPE(*ESCAPE) 0063.00 ENDDO 0064.00 ELSE CMD(DO) 0065.00 SNDPGMMSG MSGID(&MSGID) MSGF(&MSGFLIB/&MSGF) + 0066.00 MSGDTA(&MSGDTA) TOMSGQ(*TOPGMQ) + 0067.00 MSGTYPE(*ESCAPE) 0068.00 ENDDO 0069.00 ENDDO /* 対話型 */ 0070.00 ENDPGM
【解説】
このサンブルCLPはサンプルとは言ってもエラー処理は相当、念入りにバッチや対話式で
行なわれた場合も含めて考慮されている。
API : QUSROBJD は
0024.00 CALL PGM(QUSROBJD) PARM(&RCVVAR &RCVLEN + 0025.00 'OBJD0100' 'SPOOLWTR *LIBL ' + 0026.00 '*LIB ' &APIERR)
として実行されていて、ライブラリー SPOOLWTR の 変更日付 と 時刻 を調べようとしている。
API の結果の値を受け取るレシーバー変数 &RCVVAR は 90 バイトで十分であるが
将来、API が拡張されることに準備して 256 バイトと余裕を持った長さで定義されており
レシーバー変数の長さ : &RCVLEN も
0016.00 DCL VAR(&RCVLEN) TYPE(*CHAR) LEN(4) + 0017.00 VALUE(X'00000100')
として 256バイトとして定義されている。
このように API による戻り値は i5/OS のリリース・アップに伴って予告なく拡張されることが
多いので戻り値はつねに余裕を持って大きく定義しておかねばならない。
弊社ではつねに大きめに定義はしているものの、それでも予測を超えて大きな拡張が
IBM によって行われる場合がある。
さて、API : QUSROBJD を実行したときのエラーを受け取るためには エラー・コード &APIERR は
NULL ではなく、
0011.00 DCL VAR(&APIERR) TYPE(*CHAR) LEN(116) + 0012.00 VALUE(X'000074') /* 2 進数 */
として 116 バイトで定義しておく必要がある。
0027.00 IF COND(%SST(&APIERR 5 4) *NE &NULL4) THEN(DO) 0028.00 GOTO APIERR 0029.00 ENDDO
のように API : QUSROBJD の実行でエラーがあった場合は QCPFMSG の MSGID と MSGDTA を
0038.00 APIERR: 0039.00 CHGVAR VAR(&MSGID) VALUE(%SST(&APIERR 9 7)) 0040.00 CHGVAR VAR(&MSGF) VALUE('QCPFMSG ') 0041.00 CHGVAR VAR(&MSGDTA) VALUE(%SST(&APIERR 17 100)) 0042.00 RTVMSG MSGID(&MSGID) MSGF(QCPFMSG) MSGDTA(&MSGDTA) + 0043.00 MSG(&MSG) 0044.00 GOTO SNDMSG
のようにして取得してエラー・メッセージを表示することができる。
首尾よく &RCVMSG を受け取ることができたら
0030.00 CHGVAR VAR(&CHG_DATE) VALUE(%SST(&RCVVAR 78 13)) 0031.00 CHGVAR VAR(&DATE) VALUE('20' *CAT %SST(&CHG_DATE + 0032.00 2 4)) 0033.00 SNDPGMMSG MSG('DATE = ' *CAT &DATE) MSGTYPE(*DIAG) 0034.00 CHGVAR VAR(&TIME) VALUE(%SST(&CHG_DATE 8 6)) 0035.00 SNDPGMMSG MSG('TIME = ' *CAT &TIME) MSGTYPE(*DIAG) 0036.00 RETURN
のようにして 変更日付 と 時刻 を検索することができる。