CL

182. AIもできなかったヘルブ・テキストの取出し

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はないので一般の人は
独力で用意するしかないだろう。