4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【小技】CLLE - SMBJOB & CALL の PARMオプションに渡す型指定方法

Last updated at Posted at 2025-12-07

今回も小技をご紹介します。IBM i の CLLE(※以後 CLP も同じです) のお話です。
IBM i V7R4 TRxx くらいからでしょうか? CALL コマンドPARM に引数型を指定して呼び出すことが出来る様になっています。

参考リンク

今回のサンプルコード

以下の様な CLLE サンプルコード です。この CLLE では次の RPGLE

RPGLE は単純にパック10進数を受け取り DSPLY 命令で出力しております。

Q250801C1.CLLE
     /*****************************************************************/
     /*                                                               */
     /*   システム名      :‚Qiitaアドベントカレンダー       €*/
     /*   サブシステム名  :‚2025                             €*/
     /*   プログラム名    :‚パック10進数の引数指定             €*/
     /*   プログラムID  :‚ Q250801C1                             €*/
     /*   会 社 名    :‚株式会社中部システム                 €*/
     /*                                                               */
     /*     作 成 者    :‚ CSC)Y.USHIDA                          €*/
     /*     作 成 日    :‚ 2025/11/20                            €*/
     /*     テンプレート№:‚ _______________                       €*/
     /*                                                               */
     /*     変 更 者    :‚                   €*/
     /*     変 更 日    :‚ ____/__/__                            €*/
     /*                                                               */
     /*  プログラム特記事項                                         */
     /*                              €*/
     /*                              €*/
     /*                                                               */
     /*****************************************************************/
       PGM


      /*======================================*/
      /*‚変数定義                        €*/
      /*======================================*/
       DCL VAR(&P@PARM1  ) TYPE(*DEC ) LEN(003 0)
       DCL VAR(&W@PARM1  ) TYPE(*DEC ) LEN(005 0)
       DCL VAR(&C@PARM1  ) TYPE(*CHAR) LEN(003  ) STG(*DEFINED ) DEFVAR(&W@PARM1  )

      /*======================================*/
      /*‚初期処理                        €*/
      /*======================================*/

      /*‚CL内のCALLはコンパイルエラーとなり指定できない€*/
  /*  CALL PGM(Q250101R) PARM((&P@PARM1 (*DEC 5 0)))      */

      /*------------------------------------*/
      /*‚SBMJOBでは使うことができる€*/
      /*------------------------------------*/
      CHGVAR     VAR(&W@PARM1   ) VALUE(-123        )
      /*‚従来)SBMJOB制約で同型でもエラー€*/
      SBMJOB CMD(                                          +
        CALL PGM(Q250101R) PARM( &W@PARM1            )     +
      ) JOB(Q250801C11 )

      CHGVAR     VAR(&W@PARM1   ) VALUE(-234        )
      /*従来)SBMJOB制約の暗黙型15P 5に合わせれば正常€*/
      SBMJOB CMD(                                          +
        CALL PGM(Q250801R) PARM( &W@PARM1            )     +
      ) JOB(Q250801C12 )

      /*‚従来)文字列相当にキャストして渡す方法€*/
      CHGVAR     VAR(&W@PARM1   ) VALUE(-345        )
      SBMJOB CMD(                                          +
        CALL PGM(Q250101R) PARM( &C@PARM1            )     +
      ) JOB(Q250801C13 )

      /*‚型指定で正常に実行される€*/
      CHGVAR     VAR(&P@PARM1   ) VALUE(-456        )
      SBMJOB CMD(                                          +
        CALL PGM(Q250101R) PARM((&P@PARM1 (*DEC 5 0)))     +
      ) JOB(Q250801C14 )

      WRKACTJOB SBS(QBATCH  )

      /*‚終了€*/
      CALLSUBR   SUBR(@END)


   /*====================================================================*/
   /*‚終了処理                                                        €*/
   /*====================================================================*/
   SUBR       @END

       /* 終了*/
       RETURN

   ENDSUBR
             ENDPGM

CL内 での CALL コマンド PARM の型指定の扱い

CLLE での CALL コマンド PARM の型指定の扱いを見ていきます。
まず、CL 内で CALL コマンドの PARM 型指定を行うとコンパイルエラーとなります。

