如何使用基于数据库字段动态的规则将参数传递给Progress程序?

时间:2015-05-04 22:22:30

标签: progress-4gl openedge

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

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

我的数据库字段存储如下:

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.

然后我尝试使用include运行程序来传递参数(在本例中,程序有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   
---------------------------

任何人都可以帮我吗? 提前谢谢。

3 个答案:

答案 0 :(得分:4)

看起来好像在尝试使用变量参数定义。 看看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.

答案 1 :(得分:1)

了解这类预处理器相关问题的最佳方法是使用预处理列表进行编译,然后对预处理文件进行语法检查。一旦你知道结果预处理文件中的错误在哪里,你必须找出哪个include / define导致了不能编译的代码。

  1. 在程序编辑器中 编译source.w preprocess source.pp。
  2. 在过程编辑器中打开 source.pp 并执行语法检查
  3. 查看原始源以查找导致无法编译的代码的include或preprocessor构造。

答案 2 :(得分:0)

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

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

类似于:

METHOD PUBLIC VOID storeParam(输入cParam为char):         dbfield = cParam。         RETURN。

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.

END METHOD。

只是一个想法。