API: QUHRHLPT は任意のヘルプのテキストを
文字列として取り出すことができる。
しかしIBM のAPIの説明
を読んでも複雑で意味を読み取ることができない。
■ Copilotによるサンプル作成
そこでAIを頼ってまず Copilotにサンプル・ソースを作らせてみたが
Copilotが作ったのは
・パラメータが8個必要なのに5個しかない
・設定が必要なパラメータに対して *YES, *UIM とか
意味不明な設定をする。
ということで数時間、やり直してもできなかった。
ひどいのは
CHGVAR %BIN(&LEN) 32767
のような文字フィールドにバイナリを設定する記述は
誤りでありCHGVARの左辺はフィールド名して指定できないと
断言する始末であった。
CHGVAR %SST(&VALUE 10 3) = ‘ABC’
という文字の埋め込みも許さないという始末で
何百回とこのような演算はしていると言っても
最初は認めなかったがしばらくすると自分の過ちを
認めた。
AIにCLPの文法を教えなければならないとは
あきれてしまってとうとう最後にはCopilotは
投げ出してしまった。
■ Gemini によるサンプル作成
次にGoogle Gemini の相談してみると
最初は QtmmGetPanelGroupText というAPIで
ヘルプの文字列を取り出すことができると言うので
調べてみたらそんなAPIは存在しない。
おまけにGeminiは そんなAPIは存在しない。
どこで聞いたのかと言う始末。
Gominiも同じように API: QUHRHLPT のサンプル・ソースを
作らせてみたがなかなかできない。
Geminiも半日以上かかってもできないので
独力でマニュアルを読み返して作成することができた。
独力でできた旨をGeminiに伝えるとなぜAIが
できなかったのか教えてくれと頼んできた。
CopilotもGeminiも思考回路が論理的ではなく
思いつきで「こうかな?こうかな?」という場当たり的な
思考しかできない。
マチュアルをきちんと読んで理解しようとはしていない。
これは人間でも論理的な思考ができない人は
やはり「こうかな?こうかな?」と思いつきで試すことしかできないので
解決の道が広がることはない。
通常のRPGのコーディングくらいは今のAIでもできるだろうが
IBM のAPIの理解はまだ難しいのだろう。
■ 正しいサンプル・ソース
それでは正しい QUHRHLPTの使い方のサンプル・ソースを
紹介しよう。
[ TESTHLP ]
ソースはこちらから
0001.00 PGM
0002.00 /*-------------------------------------------------------------------*/
0003.00 /* TETSHLP HELP の内容をバッファーとして取り出す */
0004.00 /* */
0005.00 /* 2026/03/24 作成 */
0006.00 /*-------------------------------------------------------------------*/
0007.00 DCL VAR(&RCVVAR) TYPE(*CHAR) LEN(1024)
0008.00 DCL VAR(&RCVLEN) TYPE(*INT) STG(*DEFINED) LEN(4) +
0009.00 DEFVAR(&RCVVAR 1)
0010.00 DCL VAR(&RCVAVL) TYPE(*INT) STG(*DEFINED) LEN(4) +
0011.00 DEFVAR(&RCVVAR 5)
0012.00 DCL VAR(&FMTNAM) TYPE(*CHAR) STG(*DEFINED) +
0013.00 LEN(8) DEFVAR(&RCVVAR 9)
0014.00 DCL VAR(&OFFSET) TYPE(*INT) STG(*DEFINED) LEN(4) +
0015.00 DEFVAR(&RCVVAR 17)
0016.00 DCL VAR(&NBRENT) TYPE(*INT) STG(*DEFINED) LEN(4) +
0017.00 DEFVAR(&RCVVAR 21)
0018.00 DCL VAR(&SIZE) TYPE(*INT) STG(*DEFINED) LEN(4) +
0019.00 DEFVAR(&RCVVAR 25)
0020.00 DCL VAR(&VALUE) TYPE(*CHAR) LEN(1024)
0021.00 DCL VAR(&RCVSIZ) TYPE(*CHAR) LEN(4)
0022.00 DCL VAR(&TITLE) TYPE(*CHAR) LEN(10) VALUE('*YES')
0023.00 DCL VAR(&TXTFMT) TYPE(*CHAR) LEN(32767) /* +
0024.00 受入れテキスト */
0025.00 DCL VAR(&TXTLEN) TYPE(*INT) STG(*DEFINED) LEN(4) +
0026.00 DEFVAR(&TXTFMT 1)
0027.00 DCL VAR(&TXTAVL) TYPE(*INT) STG(*DEFINED) LEN(4) +
0028.00 DEFVAR(&TXTFMT 5)
0029.00 DCL VAR(&TXTSIZ) TYPE(*CHAR) LEN(4)
0030.00 DCL VAR(&DATA) TYPE(*CHAR) LEN(32767)
0031.00 DCL VAR(&HLPIDEN) TYPE(*CHAR) LEN(200)
0032.00 DCL VAR(&NUMID) TYPE(*CHAR) LEN(4)
0033.00 DCL VAR(&MSG) TYPE(*CHAR) LEN(132)
0034.00 DCL VAR(&MSGID) TYPE(*CHAR) LEN(7)
0035.00 DCL VAR(&MSGF) TYPE(*CHAR) LEN(10)
0036.00 DCL VAR(&MSGFLIB) TYPE(*CHAR) LEN(10)
0037.00 DCL VAR(&MSGDTA) TYPE(*CHAR) LEN(132)
0038.00 DCL VAR(&PNLGRP) TYPE(*CHAR) LEN(20) +
0039.00 VALUE('QHCDCMD QSYS ')
0040.00 DCL VAR(&TYPE) TYPE(*CHAR) LEN(1)
0041.00 DCL VAR(&ERR) TYPE(*CHAR) LEN(1)
0042.00 DCL VAR(&TOPGMQ) TYPE(*CHAR) LEN(10)
0043.00 DCL VAR(&MSGTYPE) TYPE(*CHAR) LEN(10) +
0044.00 VALUE('*ESCAPE ')
0045.00 DCL VAR(&APIERR) TYPE(*CHAR) LEN(116) +
0046.00 VALUE(X'0000007400000000') /* 2 進数 */
0047.00 DCL VAR(&NULL4) TYPE(*CHAR) LEN(4) +
0048.00 VALUE(X'00000000')
0049.00 MONMSG MSGID(CPF0000) EXEC(GOTO CMDLBL(ERROR))
0050.00
0051.00 /*( 環境の取得 )*/
0052.00 RTVJOBA TYPE(&TYPE)
0053.00 IF COND(&TYPE *EQ '0') THEN(DO) /* バッチ */
0054.00 CHGVAR VAR(&TOPGMQ) VALUE('*SYSOPR ')
0055.00 ENDDO /* バッチ */
0056.00 ELSE CMD(DO) /* 対話式 */
0057.00 CHGVAR VAR(&TOPGMQ) VALUE('*TOPGMQ ')
0058.00 ENDDO /* 対話式 */
0059.00
0060.00 /*( 初期ルーチン )*/
0061.00 /*---------------------------*/
0062.00 CALLSUBR SUBR(INZSUBR)
0063.00 /*---------------------------*/
0064.00 IF COND(%SST(&APIERR 5 4) *NE &NULL4) THEN(DO)
0065.00 GOTO APIERR
0066.00 ENDDO
0067.00 IF COND(&MSG *NE ' ') THEN(DO)
0068.00 GOTO SNDMSG
0069.00 ENDDO
0070.00 IF COND(&ERR = 'E') THEN(DO)
0071.00 GOTO ERROR
0072.00 ENDDO
0073.00
0074.00 /*( API の実行 )*/
0075.00 CHGVAR VAR(%SST(&HLPIDEN 1 32)) VALUE('DSPCMD')
0076.00 CHGVAR VAR(%SST(&HLPIDEN 33 10)) VALUE('QHCDCMD')
0077.00 CHGVAR VAR(%SST(&HLPIDEN 43 10)) VALUE('QHLPSYS')
0078.00 CHGVAR VAR(%SST(&HLPIDEN 53 10)) VALUE('*PNLGRP')
0079.00 CHGVAR VAR(%BIN(&RCVSIZ)) VALUE(1024)
0080.00 CHGVAR VAR(%BIN(&NUMID)) VALUE(1)
0081.00 CHGVAR VAR(%BIN(&TXTSIZ)) VALUE(32767)
0082.00 /*-----------------------------------------------------------*/
0083.00 CALL PGM(QUHRHLPT) PARM(&RCVVAR &RCVSIZ +
0084.00 'RHLP0100' &HLPIDEN &NUMID &TXTFMT &TXTSIZ +
0085.00 &APIERR)
0086.00 /*-----------------------------------------------------------*/
0087.00 IF COND(%SST(&APIERR 5 4) *NE &NULL4) THEN(DO)
0088.00 SNDPGMMSG +
0089.00 MSG('API: QUHRHLPT の実行で次のエラーが発生 +
0090.00 しました。 ') MSGTYPE(*DIAG)
0091.00 GOTO APIERR
0092.00 ENDDO
0093.00 CHGVAR VAR(&DATA) VALUE(%SST(&TXTFMT 6 &TXTAVL))
0094.00 SNDPGMMSG MSG(&DATA) MSGTYPE(*DIAG)
0095.00 RETURN
0096.00
0097.00 APIERR:
0098.00 CHGVAR VAR(&MSGID) VALUE(%SST(&APIERR 9 7))
0099.00 CHGVAR VAR(&MSGDTA) VALUE(%SST(&APIERR 17 100))
0100.00 CHGVAR VAR(&MSGF) VALUE('QCPFMSG ')
0101.00 CHGVAR VAR(&MSGFLIB) VALUE('QSYS ')
0102.00 GOTO SNDMSG
0103.00
0104.00 ERROR: RCVMSG MSGTYPE(*LAST) RMV(*NO) MSG(&MSG) +
0105.00 MSGDTA(&MSGDTA) MSGID(&MSGID) MSGF(&MSGF) +
0106.00 MSGFLIB(&MSGFLIB)
0107.00 SNDMSG: IF COND(&MSGID *EQ ' ') THEN(DO)
0108.00 SNDPGMMSG MSGID(CPF9897) MSGF(QCPFMSG) MSGDTA(&MSG) +
0109.00 TOMSGQ(&TOPGMQ) MSGTYPE(&MSGTYPE)
0110.00 ENDDO
0111.00 ELSE CMD(DO)
0112.00 SNDPGMMSG MSGID(&MSGID) MSGF(&MSGFLIB/&MSGF) +
0113.00 MSGDTA(&MSGDTA) TOMSGQ(&TOPGMQ) +
0114.00 MSGTYPE(&MSGTYPE)
0115.00 ENDDO
0116.00 /******************************/
0117.00 SUBR SUBR(INZSUBR)
0118.00 /******************************/
0120.00 ENDPGM
[解説]
確かにこのAPIの利用は難易度が高い。
PNLGRPで作成されたヘルプの内容を文字列として取り出すのであるが
ここでは コマンド: DSPCMD のヘルプ: QHCDCMD か取り出すことになる。
DSPCMD で DSPCMD DSPCMD で調べてみればわかるが DSPCMD のヘルプは
QHCDCMDという名前で QSYSではなくライブラリー QHLPSYS に保管されている。
0083.00 CALL PGM(QUHRHLPT) PARM(&RCVVAR &RCVSIZ + 0084.00 'RHLP0100' &HLPIDEN &NUMID &TXTFMT &TXTSIZ + 0085.00 &APIERR)
に対してパラメータの説明を行う。
&RCVVAR……………. 受取りバッファーとなる構造体であり
0007.00 DCL VAR(&RCVVAR) TYPE(*CHAR) LEN(1024) 0008.00 DCL VAR(&RCVLEN) TYPE(*INT) STG(*DEFINED) LEN(4) + 0009.00 DEFVAR(&RCVVAR 1) 0010.00 DCL VAR(&RCVAVL) TYPE(*INT) STG(*DEFINED) LEN(4) + 0011.00 DEFVAR(&RCVVAR 5)
として構造が定義されているがここには取り出したヘルプの文字列は返ってこない。
多くのAPIでは際者のパラメータに求める値がかえってくるがこの場合は
この値はヘルプなどの名前の情報だけ返ってくるだけである。
&RCVSIZ …………… &RCVVARの長さの宣言であり
&RCVVARは1024バイトとして定義されているので
0079.00 CHGVAR VAR(%BIN(&RCVSIZ)) VALUE(1024)
として1024の値を宣言している。
‘RHLP0100’ …………. このAPIのフォーマット名でありこの名前だけしか
定義されていない。
&HLPIDEN …………… APIの渡すヘルプ・モジュールの名前を宣言している。
0075.00 CHGVAR VAR(%SST(&HLPIDEN 1 32)) VALUE('DSPCMD')
0076.00 CHGVAR VAR(%SST(&HLPIDEN 33 10)) VALUE('QHCDCMD')
0077.00 CHGVAR VAR(%SST(&HLPIDEN 43 10)) VALUE('QHLPSYS')
0078.00 CHGVAR VAR(%SST(&HLPIDEN 53 10)) VALUE('*PNLGRP')
&NUMID …………….. &HLPIDENで宣言したヘルプ・モジュールの数であり
今回は1個だけなので
0080.00 CHGVAR VAR(%BIN(&NUMID)) VALUE(1)
と設定している。
&TXTFMT ……………. これがどのAIも理解できなかった構造体でヘルプの
文字列が入るのはこの部分であり
0023.00 DCL VAR(&TXTFMT) TYPE(*CHAR) LEN(32767) /* + 0024.00 受入れテキスト */ 0025.00 DCL VAR(&TXTLEN) TYPE(*INT) STG(*DEFINED) LEN(4) + 0026.00 DEFVAR(&TXTFMT 1) 0027.00 DCL VAR(&TXTAVL) TYPE(*INT) STG(*DEFINED) LEN(4) + 0028.00 DEFVAR(&TXTFMT 5) 0029.00 DCL VAR(&TXTSIZ) TYPE(*CHAR) LEN(4) 0030.00 DCL VAR(&DATA) TYPE(*CHAR) LEN(32767)
として定義されている。&DATAに文字列が戻されるのだが
0093.00 CHGVAR VAR(&DATA) VALUE(%SST(&TXTFMT 6 &TXTAVL))
によって構造体の中から文字列を取り出すことができる。
&TXTSIZ …………. テキスト構造体の長さを示すものなので
0081.00 CHGVAR VAR(%BIN(&TXTSIZ)) VALUE(32767)
のようにして32767バイトを設定している。
このように4バイト変数に%BINを使って2進数としての
値を設定することはよく使う手法であるが
Copilotには理解できなんったようである。
■ AIの総評
最近はAIを利用する機会が多くなっているがAIはネットの情報を
短時間で収集してくれるので役に立つことが多いが完全ではない。
AIというと神さまみたいとAIの言うことは絶対であると
信じている人も多いようだが今回のようにAPIを調べさせるとなると
極端にその能力の低さを露呈する。
記憶力や情報収集能力は高いのだが論理的思考力や学習能力には
欠けるものがある。
思考力はまだ高校一年生レベルであるシンギュラリティは
またまだ先の話である。
最後に QUHRHLPT で取り出した&DATAはEBCDICではなく
UTF-8でXML型式で書かれている。
UTF-8からEBCDICに変換するAPIはないので一般の人は
独力で用意するしかないだろう。
