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でもポインタ渡しをこのように有効に活用することが望ましい。・