CL内CALLでの型指定はコンパイルエラー
    /*  CL内のCALLはコンパイルエラーとなり指定できない  */
/*  CALL PGM(Q250101R) PARM((&P@PARM1 (*DEC 5 0)))      */
* CPD08A4 40  パラメーター 0001 値はパラメーターのタイプと長さに合っていない

これはコマンドラインで型指定ができた様に、あくまでもリテラル値をパースする処理で、指定型へ合わせにいっているだけで、CLの様な動的な変数(参照やポインタ)をキャストしている訳ではないということなのでしょうね。

CL内 での SBMJOB コマンドでの CALL PARM の型指定の扱い

続いて SBMJOB を見ていきます。こちらは、コマンドラインと同様に、あくまで主体は SBMJOB であり、親のジョブから切り離され、CALLコマンドは、CL変数の参照を受け取ることが出来ません。従ってコマンドライン同様に、PARM の型指定をすることができます。恐らく内部的にはコマンドライン同様のパーサーが使用されているからでしょうか?

まずは、さきほどのサンプル CL を実行した結果は次のとおりになります。

サンプルCLを実行した結果
(C G D F) 10 進数データ・エラーが起こった。(※1)
 DSPLY   引数は「           -234.00000 」(※2)
 DSPLY   引数は「    -345 」(※3)
 DSPLY   引数は「    -456 」(※4)

従来の SBMJOB での CALL 引数

PARM の型指定を行わない、且つ RPGLE の引数の型が PACKED(5 :0) の場合サンプルでは次のコードを実行しております。

従来のSBMJOB エラーになる場合
CHGVAR     VAR(&W@PARM1   ) VALUE(-123        )
/*‚従来)SBMJOB制約で同型でもエラー€*/
SBMJOB CMD(                                          +
  CALL PGM(Q250101R) PARM( &W@PARM1            )     +
) JOB(Q250801C11 )

結果は (C G D F) 10 進数データ・エラーが起こった。(※1) となります。
これは SBMJOB 制約で数値は 15P 5 と定数変換されるため、RPG 側の型が不一致で10進数エラーとなります。

次に RPGLESBMJOB 制約 PACKED(15 :5) に合わせる形した場合は正常に実行されます。

従来のSBMJOB RPGをPACKED(15 :5) に合わせる
CHGVAR     VAR(&W@PARM1   ) VALUE(-234        )
/*‚従来)SBMJOB制約の暗黙型15P 5に合わせれば正常€*/
SBMJOB CMD(                                          +
  CALL PGM(Q250801R) PARM( &W@PARM1            )     +
) JOB(Q250801C12 )

結果は DSPLY 引数は「 -234.00000 」(※2) となります。

また、RPGLE の型を変更せずに行う方法として以下の方法があります。

文字列相当にキャストして実行
DCL VAR(&W@PARM1  ) TYPE(*DEC ) LEN(005 0)
DCL VAR(&C@PARM1  ) TYPE(*CHAR) LEN(003  ) STG(*DEFINED ) DEFVAR(&W@PARM1  )
/*‚従来)文字列相当にキャストして渡す方法€*/
CHGVAR     VAR(&W@PARM1   ) VALUE(-345        )
SBMJOB CMD(                                          +
  CALL PGM(Q250101R) PARM( &C@PARM1            )     +
) JOB(Q250801C13 )

結果は DSPLY 引数は「 -345 」(※3) となります。

SBMJOB での CALL 引数型指定

従来は、SBMJOB で変数を渡す場合は、ある一定の制約や少し神経質になる部分がありましたが、コマンドラインと同様型指定にて、渡すことでシンプルに記述することが出来ます。記述は次のとおりになります。

PARM 型指定によるSBMJOB
/*‚型指定で正常に実行される€*/
CHGVAR     VAR(&P@PARM1   ) VALUE(-456        )
SBMJOB CMD(                                          +
  CALL PGM(Q250101R) PARM((&P@PARM1 (*DEC 5 0)))     +
) JOB(Q250801C14 )

結果は DSPLY 引数は「 -456 」(※4) となります。
文字列における SBMJOB 制約も型指定を行うことで制約を受けない記述方法となるので、古い記述がある場合はリファクタリングを行うと良いでのではないでしょうか。

4
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?