コマンド

53. コマンドの妥当性検査

コマンドの入力妥当性検査は PARM文に VLDCKRキー・ワードを
指定するだけでユーザー・プログラムで自由に妥当性を検査することができる。

                               印刷の出力  (OUTPUT)                 
                                                                    
  選択項目を入力して,実行キーを押してください。                    
                                                                    
  担当者コード  . . . . . . . . .                  文字値           
  出力オプション  . . . . . . . .   *PRINT        *PRINT, *OUTFILE  
                                                                    

                                                                            
                                                                        終り
F3= 終了    F4=プロンプト   F5= 最新表示    F12= 取り消し                      
F13= この画面の使用法                    F24= キーの続き                    

このコマンドのソースを次に示す。

[コマンド: OUTPUT ]

ソースはこちらから

0001.00              CMD        PROMPT(' 印刷の出力 ') VLDCKR(QUATTRO/OUTCHK)  
0002.00              PARM       KWD(TANCOD) TYPE(*CHAR) LEN(4) MIN(1) +        
0003.00                           PROMPT(' 担当者コード ')                     
0004.00              PARM       KWD(OPTION) TYPE(*CHAR) LEN(10) RSTD(*YES) +   
0005.00                           DFT(*PRINT) VALUES(*PRINT *OUTFILE) +        
0006.00                           PROMPT(' 出力オプション ')      


             

[解説]

VLDCKR(QUATTRO/OUTCHK) という記述に注目して欲しい。
これは 妥当性検査プログラム(VLDCKR)の定義でエンド・ユーザーが実行キーを
押したときに呼び出されて入力値の妥当性を検査することができる。

妥当性検査プログラム(VLDCKR)はコマンドのコンパイルのときに

CRTCMD CMD(QUATTRO/OUTPUT) PGM(QUATTRO/OUTPUTCL) SRCFILE(R610SRC/QCMDSRC)
VLDCKR(QUATTRO/OUTCHK) AUT(*ALL)

のようにして VLDCKRを指定してもよいのだが再コンパイルのときに
いちいちコマンドの内容をDSPCMDで調べて VLDCKRなどの必要なコンパイルの指定を
調べなければならない。

CMD行のソースに VLDCKRを指定しておけば

CRTCMD CMD(QUATTRO/OUTPUT) PGM(QUATTRO/OUTPUTCL) SRCFILE(R610SRC/QCMDSRC)
AUT(*ALL)

のように VLDCKRを指定する必要がないので便利である。
次にこのコマンドの処理プログラムのソースを次のように紹介する。

[処理プログラム: OUTPUTCL ]

ソースはこちらから

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

                                            

さて妥当性検査プログラム(VLDCKR)を次に紹介する。

[妥当性検査プログラム: OUTCHK ]

ソースはこちらから

