今回は小技をご紹介します。IBM i のコマンドラインのお話です。
IBM i V7R4 TRxx くらいからでしょうか? コマンドラインで CALL コマンド の PARM に引数型を指定して呼び出すことが出来る様になっています。
参考リンク
今回のサンプルコード
以下の様な サンプルコード です。
単純に 5 桁のパック10進数を受け取り DSPLY 命令で出力しております。
**FREE
// H**********************************************************************
// H* *
// H* システム名 :RPG教育 *
// H* サブシステム名 :教育プログラム *
// H* プログラム名 :パック10進数の引数指定 *
// H* プログラムID : Q250101R *
// H* 会 社 名 :株式会社中部システム *
// H* *
// H* 作 成 者 :㈱中部システム Y.USHIDA *
// H* 作 成 日 : 2025/11/20 *
// H* 管 理 番 号: ____________ *
// H* *
// H* 変 更 者 : *
// H* 変 更 日 : ____/__/__ *
// H* 管 理 番 号: *
// H* *
// H* プログラム特記事項 *
// H* _ *
// H* _ *
// H* *
// H*-*******************************************************************
// H*-*H仕様書 **
// H*-*******************************************************************
CTL-OPT
DFTACTGRP(*NO) ACTGRP(*NEW)
DATEDIT(*YMD)
DECEDIT('0.')
EXPROPTS(*RESDECPOS)
CURSYM('¥')
COPYRIGHT('...')
;
// D*-*******************************************************************
// D*-*D仕様書 **
// D*-*******************************************************************
// D*-----------------------------------
// D*メインプロシージャ
// D*-----------------------------------
DCL-PI *N ;
IN_PARM1 PACKED( 5 : 0) ; //引数1
END-PI;
// D*-********************************************************************
// D*-* 変数等宣言 **
// D*-********************************************************************
DCL-S W#MSG CHAR(040 ) ; //メッセージ
// C*-********************************************************************
// C*-* メインルーチン **
// C*-********************************************************************
W#MSG = '引数は「'
+ %EDITC(IN_PARM1 : 'N')
+ '」'
;
DSPLY W#MSG ;
*INLR = *ON ;
RETURN ;
従来のコマンドラインでの渡し方
従来パック10進数を渡す場合は、Hexで指定する必要があり、次の様な記述となります。
CALL PGM(Q250101R) PARM((X'00123F')) マイナスなら CALL PGM(Q250101R) PARM((X'12345D'))
結果はそれぞれ DSPLY 引数は「 123 」 DSPLY 引数は「 -12,345 」 となります。
これを次の様に渡すと、皆さんご存知、初学者は目を背けたくなる、10進数エラー となります。
CALL PGM(Q250101R) PARM(123) は→ (C G D F) 10 進数データ・エラーが起こった
これは実は省略値である *DFT という型指定のオプションが指定された、こちら CALL PGM(Q250101R) PARM((123 *DFT)) のコマンドと同意で当然これもエラーになります。
型指定でのコマンドラインでの渡し方
*DFT 箇所にちゃんと型指定をすると、所謂見た目の数値どおりに引数を渡すことができます。マニュアルによると指定可能の型は *DEC, *CHAR, *LGL, *INT, *UINT, *FLT となっています。パック10進数は *DEC となります。コマンドラインで(*DEC 全体桁 小数桁) で指定します。
CALL PGM(Q250101R) PARM((123 (*DEC 5 0)))
DSPLY 引数は「 123 」
CALL PGM(Q250101R) PARM((-12345 (*DEC 5 0)))
DSPLY 引数は「 -12,345 」
型指定が不一致の場合
型指定が実際のと RPGプログラム と不一致の場合はどうなるでしょうか?
結果は次のとおりになりました。
/* (1)渡されたリテラルより型が短い */
CALL PGM(Q250101R) PARM((12345 (*DEC 3 0)))
CALL PGM(Q250101R) PARM((-12345 (*DEC 4 0)))
パラメーター 0001 値はパラメーターのタイプと長さに合っていない
CALL コマンドでエラーが見つかった。
/* (2)型がRPGより短いその1 */
CALL PGM(Q250101R) PARM((123 (*DEC 3 0)))
(C G D F) 10 進数データ・エラーが起こった
/* (3)型がRPGより短いその2 */
CALL PGM(Q250101R) PARM((-1234 (*DEC 4 0)))
DSPLY 引数は「 -1,234 」
まず (1)渡されたリテラルより型が短い 場合はコマンドライン上で、CALLが実行される前に論理的エラーとなります。この場合はプログラムの呼び出しに到達していません。
次に (2)型がRPGより短いその1 は、プログラムが実行され、みんな大嫌い 10進数エラー となります。想定どおりですね。
最後に (3)型がRPGより短いその2 は、(2) 同様にプログラムが実行されますが、こちらは 10進数エラー となりません。ならない理由は アレ ですね。
感の良い方はお気づきかも知れませんが、もし「なぜエラーにならないのか?」私は判ったよという方、コメント欄に是非 Answer をどうぞ。
もしコメントが入らない場合は、クリスマス🎄🎅に回答します!
因みに小数も見た目通り渡すだけです。
CALL PGM(Q250103R) PARM((-1234.1 (*DEC 5 1))) で DSPLY 引数は「 -1,234.1」 こうなります。
次回は、CLLE で型指定をした場合にどうなるか?ご紹介します。