コマンドの入力値は RANGE や 有効な値を定義することによって、静的な妥当性の検査を定義することはできる。
しかし、もう一歩進んでプログラムなどによって動的に妥当性を検査することも可能である。
【 CMDソース 】
0001.00 CMD PROMPT('OPNDTA 実行コマンドの作成 ')
0002.00 PARM KWD(OPNDFN) TYPE(OPNDFN) +
0003.00 PROMPT('OPNDTA 定義 ')
0004.00 OPNDFN: QUAL TYPE(*NAME) LEN(10) CHOICE(*PGM) +
0005.00 CHOICEPGM(RDALIB/SELOPNCL)
0006.00 QUAL TYPE(*NAME) LEN(10) DFT(*LIBL) +
0007.00 SPCVAL((*LIBL) (*CURLIB)) +
0008.00 PROMPT(' ライブラリー ')
0009.00 PARM KWD(OPTION) TYPE(*CHAR) LEN(4) RSTD(*YES) +
0010.00 DFT(*NO) VALUES(*YES *NO) +
0011.00 PROMPT(' パラメーターの作成 ') 
【 解説 】
このコマンドに対してコマンドのコンパイルのときには妥当性検査プログラムを定義しておく。
妥当性検査のCLPソースの例を次に示す。
【 CLPソース 】
0001.00 PGM PARM(&OPNDFNLIB &OPTION)
0002.00 /*---------------------------------------------------------*/
0003.00 /* CRTOPNCHK: CRTOPNCMD 妥当性検査 */
0004.00 /*---------------------------------------------------------*/
0005.00 DCL VAR(&OPNDFNLIB) TYPE(*CHAR) LEN(20)
0006.00 DCL VAR(&OPNDFN) TYPE(*CHAR) LEN(10)
0007.00 DCL VAR(&OPTION) TYPE(*CHAR) LEN(4)
0008.00 DCL VAR(&OBJLIB) TYPE(*CHAR) LEN(10)
0009.00 DCL VAR(&USRDFN) TYPE(*CHAR) LEN(10)
0010.00 DCL VAR(&MSG) TYPE(*CHAR) LEN(80)
0011.00 DCL VAR(&MSGKEY) TYPE(*CHAR) LEN(4)
0012.00 DCL VAR(&USER) TYPE(*CHAR) LEN(10)
0013.00 MONMSG MSGID(CPF0000) EXEC(GOTO CMDLBL(ERROR))
0014.00
0015.00 CHGVAR VAR(&OPNDFN) VALUE(%SST(&OPNDFNLIB 01 10))
0016.00 CHGVAR VAR(&OBJLIB) VALUE(%SST(&OPNDFNLIB 11 10))
0017.00 /* ************************************************ */
0018.00 /* *PRV ライブラリーの変更 */
0019.00 /* ************************************************ */
0020.00 RTVJOBA USER(&USER)
0021.00 CHGDTAARA DTAARA(QGPL/&USER (11 10)) VALUE(&OBJLIB)
0022.00
0023.00 IF COND(&OPNDFN *EQ ' ') THEN(DO)
0024.00 SNDPGMMSG MSGID(CPD0006) MSGF(QCPFMSG) MSGDTA('0000 +
0025.00 OPNDTA 定義を指定してください。 +
0026.00 ') MSGTYPE(*DIAG)
0027.00 GOTO CMDERR
0028.00 ENDDO
0029.00 /*( OPNDTA 定義のチエック )*/
0030.00 IF COND(&OPNDFN *NE '*NONE ') THEN(DO)
0031.00 CHGVAR VAR(&OPNDFN) VALUE(&OPNDFN *TCAT '_OPN')
0032.00 RTVOBJD OBJ(&OBJLIB/&OPNDFN) OBJTYPE(*FILE) +
0033.00 RTNLIB(&OBJLIB) USRDFNATR(&USRDFN)
0034.00 MONMSG MSGID(CPF9800 CPF2100) EXEC(DO)
0035.00 RCVMSG MSGTYPE(*LAST) RMV(*NO) KEYVAR(&MSGKEY) +
0036.00 MSG(&MSG)
0037.00 SNDPGMMSG MSGID(CPD0006) MSGF(QCPFMSG) +
0038.00 MSGDTA('0000' *CAT &MSG) MSGTYPE(*DIAG)
0039.00 GOTO CMDERR
0040.00 ENDDO
0041.00 IF COND(&USRDFN *NE 'OPNDFN ') THEN(DO)
0042.00 SNDPGMMSG MSGID(CPD0006) MSGF(QCPFMSG) +
0043.00 MSGDTA('0000' *CAT ' ライブラリー ' *TCAT
0044.00 &OBJLIB *TCAT ' の ' *TCAT +
0045.00 &OPNDFN *TCAT ' は OPNDTA 定義ではありません。 ') +
0046.00 MSGTYPE(*DIAG)
0047.00 GOTO CMDERR
0048.00 ENDDO
0049.00 ENDDO
0050.00 RETURN
0051.00 CMDERR:
0052.00 SNDPGMMSG MSGID(CPF0002) MSGF(QSYS/QCPFMSG) +
0053.00 MSGTYPE(*ESCAPE)
0054.00 RETURN
0055.00 ERROR: RCVMSG RMV(*NO) MSG(&MSG)
0056.00 SNDPGMMSG MSG(&MSG) MSGTYPE(*DIAG)
0057.00 ENDPGM: ENDPGM
【 解説 】
エラーがあった場合はメッセージ CPD0006 を戻すように取り決められている。
これまでのコマンドの解説によっておわかりのようにコマンドの制御によってできないことはほとんどない。
ちょっとした入力などを受け付けるために DSPF を記述することよりも、コマンドを使用すれば画面レイアウトを
いちいち行う必要はない。
またコマンドであれば画面レイアウトはOS/400によって行われるために、つねに見やすく適正な画面配置がされ、
操作性も統一される。
DSPF を作る前に、是非コマンドの使用を検討されることをお勧めする。
