コマンドで複合パラメータは良く使われる。
[例: 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 は挿入されない。
_