文字列を数字に変換する %DEC の使い方を紹介する。
・%DEC の基本形
%DEC(変換する文字列:長さ:小数)
の形式で必ず変換先の数字の長さと小数を合わせて指定しなければ
ならない。
・カンマ(,)は無視、マイナス(-)、小数点(.)は認識される
カンマ(,)は無視されエラーとはならないがその時点で変換は
終了する。
例えば 13,2 は 13 と変換される。
ハイフン(-)はマイナス符号と見なされる。
ピリオド(.)は小数点として認識される。
・上記以外の英字や記号はエラーとなる。
前述以外の英字(A-Z)や記号(カッコ((や), [ ] …)が変換対象に
含まれている場合は変換エラーとなる。
RNX0105 : 数値の文字表現にエラーがあります
で終了する。
..これは%DECの不便なところで要注意である。
カンマ(,)の場合と同じようにその時点で変換が終了すれば
よいのだがエラーとして異常終了してしまう。
これが %DEC を使うときの注意点である。
C言語にも atoi という関数があり、文字列を整数(INTEGER)に
変換することができるが atoi は決してエラーにはならず
数字以外の文字が見つかるとそこで変換が終了する。
%DECもそうあって欲しいものであるがエラーとなってしまう。
[%DECを使うサンプルRPG: TESTDEC6 ]
ソースはこちらから
0001.00 H DFTNAME(TESTDEC6) DATEDIT(*YMD/) 0002.00 D STR S 80A 0003.00 D ROW S 10I 0 0004.00 D COL S 10I 0 0005.00 D N S 4S 0 0006.00 D VALUE S 10A 0007.00 C EVAL STR = 'POS(13,25)' 0008.00 C 'POS(' SCAN STR:1 N 50 0009.00 C *IN50 IFEQ *ON POS( 0010.00 C ADD 4 N 0011.00 C EVAL VALUE = %SUBST(STR:N:4) 0012.00 C EVAL ROW = %DEC(VALUE:4:0) 0013.00 C ',' SCAN STR:1 N 50 0014.00 C *IN50 IFEQ *ON , 0015.00 C ADD 1 N 0016.00 C EVAL VALUE = %SUBST(STR:N:4) 0017.00 C EVAL COL = %DEC(VALUE:4:0) 0018.00 C ENDIF , 0019.00 C ENDIF POS( 0020.00 C SETON LR
[解説]
0011.00 C EVAL VALUE = %SUBST(STR:N:4)
の演算によってフィールド:VALUE には 13,2 という値が入る。
これを
0012.00 C EVAL ROW = %DEC(VALUE:4:0)
で変換すると ROW には 13 という値が入る。
次に
0016.00 C EVAL VALUE = %SUBST(STR:N:4)
の演算では VALUE には 25) という値が入る。
これを
0017.00 C EVAL COL = %DEC(VALUE:4:0)
で変換を試みると
数値の文字表現にエラーがあります
というエラーが発生する。変換対象の文字列の中に ) という文字が含まれているからである。
このエラーを避けるのは上記のTESTDEC6 は次のように修正する必要がある。
[修正したTESTDEC61 ]
ソースはこちらから
0001.00 H DFTNAME(TESTDEC6) DATEDIT(*YMD/) 0002.00 D STR S 80A 0003.00 D ROW S 10I 0 0004.00 D COL S 10I 0 0005.00 D N S 4S 0 0006.00 D M S 4S 0 0007.00 D L S 4S 0 0008.00 D VALUE S 10A 0009.00 C EVAL STR = 'POS(13,25)' 0010.00 C 'POS(' SCAN STR:1 N 50 0011.00 C *IN50 IFEQ *ON POS( 0012.00 C ADD 4 N 0013.00 C EVAL VALUE = %SUBST(STR:N:4) 0014.00 C EVAL ROW = %DEC(VALUE:4:0) 0015.00 C ',' SCAN STR:1 N 50 0016.00 C *IN50 IFEQ *ON , 0017.00 C ADD 1 N 0018.00 C ')' SCAN STR:N M 50 0019.00 C EVAL L = M - N 0020.00 C EVAL VALUE = %SUBST(STR:N:L) 0021.00 C EVAL COL = %DEC(VALUE:4:0) 0022.00 C ENDIF , 0023.00 C ENDIF POS( 0024.00 C SETON LR
[解説]
演算
0018.00 C ')' SCAN STR:N M 50
によって閉じカッコ ) の位置を調べて
0019.00 C EVAL L = M - N
によって数字だけの長さ L を取得して
0020.00 C EVAL VALUE = %SUBST(STR:N:L)
で取り出すと VALUE には 25という値が入るので
0021.00 C EVAL COL = %DEC(VALUE:4:0)
を行うと COLには首尾よく 25という値を取得することができる。
ところでTESTDEC61の演算方法は複雑で読み手にとって難解なものとなってしまっている。
これは単純な演算を複数組み合わせているために読み手にとって
流れを把握しにくくなってしまっているのだ。
フリー・フォーマットであれば複数の演算をまとめて記述することができるので
演算の意図を読み手にわかりやすく表現することができる。
[フリー・フォーマットにしたTESTDEC62]
ソースはこちらから
0001.00 H DFTNAME(TESTDEC62) DATEDIT(*YMD/) 0002.00 D STR S 80A 0003.00 D ROW S 10I 0 0004.00 D COL S 10I 0 0005.00 D N S 4S 0 0006.00 D M S 4S 0 0007.00 D L S 4S 0 0008.00 C EVAL STR = 'POS(13,25)' 0009.00 C 'POS(' SCAN STR:1 N 50 0010.00 C *IN50 IFEQ *ON POS( 0011.00 /FREE 0012.00 ROW = %DEC(%SUBST(STR:N+4:4):4:0); 0013.00 /END-FREE 0014.00 C ',' SCAN STR:1 N 50 0015.00 C ')' SCAN STR:N M 50 0016.00 C *IN50 IFEQ *ON , 0017.00 /FREE 0018.00 L = M - N - 1; 0019.00 COL = %DEC(%SUBST(STR:N+1:L):4:0); 0020.00 /END-FREE 0021.00 C ENDIF , 0022.00 C ENDIF POS( 0023.00 C SETON LR
[解説]
フリー・フォーマットにすると複数の演算がひとつにまとめられている。
演算
0012.00 C ADD 4 N 0013.00 C EVAL VALUE = %SUBST(STR:N:4) 0014.00 C EVAL ROW = %DEC(VALUE:4:0)
は
0012.00 ROW = %DEC(%SUBST(STR:N+4:4):4:0);
としてまとめられているし
演算
0017.00 C ADD 1 N 0018.00 C ')' SCAN STR:N M 50 0019.00 C EVAL L = M - N 0020.00 C EVAL VALUE = %SUBST(STR:N:L) 0021.00 C EVAL COL = %DEC(VALUE:4:0)
も
0018.00 L = M - N - 1; 0019.00 COL = %DEC(%SUBST(STR:N+1:L):4:0);
にまとめられている。
これは 1行にもすることができるが長さL = M – N – 1の意味がわかりにくく
なってしまうのであえてこの演算を残した。
このようにフリー・フォーマットは単に自由形式で記述するというのではなく
複数の演算をまとめて記述することができる。
例えば
URIAGE = (SURYO x TANKA) X 1.10 + SORYO
を計算するのに
0022.01 C SURYO MULT TANKA URIAGE 0022.02 C URIAGE MULT 1.10 URIAGE 0022.03 C ADD SORYO URIAGE
と記述するのと
0022.04 /FREE 0022.05 URIAGE = (SURYO * TANKA) * 1.10 + SORYO; 0022.06 /END-FREE
の記述するのとどちらが簡単で読み手にもわかりやすいのだろうか?
RPG IIIからILE-RPGへの移行をためらっている人やフリー・フォーマットは
難しそうだと思っている人は少しずつでもフリー・フォーマットへ
一部ずつでも記述してみることをお奨めする。