CL命令如何建立其确切的参数列表? [英] How do CL commands build their exact parameter lists?

查看:92
本文介绍了CL命令如何建立其确切的参数列表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个驱动RPGLE程序的CMD命令对象.由于可以使用几个不同的参数来调用命令,其中一些参数是互斥的,因此我解析了使用RPGLE中的数据结构传递的参数,因此我可以处理在不同位置传递参数的不同情况.

I have a CMD command object that drives an RPGLE program. Because the command may be called with several different parameters, some of which are mutually exclusive, I parse the parameter passed by using a data structure in the RPGLE so I can handle the different scenarios that pass the parameters in various positions.

例如,CMD文件具有:

For example, the CMD file has:

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程序.

The user can print by various criteria: order number, date, date range. Only one of these three methods can be chosen. Depending on what the user chooses, the parameters get delivered to the called RPGLE program differently.

  ********************************************************************                           
  *      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的一些行为与pass属性结合在一起,足以使用它,但不足以完全理解它.

As you can see, the position of the later parameters like TRANSTYPE shift position depending on which of the earlier parameters was chosen. OrdInvCM starts at 22, DteInvCM starts at 14, RgeInvCM starts at 30. This is not a problem as this data structure and the code using it is able to pick out the right position to read from based on the mysterious little attribute that I am calling ParmType. As far as I can tell, this attribute is not documented anywhere in the CL manuals on the internet or in the help included in the SEU editor (which has information on PASSATR that is not in the online manuals). I have pieced together a little of ParmType's behavior in relation to the pass attributes, enough to use it, but not enough to fully understand it.

一些常量使得解析PASSATR更加容易(并非每种可能性):

Some constants to make parsing the PASSATR easier (not every possibility):

 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'.当参数为订单号"的压缩* DEC(6P 0)打包时,ParmType的十六进制值为'02'.

In other words the ParmType has a hex value of '00' when the parameter is either a date or a date range. The ParmType has a hex value of '02' when the parameter is a packed *DEC (6P 0) for 'Order number'.

我想了解如何将此ParmType值设置为给定的数字,因此我可以健壮地编写可以接受各种参数组合的程序.我也没有看到为什么数据范围字段从14开始而不是像单个日期一样从4开始的特殊原因.我能够利用这一事实做出必要的区分,但是我不知道命令系统是否故意这样做 ,因为它看到我有两种相同数据类型的可能性,或者这是否是只是不能保证发生的幸运休息.如果我想添加其他打包参数作为选择,例如发票编号,则会发生类似的问题. 'A1'的'PASSATR'十六进制值可以告诉您它是带包装的,但不能告诉您是哪种类型(订单号或发票号).可能是命令系统将其位置移到了与日期范围相似的位置,但是我没有运行该特定实验.

I would like to understand how this ParmType value gets set at a given number so I can robustly write programs that can accept various parameter combinations. I also do not see a particular reason why the data range fields start over at 14 rather than at 4 like the single date does. I was able to exploit this fact to make the necessary distinction, but I do not know if the command system did this on purpose because it saw that I had two possibilities of the same data type or if this is just a lucky break that is not guaranteed to occur. A similar question occurs if I want to add a additional packed parameter as a choice, say an invoice number. The 'PASSATR' hex value of 'A1' could tell you it was packed, but not which type (order number or invoice number). It might be that the command system shifts the position similar to what it did with date range, but I have not run that particular experiment.

简而言之,是否有关于命令如何构建其参数列表的文档或至少推论出的算法,以便人们可以预测这些字段将包含哪些内容以及它们将位于何处?

推荐答案

无论是否输入值,都将传递所有参数,并且它们将按照命令中提供的顺序显示.

All parameters will be passed whether values are entered or not, and they will appear in the order provided in the command.

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)

混合列表ORDERNUMDATERANGE将出现,其中元素的整数作为前两个字节.如果混合列表参数为空或未传递,则此整数将包含0.

Mixed lists ORDERNUM and DATERANGE will appear with an Integer number of elements as the first two bytes. If a mixed list parameter is empty, or not passed, this integer will contain 0.

这是在CL中编写命令处理程序的方式

Here is how you could code a command processing program in 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.

Notice the structures for the mixed list (ELEM) parameters. Only the element count &xxelmcnt fields in these structures are valid if the number of elements in the list is 0. Also note that these will always contain 0, or 2 (the number of defined elements in each list). The ORDERNUM parameter will contain 2 if it is provided even if the shipper number is left blank. The value passed for shipper number in this case will be 0.

您可以在RPG程序中以类似方式进行处理:

You can process this in a similar way in an RPG program:

   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 is some documentation for how mixed list parameters are handled. surrounding it in the manual are descriptions for simple lists, and lists within lists (very complex).

编辑,您正在尝试在示例中将参数值作为单个块进行访问.这几乎可以确保引起混乱,因为除了程序中定义的参数引用外,没有关于如何将参数加载到内存的(公共)定义.参数通过引用传递,由调用程序确定它们在内存中的位置.假设每个参数在物理上都与先前的参数相邻可能是一个危险的假设.访问给定参数的唯一安全方法是使用其单独的参数引用.尝试从参数1的引用访问参数2是一个坏主意.即使可以使用一次,也不一定总是可以使用.如您所见,命令对象根据用户键入的内容在内存中四处移动.

Edit as Charles pointed out, you are trying to access the parameter values as a single block in your example. That is almost guaranteed to cause confusion as there is no (public) definition around how parameters are loaded into memory other than the parameter references defined in the program. Parameters are passed by reference, and it is the calling program that determines where they are in memory. Assuming that each parameter is physically adjacent to the previous parameter can be a dangerous assumption. The only safe way to access a given parameter is by using its individual parameter reference. It is a bad idea to try to access parameter 2 from parameter 1's reference. Even if works once, it will not necessarily always work. As you have seen, the command object moves things around in memory based on what the user keys.

由于我们知道上面的命令定义了4个参数,即4个PARM元素,因此我们可以确信,这4个参数中的每一个将完全按照命令中的定义传递给命令处理程序.但是,我们对内存中任何参数后面的内容没有把握.

Since we know that the command above defines 4 parameters, that is 4 PARM elements, we can be confident that each of the 4 parameters will be passed to the command processing program exactly as they are defined in the command. But, we cannot have confidence in what comes after any parameter in memory.

这篇关于CL命令如何建立其确切的参数列表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