【问题标题】:How to pass parameters to a Progress program using database field dynamic-based rules?如何使用基于数据库字段动态的规则将参数传递给 Progress 程序?
【发布时间】:2015-05-04 22:22:29
【问题描述】:

我的数据库中有一组记录集中了关于我的 .W 的信息,例如窗口名称、父目录、文件名、程序类型(用于内部处理),用于构建我的主菜单。有了这些数据,我正在为我维护的 ERP 开发一个新的启动程序,并利用这个机会重写一些真正过时的功能和程序并实现新功能。到目前为止,我没有任何问题,但是当我开始开发 .P 程序时,它将检查从这个新启动程序的菜单中调用的程序的数据库寄存器 - 检查它是否需要接收固定参数以运行及其数据类型 - 我发现了一个我无法找到解决方案的问题。

在这个表中,我在其中一个字段中存储了程序所需的参数,每个参数都有对应的数据类型。问题在于如何仅根据存储的数据将不同的数据类型传递给过程。我尝试使用 CASE 子句和包含来预转换数据以检查参数字段是否正确发送参数,但包含没有按预期工作。

我的数据库字段是这样存储的:

Description | DATATYPE | Content

我已经声明了一些变量并将存储的数据正确转换为正确的数据类型变量。

DEF VAR c-param-exec        AS CHAR     NO-UNDO EXTENT 9 INIT ?.
DEF VAR i-param-exec        AS INT      NO-UNDO EXTENT 9 INIT ?.
DEF VAR de-param-exec       AS DEC      NO-UNDO EXTENT 9 INIT ?.
DEF VAR da-param-exec       AS DATE     NO-UNDO EXTENT 9 INIT ?.
DEF VAR l-param-exec        AS LOG      NO-UNDO EXTENT 9 INIT ?.
DEF VAR i-count             AS INT      NO-UNDO.

blk-count:
DO i-count = 0 TO 8:
    IF TRIM(programa.parametro[i-count]) = '' THEN
        LEAVE blk-count.
    i-count = i-count + 1.

    CASE ENTRY(2,programa.parametro[i-count],CHR(1)):
        WHEN 'CHARACTER' THEN
            c-param-exec[i-count]   = ENTRY(3,programa.parametro[i-count],CHR(1)).
        WHEN 'INTEGER' THEN
            i-param-exec[i-count]   = INT(ENTRY(3,programa.parametro[i-count],CHR(1))).
        WHEN 'DECIMAL' THEN
            de-param-exec[i-count]  = DEC(ENTRY(3,programa.parametro[i-count],CHR(1))).
        WHEN 'DATE' THEN
            da-param-exec[i-count]  = DATE(ENTRY(3,programa.parametro[i-count],CHR(1))).
        WHEN 'LOGICAL' THEN
            l-param-exec[i-count]   = (ENTRY(3,programa.parametro[i-count],CHR(1)) = 'yes').
        OTHERWISE
            c-param-exec[i-count]   = ENTRY(3,programa.parametro[i-count],CHR(1)).
    END CASE.

END.

然后我尝试使用包含传递参数来运行程序(在此示例中,程序有 3 个INPUT 参数)。

RUN VALUE(c-prog-exec) ({util\abrePrograma.i 1}, 
                        {util\abrePrograma.i 2}, 
                        {util\abrePrograma.i 3}).

这是我的abrePrograma.i

/* abrePrograma.i */

(IF ENTRY(2,programa.parametro[{1}],CHR(1)) = 'CHARACTER' THEN c-param-exec[{1}]  ELSE
 IF ENTRY(2,programa.parametro[{1}],CHR(1)) = 'INTEGER' THEN i-param-exec[{1}] ELSE
 IF ENTRY(2,programa.parametro[{1}],CHR(1)) = 'DECIMAL' THEN de-param-exec[{1}] ELSE
 IF ENTRY(2,programa.parametro[{1}],CHR(1)) = 'DATE' THEN da-param-exec[{1}] ELSE
 IF ENTRY(2,programa.parametro[{1}],CHR(1)) = 'LOGICAL' THEN l-param-exec[{1}]  ELSE
 c-param-exec[{1}])

如果我从包含中抑制第 2、第 3、第 4 和第 5 个IF 或在所有IF 中仅使用一种数据类型(例如,仅 CHAR、仅 DATE 等),则程序正常工作并像魅力一样执行,但我需要调用一些旧程序,这些程序在其 INPUT 参数中需要不同的数据类型,并且使用所描述的程序 OpenEdge 不会编译调用者,触发错误号 223。

---------------------------
Erro (Press HELP to view stack trace)
---------------------------
** Tipos de dados imcompativeis em expressao ou atribuicao. (223)
**  Nao entendi a linha 86. (196)
---------------------------
OK   Ajuda   
---------------------------

谁能帮我解决这个问题? 提前致谢。

【问题讨论】:

    标签: progress-4gl openedge


    【解决方案1】:

    看起来好像您正在尝试使用可变参数定义。 查看 ABL 参考中的“create call”语句。

    http://documentation.progress.com/output/ua/OpenEdge_latest/index.html#page/dvref/call-object-handle.html#wwconnect_header

    文档示例

    DEFINE VARIABLE hCall AS HANDLE NO-UNDO.
    
    CREATE CALL hCall.
    
    /* Invoke hello.p non-persistently */
    hCall:CALL-NAME      = "hello.p".
    
    /* Sets CALL-TYPE to the default */
    hCall:CALL-TYPE  = PROCEDURE-CALL-TYPE
    hCall:NUM-PARAMETERS = 1.
    hCall:SET-PARAMETER(1, "CHARACTER", "INPUT", "HELLO WORLD").
    hCall:INVOKE.
    
    /* Clean up */
    DELETE OBJECT hCall.
    

    【讨论】:

    • 我已经对此进行了测试,它以所有可以想象的方式解决了我的问题,即使使用 PERSISTENT 程序和 .W 也是如此。非常感谢。
    【解决方案2】:

    了解这些预处理器相关问题的最佳方法是使用预处理列表进行编译,然后对预处理文件进行语法检查。一旦您知道错误在生成的预处理文件中的位置,您就必须找出哪个包含/定义导致代码无法编译。

    1. 在程序编辑器中 编译 source.w 预处理 source.pp.
    2. 在程序编辑器中打开 source.pp 并进行语法检查
    3. 查看原始源代码以查找导致代码无法编译的包含或预处理器构造。

    【讨论】:

      【解决方案3】:

      好吧,我有点迷失了(经常发生在我身上,有很多预处理器),但是在进出数据库字段的过程中,您将值存储为字符,对吗?因此,在数据库中存储参数时,您必须将其转换为 Char,并且在离开数据库的过程中,您必须将其转换回正确的数据类型。不这样做会导致类型不匹配。

      此外,只是大声思考(没有一直思考)想知道是否使用 OOABL(面向对象的 ABL)取决于您的 Release 是否可用,通过定义不同数据类型的签名然后根据您调用它的输入或输出参数类型,它将使用正确的签名和正确的转换方法。

      类似:

      METHOD PUBLIC VOID storeParam(input cParam as char ): dbfield = cParam。 返回。

      END METHOD.
      METHOD PUBLIC VOID storeParam(input iParam as int  ):
          dbfield = string(iParam).
          RETURN.
      
      END METHOD.
      METHOD PUBLIC VOID storeParam(input dParam as date  ):
          dbfield = string(dParam).
          RETURN.
      

      结束方法。

      只是一个想法。

      【讨论】:

        猜你喜欢
        • 2021-09-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-07-05
        • 1970-01-01
        相关资源
        最近更新 更多