コマンドで複合パラメータは良く使われる。
[例: TETSFONT ]
FONT の指定 (TESTFONT)
選択項目を入力して,実行キーを押してください。
フォント :
識別コード名 . . . . . . . . > 'MS-GOTHIC' 文字値
フォント・サイズ . . . . . . > 13.5 数値
[解説]
このように複数の項目をまとめて複合パラメータとして表示すれば
見やすくわかりやすくなる。
_
[コマンド: TESTFONT ]
ソースはこちらから
0001.00 CMD PROMPT('FONT の指定 ')
0002.00 PARM KWD(FONT) +
0003.00 TYPE(FONT) +
0004.00 PROMPT(' フォント ')
0005.00 FONT: ELEM TYPE(*CHAR) +
0006.00 LEN(10) +
0007.00 PROMPT(' 識別コード名 ')
0008.00 ELEM TYPE(*DEC) +
0009.00 LEN(5 1) +
0010.00 PROMPT(' フォント・サイズ ')
[コンパイル]
CRTCMD CMD(OBJLIB/TESTFONT) PGM(OBJLIB/TESTFONTCL) SRCFILE(SRCLIB/QMDSRC) AUT(*ALL)
[解説]
この複合パラメータ: FONT はひとつの変数としてCLPに渡されるので
CLPでそれを分割して使用しなければならない。
[ CLP: TESTFONTCL ]
ソースはこちらから
0001.00 PGM PARM(+
0002.00 &FONTINFO +
0003.00 )
0004.00 /*----------------------------------------------------------------------*/
0005.00 /* TESTFONTCL:FONT の指定 */
0006.00 /* */
0007.00 /* 作成 : 2023/07/01 */
0008.00 /*----------------------------------------------------------------------*/
0009.00 DCL VAR(&FONTINFO) TYPE(*CHAR) LEN(15)
0010.00 DCL VAR(&FONT) TYPE(*CHAR) STG(*DEFINED) LEN(10) +
0011.00 DEFVAR(&FONTINFO 3)
0012.00 DCL VAR(&FONTSIZ) TYPE(*DEC) STG(*DEFINED) LEN(5 +
0013.00 2) DEFVAR(&FONTINFO 13)
0014.00 DCL VAR(&MSG) TYPE(*CHAR) LEN(132)
0015.00 DCL VAR(&STMMSG) TYPE(*CHAR) LEN(132)
0016.00 DCL VAR(&MSGID) TYPE(*CHAR) LEN(7)
0017.00 DCL VAR(&MSGF) TYPE(*CHAR) LEN(10)
0018.00 DCL VAR(&MSGFLIB) TYPE(*CHAR) LEN(10)
0019.00 DCL VAR(&MSGKEY) TYPE(*CHAR) LEN(4)
0020.00 DCL VAR(&MSGDTA) TYPE(*CHAR) LEN(132)
0021.00 DCL VAR(&ERRDTA) TYPE(*CHAR) LEN(132)
0022.00 DCL VAR(&TYPE) TYPE(*CHAR) LEN(1)
0023.00 DCL VAR(&TOPGMQ) TYPE(*CHAR) LEN(10)
0024.00 DCL VAR(&MSGTYPE) TYPE(*CHAR) LEN(10) +
0025.00 VALUE('*ESCAPE ')
0026.00 DCL VAR(&ERR) TYPE(*CHAR) LEN(1)
0027.00 DCL VAR(&NULL4) TYPE(*CHAR) LEN(4) +
0028.00 VALUE(X'00000000')
0029.00 DCL VAR(&APIERR) TYPE(*CHAR) LEN(116) +
0030.00 VALUE(X'0000007400000000') /* 2 進数 */
0031.00 MONMSG MSGID(CPF9999) EXEC(GOTO CMDLBL(ERROR))
0032.00
0033.00 /*( 環境の取得 )*/
0034.00 RTVJOBA TYPE(&TYPE)
0035.00 IF COND(&TYPE *EQ '0') THEN(DO) /* バッチ */
0036.00 CHGVAR VAR(&TOPGMQ) VALUE('*SYSOPR ')
0037.00 ENDDO /* バッチ */
0038.00 ELSE CMD(DO) /* 対話式 */
0039.00 CHGVAR VAR(&TOPGMQ) VALUE('*TOPGMQ ')
0040.00 ENDDO /* 対話式 */
0041.00
0042.00 /*( 入力パラメータの検査 )*/
0043.00
0044.00 /*( プログラムの実行 )*/
0045.00 CALL PGM(TESTFONT) PARM(&ERR &MSG)
0046.00 IF COND(&ERR *EQ ' ') THEN(DO)
0047.00 CHGVAR VAR(&MSGTYPE) VALUE('*DIAG ')
0048.00 ENDDO
0049.00 IF COND(&MSG *NE ' ') THEN(DO)
0050.00 GOTO SNDMSG
0051.00 ENDDO
0052.00 RETURN
0053.00
0054.00 ERROR: RCVMSG MSGTYPE(*LAST) RMV(*NO) KEYVAR(&MSGKEY) +
0055.00 MSGDTA(&MSGDTA) MSGID(&MSGID) MSGF(&MSGF) +
0056.00 SNDMSGFLIB(&MSGFLIB)
0057.00 IF COND(&MSGID *EQ 'CPF9999') THEN(DO)
0058.00 CHGVAR VAR(&ERRDTA) VALUE(&MSGDTA)
0059.00 RCVMSG MSGTYPE(*PRV) MSGKEY(&MSGKEY) RMV(*NO) +
0060.00 MSG(&MSG) MSGDTA(&MSGDTA) MSGID(&MSGID) +
0061.00 MSGF(&MSGF) MSGFLIB(&MSGFLIB)
0062.00 CHGVAR VAR(&STMMSG) VALUE(' プログラム ' *CAT +
0063.00 %SST(&ERRDTA 8 10) *TCAT +
0064.00 ' のステートメント ' *CAT %SST(&ERRDTA +
0065.00 24 4) *CAT ' で次のエラーが発生しました。 ')
0066.00 SNDPGMMSG MSGID(CPF9897) MSGF(QCPFMSG) MSGDTA(&STMMSG) +
0067.00 TOMSGQ(&TOPGMQ) MSGTYPE(*DIAG)
0068.00 ENDDO
0069.00 SNDMSG: IF COND(&MSGID *EQ ' ') THEN(DO)
0070.00 SNDPGMMSG MSGID(CPF9897) MSGF(QCPFMSG) MSGDTA(&MSG) +
0071.00 TOMSGQ(&TOPGMQ) MSGTYPE(&MSGTYPE)
0072.00 MONMSG MSGID(CPF2400) EXEC(RETURN)
0073.00 ENDDO
0074.00 ELSE CMD(DO)
0075.00 SNDPGMMSG MSGID(&MSGID) MSGF(&MSGFLIB/&MSGF) +
0076.00 MSGDTA(&MSGDTA) TOMSGQ(&TOPGMQ) +
0077.00 MSGTYPE(&MSGTYPE)
0078.00 MONMSG MSGID(CPF2400) EXEC(RETURN)
0079.00 ENDDO
0080.00 ENDPGM
[コンパイル]
CRTCLPGM PGM(OBJLIB/TESTFONTCL) SRCFILE(SRCLIB/QCLSRC) OPTION(*SRCDBG) AUT(*ALL)
[解説]
&FONTINFO というひとつの名前の変数でパラメータ値を受取るのだが
これを &FONT と &FONTSIZ というふたつの変数に分解しなければならない。
これを演算命令で
CHGVAR VAR(&FONT) VALUE(%SST(&FONTINFO 3 10)) CHGVAR VAR(&FONTSIZC) VALUE(%SST(&FONTINFO 13 2))
のように実行する必要はない。
特に フォント・サイズは数字であり
DCL VAR(&FONTSIZ) TYPE(*DEC) LEN(5 2)
と定義されるのでいったん2バイトの文字として取り出してそれをベースとした
ポインタからバック10進数(*DEC)を生成しなければならず
かなり面倒である。
しかしここでは DEFINEを使って
0010.00 DCL VAR(&FONT) TYPE(*CHAR) STG(*DEFINED) LEN(10) + 0011.00 DEFVAR(&FONTINFO 3) 0012.00 DCL VAR(&FONTSIZ) TYPE(*DEC) STG(*DEFINED) LEN(5 + 0013.00 2) DEFVAR(&FONTINFO 13)
として &FONT と &FONTSIZ が &FONTINFO の一部であると同時定義してしまえば
演算の必要はなくて非常にスマートである。
&FONTSIZ はバック10進数(*DEC)であるが直ちに使用することができる。
なお &FONT を &FONTINFO の先頭から3バイト目から取り出しているのは
&FONTINFOが ELEM パラメータで構成されているからである。
ELEM パラメータで構成された場合は最初の2バイトは Short Int の長さが
i5/OSによって挿入されてしまうのでそれを迂回して先頭から 3バイト目以降から
取り出すようにしている。
ELEM でなく QUALパラメータで構成されている場合は 2バイトのShort Int は挿入されない。
_
