CL 命令如何构建其确切的参数列表?
How do CL commands build their exact parameter lists?
我有一个驱动 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
。据我所知,这个属性在 Internet 上的 CL 手册或 SEU 编辑器中包含的帮助中没有任何记录(其中包含在线手册中没有的关于 PASSATR
的信息)。我拼凑了一些 ParmType
与传递属性相关的行为,足以使用它,但还不足以完全理解它。
一些使 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”。当参数为 'Order number'.
的压缩 *DEC (6P 0) 时,ParmType
的十六进制值为“02”
我想了解这个 ParmType
值是如何设置为给定数字的,这样我就可以稳健地编写可以接受各种参数组合的程序。我也没有看到为什么数据范围字段从 14 开始而不是像单个日期那样从 4 开始的特殊原因。我能够利用这一事实做出必要的区分,但我不知道命令系统是否故意这样做,因为它看到我有两种可能的相同数据类型或如果这只是幸运的突破,则不能保证会发生。如果我想添加一个额外的打包参数作为选择,会出现类似的问题,比如发票号。 'A1' 的 'PASSATR' 十六进制值可以告诉您它已包装,但不能告诉您是哪种类型(订单号或发票号)。可能是命令系统移动了类似于日期范围的位置,但我没有 运行 那个特定的实验。
简而言之,是否有关于命令如何构建其参数列表的文档或至少推导的算法,以便可以预测这些字段将包含什么以及它们将位于何处?
我依稀想起了Bob Cozzi 的一篇文章,其中谈到了PASSATR 属性。也许它会帮助... https://www.mcpressonline.com/programming/rpg/retrieving-user-space-data
PASSATR is documented here Pass attribute byte (PASSATR)
*YES
An attribute byte is passed with the parameter.
The attribute byte has two fields:
- The leftmost bit of the attribute byte indicates whether or not a value was specified. If the leftmost bit is '0'B, the value passed to the command processing program is a default value and was not specified in the command string. If the leftmost bit is '1'B, the value passed to the command processing program was specified in the command string.
- The remaining seven bits describe the value passed to the command processing program when *CHAR is specified for the Type of value (TYPE) parameter.
Attribute Description
---------- --------------------------------------
'0000010'B Meets *NAME rules, like A_B
'0000100'B Meets <em>GENERIC rules, like AB</em>
'1000101'B Quoted character string, like 'A B'
'0000101'B Unquoted character string, like 5A
'1001000'B Logical constant, '0' or '1'
'0001100'B Hexadecimal value, like X'C1C2'
'0100001'B Unsigned numeric value, like 5
'0101001'B Unsigned numeric with decimal point,
like 5.2
'0110001'B Signed numeric value, like -5
'0111001'B Signed numeric with decimal point,
like -5.2
Also look at Value to pass if unspecified (PASSVAL), which is documented right underneath PASSATR.
Value to pass if unspecified (PASSVAL)
Specifies whether a value is
passed to the command processing program for this parameter. *NULL is
not valid if the parameter is a constant parameter (a parameter in
which a value has been specified for the Constant value (CONSTANT)
parameter, or a parameter for which *ZEROELEM or *NULL has been
specified for the Type of value (TYPE) parameter, or a list/qualified
name defined by all constant ELEM or QUAL statements). *NULL also is
not valid if *YES has been specified on the Return value (RTNVAL)
parameter, or if the value specified for the Minimum values required
(MIN) parameter is greater than zero. A DEP statement or the REL and
RANGE keywords of other PARM statements may not refer to the value of
a parameter defined with *NULL.
If you PASSVAL
unspecified parameters as *NULL, you should be able to define them in RPGLE as OPTION(*OMIT)
and then check if %addr(myOptParm) <> 0;
EDIT
What you're trying to do, pass all parms as a single chunk is a bad idea. You might get it to work today, but it could break with the application of a PTF or during an OS upgrade. The system is designed to pass individual parameters.
Just pass them all to your RPG program and check to see what was actually used.
无论是否输入值,所有参数都将被传递,它们将按照命令中提供的顺序出现。
PASSATR
不需要,省略。
CMD PROMPT('Reprint Invoices and Credits')
PARM KWD(ORDERNUM) TYPE(ORDER) +
PROMPT('For order number:')
PARM KWD(INVDATE) TYPE(*DATE) +
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) +
PROMPT('Transactions to print')
DTRANGE: ELEM TYPE(*DATE) MIN(1) +
PROMPT('Beginning date')
ELEM TYPE(*DATE) MIN(1) +
PROMPT('Ending date')
ORDER: ELEM TYPE(*DEC) LEN(6) MIN(1) +
PROMPT('Order number')
ELEM TYPE(*DEC) LEN(2) MIN(0) +
PROMPT('Shipment number (optional)')
DEP CTL(*ALWAYS) PARM(ORDERNUM INVDATE DATERANGE) +
NBRTRUE(*EQ 1)
混合列表 ORDERNUM
和 DATERANGE
将以整数元素作为前两个字节出现。如果混合列表参数为空或未传递,则此整数将包含 0。
以下是如何在 CL 中编写命令处理程序
PGM PARM(&ORDERNUM &INVDATE &DATERANGE &TRANSTYPE)
DCL VAR(&ORDERNUM) TYPE(*CHAR)
DCL VAR(&ONELMCNT) TYPE(*INT) STG(*DEFINED) +
LEN(2) DEFVAR(&ORDERNUM 1)
DCL VAR(&ONORDER) TYPE(*DEC) STG(*DEFINED) LEN(6 +
0) DEFVAR(&ORDERNUM 3)
DCL VAR(&ONSHIPNO) TYPE(*DEC) STG(*DEFINED) +
LEN(2 0) DEFVAR(&ORDERNUM 7)
DCL VAR(&INVDATE) TYPE(*CHAR) LEN(7)
DCL VAR(&DATERANGE) TYPE(*CHAR)
DCL VAR(&DRELMCNT) TYPE(*INT) STG(*DEFINED) +
LEN(2) DEFVAR(&DATERANGE 1)
DCL VAR(&DRBDATE) TYPE(*CHAR) STG(*DEFINED) +
LEN(7) DEFVAR(&DATERANGE 3)
DCL VAR(&DREDATE) TYPE(*CHAR) STG(*DEFINED) +
LEN(7) DEFVAR(&DATERANGE 10)
DCL VAR(&TRANSTYPE) TYPE(*CHAR) LEN(9)
if (&onelmcnt *ne 0) do
/* ORDERNUM parameter has been entered */
enddo
if (&invdate *ne '0000000') do
/* INVDATE parameter has been entered */
enddo
if (&drelmcnt *ne 0) do
/* DATERANGE parameter has been entered */
enddo
if (&transtype *ne ' ') do
enddo
done: endpgm
注意混合列表 (ELEM
) 参数的结构。如果列表中的元素数为 0,则这些结构中只有元素计数 &xxelmcnt
字段有效。另请注意,这些字段将始终包含 0 或 2(每个列表中定义的元素数)。如果提供 ORDERNUM
参数,即使托运人编号留空,也会包含 2。在这种情况下,为托运人编号传递的值将为 0。
您可以在 RPG 程序中以类似的方式进行处理:
ctl-opt Main(testcmd);
dcl-ds ordernum_t qualified template;
elements Int(5);
order Packed(6:0);
shipper Packed(2:0);
end-ds;
dcl-ds daterange_t qualified template;
elements Int(5);
begindt Char(7);
enddt Char(7);
end-ds;
dcl-proc testcmd;
dcl-pi *n ExtPgm('TESTCMD');
ordernum LikeDs(ordernum_t) const;
invdate Char(7) const;
daterange LikeDs(daterange_t) const;
transtype Char(9) const;
end-pi;
if ordernum.elements <> 0;
// parameter has been entered
endif;
if invdate <> '0000000';
// parameter has been entered
endif;
if daterange.elements <> 0;
// parameter has been entered
endif;
if transtype <> '';
// parameter has been entered
endif;
return;
end-proc;
Here 是一些关于如何处理混合列表参数的文档。手册中围绕它的是简单列表和列表中的列表(非常复杂)的描述。
Edit 正如 Charles 指出的那样,您正试图在您的示例中将参数值作为单个块访问。这几乎肯定会引起混淆,因为除了程序中定义的参数引用之外,没有 (public) 定义参数如何加载到内存中。参数通过引用传递,调用程序决定它们在内存中的位置。假设每个参数在物理上都与前一个参数相邻可能是一个危险的假设。访问给定参数的唯一安全方法是使用其单独的参数引用。尝试从参数 1 的引用访问参数 2 是个坏主意。即使一次有效,也不一定总是有效。如您所见,命令对象根据用户键入的内容在内存中四处移动。
因为我们知道上面的命令定义了 4 个参数,即 4 个 PARM
元素,我们可以确信这 4 个参数中的每一个都将完全按照它们在中定义的那样传递给命令处理程序命令。但是,我们无法确定内存中任何参数之后的内容。
我有一个驱动 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
。据我所知,这个属性在 Internet 上的 CL 手册或 SEU 编辑器中包含的帮助中没有任何记录(其中包含在线手册中没有的关于 PASSATR
的信息)。我拼凑了一些 ParmType
与传递属性相关的行为,足以使用它,但还不足以完全理解它。
一些使 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”。当参数为 'Order number'.
ParmType
的十六进制值为“02”
我想了解这个 ParmType
值是如何设置为给定数字的,这样我就可以稳健地编写可以接受各种参数组合的程序。我也没有看到为什么数据范围字段从 14 开始而不是像单个日期那样从 4 开始的特殊原因。我能够利用这一事实做出必要的区分,但我不知道命令系统是否故意这样做,因为它看到我有两种可能的相同数据类型或如果这只是幸运的突破,则不能保证会发生。如果我想添加一个额外的打包参数作为选择,会出现类似的问题,比如发票号。 'A1' 的 'PASSATR' 十六进制值可以告诉您它已包装,但不能告诉您是哪种类型(订单号或发票号)。可能是命令系统移动了类似于日期范围的位置,但我没有 运行 那个特定的实验。
简而言之,是否有关于命令如何构建其参数列表的文档或至少推导的算法,以便可以预测这些字段将包含什么以及它们将位于何处?
我依稀想起了Bob Cozzi 的一篇文章,其中谈到了PASSATR 属性。也许它会帮助... https://www.mcpressonline.com/programming/rpg/retrieving-user-space-data
PASSATR is documented here Pass attribute byte (PASSATR)
*YES
An attribute byte is passed with the parameter.
The attribute byte has two fields:
- The leftmost bit of the attribute byte indicates whether or not a value was specified. If the leftmost bit is '0'B, the value passed to the command processing program is a default value and was not specified in the command string. If the leftmost bit is '1'B, the value passed to the command processing program was specified in the command string.
- The remaining seven bits describe the value passed to the command processing program when *CHAR is specified for the Type of value (TYPE) parameter.
Attribute Description
---------- --------------------------------------
'0000010'B Meets *NAME rules, like A_B
'0000100'B Meets <em>GENERIC rules, like AB</em>
'1000101'B Quoted character string, like 'A B'
'0000101'B Unquoted character string, like 5A
'1001000'B Logical constant, '0' or '1'
'0001100'B Hexadecimal value, like X'C1C2'
'0100001'B Unsigned numeric value, like 5
'0101001'B Unsigned numeric with decimal point,
like 5.2
'0110001'B Signed numeric value, like -5
'0111001'B Signed numeric with decimal point,
like -5.2
Also look at Value to pass if unspecified (PASSVAL), which is documented right underneath PASSATR.
Value to pass if unspecified (PASSVAL)
Specifies whether a value is passed to the command processing program for this parameter. *NULL is not valid if the parameter is a constant parameter (a parameter in which a value has been specified for the Constant value (CONSTANT) parameter, or a parameter for which *ZEROELEM or *NULL has been specified for the Type of value (TYPE) parameter, or a list/qualified name defined by all constant ELEM or QUAL statements). *NULL also is not valid if *YES has been specified on the Return value (RTNVAL) parameter, or if the value specified for the Minimum values required (MIN) parameter is greater than zero. A DEP statement or the REL and RANGE keywords of other PARM statements may not refer to the value of a parameter defined with *NULL.
If you PASSVAL
unspecified parameters as *NULL, you should be able to define them in RPGLE as OPTION(*OMIT)
and then check if %addr(myOptParm) <> 0;
EDIT
What you're trying to do, pass all parms as a single chunk is a bad idea. You might get it to work today, but it could break with the application of a PTF or during an OS upgrade. The system is designed to pass individual parameters.
Just pass them all to your RPG program and check to see what was actually used.
无论是否输入值,所有参数都将被传递,它们将按照命令中提供的顺序出现。
PASSATR
不需要,省略。
CMD PROMPT('Reprint Invoices and Credits')
PARM KWD(ORDERNUM) TYPE(ORDER) +
PROMPT('For order number:')
PARM KWD(INVDATE) TYPE(*DATE) +
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) +
PROMPT('Transactions to print')
DTRANGE: ELEM TYPE(*DATE) MIN(1) +
PROMPT('Beginning date')
ELEM TYPE(*DATE) MIN(1) +
PROMPT('Ending date')
ORDER: ELEM TYPE(*DEC) LEN(6) MIN(1) +
PROMPT('Order number')
ELEM TYPE(*DEC) LEN(2) MIN(0) +
PROMPT('Shipment number (optional)')
DEP CTL(*ALWAYS) PARM(ORDERNUM INVDATE DATERANGE) +
NBRTRUE(*EQ 1)
混合列表 ORDERNUM
和 DATERANGE
将以整数元素作为前两个字节出现。如果混合列表参数为空或未传递,则此整数将包含 0。
以下是如何在 CL 中编写命令处理程序
PGM PARM(&ORDERNUM &INVDATE &DATERANGE &TRANSTYPE)
DCL VAR(&ORDERNUM) TYPE(*CHAR)
DCL VAR(&ONELMCNT) TYPE(*INT) STG(*DEFINED) +
LEN(2) DEFVAR(&ORDERNUM 1)
DCL VAR(&ONORDER) TYPE(*DEC) STG(*DEFINED) LEN(6 +
0) DEFVAR(&ORDERNUM 3)
DCL VAR(&ONSHIPNO) TYPE(*DEC) STG(*DEFINED) +
LEN(2 0) DEFVAR(&ORDERNUM 7)
DCL VAR(&INVDATE) TYPE(*CHAR) LEN(7)
DCL VAR(&DATERANGE) TYPE(*CHAR)
DCL VAR(&DRELMCNT) TYPE(*INT) STG(*DEFINED) +
LEN(2) DEFVAR(&DATERANGE 1)
DCL VAR(&DRBDATE) TYPE(*CHAR) STG(*DEFINED) +
LEN(7) DEFVAR(&DATERANGE 3)
DCL VAR(&DREDATE) TYPE(*CHAR) STG(*DEFINED) +
LEN(7) DEFVAR(&DATERANGE 10)
DCL VAR(&TRANSTYPE) TYPE(*CHAR) LEN(9)
if (&onelmcnt *ne 0) do
/* ORDERNUM parameter has been entered */
enddo
if (&invdate *ne '0000000') do
/* INVDATE parameter has been entered */
enddo
if (&drelmcnt *ne 0) do
/* DATERANGE parameter has been entered */
enddo
if (&transtype *ne ' ') do
enddo
done: endpgm
注意混合列表 (ELEM
) 参数的结构。如果列表中的元素数为 0,则这些结构中只有元素计数 &xxelmcnt
字段有效。另请注意,这些字段将始终包含 0 或 2(每个列表中定义的元素数)。如果提供 ORDERNUM
参数,即使托运人编号留空,也会包含 2。在这种情况下,为托运人编号传递的值将为 0。
您可以在 RPG 程序中以类似的方式进行处理:
ctl-opt Main(testcmd);
dcl-ds ordernum_t qualified template;
elements Int(5);
order Packed(6:0);
shipper Packed(2:0);
end-ds;
dcl-ds daterange_t qualified template;
elements Int(5);
begindt Char(7);
enddt Char(7);
end-ds;
dcl-proc testcmd;
dcl-pi *n ExtPgm('TESTCMD');
ordernum LikeDs(ordernum_t) const;
invdate Char(7) const;
daterange LikeDs(daterange_t) const;
transtype Char(9) const;
end-pi;
if ordernum.elements <> 0;
// parameter has been entered
endif;
if invdate <> '0000000';
// parameter has been entered
endif;
if daterange.elements <> 0;
// parameter has been entered
endif;
if transtype <> '';
// parameter has been entered
endif;
return;
end-proc;
Here 是一些关于如何处理混合列表参数的文档。手册中围绕它的是简单列表和列表中的列表(非常复杂)的描述。
Edit 正如 Charles 指出的那样,您正试图在您的示例中将参数值作为单个块访问。这几乎肯定会引起混淆,因为除了程序中定义的参数引用之外,没有 (public) 定义参数如何加载到内存中。参数通过引用传递,调用程序决定它们在内存中的位置。假设每个参数在物理上都与前一个参数相邻可能是一个危险的假设。访问给定参数的唯一安全方法是使用其单独的参数引用。尝试从参数 1 的引用访问参数 2 是个坏主意。即使一次有效,也不一定总是有效。如您所见,命令对象根据用户键入的内容在内存中四处移动。
因为我们知道上面的命令定义了 4 个参数,即 4 个 PARM
元素,我们可以确信这 4 个参数中的每一个都将完全按照它们在中定义的那样传递给命令处理程序命令。但是,我们无法确定内存中任何参数之后的内容。