RPG

353. API: QUSCRTUS :ユーザー・スペースの作成

API(=Application Programing Interface)とはIBM iが内部で使用している
プログラムでユーザーでも使えるように解放しているものである。
一般にはIBM iのOSのプログラムをユーザーが呼び出すと違反として
実行することはできない。
APIとしてIBMが公開しているものだけがユーザーでも使用することが
できる。

APIを利用することができるようになれば開発の範囲は大幅に広がるし
高度な開発もできるようになる。
しかしAPIはAPI解説書に公開されているがほとんど使用例やサンプルは少ない。
そこで、これからのシリーズではRPGによるAPIの利用方法を
サンプルを交えて紹介していきたい。

弊社製品の開発ではAPIが内部で頻繁に利用されていて
APIを使っていないプログラムがむしろ少ないくらいである。
それくらいAPIの利用頻度が高い。
(現在ではAPIでは必要な機能は足らなくなっているくらいであるが)

最初に紹介するのは API: QUSCRTUS (ユーザー・スペースの作成)である。
APIの報告はユーザー・スペース(*USRSPC)というオブジェクトに
出力されることを基本として作られている。
例えばレコードの一覧やフィールドの一覧、ファイルの一覧なども
APIはそれらをユーザー・スペース(*USRSPC)に出力する。
そしてユーザー・スペース(*USRSPC)を読み取って目的の一覧表を
入手するという具合である。

(1)ユーザー・スペース(*USRSPC)の作成

(2)ユーザー・スペース(*USRSPC)へAPIで出力

(3)ユーザー・スペース(*USRSPC)の読取り

という手順がAPIによる情報を得る手段として一般的である。
もちろんひとつのAPIだけで情報を取得することができる場合もある。

中にはこのユーザー・スペースの構造が莫大であり
数十個のAPIを使って読取らなければならないような構造体もある。

それではRPGによるユーザー・スペースの作成するソースを紹介する。

[RPG:USCRTUS:ユーザー・スペースの作成]

ソースはこちらから

0001.00 H DFTNAME(USCRTUS)   DATEDIT(*YMD/)                                       
0002.00 F********** ユーザー・スペースの作成 **********************************   
0003.00 F*                                                                        
0004.00 F**********************************************************************   
0005.00 D USRSPC          S             20A   INZ('QUSLRCD   QTEMP     ')         
0006.00 D  INZSIZE        S              4B 0 INZ(1000)                           
0007.00 D USRTXT          S             50A   INZ('FOR API USE         ')         
0008.00                                                                           
0009.00 D APIERR          DS                                                      
0010.00 D  GETBYT                 1      4B 0 INZ(160)                            
0011.00 D  AVLBYT                 5      8B 0 INZ(0)                              
0012.00 D  MSGID                  9     15                                        
0013.00 D  MSGDTA                17    160                                        
0014.00                                                                           
0015.00 C*----------------------------------------------------+                   
0016.00 C     *ENTRY        PLIST                                                 
0017.00 C                   PARM                    ERR               1           
0018.00 C                   PARM                    APIPRM          160           
0019.00 C*----------------------------------------------------+                   
0020.00 C*( ユーザースペースの作成 )                                              
0021.00 C*----------------------------------------------------+                   
0022.00 C                   CALL      'QUSCRTUS'                                  
0023.00 C                   PARM                    USRSPC                        
0024.00 C                   PARM      'PF        '  ATTR             10     
0025.00 C                   PARM      1000          SIZE             13 5   
0026.00 C                   PARM      ' '           INZCHR            1     
0027.00 C                   PARM      '*ALL      '  AUT              10     
0028.00 C                   PARM                    USRTXT                  
0029.00 C                   PARM      '*YES      '  REPLCE           10     
0030.00 C                   PARM                    APIERR                  
0031.00 C*----------------------------------------------------+             
0032.00 C     AVLBYT        IFNE      *ZEROS                                
0033.00 C                   MOVE      'E'           ERR                     
0034.00 C                   ENDIF                                           
0035.00 C                   MOVE      APIERR        APIPRM                  
0036.00 C                   SETON                                        LR 
0037.00 C                   RETURN   


                                        

[解説]

API: QUSCRTUS を使ってライブラリーQTEMPにQUSLRCDという名前のユーザー・スペースを
作成している。
ユーザー・スペースは使ってしまえば不要なので一般的には
ライブラリーQTEMPに作成することが多い。
ユーザー・スペースの初期サイズは1000バイトに設定しているがこれは
APIでこのユーザー・スペースに出力されるときに自動的に拡張されるので
最初は1000バイトでもかまわない。

APIは一般的にメッセージ構造体APIERRを持っていてエラーがあれば
これにMSGIDとMSGDTAを返す。
MSGFの記述はないがQSYS/QCPFMSG と決まっているので特に記述はない。

0009.00 D APIERR          DS                                                      
0010.00 D  GETBYT                 1      4B 0 INZ(160)                            
0011.00 D  AVLBYT                 5      8B 0 INZ(0)                              
0012.00 D  MSGID                  9     15                                        
0013.00 D  MSGDTA                17    160

エラーが発生すればAVLBYTに長さが入るのでこれでエラーが発生したことを
検知することができる。
これはすべてのAPIに関して共通である。

