C*-------------------------------------------------------------------------+ C *ENTRY PLIST | C PARM TOMBR 10 | C*-------------------------------------------------------------------------+
RPGの *ENTRYパラメータの受け渡しでは
パラメータ値を変更して戻すと相手側のプログラムにも
変更値が戻されるようになっていてRPGの開発者は
よくご存知であると思うがこれは一般的に開発言語では
むしろ例外的なことでありパラメータそのものは
値を渡すだけなので渡した側のプログラムに
パラメータ値が反映されて戻ることはあり得ない。

RPGのプロシージャーの場合も他言語と同様であり
プロシージャーのパラメータ値に値が反映されて
戻ることはない。
しかし意図的にパラメータに値を戻したい場合がある。
そのようなときには他言語ではパラメータを
ポインタとして渡す手法が用いられる。
ポインタであればそこからの値を変更してやれば
ポインタ自体は変わっていなくてもその位置(ポインタ)からの
値を変えることができるからである。
このことを示す例を紹介しよう。
プロシージャーを使う場合に複数の値を戻したいときに
役に立つはずである。
[ RPG: TESTPROC2 ]
ソースはこちらから
0001.00 H DFTNAME(TESTPROC2) DATEDIT(*YMD/) BNDDIR('QC2LE')
0002.00 F********** プロシージャーのテスト (2)*********************************
0003.00 F*
0004.00 F**********************************************************************
0005.00
0006.00 * CRTBNDRPG PGM(MYLIB/TESTPROC2) SRCFILE(MYSRCLIB/QRPGLESRC) DFTACTGRP(*NO)
0007.00 * ACTGRP(*NEW) DBGVIEW(*SOURCE) AUT(*ALL)
0008.00
0009.00 *-------------------------------------------------------------------*
0010.00 * 2021/10/28 : 作成
0011.00 *-------------------------------------------------------------------*
0012.00 *( 作業変数 )
0013.00 D TRUE# S 4B 0 INZ(0)
0014.00 D FALSE# S 4B 0 INZ(-1)
0015.00 D DATA1 S 7A INZ('AA11111')
0016.00 D DATA2 S 7A INZ('BB22222')
0017.00 D DATA2_P S * INZ(%ADDR(DATA2))
0018.00 D ANS S 1A
0019.00
0020.00 D*( MYPROC のプロトタイプ宣言 )
0021.00 D MYPROC PR 4B 0
0022.00 D DATA1 7A Value
0023.00 D DATA2 * Value OPTIONS(*NOPASS)
0024.00
0025.00 C*( メイン・ルーチンの始まり )
0026.00 /FREE
0027.00 IF MYPROC(DATA1: DATA2_P) = FALSE#;
0028.00 DSPLY ('DATA1=' + DATA1);
0029.00 DSPLY ('DATA2=' + DATA2);
0030.00 DSPLY ' 結果を確認してください。 ' '' ANS;
0031.00 ENDIF;
0032.00 /END-FREE
0033.00 C SETON LR
0034.00 C RETURN
0042.00 *********************************************************
0043.00 * MYPROC: メッセージを現在の CALLSTACK に送信 *
0044.00 *********************************************************
0045.00 *---( MYPROC PROCEDURE ここから )------------------------*
0046.00 P MYPROC B EXPORT
0047.00 D PI 4B 0
0048.00 D DATA1 7A Value
0049.00 D DATA2_P * value OPTIONS(*NOPASS)
0050.00
0051.00 D DATA2 S 7A BASED(DATA2_P)
0052.00
0053.00 /FREE
0054.00 DATA1 = 'XX22222';
0055.00 DATA2 = 'YY22222';
0056.00 /END-FREE
0057.00 C RETURN FALSE#
0058.00 P E
0059.00 *---( MYPROC PROCEDURE ここまで )------------------------*
[コンパイル]
CRTBNDRPG PGM(MYLIB/TESTPROC2) SRCFILE(MYSRCLIB/QRPGLESRC) DFTACTGRP(*NO) ACTGRP(*NEW) DBGVIEW(*SOURCE) AUT(*ALL)
[解説]
プロシージャー : MYPROC には2つのパラメータがあり
ひとつは値を渡していてもうひとつのパラメータはポインタを渡している。
0020.00 D*( MYPROC のプロトタイプ宣言 ) 0021.00 D MYPROC PR 4B 0 0022.00 D DATA1 7A Value 0023.00 D DATA2 * Value OPTIONS(*NOPASS)
最初には初期値をそれぞれにセットしておく
0015.00 D DATA1 S 7A INZ('AA11111')
0016.00 D DATA2 S 7A INZ('BB22222')
これを受取ったプロシージャーが側では両方とも次のように更新して戻す。
0053.00 /FREE 0054.00 DATA1 = 'XX22222'; 0055.00 DATA2 = 'YY22222'; 0056.00 /END-FREE 0057.00 C RETURN FALSE#
受取った値は次の命令で表示される。
0028.00 DSPLY ('DATA1=' + DATA1);
0029.00 DSPLY ('DATA2=' + DATA2);
0030.00 DSPLY ' 結果を確認してください。 ' '' ANS;
またこのDSPLY命令の使い方にも注目して欲しい。
フリーメフォーマットでDSPLY命令を使うと見やすくわかりやすくなる。
実行結果は次のようになる。
プログラム・メッセージの表示
DSPLY DATA1=AA11111
DSPLY DATA2=YY22222
DSPLY 結果を確認してください。
応答を入力して,実行キーを押してください。
応答 . . .
F3= 終了 F12= 取消し
[解説]
DATA1は 最初の AA11111 の値のままであり変化はないが
ポインタ渡しにしたDATA2 は YY22222 と
0055.00 DATA2 = 'YY22222';
で更新した値が反映されている。
このように結果が成功したか失敗したかは結果を RETURN 命令で
RETURN TRUE# や FALSE# で戻して更新した値はパラメータに反映して
戻すというやり方はオープン系の開発言語でよく行われる手法である。
プロシージャーのパラメータはポインタであればパラメータ値の変更を反映させることができる
ILE-RPGでもポインタ渡しをこのように有効に活用することが望ましい。・
