CL

130. オープン・リストAPI : QGYOLSPL

APIによって結果を得る方法として

(1) APIからの戻り変数を取得する

(2) APIがユーザー・スペースに出力した結果を読取る

という方法が多く、特に複数の結果を受取る方法は
(2)のパターンでユーザー・スペースを読取る方法が
多く利用されている。
ところがあまり使われていないがもうひとつの方法がある。

(3) APIが結果をメモリとして戻してそのメモリを読取る。

という方法である。ユーザー・スペースではなく
メモリに直接結果が戻されてそれを読むという方法である。

この方法は(2)に比べて圧倒的にパフォーマンスにおいて
優れている。
1万レコード以上の結果があっても瞬時で終わってしまう。
ただしこのAPIのパターンは使うのに非常に難しい。
サンプルの例がほとんどなくAPIの解説も十分ではない。
日本語のサンプル・ソースがあったとしても
IBMマニュアルをそのまま書き写しただけなのに
「やさしい」とか言ってるが実は本人が書いたものでは
なく肝心な部分は丸写しで実践的なテストはされていない。
実際に実行したのであればそのパフォーマンスに驚くはずであるが
何も書かれていない。
海外サイトでもQGYOLSPLの使用方法を教えて欲しいという
書き込みがあるがサンプル・ソースの公開はない。

また多くの技術解説はマニュアルをただコピーしただけのものが多い。

そこでこのシリーズでは(3)のオーブン・リストと呼ばれる
パターンのサンプルを紹介する。
これらは実際に製品に使用されている使い方を示している。

今回、最初に紹介するのはスプールの一覧を検索するための
API: QGYOLSPL の利用方法である。

API: QGYOLSPL が優れているのはパフォーマンスだけではない。
今までのスプール一覧はOUTQ単位の出力であった。
つまり装置を主体として一覧表の出力である。
しかし QGYOLSPL ではジョブ単位でもOUTQ単位でも自由に
設定してスプールを抽出することができる。
つまり自分が出力したスプールがどのOUTQに分散されて
保管されていたとしてもまとめて抽出することができる。
これは装置主体ではなく使用者を主体としていることである。

[TESTSPLL: QGYOLSPL: SPLF の一覧表 ]

ソースはこちらから

