コマンド

34.複合パラメータから値を取得するには (1)

2つ以上のパラメータからなる複合パラメータの取得の方法について
紹介する。
複合パラメータとは例えば次のようなパラメータである。

                        プリンターの開始1  (TESTCMD1)                       
                                                                             
選択項目を入力して,実行キーを押してください。                               
                                                            
ページ・サイズ :                                                             
  用紙  . . . . . . . . . . . .   *SPLF         *SPLF, *A3, *A4, *A5, *A6... 
  用紙方向  . . . . . . . . . .                 *LANDSCAPE, *PORTRAIT        
                                                                         
			

このような例はOS400のユーティリティでよく見かける。

                               SEU 開始  (STRSEU)                               
                                                                                
  選択項目を入力して,実行キーを押してください。                                
                                                                                
  ソース・ファイル  . . . . . . . > QCLSRC         名前 , *PRV                  
    ライブラリー  . . . . . . . . >   R610SRC      名前 , *LIBL, *CURLIB, *PRV  
  ソース・メンバー  . . . . . . . > TESTCMD1CL     名前 , *PRV, *SELECT         
  ソース仕様タイプ  . . . . . . . > CLP            名前 , *SAME, BAS, BASP...   
  オプション  . . . . . . . . . .   *BLANK        *BLANK, ' ', 2, 5, 6          
  テキスト ' 記述 ' . . . . . . . > ' プリンターの開始 1'                       
                                                                                
			

上記の

ソース・ファイル  . . . . . . . > QCLSRC         名前 , *PRV                  
  ライブラリー  . . . . . . . >   R610SRC      名前 , *LIBL, *CURLIB, *PRV

の部分も複合パラメータとして定義されている。

さて先に紹介した複合パラメータのソースは次のようなものである。

【 サンプル・ソース: TESTCMD1 】

0001.00              CMD        PROMPT(' プリンターの開始1 ')                
0002.00              PARM       KWD(PAGESIZE) TYPE(PAGESIZE) DFT(*SPLF) +     
0003.00                           SNGVAL((*SPLF)) CHOICE(*NONE) +             
0004.00                           PROMPT(' ページ・サイズ ')  
0005.00  PAGESIZE:   ELEM       TYPE(*CHAR) LEN(7) RSTD(*YES) VALUES(*A3 *A4 +
0006.00                           *A5 *A6 *B3 *B4 *B5 *LETTER *LEGAL) +       
0007.00                           PROMPT(' 用紙 ')                            
0008.00              ELEM       TYPE(*CHAR) LEN(10) RSTD(*YES) +              
0009.00                           DFT(*LANDSCAPE) VALUES(*LANDSCAPE +         
0010.00                           *PORTRAIT) PROMPT(' 用紙方向 ')             

もう一度このパラメータの実行を見てみよう。

                        プリンターの開始1  (TESTCMD1)                       
                                                                             
選択項目を入力して,実行キーを押してください。                               
                                                            
ページ・サイズ :                                                             
  用紙  . . . . . . . . . . . .   *SPLF         *SPLF, *A3, *A4, *A5, *A6... 
  用紙方向  . . . . . . . . . .                 *LANDSCAPE, *PORTRAIT        
                     

ページ・サイズという複合のパラメータは *SPLF のように最初のひとつだけ入力される
場合もあるし

  ページ・サイズ :                                                           
  用紙  . . . . . . . . . . . .   *A4           *SPLF, *A3, *A4, *A5, *A6..
  用紙方向  . . . . . . . . . .   *PORTRAIT     *LANDSCAPE, *PORTRAIT

のように *A4 *PORTRAIT の2つのパラメータを入力する場合がある。
「用紙」パラメータは

0005.00  PAGESIZE:   ELEM       TYPE(*CHAR) LEN(7) RSTD(*YES) VALUES(*A3 *A4 +
0006.00                           *A5 *A6 *B3 *B4 *B5 *LETTER *LEGAL) +       
0007.00                           PROMPT(' 用紙 ')

として 10バイトで定義されている。

従ってこのコマンドを処理するプログラム (多くの場合はCLP) に 10 + 7 = 17バイトとして
値が渡るのではなく

