我有一个驱动 RPGLE 程序的 CMD 命令对象。因为命令可能调用几个不同的参数,其中一些是互斥的,所以我使用RPGLE中的数据结构解析传递的参数,以便处理不同位置传递参数的不同场景。
例如,CMD 文件有:
CMD PROMPT('Reprint Invoices and Credits')
PARM KWD(ORDERNUM) TYPE(ORDER) +
PROMPT('For order number:')
PARM KWD(INVDATE) TYPE(*DATE) PASSATR(*YES) +
PROMPT('For invoice date')
PARM KWD(DATERANGE) TYPE(DTRANGE) +
PROMPT('For date range:')
PARM KWD(TRANSTYPE) TYPE(*CHAR) LEN(9) RSTD(*YES) +
DFT(*BOTH) VALUES(*INVOICES *CREDITS *BOTH) +
PASSATR(*YES) PROMPT('Transactions to print')
DTRANGE: ELEM TYPE(*DATE) MIN(1) PASSATR(*YES) +
PROMPT('Beginning date')
ELEM TYPE(*DATE) MIN(1) PASSATR(*YES) +
PROMPT('Ending date')
ORDER: ELEM TYPE(*DEC) LEN(6) MIN(1) PASSATR(*YES) +
PROMPT('Order number')
ELEM TYPE(*DEC) LEN(2) MIN(0) PASSATR(*YES) +
PROMPT('Shipment number (optional)')
DEP CTL(*ALWAYS) PARM(ORDERNUM INVDATE DATERANGE) +
NBRTRUE(*EQ 1)
用户可以按各种标准打印:订单号、日期、日期范围。这三种方法只能选择一种。根据用户的选择,参数以不同的方式传递给被调用的 RPGLE 程序。
********************************************************************
* Parameters from CMD object INV_REPRNT
D InputParms DS TEMPLATE QUALIFIED
D AllParms 143A
D ParmType 2 2A Can't find in manual
D 'Type' might be
D a misnomer
D
D OrdDteAttr 3 3A For attr's, see
D OrderNum 4 7P 0 SEU help for
D ShipAttr 8 8A CMD PASSATR
D Shipment 9 10P 0
D OrdInvCMAttr 21 21A
D OrdInvCM 22 30A char 9
D
D InvDate@ 4 10A
D DteInvCMAttr 13 13A
D DteInvCM 14 22A char 9
D
D BeginDateAttr 13 13A
D BeginDate@ 14 20A
D EndDateAttr 21 21A
D EndDate@ 22 28A
D RgeInvCMAttr 29 29A
D RgeInvCM 30 38A char 9
如您所见,后面参数的位置(如TRANSTYPE
移位位置)取决于选择了哪个较早的参数。 OrdInvCM
从 22 开始,DteInvCM
从 14 开始,RgeInvCM
从 30 开始。这不是问题,因为这个数据结构和使用它的代码能够根据我正在调用的神秘小属性选择正确的读取位置ParmType
。据我所知,互联网上的 CL 手册或 SEU 编辑器中包含的帮助中没有记录此属性(PASSATR
在线手册中没有相关信息)。我已经拼凑了一点ParmType
's 与 pass 属性有关的行为,足以使用它,但不足以完全理解它。
一些使解析PASSATR
更容易的常量(不是所有可能性):
D Null C CONST(X'00')
D Parm2 C CONST(X'02')
D NumSpecd C CONST(X'A1') 1010 0001
D NumUnspecd C CONST(X'21') 0010 0001
D CharQSpecd C CONST(X'C5') 1100 0101 Quoted
D CharQUnspecd C CONST(X'45') 0100 0101 Quoted
D CharUQSpecd C CONST(X'85') 1000 0101 Unquoted
D CharUQUnspecd C CONST(X'05') 0000 0101 Unquoted
D
D IsSpecd C CONST(X'80') >= 1000 0000
我发现:
IF P.ParmType = Null;
IF P.OrdDteAttr >= IsSpecd;
// this is a single date
ELSE;
IF P.BeginDateAttr >= IsSpecd;
// this is a data range
ELSE;
// this is error condition I have not gotten yet
ENDIF;
ENDIF;
ELSE;
IF P.OrdDteAttr >= IsSpecd;
// this is an order number
ELSE;
// this is error condition I have not gotten yet
ENDIF;
ENDIF;
换句话说,ParmType
当参数是日期或日期范围时,它的十六进制值为“00”。当ParmType
参数是“订单号”的打包 *DEC (6P 0) 时,它的十六进制值为“02”。
我想了解如何将此ParmType
值设置为给定数字,以便我可以稳健地编写可以接受各种参数组合的程序。我也没有看到为什么数据范围字段从 14 开始而不是像单个日期那样从 4 开始的特定原因。我能够利用这一事实进行必要的区分,但我不知道指挥系统是否故意这样做因为它看到我有两种相同数据类型的可能性,或者这只是一个幸运的突破,不能保证会发生。如果我想添加一个额外的打包参数作为选择,就会出现类似的问题,比如发票号码。'A1' 的 'PASSATR' 十六进制值可以告诉您它已包装,但不能告诉您是哪种类型(订单号或发票号)。可能是命令系统移动位置类似于它对日期范围所做的那样,但我没有运行那个特定的实验。
简而言之,是否有关于命令如何构建其参数列表的文档或至少推导出算法,以便可以预测这些字段将包含什么以及它们将位于何处?