0001.00              PGM        PARM(&TANCOD &OPTION)                           
0002.00 /*-------------------------------------------------------------------*/ 
0003.00 /*   OUTCHK    :   コマンドの妥当性検査プログラム  VLDCKR            */ 
0004.00 /*                                                                   */ 
0005.00 /*   2020/04/11  作成                                                */ 
0006.00 /*-------------------------------------------------------------------*/ 
0007.00              DCL        VAR(&TANCOD) TYPE(*CHAR) LEN(4)                 
0008.00              DCL        VAR(&OPTION) TYPE(*CHAR) LEN(10)                
0009.00              DCL        VAR(&DEV) TYPE(*CHAR) LEN(10)                   
0010.00              DCL        VAR(&MSG) TYPE(*CHAR) LEN(132)                  
0011.00              DCL        VAR(&MSGID) TYPE(*CHAR) LEN(7)                  
0012.00              DCL        VAR(&MSGF) TYPE(*CHAR) LEN(10)                  
0013.00              DCL        VAR(&MSGFLIB) TYPE(*CHAR) LEN(10)               
0014.00              DCL        VAR(&MSGDTA) TYPE(*CHAR) LEN(132)               
0015.00              DCL        VAR(&TYPE) TYPE(*CHAR) LEN(1)                   
0016.00              DCL        VAR(&TOPGMQ) TYPE(*CHAR) LEN(10)                
0017.00              DCL        VAR(&MSGTYPE) TYPE(*CHAR) LEN(10) +             
0018.00                           VALUE('*ESCAPE   ')                           
0019.00              DCL        VAR(&ERR) TYPE(*CHAR) LEN(1)                    
0020.00              DCL        VAR(&NULL4) TYPE(*CHAR) LEN(4) +                
0021.00                           VALUE(X'00000000')                            
0022.00              MONMSG     MSGID(CPF0000) EXEC(GOTO CMDLBL(ERROR))         
0023.00                                                                         
0024.00 /*( 環境の取得 )*/                                                     
0025.00              RTVJOBA    TYPE(&TYPE)                                    
0026.00              IF         COND(&TYPE *EQ '0') THEN(DO) /*  バッチ  */    
0027.00              CHGVAR     VAR(&TOPGMQ) VALUE('*SYSOPR   ')               
0028.00              ENDDO      /*  バッチ  */                                 
0029.00              ELSE       CMD(DO) /*  対話式  */                         
0030.00              CHGVAR     VAR(&TOPGMQ) VALUE('*TOPGMQ   ')               
0031.00              ENDDO      /*  対話式  */                                 
0032.00                                                                        
0033.00 /*( 入力パラメータの検査 )*/                                           
0034.00              IF         COND(&TANCOD *EQ ' ') THEN(DO)                 
0035.00              CHGVAR     VAR(&MSG) +                                    
0036.00                           VALUE(' 担当者コードが入力されていません。 ')
0037.00              GOTO       SNDMSG                                         
0038.00              ENDDO                                                     
0039.00                                                                        
0040.00 /*( プログラムの実行 )*/                                               
0041.00              IF         COND((&TANCOD *EQ '0001') *OR (&TANCOD *EQ +   
0042.00                           '0002') *OR (&TANCOD *EQ '0003')) THEN(DO)   
0043.00              RETURN                                                    
0044.00              ENDDO                                                     
0045.00              ELSE       CMD(DO)                                        
0046.00              CHGVAR     VAR(&MSG) VALUE(' 担当者コード ' *CAT +        
0047.00                           &TANCOD *TCAT ' の誤りです。 ')              
0048.00              GOTO       SNDMSG                                         
0049.00              ENDDO                                                     
0050.00                                                                        
0051.00  ERROR:      RCVMSG     MSGTYPE(*LAST) RMV(*NO) MSG(&MSG) +            
0052.00                           MSGDTA(&MSGDTA) MSGID(&MSGID) MSGF(&MSGF) +  
0053.00                           MSGFLIB(&MSGFLIB)                            
0054.00  SNDMSG:     CHGVAR     VAR(&MSGDTA) VALUE('0000' *CAT &MSG)           
0055.00              /*( 妥当性検査のエラーは最初に CPD0006 を戻します )*/     
0056.00              SNDPGMMSG  MSGID(CPD0006) MSGF(QCPFMSG) MSGDTA(&MSGDTA) + 
0057.00                           MSGTYPE(*DIAG)                               
0058.00              MONMSG     MSGID(CPF2400) EXEC(RETURN)                    
0059.00              /*( 妥当性検査のエラーは CPF0002 を戻します )*/           
0060.00              SNDPGMMSG  MSGID(CPF0002) MSGF(QCPFMSG) MSGTYPE(*ESCAPE)  
0061.00              ENDPGM     


                                                                                                                      

[解説]

この妥当性検査プログラム: OUTCHKが受取るパラメータは

0001.00              PGM        PARM(&TANCOD &OPTION)

 

であり、これはコマンドの処理プログラムと同じパラメータを受取るように
記述しなければならない。

次にこの妥当性検査プログラムではサンプルとしてわかりやすくするために
担当者コードが 0001, 0002または 0003以外はエラーとすると処理している。
それが

0041.00              IF         COND((&TANCOD *EQ '0001') *OR (&TANCOD *EQ +   
0042.00                           '0002') *OR (&TANCOD *EQ '0003')) THEN(DO)   
0043.00              RETURN                                                    
0044.00              ENDDO 

の部分である。
それ以外はエラーとしてエラー・メッセージを次のようにして作成している。

0046.00              CHGVAR     VAR(&MSG) VALUE(' 担当者コード ' *CAT +        
0047.00                           &TANCOD *TCAT ' の誤りです。 ')              
0048.00              GOTO       SNDMSG                                         
0049.00              ENDDO 

 

最後にエラー・メッセージをMSGID: CPD0006 に組み込んで

0055.00              /*( 妥当性検査のエラーは最初に CPD0006 を戻します )*/     
0056.00              SNDPGMMSG  MSGID(CPD0006) MSGF(QCPFMSG) MSGDTA(&MSGDTA) + 
0057.00                           MSGTYPE(*DIAG)

として *DIAG で出力すると同時に最後には

0059.00              /*( 妥当性検査のエラーは CPF0002 を戻します )*/           
0060.00              SNDPGMMSG  MSGID(CPF0002) MSGF(QCPFMSG) MSGTYPE(*ESCAPE)

 

として *ESCAPEメッセージを送出する。
これは i5/OSに仕様として決められていることなのでこのルールに従って出力しなければならない。
実際にエラーは次のように出力される。

この画面は左下に高輝度でメッセージが出力されていていかにもプログラムで
エラー・メッセージを出力しているように見える。
  コマンドの妥当性検査プログラムの書き方を覚えておくとどのようなコマンドでも
妥当性検査をユーザー・プログラムで行うことができるので
コマンドの使用範囲は大幅に広がる。
コマンドでは入力チェックができないのでコマンドは使えないと思っていた人には
朗報となるだろう。