コマンド

62. コマンド処理に便利なDEFINE定義

コマンドで複合パラメータは良く使われる。

[例: TETSFONT ]

                            FONT の指定  (TESTFONT)       
                                                          
 選択項目を入力して,実行キーを押してください。           
                                                          
 フォント :                                               
   識別コード名  . . . . . . . . > 'MS-GOTHIC'    文字値  
   フォント・サイズ  . . . . . . > 13.5           数値    
                                                          

[解説]

このように複数の項目をまとめて複合パラメータとして表示すれば
見やすくわかりやすくなる。
_

[コマンド: TESTFONT ]

ソースはこちらから

0001.00              CMD        PROMPT('FONT の指定 ')       
0002.00              PARM       KWD(FONT) +                  
0003.00                         TYPE(FONT) +                 
0004.00                         PROMPT(' フォント ')         
0005.00 FONT:        ELEM       TYPE(*CHAR) +                
0006.00                         LEN(10) +                    
0007.00                         PROMPT(' 識別コード名 ')     
0008.00              ELEM       TYPE(*DEC) +                 
0009.00                         LEN(5 1) +                   
0010.00                         PROMPT(' フォント・サイズ ') 


   

[コンパイル]

CRTCMD CMD(OBJLIB/TESTFONT) PGM(OBJLIB/TESTFONTCL) SRCFILE(SRCLIB/QMDSRC) AUT(*ALL)
[解説]
この複合パラメータ: FONT はひとつの変数としてCLPに渡されるので
CLPでそれを分割して使用しなければならない。

[ CLP: TESTFONTCL ]

ソースはこちらから

0001.00              PGM        PARM(+                                                
0002.00                         &FONTINFO +                                           
0003.00                         )                                                     
0004.00 /*----------------------------------------------------------------------*/    
0005.00 /*    TESTFONTCL:FONT の指定                                            */    
0006.00 /*                                                                      */    
0007.00 /*     作成 : 2023/07/01                                                */    
0008.00 /*----------------------------------------------------------------------*/    
0009.00              DCL        VAR(&FONTINFO) TYPE(*CHAR) LEN(15)                    
0010.00              DCL        VAR(&FONT) TYPE(*CHAR) STG(*DEFINED) LEN(10) +        
0011.00                           DEFVAR(&FONTINFO 3)                                 
0012.00              DCL        VAR(&FONTSIZ) TYPE(*DEC) STG(*DEFINED) LEN(5 +        
0013.00                           2) DEFVAR(&FONTINFO 13)                             
0014.00              DCL        VAR(&MSG) TYPE(*CHAR) LEN(132)                        
0015.00              DCL        VAR(&STMMSG) TYPE(*CHAR) LEN(132)                     
0016.00              DCL        VAR(&MSGID) TYPE(*CHAR) LEN(7)                        
0017.00              DCL        VAR(&MSGF) TYPE(*CHAR) LEN(10)                        
0018.00              DCL        VAR(&MSGFLIB) TYPE(*CHAR) LEN(10)                     
0019.00              DCL        VAR(&MSGKEY) TYPE(*CHAR) LEN(4)                       
0020.00              DCL        VAR(&MSGDTA) TYPE(*CHAR) LEN(132)                     
0021.00              DCL        VAR(&ERRDTA) TYPE(*CHAR) LEN(132)                     
0022.00              DCL        VAR(&TYPE) TYPE(*CHAR) LEN(1)                         
0023.00              DCL        VAR(&TOPGMQ) TYPE(*CHAR) LEN(10)                      
0024.00              DCL        VAR(&MSGTYPE) TYPE(*CHAR) LEN(10) +         
0025.00                           VALUE('*ESCAPE   ')                       
0026.00              DCL        VAR(&ERR) TYPE(*CHAR) LEN(1)                
0027.00              DCL        VAR(&NULL4) TYPE(*CHAR) LEN(4) +            
0028.00                           VALUE(X'00000000')                        
0029.00              DCL        VAR(&APIERR) TYPE(*CHAR) LEN(116) +         
0030.00                           VALUE(X'0000007400000000') /* 2 進数  */  
0031.00              MONMSG     MSGID(CPF9999) EXEC(GOTO CMDLBL(ERROR))     
0032.00                                                                     
0033.00 /*( 環境の取得 )*/                                                  
0034.00              RTVJOBA    TYPE(&TYPE)                                 
0035.00              IF         COND(&TYPE *EQ '0') THEN(DO) /*  バッチ  */ 
0036.00              CHGVAR     VAR(&TOPGMQ) VALUE('*SYSOPR   ')            
0037.00              ENDDO      /*  バッチ  */                              
0038.00              ELSE       CMD(DO) /*  対話式  */                      
0039.00              CHGVAR     VAR(&TOPGMQ) VALUE('*TOPGMQ   ')            
0040.00              ENDDO      /*  対話式  */                              
0041.00                                                                     
0042.00 /*( 入力パラメータの検査 )*/                                        
0043.00                                                                     
0044.00 /*( プログラムの実行 )*/                                            
0045.00              CALL       PGM(TESTFONT) PARM(&ERR &MSG)               
0046.00              IF         COND(&ERR *EQ ' ') THEN(DO)                 
0047.00              CHGVAR     VAR(&MSGTYPE) VALUE('*DIAG     ')           
0048.00              ENDDO                                                       
0049.00              IF         COND(&MSG *NE ' ') THEN(DO)                      
0050.00              GOTO       SNDMSG                                           
0051.00              ENDDO                                                       
0052.00              RETURN                                                      
0053.00                                                                          
0054.00  ERROR:      RCVMSG     MSGTYPE(*LAST) RMV(*NO) KEYVAR(&MSGKEY) +        
0055.00                           MSGDTA(&MSGDTA) MSGID(&MSGID) MSGF(&MSGF) +    
0056.00                           SNDMSGFLIB(&MSGFLIB)                           
0057.00              IF         COND(&MSGID *EQ 'CPF9999') THEN(DO)              
0058.00              CHGVAR     VAR(&ERRDTA) VALUE(&MSGDTA)                      
0059.00              RCVMSG     MSGTYPE(*PRV) MSGKEY(&MSGKEY) RMV(*NO) +         
0060.00                           MSG(&MSG) MSGDTA(&MSGDTA) MSGID(&MSGID) +      
0061.00                           MSGF(&MSGF) MSGFLIB(&MSGFLIB)                  
0062.00              CHGVAR     VAR(&STMMSG) VALUE(' プログラム ' *CAT +         
0063.00                           %SST(&ERRDTA 8 10) *TCAT +                     
0064.00                           ' のステートメント ' *CAT %SST(&ERRDTA +       
0065.00                           24 4) *CAT ' で次のエラーが発生しました。 ')   
0066.00              SNDPGMMSG  MSGID(CPF9897) MSGF(QCPFMSG) MSGDTA(&STMMSG) +   
0067.00                           TOMSGQ(&TOPGMQ) MSGTYPE(*DIAG)                 
0068.00              ENDDO                                                       
0069.00  SNDMSG:     IF         COND(&MSGID *EQ ' ') THEN(DO)                    
0070.00              SNDPGMMSG  MSGID(CPF9897) MSGF(QCPFMSG) MSGDTA(&MSG) +      
0071.00                           TOMSGQ(&TOPGMQ) MSGTYPE(&MSGTYPE)              
0072.00              MONMSG     MSGID(CPF2400) EXEC(RETURN)           
0073.00              ENDDO                                            
0074.00              ELSE       CMD(DO)                               
0075.00              SNDPGMMSG  MSGID(&MSGID) MSGF(&MSGFLIB/&MSGF) +  
0076.00                           MSGDTA(&MSGDTA) TOMSGQ(&TOPGMQ) +   
0077.00                           MSGTYPE(&MSGTYPE)                   
0078.00              MONMSG     MSGID(CPF2400) EXEC(RETURN)           
0079.00              ENDDO                                            
0080.00              ENDPGM   


                                           