のようにして先頭にパラメータ数を示す 2バイトが付加された形式でプログラムに渡される。
つまり常に同じ長さのパラメータとして渡されるのではなく、
エンド・ユーザーが入力したパラメータ数に応じて動的に変化する。
従ってプログラムでは最初の 2バイト(=2進数)を読んで判断する必要がある。
この判断を加えたCLPをサンプルとして次に示す。

【 サンプルCLP:TESTCMD1CL 】

0001.00              PGM        PARM(&PAGESIZEP)                                    
0002.00 /*-------------------------------------------------------------------*/     
0003.00 /*   TESTCMD1   :   プリンターの開始 1                               */     
0004.00 /*-------------------------------------------------------------------*/     
0005.00              DCL        VAR(&PAGESIZEP) TYPE(*CHAR) LEN(19)                 
0006.00              DCL        VAR(&PAGESIZE) TYPE(*CHAR) LEN(17)                  
0007.00              DCL        VAR(&FORM) TYPE(*CHAR) LEN(7)                       
0008.00              DCL        VAR(&DIRECTION) TYPE(*CHAR) LEN(10)                 
0009.00              DCL        VAR(&PRMSU) TYPE(*CHAR) LEN(2) /* 2 進数  */        
0010.00                                                                             
0011.00              /*( PAGESIZE パラメータの取得 )*/                              
0012.00              CHGVAR     VAR(&PRMSU) VALUE(%SST(&PAGESIZEP 1 2))             
0013.00              IF         COND(%BIN(&PRMSU) *EQ 1) THEN(DO)                   
0014.00              CHGVAR     VAR(&FORM) VALUE(%SST(&PAGESIZEP 3 7))              
0015.00              ENDDO                                                          
0016.00              ELSE       CMD(DO)                                             
0017.00              CHGVAR     VAR(&FORM) VALUE(%SST(&PAGESIZEP 3 7))              
0018.00              CHGVAR     VAR(&DIRECTION) VALUE(%SST(&PAGESIZEP 10 10))       
0019.00              ENDDO                                                          
0020.00              CHGVAR     VAR(&PAGESIZE) VALUE(&FORM *CAT &DIRECTION)         
0021.00                                                                             
0022.00              SNDPGMMSG  MSG('PAGESIZE = ' *CAT &PAGESIZE) +                 
0023.00                           MSGTYPE(*DIAG)                                    
0024.00              ENDPGM
【解説】

受取りパラメータの長さは 7 + 10 = 17バイトに先頭のパラメータ数の 2バイトを加えて
17 + 2 = 19バイトとして

DCL VAR(&PAGESIZEP) TYPE(*CHAR) LEN(19)

上記のように定義している。
求めたいのは

DCL VAR(&FORM) TYPE(*CHAR) LEN(7)
DCL VAR(&DIRECTION) TYPE(*CHAR) LEN(10)を加えた
DCL VAR(&PAGESIZE) TYPE(*CHAR) LEN(17)

という 17バイトである。

最初に

0012.00              CHGVAR     VAR(&PRMSU) VALUE(%SST(&PAGESIZEP 1 2))

上記で先頭の 2バイトのパラメータ数を取得して
パラメータ数が 1 か 2によって処理を行う。

0013.00              IF         COND(%BIN(&PRMSU) *EQ 1) THEN(DO)                   
0014.00              CHGVAR     VAR(&FORM) VALUE(%SST(&PAGESIZEP 3 7))              
0015.00              ENDDO                                                          
0016.00              ELSE       CMD(DO)                                             
0017.00              CHGVAR     VAR(&FORM) VALUE(%SST(&PAGESIZEP 3 7))              
0018.00              CHGVAR     VAR(&DIRECTION) VALUE(%SST(&PAGESIZEP 10 10))       
0019.00              ENDDO   

パラメータ数を取得してから

0020.00              CHGVAR     VAR(&PAGESIZE) VALUE(&FORM *CAT &DIRECTION)

を求めている。
このように複合パラメータをコマンドで定義した場合は
パラメータ数を判断して処理を分岐させる必要がある。