自己学習メモインデックス
概要
フリーフォーマットでもないRPGⅣの定位置記入方式の環境において、乱数を生成することが困難だという話しを小耳に挟んだ。
完全に定位置記入方式を突き詰めることはできないけども、一部フリーフォーマットのRPGプログラムを利用し、FUNCTIONのように利用して乱数を生成し、CALLやDSPLYは定位置側のRPGⅣプログラム側で実行できればいいかなと思い、技術検証した内容をまとめました。
ここでの乱数は1桁の数値です。
本来はもう少し桁数が必要かもしれませんが、サンプルプログラムの変数のサイズ(INZ)を変更することで対処可能です。
サンプルコード
フリーフォーマットのRPGプログラムと組み合わせた乱数のサンプル
QRPGLESRC/GET_RANDOM
のソースを新規で作り、この中では0〜9までの乱数を生成し、
返却用のパラメータP@RTCD
にセットする処理を行っています。
0〜9までの数値の設定としては、7行目〜8行目のhighno
とlowno
のInzの値で制御可能です。
FMT H HKeywords+++++++++++++++++++++++++++++++++++++++++++++++++++
*************** Beginning of data **************************
0001.00 H DFTACTGRP(*NO) ACTGRP('QILE')
0002.00 D CEERAN0 PR
0003.00 D seed 10I 0
0004.00 D ranno 8F
0005.00 D fc 12A options(*omit)
0006.00
0007.00 D highno s 10I 0 Inz(9)
0008.00 D lowno s 10I 0 Inz(0)
0009.00 D seed s 10I 0 inz(0)
0010.00 D rand S 8F
0011.00 D range S 10I 0
0012.00 D result S 10I 0
0013.00
0014.00 * パラメータ:リターンコード
0015.00 D P@RTCD S 1S 0
0016.00 * パラメータリスト
0017.00 C *ENTRY PLIST
0018.00 C PARM P@RTCD
0019.00 /free
0020.00 range = (highno - lowno) + 1;
0021.00 CEERAN0( seed : rand : *omit );
0022.00 result = %int(rand * range) + lowno;
0023.00 P@RTCD = result;
0024.00 // dsply result;
0025.00 return;
0026.00 /end-free
上記プログラムをCALLする、RPGⅣの定位置記入方式のRPGプログラムは以下のような感じです。
7行目でCALLして、リターンコードP@RTCD
をDSPLYで画面表示しているだけです。
FMT * *. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ..
*************** Beginning of data **********************************
0001.00 * パラメータリストの定義
0002.00 C PL@PARAM PLIST
0003.00 C PARM P@RTCD 1
0004.00
0005.00 * 電話番号の正規表現チェック処理実行
0006.00 C EVAL P@RTCD = '0'
0007.00 C CALL 'GET_RANDOM' PL@PARAM
0008.00 C P@RTCD DSPLY
0009.00
0010.00 C EVAL *INLR = *ON
****************** End of data *************************************
作ったプログラムをコンパイルして実行すると以下のような感じになります。
なんちゃっての乱数もどきのサンプル
定位置記入方式のRPGⅣのみを利用し、且つ1桁の乱数という条件であれば、
乱数もどきの動きをしてくれるプログラムを構築することが可能だと思ったので、そのサンプルも参考までに。
これが10桁20桁の乱数となると、このサンプルは全く利用価値がありませんのでご注意ください。
ここでやっているのは、タイムスタンプ(20桁)を生成して、その一番右の桁(20桁目)に該当するミリ秒の部分1桁を利用しているだけです。
ミリ秒なので、0〜9までが頻繁に入れ替わる1桁の乱数のように動いてくれると思って作りました。
FMT D DName+++++++++++ETDsFrom+++To/L+++IDc.Keywords++++++++++++++++++++++
*************** Beginning of data **********************************
0001.00 D timestamp s Z
0002.00 D Output s 40A
0003.00 D rand s 1A
0004.00
0005.00 * 年月日時分秒ミリ秒のタイムスタンプを生成
0006.00 C EVAL timestamp = %TIMESTAMP()
0007.00 C EVAL Output = %char(timestamp:*iso0)
0008.00 * タイムスタンプ文字列の一番右側の値を1文字だけ取得
0009.00 C SUBST Output:20 rand 1
0010.00 * 上記数字を1桁のランダム数値として扱って表示
0011.00 C rand DSPLY
0012.00
0013.00 C EVAL *INLR = *ON
****************** End of data *************************************
上記の動作結果は、以下のような感じになります。