[CLP: USCRTUSCL: ユーザー・スペースの作成]

ソースはこちらから

0001.00              PGM                                                          
0002.00 /*-------------------------------------------------------------------*/   
0003.00 /*   USCRTUS    :  ユーザー・スペースの作成                          */   
0004.00 /*                                                                   */   
0005.00 /*   2020/05/01  作成                                                */   
0006.00 /*-------------------------------------------------------------------*/   
0007.00              DCL        VAR(&MSG) TYPE(*CHAR) LEN(132)                    
0008.00              DCL        VAR(&MSGID) TYPE(*CHAR) LEN(7)                    
0009.00              DCL        VAR(&MSGF) TYPE(*CHAR) LEN(10)                    
0010.00              DCL        VAR(&MSGFLIB) TYPE(*CHAR) LEN(10)                 
0011.00              DCL        VAR(&MSGDTA) TYPE(*CHAR) LEN(132)                 
0012.00              DCL        VAR(&TYPE) TYPE(*CHAR) LEN(1)                     
0013.00              DCL        VAR(&TOPGMQ) TYPE(*CHAR) LEN(10)                  
0014.00              DCL        VAR(&MSGTYPE) TYPE(*CHAR) LEN(10) +               
0015.00                           VALUE('*ESCAPE   ')                             
0016.00              DCL        VAR(&APIERR) TYPE(*CHAR) LEN(160) +               
0017.00                           VALUE(X'000074') /* 2 進数  */                  
0018.00              DCL        VAR(&NULL4) TYPE(*CHAR) LEN(4) +                  
0019.00                           VALUE(X'00000000')                              
0020.00              DCL        VAR(&ERR) TYPE(*CHAR) LEN(1)                      
0021.00              MONMSG     MSGID(CPF0000) EXEC(GOTO CMDLBL(ERROR))           
0022.00                                                                           
0023.00 /*( 環境の取得 )*/                                                        
0024.00              RTVJOBA    TYPE(&TYPE)                                     
0025.00              IF         COND(&TYPE *EQ '0') THEN(DO) /*  バッチ  */     
0026.00              CHGVAR     VAR(&TOPGMQ) VALUE('*SYSOPR   ')                
0027.00              ENDDO      /*  バッチ  */                                  
0028.00              ELSE       CMD(DO) /*  対話式  */                          
0029.00              CHGVAR     VAR(&TOPGMQ) VALUE('*TOPGMQ   ')                
0030.00              ENDDO      /*  対話式  */                                  
0031.00                                                                         
0032.00 /*( プログラムの実行 )*/                                                
0033.00              CALL       PGM(R610OBJ/USCRTUS) PARM(&ERR &APIERR)         
0034.00              IF         COND(&ERR *EQ ' ') THEN(DO)                     
0035.00              CHGVAR     VAR(&MSGTYPE) VALUE('*DIAG     ')               
0036.00              ENDDO                                                      
0037.00              IF         COND(%SST(&APIERR 5 4) *NE &NULL4) THEN(DO)     
0038.00              SNDPGMMSG  +                                               
0039.00                           MSG('API: QUSCRTUS の実行で次のエラーが発生 + 
0040.00                            しました。 ') MSGTYPE(*DIAG)                 
0041.00              GOTO       APIERR                                          
0042.00              ENDDO                                                      
0043.00              RETURN                                                     
0044.00                                                                         
0045.00  APIERR:                                                                
0046.00              CHGVAR     VAR(&MSGID) VALUE(%SST(&APIERR 9 7))            
0047.00              CHGVAR     VAR(&MSGDTA) VALUE(%SST(&APIERR 17 100))        
0048.00              CHGVAR     VAR(&MSGF) VALUE('QCPFMSG   ')                 
0049.00              CHGVAR     VAR(&MSGFLIB) VALUE('QSYS      ')              
0050.00              GOTO       SNDMSG                                         
0051.00                                                                        
0052.00  ERROR:      RCVMSG     MSGTYPE(*LAST) RMV(*NO) MSG(&MSG) +            
0053.00                           MSGDTA(&MSGDTA) MSGID(&MSGID) MSGF(&MSGF) +  
0054.00                           MSGFLIB(&MSGFLIB)                            
0055.00  SNDMSG:     IF         COND(&MSGID *EQ ' ') THEN(DO)                  
0056.00              SNDPGMMSG  MSGID(CPF9897) MSGF(QCPFMSG) MSGDTA(&MSG) +    
0057.00                           TOMSGQ(&TOPGMQ) MSGTYPE(&MSGTYPE)            
0058.00              MONMSG     MSGID(CPF2400) EXEC(RETURN)                    
0059.00              ENDDO                                                     
0060.00              ELSE       CMD(DO)                                        
0061.00              SNDPGMMSG  MSGID(&MSGID) MSGF(&MSGFLIB/&MSGF) +           
0062.00                           MSGDTA(&MSGDTA) TOMSGQ(&TOPGMQ) +            
0063.00                           MSGTYPE(&MSGTYPE)                            
0064.00              MONMSG     MSGID(CPF2400) EXEC(RETURN)                    
0065.00              ENDDO                                                     
0066.00              ENDPGM    


                                                  

[解説]

APIエラーが発生したときはQCPFMSGを検索してエラー内容を報告する。