コマンド

33. 数字をパラメータとして使う場合の注意点

コマンドによる入力パラメータとして数字入力を指定したい場合がある。
例えば次のような場合である。

【例】
0001.00              CMD        PROMPT(' テストコマンド ')                   
0002.00              PARM       KWD(LPI) TYPE(*DEC) LEN(3 1) RSTD(*YES) +    
0003.00                           DFT(6) VALUES(6.0 3.0 4.0 7.5 7.5 8.0 9.0 +
0004.00                           12.0) EXPR(*YES) PMTCTL(*PMTRQS) +         
0005.00                           PROMPT(' 行/インチ ')                     

【解説】

パラメータ: LPI は数値の入力パラメータとして TYPE(*DEC) LEN(3 1)
定義されている。
コマンドのパラメータを数字 TYPE(*DEC)として定義すると
これはすべてパック型式の数と見なされる。
ZONE 10進数は定義することはできない。

さてここからが問題であるが変数 LPI を CLPでどのように受け取れば
よいだろうか?

【 CLP A 】 CLPで 数値として定義する
0001.00              PGM        PARM(&LPI)                              
0002.00 /*---------------------------------------------------------*/   
0003.00 /*   TESTCMDCL :  数値のパラメータの受取り A の場合        */   
0004.00 /*                                                         */   
0005.00 /*---------------------------------------------------------*/   
0006.00              DCL        VAR(&LPI) TYPE(*DEC) LEN(3 1)           
0007.00                                                                 
0008.00 /*( プログラムの実行 )*/                                        
0009.00              CALL       PGM(TEST.COM/TESTCMD) PARM(&LPI)        
0010.00                                                                 
0011.00              ENDPGM                                             

【解説】

数字は

DCL    VAR(&LPI) TYPE(*DEC) LEN(3 1)

のようにして、コマンドで定義されているとおりの数値として定義している。
見る人にとっても自然な形のように見える。

【 CLP B 】 文字として受け取って必要なときに数字に変換する。
0001.00              PGM        PARM(&LPI)                            
0002.00 /*---------------------------------------------------------*/ 
0003.00 /*   TESTCMDCL :  数値のパラメータの受取り B の場合        */ 
0004.00 /*                                                         */ 
0005.00 /*---------------------------------------------------------*/ 
0006.00              DCL        VAR(&LPI) TYPE(*CHAR) LEN(2)          
0007.00                                                               
0008.00 /*( プログラムの実行 )*/                                      
0009.00              CALL       PGM(TEST.COM/TESTCMD) PARM(&LPI)      
0010.00                                                               
0011.00              ENDPGM                                           
【解説】

パラメータは

DCL    VAR(&LPI) TYPE(*CHAR) LEN(2)

のようにして、パックであるので 2バイトの文字として定義している。
数値はプログラム TEST.COM/TESTCMD の中で変換している。

さてどちらの記述が正しいのだろう?
答えは A ではなく B である。
対話式の場合は A でも正しく動作するが


CALL PGM(TEST.COM/TESTCMD) PARM(&LPI)

ではなく


SBMJOB CMD(CALL PGM(TEST.COM/TESTCMD) PARM(&LPI))


と記述した場合 &LPI の値はプログラム : TEST.COM/TESTCMD には
正しく伝えられない。
恐らくはこれは数少ない IBM i のバグである
文字として受け取っていれば SBMJOB しても正しく値が伝えられる。
従って常に数字パラメータも文字として受け取るようにすれば
このような障害に見舞われることは絶対ない。