0001.00              PGM                                                         
0002.00 /*-------------------------------------------------------------------*/  
0003.00 /*   TESTSPLL   :  QGYOLSPL: SPLF の一覧表                           */  
0004.00 /*                                                                   */  
0005.00 /*   2020/07/05  作成    REF. TESTSPL2 QCSRC2                        */  
0006.00 /*-------------------------------------------------------------------*/  
0007.00   /*( QGYOLSPL に必要な変数 )*/                                          
0008.00              DCL        VAR(&RCVVAR) TYPE(*CHAR) LEN(4800)               
0009.00              DCL        VAR(&RCVLEN) TYPE(*CHAR) LEN(4) +                
0010.00                           VALUE(X'000012C0')                             
0011.00              DCL        VAR(&LISTINFO) TYPE(*CHAR) LEN(80)               
0012.00              DCL        VAR(&LISTSU) TYPE(*CHAR) LEN(4) +                
0013.00                           VALUE(X'00000001')                             
0014.00              DCL        VAR(&NBRRCD) TYPE(*CHAR) LEN(4) +                
0015.00                           VALUE(X'00000003')                             
0016.00              DCL        VAR(&SORT) TYPE(*CHAR) LEN(4) +                  
0017.00                           VALUE(X'00000000')                             
0018.00              DCL        VAR(&BIN1) TYPE(*CHAR) LEN(4) +                  
0019.00                           VALUE(X'00000001')                             
0020.00              DCL        VAR(&FILTER) TYPE(*CHAR) LEN(92)                 
0021.00              DCL        VAR(&JOBINFO) TYPE(*CHAR) LEN(26)                
0022.00              DCL        VAR(&JOB) TYPE(*CHAR) LEN(10)                    
0023.00              DCL        VAR(&USER) TYPE(*CHAR) LEN(10)                   
0024.00              DCL        VAR(&NBR) TYPE(*CHAR) LEN(6)                  
0025.00              DCL        VAR(&MSG) TYPE(*CHAR) LEN(132)                
0026.00              DCL        VAR(&MSGID) TYPE(*CHAR) LEN(7)                
0027.00              DCL        VAR(&MSGF) TYPE(*CHAR) LEN(10)                
0028.00              DCL        VAR(&MSGFLIB) TYPE(*CHAR) LEN(10)             
0029.00              DCL        VAR(&MSGDTA) TYPE(*CHAR) LEN(132)             
0030.00              DCL        VAR(&TYPE) TYPE(*CHAR) LEN(1)                 
0031.00              DCL        VAR(&TOPGMQ) TYPE(*CHAR) LEN(10)              
0032.00              DCL        VAR(&MSGTYPE) TYPE(*CHAR) LEN(10) +           
0033.00                           VALUE('*ESCAPE   ')                         
0034.00              DCL        VAR(&APIERR) TYPE(*CHAR) LEN(116) +           
0035.00                           VALUE(X'000074') /* 2 進数  */              
0036.00              DCL        VAR(&ERR) TYPE(*CHAR) LEN(1)                  
0037.00              DCL        VAR(&NULL4) TYPE(*CHAR) LEN(4) +              
0038.00                           VALUE(X'00000000')                          
0039.00              DCL        VAR(&SPC2) TYPE(*CHAR) LEN(2)                 
0040.00              DCL        VAR(&BIN4) TYPE(*CHAR) LEN(4)                 
0041.00              DCL        VAR(&RTNSU) TYPE(*DEC) LEN(5 0)               
0042.00              DCL        VAR(&RTNSUC) TYPE(*CHAR) LEN(5)               
0043.00              MONMSG     MSGID(CPF0000) EXEC(GOTO CMDLBL(ERROR))       
0044.00                                                                       
0045.00 /*( 環境の取得 )*/                                                    
0046.00              RTVJOBA    JOB(&JOB) USER(&USER) NBR(&NBR) TYPE(&TYPE)   
0047.00              IF         COND(&TYPE *EQ '0') THEN(DO) /*  バッチ  */   
0048.00              CHGVAR     VAR(&TOPGMQ) VALUE('*SYSOPR   ')                  
0049.00              ENDDO      /*  バッチ  */                                    
0050.00              ELSE       CMD(DO) /*  対話式  */                            
0051.00              CHGVAR     VAR(&TOPGMQ) VALUE('*TOPGMQ   ')                  
0052.00              ENDDO      /*  対話式  */                                    
0053.00                                                                           
0054.00 /*( スプール・リストのオープン )*/                                        
0055.00              CHGVAR     VAR(%SST(&LISTINFO 1 4)) VALUE(&LISTSU)           
0056.00              CHGVAR     VAR(&JOBINFO) VALUE(&JOB *CAT &USER *CAT +        
0057.00                           &NBR)                                           
0058.00              CHGVAR     VAR(&FILTER) +                                    
0059.00                  VALUE(&BIN1 *CAT &USER *CAT '  ' +                       
0060.00                  *CAT  &BIN1 *CAT '*ALL                ' +                
0061.00                  *CAT  '*ALL      ' +                                     
0062.00                  *CAT  '*ALL      ' +                                     
0063.00                  *CAT  &BIN1 *CAT '*READY      ' +                        
0064.00                  *CAT  &BIN1 *CAT '*ALL        ')                         
0065.00              CALL       PGM(QGYOLSPL) PARM(&RCVVAR &RCVLEN &LISTINFO +    
0066.00                           &NBRRCD &SORT &FILTER &JOBINFO +                
0067.00                           'OSPL0300' &APIERR)                             
0068.00              IF         COND(%SST(&APIERR 5 4) *NE &NULL4) THEN(DO)       
0069.00              SNDPGMMSG  +                                                 
0070.00                           MSG('API: QGYOLSPL の実行で次のエラーが発生 +   
0071.00                            しました。 ') MSGTYPE(*DIAG)                   
0072.00              GOTO       APIERR                                       
0073.00              ENDDO                                                   
0074.00              CHGVAR     VAR(&BIN4) VALUE(%SST(&LISTINFO 1 4))        
0075.00              CHGVAR     VAR(&RTNSU) VALUE(%BIN(&BIN4))               
0076.00              IF         COND(&RTNSU *EQ 0) THEN(DO) /* +             
0077.00                            戻り数がない  */                          
0078.00              CHGVAR     VAR(&MSG) +                                  
0079.00                           VALUE(' 見つかったスプールはありません。 ')
0080.00              CHGVAR     VAR(&MSGTYPE) VALUE('*DIAG     ')            
0081.00              GOTO       ENDLIST                                      
0082.00              ENDDO      /*  戻り数がない  */                         
0083.00              IF         COND(&RTNSU > 0) THEN(DO) /*  戻り数 >0 */   
0084.00              CHGVAR     VAR(&RTNSUC) VALUE(&RTNSU)                   
0085.00  NXTDEC:     IF         COND(%SST(&RTNSUC 1 1) *EQ '0') THEN(DO)     
0086.00              CHGVAR     VAR(&RTNSUC) VALUE(%SST(&RTNSUC 2 4))        
0087.00              GOTO       NXTDEC                                       
0088.00              ENDDO                                                   
0089.00              ENDDO      /*  戻り数 >0 */                             
0090.00              CHGVAR     VAR(&MSG) VALUE(&RTNSUC *TCAT +              
0091.00                           ' 個のスプールが見つかりました ')          
0092.00              CHGVAR     VAR(&MSGTYPE) VALUE('*DIAG     ')            
0093.00  ENDLIST:    GOTO       SNDMSG                                       
0094.00                                                                      
0095.00  APIERR:                                                             
0096.00              CHGVAR     VAR(&MSGID) VALUE(%SST(&APIERR 9 7))          
0097.00              CHGVAR     VAR(&MSGDTA) VALUE(%SST(&APIERR 17 100))      
0098.00              IF         COND(%SST(&MSGID 1 3) *EQ 'GUI') THEN(DO)     
0099.00              CHGVAR     VAR(&MSGF) VALUE('QGUIMSG   ')                
0100.00              ENDDO                                                    
0101.00              ELSE       CMD(DO)                                       
0102.00              CHGVAR     VAR(&MSGF) VALUE('QCPFMSG   ')                
0103.00              ENDDO                                                    
0104.00              CHGVAR     VAR(&MSGFLIB) VALUE('QSYS      ')             
0105.00              GOTO       SNDMSG                                        
0106.00                                                                       
0107.00  ERROR:      RCVMSG     MSGTYPE(*LAST) RMV(*NO) MSG(&MSG) +           
0108.00                           MSGDTA(&MSGDTA) MSGID(&MSGID) MSGF(&MSGF) + 
0109.00                           MSGFLIB(&MSGFLIB)                           
0110.00  SNDMSG:     IF         COND(&MSGID *EQ ' ') THEN(DO)                 
0111.00              SNDPGMMSG  MSGID(CPF9897) MSGF(QCPFMSG) MSGDTA(&MSG) +   
0112.00                           TOMSGQ(&TOPGMQ) MSGTYPE(&MSGTYPE)           
0113.00              MONMSG     MSGID(CPF2400) EXEC(RETURN)                   
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(&MSGTYPE)                           
0119.00              MONMSG     MSGID(CPF2400) EXEC(RETURN)                   
0120.00              ENDDO                           
0121.00              DSPJOBLOG  JOB(*) OUTPUT(*PRINT)
0122.00              ENDPGM   


                      

[解説]

SPLF の一覧表API: QGYOLSPL は

0065.00              CALL       PGM(QGYOLSPL) PARM(&RCVVAR &RCVLEN &LISTINFO +    
0066.00                           &NBRRCD &SORT &FILTER &JOBINFO +                
0067.00                           'OSPL0300' &APIERR)

 

のようにして呼び出しているのだが

&RCVVAR ………………….. 受取り変数(CHAR* 4800)
&RCVLEN ………………….. 受取り変数の長さ(CHAR* 4) VALUE(X’000012C0′) は 4800 の意味
&LISTINFO ………………… リスト情報(CHAR* 80) リスト数 1を入れて渡す
戻ったときには受取った数が入っている。

0055.00              CHGVAR     VAR(%SST(&LISTINFO 1 4)) VALUE(&LISTSU)

&NBRRCD ………………….. 受取り最大可能数を示す。-1の場合はすべて(CHAR* 4)
&SORT ……………………. 分類情報。分類のない場合は NULLを入れておく。
&FILTER ………………….. APIの使い方が難しいのはこの部分の指定の方法がマニュアルでは不明。
フィルター情報とはデータの選択を意味するのだが
API: QGYOLSPL のフィルター情報はひとつでも省略してはならないことである。

 
0058.00              CHGVAR     VAR(&FILTER) +                                    
0059.00                  VALUE(&BIN1 *CAT &USER *CAT '  ' +                       
0060.00                  *CAT  &BIN1 *CAT '*ALL                ' +                
0061.00                  *CAT  '*ALL      ' +                                     
0062.00                  *CAT  '*ALL      ' +                                     
0063.00                  *CAT  &BIN1 *CAT '*READY      ' +                        
0064.00                  *CAT  &BIN1 *CAT '*ALL        ') 

は、*READY状態のすべてのスプールを抽出することを意味している。

 &JOBINFO …………………. スプールを選択するためのジョブ情報

0056.00              CHGVAR     VAR(&JOBINFO) VALUE(&JOB *CAT &USER *CAT +        
0057.00                           &NBR)

 

API: QGYOLSPLが成功裏に終わったときは &LISTINFOには抽出できたレコード数が入っているので

0074.00              CHGVAR     VAR(&BIN4) VALUE(%SST(&LISTINFO 1 4))        
0075.00              CHGVAR     VAR(&RTNSU) VALUE(%BIN(&BIN4))

 

によって出力レコード数を取り出すことができる。
出力結果は &RCVVAR に入っているので

 ’OSPL0300’ のレコード形式をマニュアルで調べればどのような形式で収められているのかを
知ることができる。

最後に

0098.00              IF         COND(%SST(&MSGID 1 3) *EQ 'GUI') THEN(DO)     
0099.00              CHGVAR     VAR(&MSGF) VALUE('QGUIMSG   ')                
0100.00              ENDDO                                                    
0101.00              ELSE       CMD(DO)                                       
0102.00              CHGVAR     VAR(&MSGF) VALUE('QCPFMSG   ')                
0103.00              ENDDO 

にも注目して欲しい。
リストAPIで送出されるエラーは QCPFMSGではなく QGUIMSG というメッセージ・ファイルである。
このことも実際に実行した者でないと気付かない。

実行結果

 > call testspll         
   3 個のスプールが見つかりました 

次にレコードを取り出すことになるがここではまず API:QGYOLSPL の使い方を知ってもらうために
サンプルとして示すことにした。

API:QGYOLSPLの使用サンプル・ソースはインターネットでもほとんど公開の例がなく
これが初めての公開であろう。
次回はリスト・オープンAPIの検索方法も含めて紹介する。