System API の使用例 - CL から V5R4 CL への書き直し -

CL を RPG に書き直すと読みやすくなる、ということで「System API の使用例 - CL から RPG への書き直し -」や「System API の使用例 - CL から RPG への書き直し [異版] -」を紹介してきたわけなのですが、この「活動ジョブの検査」を V5R4 時点での CL に書き直すとやはり "余計な CHGVAR" と "GOTO によるループ" がなくなることで読みやすくなります。それだけ V5R3/V5R4 での機能拡張は大きなものだったと言えるでしょう。

             PGM        PARM(&PARM1 &STS)                                       

     /* 引数の定義*/                                                                 
             DCL        VAR(&PARM1) TYPE(*CHAR) LEN(26)                         
             DCL        VAR(&JOBPARM) TYPE(*CHAR) LEN(26)                       
             DCL        VAR(&JOB) TYPE(*CHAR) STG(*DEFINED) LEN(10) +           
                          DEFVAR(&PARM1 1)                                      
             DCL        VAR(&USR) TYPE(*CHAR) STG(*DEFINED) LEN(10) +           
                          DEFVAR(&PARM1 11)                                     
             DCL        VAR(&NBR) TYPE(*CHAR) STG(*DEFINED) LEN(6) +            
                          DEFVAR(&PARM1 21)                                     
             DCL        VAR(&STS) TYPE(*CHAR) LEN(10)                           
     /* ユーザースペース*/                                                              
             DCL        VAR(&USRSPC) TYPE(*CHAR) LEN(20) +                      
                          VALUE('CHKACTJOB QTEMP     ')                         
             DCL        VAR(&USOBJ) TYPE(*CHAR) STG(*DEFINED) +                 
                          LEN(10) DEFVAR(&USRSPC 1)                             
             DCL        VAR(&USLIB) TYPE(*CHAR) STG(*DEFINED) +                 
                          LEN(10) DEFVAR(&USRSPC 11)                            
     /* リスト項目 */                                                                
             DCL        VAR(&LSTJOBE) TYPE(*CHAR) LEN(52)                       
             DCL        VAR(&JOBNAME) TYPE(*CHAR) STG(*DEFINED) +               
                          LEN(10) DEFVAR(&LSTJOBE 1)                            
             DCL        VAR(&USRNAME) TYPE(*CHAR) STG(*DEFINED) +               
                          LEN(10) DEFVAR(&LSTJOBE 11)                           
             DCL        VAR(&JOBNBR) TYPE(*CHAR) STG(*DEFINED) +                
                          LEN(6) DEFVAR(&LSTJOBE 21)                            
             DCL        VAR(&JOBSTS) TYPE(*CHAR) STG(*DEFINED) +                
                          LEN(10) DEFVAR(&LSTJOBE 43)                           
     /* ヘッダ項目 */                                                                
             DCL        VAR(&ENTRY) TYPE(*UINT) LEN(4)                          
             DCL        VAR(&STR) TYPE(*UINT) LEN(4)                            
             DCL        VAR(&OFFSET) TYPE(*UINT) LEN(4)                         
             DCL        VAR(&ENTLEN) TYPE(*UINT) LEN(4)                         
     /* カウンタ */                                                                 
             DCL        VAR(&I) TYPE(*INT) LEN(2)  
                             
     /* 引数のチェック*/                                                               
             IF         COND(&JOB = '          ') THEN(CHGVAR +                 
                          VAR(&JOB) VALUE('*ALL     '))                         
             IF         COND(&USR = '          ') THEN(CHGVAR +                 
                          VAR(&USR) VALUE('*ALL     '))                         
             IF         COND(&NBR = '      ') THEN(CHGVAR VAR(&NBR) +           
                          VALUE('*ALL  '))                                      
             IF         COND(&STS = '          ') THEN(CHGVAR +                 
                          VAR(&STS) VALUE('*ALL     '))                         
     /* 初期化*/                                                                   
             CHKOBJ     OBJ(&USLIB/&USOBJ) OBJTYPE(*USRSPC)                     
             MONMSG     MSGID(CPF9801) EXEC(+                                   
             CALL       PGM(QUSCRTUS) PARM(&USRSPC 'CHKACTJOB ' +               
                          X'00000100' ' ' '*ALL      ' 'CHKACTJOB +             
                          TEMPORARY USER SPACE'))                               
             CLRPFM     FILE(QCHKACTJ)                                          
     /* ジョブ情報の取得*/                                                              
             CHGVAR     VAR(%SST(&JOBPARM 1 10)) VALUE(&JOB)                    
             CHGVAR     VAR(%SST(&JOBPARM 11 10)) VALUE(&USR)                   
             CHGVAR     VAR(%SST(&JOBPARM 21 6)) VALUE(&NBR)                    
             CALL       PGM(QUSLJOB) PARM(&USRSPC 'JOBL0100' +                  
                          &JOBPARM &STS)                                        
     /* ジョブ情報項目の取得*/                                                            
             CALL       PGM(QUSRTVUS) PARM(&USRSPC X'00000085' +                
                          X'00000004' &ENTRY)                                   
             IF         COND(&ENTRY = 0) THEN(GOTO CMDLBL(NOJOB))               
             CALL       PGM(QUSRTVUS) PARM(&USRSPC X'00000089' +                
                          X'00000004' &ENTLEN)                                  
             CALL       PGM(QUSRTVUS) PARM(&USRSPC X'0000007D' +                
                          X'00000004' &OFFSET)                                  
             CHGVAR     VAR(&STR) VALUE(&OFFSET + 1)                            
     /* ループ*/                                                                   
             DOFOR      VAR(&I) FROM(1) TO(&ENTRY) BY(1)                        
             CALL       PGM(QUSRTVUS) PARM(&USRSPC &STR &ENTLEN +               
                          &LSTJOBE)                                             
             CALLPRC    PRC(WRITEFILE) PARM(&JOBNAME &USRNAME +                 
                          &JOBNBR &JOBSTS)                                      
             CHGVAR     VAR(&STR) VALUE(&STR + &ENTLEN)                         
             ENDDO                                                              

 NOJOB:      ENDPGM

見直してみるといろいろ書き直せるポイントが発見できます。

オブジェクトの存在チェック

たとえば

             DLTUSRSPC  USRSPC(QTEMP/&OBJ)                                       
             MONMSG     MSGID(CPF0000)                                           
             CLRPFM     FILE(QCHKACTJ)                                           
             CALL       PGM(QUSCRTUS) PARM(&USRSPC 'CHKACTJOB ' +               
                          X'00000100' ' ' '*ALL      ' 'CHKACTJOB +             
                          TEMPORARY USER SPACE')                                 

             CHKOBJ  OBJ(QTEMP/&OBJ) OBJTYPE(*USRSPC)                                       
             MONMSG     MSGID(CPF9801) EXEC( +                                          
             CALL       PGM(QUSCRTUS) PARM(&USRSPC 'CHKACTJOB ' +               
                          X'00000100' ' ' '*ALL      ' 'CHKACTJOB +             
                          TEMPORARY USER SPACE'))     
             CLRPFM     FILE(QCHKACTJ)                                                      

というようにも書き換えられますね。こちらの方が毎回 DLTUSRSSPC をやらない分 CPU は無駄にしないでいいのかなという気もします。
これは V5R4 の機能でもなんでもなく単なる処理の見直しですね。
"CPF9801" というのは↓のメッセージです。

定義済み変数

V5R4 での CL の拡張」で紹介した「定義済み変数」を使用することで、CHGVAR を DCL 文であらかじめ定義しておくことができます。
RPG の D 仕様書のようなかんじですね。データ・ストラクチャ的に使用できますし、C でいう構造体のような使い方もでき、今どきのプログラミングモデルにも合致しています。

たとえば

             DCL        VAR(&PARM1) TYPE(*CHAR) LEN(26)                         

             DCL        VAR(&JOB) TYPE(*CHAR) LEN(10)                           
             DCL        VAR(&USR) TYPE(*CHAR) LEN(10)                           
             DCL        VAR(&NBR) TYPE(*CHAR) LEN(6)                             

             CHGVAR     VAR(&JOB) VALUE(%SST(&PARM1 1 10))                       
             CHGVAR     VAR(&USR) VALUE(%SST(&PARM1 11 10))                     
             CHGVAR     VAR(&NBR) VALUE(%SST(&PARM1 21 6))           

             DCL        VAR(&PARM1) TYPE(*CHAR) LEN(26)                         

             DCL        VAR(&JOB) TYPE(*CHAR) STG(*DEFINED) LEN(10) DEFVAR(&PARM1 1)                                      
             DCL        VAR(&USR) TYPE(*CHAR) STG(*DEFINED) LEN(10) DEFVAR(&PARM1 11)                                     
             DCL        VAR(&NBR) TYPE(*CHAR) STG(*DEFINED) LEN(6) DEFVAR(&PARM1 21)            

のように書き直すことができます。

INTEGER 型と API

V5R3 からですが、Integer がデータ型として使用できるようになったため、API の戻り値を変換することなく使用できるようになりました。

             DCL        VAR(&BIN4) TYPE(*CHAR) LEN(4)                           
             DCL        VAR(&ENTRY) TYPE(*DEC) LEN(8 0)                         

             CALL       PGM(QUSRTVUS) PARM(&USRSPC X'00000085' +                 
                          X'00000004' &BIN4)                                     
             CHGVAR     VAR(&ENTRY) VALUE(%BIN(&BIN4))                           

             DCL        VAR(&ENTRY) TYPE(*UINT) LEN(4)                          

             CALL       PGM(QUSRTVUS) PARM(&USRSPC X'00000085' +                
                          X'00000004' &ENTRY)                                   

で済んでしまうわけです。

処理部分だけで見てみると、

             CALL       PGM(QUSLJOB) PARM(&USRSPC 'JOBL0100'  &JOBPARM &STS)                                         
             CALL       PGM(QUSRTVUS) PARM(&USRSPC X'00000085'  X'00000004' &BIN4)                                     
             CHGVAR     VAR(&ENTRY) VALUE(%BIN(&BIN4))                           
             IF         COND(&ENTRY = 0) THEN(GOTO CMDLBL(NOJOB))               
             CALL       PGM(QUSRTVUS) PARM(&USRSPC X'00000089'  X'00000004' &ENTLENB)                                 
             CHGVAR     VAR(&ENTLEN) VALUE(%BIN(&ENTLENB))                       
             CALL       PGM(QUSRTVUS) PARM(&USRSPC X'0000007D'  X'00000004' &OFFSETB)                                 
             CHGVAR     VAR(&OFFSET) VALUE(%BIN(&OFFSETB))                       
             CHGVAR     VAR(&STR) VALUE(&OFFSET + 1)     

             CALL       PGM(QUSRTVUS) PARM(&USRSPC X'00000085'  X'00000004' &ENTRY)                                   
             IF         COND(&ENTRY = 0) THEN(GOTO CMDLBL(NOJOB))               
             CALL       PGM(QUSRTVUS) PARM(&USRSPC X'00000089'  X'00000004' &ENTLEN)                                  
             CALL       PGM(QUSRTVUS) PARM(&USRSPC X'0000007D'  X'00000004' &OFFSET)                                  
             CHGVAR     VAR(&STR) VALUE(&OFFSET + 1)                            

になっています。
こちらの方がすっきりしているのは間違いのないところでしょう。

ループ

定義済み変数の力も借りていますが、ループについては、

 DO:         CHGVAR     VAR(%BIN(&BIN4)) VALUE(&STR)                             
             CALL       PGM(QUSRTVUS) PARM(&USRSPC &BIN4 &ENTLENB &LSTJOBE)                                             
             CHGVAR     VAR(&JOBNAME) VALUE(%SST(&LSTJOBE 1 10))                 
             CHGVAR     VAR(&USRNAME) VALUE(%SST(&LSTJOBE 11 10))               
             CHGVAR     VAR(&JOBNBR) VALUE(%SST(&LSTJOBE 21 6))                 
             CHGVAR     VAR(&JOBSTS) VALUE(%SST(&LSTJOBE 43 10))   
             CALLPRC    PRC(WRITEFILE) PARM(&JOBNAME &USRNAME &JOBNBR &JOBSTS)                                       
             CHGVAR     VAR(&STR) VALUE(&STR + &ENTLEN)                         
             CHGVAR     VAR(&ENTRY) VALUE(&ENTRY - 1)                           
             IF         COND(&ENTRY = 0) THEN(GOTO CMDLBL(NOJOB))               
             GOTO       CMDLBL(DO)

             DOFOR      VAR(&I) FROM(1) TO(&ENTRY) BY(1)                        
             CALL       PGM(QUSRTVUS) PARM(&USRSPC &STR &ENTLEN &LSTJOBE)                                             
             CALLPRC    PRC(WRITEFILE) PARM(&JOBNAME &USRNAME &JOBNBR &JOBSTS)                                      
             CHGVAR     VAR(&STR) VALUE(&STR + &ENTLEN)                         
             ENDDO                                                              

になっています。
やはりこちらの方が見やすいしわかりやすいと思います。


(参考までに) 元のプログラム

こちらが元の CL プログラムになります。まぁ微妙な違いかもしれませんが、けっこう大きなことだと思います。

             PGM        PARM(&PARM1 &STS)                                       
             DCL        VAR(&FILE) TYPE(*CHAR) LEN(10)                           
             DCL        VAR(&PARM1) TYPE(*CHAR) LEN(26)                         
             DCL        VAR(&JOBPARM) TYPE(*CHAR) LEN(26)                       
             DCL        VAR(&JOB) TYPE(*CHAR) LEN(10)                           
             DCL        VAR(&USR) TYPE(*CHAR) LEN(10)                           
             DCL        VAR(&NBR) TYPE(*CHAR) LEN(6)                             
             DCL        VAR(&STS) TYPE(*CHAR) LEN(10)                           
             DCL        VAR(&OBJ) TYPE(*CHAR) LEN(10)                           
             DCL        VAR(&USRSPC) TYPE(*CHAR) LEN(20) +                       
                          VALUE('CHKACTJOB QTEMP     ')                         
             DCL        VAR(&JOBNAME) TYPE(*CHAR) LEN(10)                       
             DCL        VAR(&USRNAME) TYPE(*CHAR) LEN(10)                       
             DCL        VAR(&JOBNBR) TYPE(*CHAR) LEN(6)                         
             DCL        VAR(&JOBSTS) TYPE(*CHAR) LEN(10)                         
             DCL        VAR(&LSTJOBE) TYPE(*CHAR) LEN(52)                       
             DCL        VAR(&BIN4) TYPE(*CHAR) LEN(4)                           
             DCL        VAR(&ENTRY) TYPE(*DEC) LEN(8 0)                         
             DCL        VAR(&STR) TYPE(*DEC) LEN(8 0)                           
             DCL        VAR(&OFFSET) TYPE(*DEC) LEN(8 0)                         
             DCL        VAR(&OFFSETB) TYPE(*CHAR) LEN(4)                         
             DCL        VAR(&ENTLEN) TYPE(*DEC) LEN(8 0)                         
             DCL        VAR(&ENTLENB) TYPE(*CHAR) LEN(4)                         
             CHGVAR     VAR(&JOB) VALUE(%SST(&PARM1 1 10))                       
             CHGVAR     VAR(&USR) VALUE(%SST(&PARM1 11 10))                     
             CHGVAR     VAR(&NBR) VALUE(%SST(&PARM1 21 6))                       
             IF         COND(&JOB = '          ') THEN(CHGVAR +                 
                          VAR(&JOB) VALUE('*ALL     '))                         
             IF         COND(&USR = '          ') THEN(CHGVAR +                 
                          VAR(&USR) VALUE('*ALL     '))                         
             IF         COND(&NBR = '      ') THEN(CHGVAR VAR(&NBR) +           
                          VALUE('*ALL  '))                                       
             IF         COND(&STS = '          ') THEN(CHGVAR +                 
                          VAR(&STS) VALUE('*ALL     '))                         
             CHGVAR     VAR(&OBJ) VALUE(%SST(&USRSPC 1 10))                     
             DLTUSRSPC  USRSPC(QTEMP/&OBJ)                                       
             MONMSG     MSGID(CPF0000)                                           
             CLRPFM     FILE(QCHKACTJ)                                           
             CALL       PGM(QUSCRTUS) PARM(&USRSPC 'CHKACTJOB ' +               
                          X'00000100' ' ' '*ALL      ' 'CHKACTJOB +             
                          TEMPORARY USER SPACE')                                 
             CHGVAR     VAR(%SST(&JOBPARM 1 10)) VALUE(&JOB)                     
             CHGVAR     VAR(%SST(&JOBPARM 11 10)) VALUE(&USR)                   
             CHGVAR     VAR(%SST(&JOBPARM 21 6)) VALUE(&NBR)                     
             CALL       PGM(QUSLJOB) PARM(&USRSPC 'JOBL0100' +                   
                          &JOBPARM &STS)                                         
             CALL       PGM(QUSRTVUS) PARM(&USRSPC X'00000085' +                 
                          X'00000004' &BIN4)                                     
             CHGVAR     VAR(&ENTRY) VALUE(%BIN(&BIN4))                           
             IF         COND(&ENTRY = 0) THEN(GOTO CMDLBL(NOJOB))               
             CALL       PGM(QUSRTVUS) PARM(&USRSPC X'00000089' +                 
                          X'00000004' &ENTLENB)                                 
             CHGVAR     VAR(&ENTLEN) VALUE(%BIN(&ENTLENB))                       
             CALL       PGM(QUSRTVUS) PARM(&USRSPC X'0000007D' +                 
                          X'00000004' &OFFSETB)                                 
             CHGVAR     VAR(&OFFSET) VALUE(%BIN(&OFFSETB))                       
             CHGVAR     VAR(&STR) VALUE(&OFFSET + 1)                             
 DO:         CHGVAR     VAR(%BIN(&BIN4)) VALUE(&STR)                             
             CALL       PGM(QUSRTVUS) PARM(&USRSPC &BIN4 &ENTLENB +             
                          &LSTJOBE)                                             
             CHGVAR     VAR(&JOBNAME) VALUE(%SST(&LSTJOBE 1 10))                 
             CHGVAR     VAR(&USRNAME) VALUE(%SST(&LSTJOBE 11 10))               
             CHGVAR     VAR(&JOBNBR) VALUE(%SST(&LSTJOBE 21 6))                 
             CHGVAR     VAR(&JOBSTS) VALUE(%SST(&LSTJOBE 43 10))                 
             CHGVAR     VAR(&FILE) VALUE('QCHKACTJ')                             
       /*    CALL       PGM(WRITEFILE) PARM(&JOBNAME &USRNAME +                 
                          &JOBNBR &JOBSTS)                        */             
             CALLPRC    PRC(WRITEFILE) PARM(&JOBNAME &USRNAME +                 
                          &JOBNBR &JOBSTS)                                       
             CHGVAR     VAR(&STR) VALUE(&STR + &ENTLEN)                         
             CHGVAR     VAR(&ENTRY) VALUE(&ENTRY - 1)                           
             IF         COND(&ENTRY = 0) THEN(GOTO CMDLBL(NOJOB))               
             GOTO       CMDLBL(DO)                                               
 NOJOB:      ENDPGM

[Top Pageに戻る]

Ads by TOK2