[コンパイル]

CRTCLPGM PGM(OBJLIB/TESTFONTCL) SRCFILE(SRCLIB/QCLSRC) OPTION(*SRCDBG) AUT(*ALL)

[解説]

&FONTINFO というひとつの名前の変数でパラメータ値を受取るのだが
これを &FONT と &FONTSIZ というふたつの変数に分解しなければならない。
これを演算命令で

CHGVAR     VAR(&FONT) VALUE(%SST(&FONTINFO 3 10))     
CHGVAR     VAR(&FONTSIZC) VALUE(%SST(&FONTINFO 13 2)) 

のように実行する必要はない。
特に フォント・サイズは数字であり

            DCL        VAR(&FONTSIZ) TYPE(*DEC) LEN(5 2)

と定義されるのでいったん2バイトの文字として取り出してそれをベースとした
ポインタからバック10進数(*DEC)を生成しなければならず
かなり面倒である。
しかしここでは DEFINEを使って

0010.00              DCL        VAR(&FONT) TYPE(*CHAR) STG(*DEFINED) LEN(10) +        
0011.00                           DEFVAR(&FONTINFO 3)                                 
0012.00              DCL        VAR(&FONTSIZ) TYPE(*DEC) STG(*DEFINED) LEN(5 +        
0013.00                           2) DEFVAR(&FONTINFO 13) 

として &FONT と &FONTSIZ が &FONTINFO の一部であると同時定義してしまえば
演算の必要はなくて非常にスマートである。

&FONTSIZ はバック10進数(*DEC)であるが直ちに使用することができる。

なお &FONT を &FONTINFO の先頭から3バイト目から取り出しているのは
&FONTINFOが ELEM パラメータで構成されているからである。
ELEM パラメータで構成された場合は最初の2バイトは Short Int の長さが
i5/OSによって挿入されてしまうのでそれを迂回して先頭から 3バイト目以降から
取り出すようにしている。
ELEM でなく QUALパラメータで構成されている場合は 2バイトのShort Int は挿入されない。
_