如何为每个循环导出文本文件?

问题描述 投票:2回答:3

我已经编写了一个用于将文件导出到特定目录的程序,我觉得我已经编写了一些不需要的逻辑。所以我想知道导出文件的最佳方法。让我分享我的尝试

DEFINE VARIABLE cData AS CHARACTER NO-UNDO.
DEFINE VARIABLE i     AS INTEGER NO-UNDO.
DEFINE VARIABLE icount AS INTEGER NO-UNDO.
DEFINE VARIABLE cName AS CHARACTER NO-UNDO.
DEFINE VARIABLE cPath AS CHARACTER NO-UNDO.

DEFINE TEMP-TABLE ttdata
    FIELD GetName  AS CHARACTER 
    FIELD iValue   AS INTEGER.

ASSIGN
    icount = 2
    cPath  = "*******".

DO I = 1 TO icount:
    IF I = 1  THEN cName = "David".
    IF I = 2  THEN cName = "Macavo".


   CREATE ttdata.
   ASSIGN
        ttdata.GetName = cName
        ttdata.iValue  =  100.
END.

/** ttdata has two records now*/
FOR EACH ttdata.
    RUN CallProc.p (INPUT ttdata.GetName,
                    INPUT ttdata.iValue).
END.

PROCEDURE CallProc:

    DEFINE INPUT PARAMETER getName AS CHARACTER NO-UNDO.
    DEFINE INPUT PARAMETER iValue  AS INTEGER   NO-UNDO.

    OUTPUT TO cPath.
    PUT UNFORMATTED ttdata.GetName ttdata.GetName.
    OUTPUT CLOSE.
END PROCEDURE.

根据我的逻辑,它可以正常工作,并且可以按预期导出2个文件,但是调用另一个过程却不明智。请帮助此情况。

openedge progress-4gl
3个回答
2
投票

在我的示例中,我将使用sports2000数据库。每个人都有一个副本,因此可以轻松运行该示例。

define stream outFile.  /* using a named stream rather than the default, unnamed, stream avoids unintended conflicts if someone else's code is lazily using the unnamed stream */

function mkTemp returns character ( input tmpid as character, input extension as character ):

  define variable fname as character no-undo.
  run adecomm/_tmpfile.p ( tmpid, extension, output fname ).

  /* create the temp file with no content
   */

  output stream outFile to value( fname ).
  output stream outFile close.

  return fname.

end.


procedure doStuff:

  define input parameter tmpfile as character no-undo.
  define input parameter custid  as integer   no-undo.

  output stream outFile to value( tmpFile ) append.  /* open the existing file in append mode */

  put stream outFile "customer:" custId skip.
  for each order no-lock where order.custNum = custId and orderStatus <> "shipped" and salesRep = "bbb":
    put stream outFile orderNum " " promised skip.
  end.

  output stream outFile close.

  return.

end.

define variable i       as integer no-undo.
define variable tmpName as character no-undo.

/* tmpName = mkTemp( "xyzzy", ".tmp" ). */  /* if you only need one temp file get the name here and comment it out below */

for each customer no-lock:

  tmpName = mkTemp( "xyzzy", ".tmp" ).  /* use this if every customer should get a distinct temp file */

  run doStuff ( tmpName, custNum ).

  /* if there is no good reason to be calling the doStuff() procedure then just remove it and do it inline like this: */

  /*
   *
  output stream outFile to value( tmpFile ) append.  /* open the existing file in append mode */

  put stream outFile "customer:" customer.custNum skip.
  for each order no-lock where order.custNum = customer.CustNum and orderStatus <> "shipped" and salesRep = "bbb":
    put stream outFile orderNum " " promised skip.
  end.

  output stream outFile close.

   */

  i = i + 1.
  if i >= 3 then leave.  /* just do 3 customers for the sample run... */

end.

2
投票

乍一看程序看起来还不错,但是有几个问题。

DEFINE TEMP-TABLE可以使用NO-UNDO。

您可能应该使用“ FOR EACH ttdata:”代替“ FOR EACH ttdata”。这是旧样式。

您正在运行CallProc.p,它是一个外部程序,而不是示例中包含的内部过程。如果您的代码实际运行,则必须在CallProc.p中向我们显示代码。

假设来自CallProc的代码,您打开的文件名为cPath。 (我不明白为什么要说要写入两个文件。)如果要将文件命名为“ *******”,则必须写入value(cPath)而不是cPath,但是要写“ ****” ***”在Windows中仍然是无效的名称。

为每一行运行一个程序并没有太大的伤害。更大的问题是您每次都打开和关闭文件。在每个文件之前打开文件,然后将其关闭。如果您使用的是当前的OpenEdge版本,则应在finally块中将其关闭。

也要在不带APPEND的情况下打开文件,这意味着您每次都将其覆盖,因此只有最后一条记录被写入。

关于不使用过程,这应该是微不足道的,特别是因为您不使用传递给过程的参数。不过,您当前正在输出ttdata.GetName两次,这可能是一个错误。另外,由于UNFORMATTED不会添加任何空格,因此您在put语句的末尾缺少一个SKIP,并且两者之间没有空格。我想您应该已经编写了PUT UNFORMATTED getName“” iValue跳过。

我想这是某种作业?


2
投票

如果要两个(或多个)单独的导出文件,则需要为其指定唯一的名称。我在这里通过重用您的'I'变量并每次都重新分配cPath来做到这一点。尽管我不同意调用一个单独的过程来写文件不是一个好主意,但我已将其合并到单个FOR-EACH循环中。我还修复了idspispopd提出的一些观点。

DEFINE VARIABLE i     AS INTEGER NO-UNDO.
DEFINE VARIABLE icount AS INTEGER NO-UNDO.
DEFINE VARIABLE cName AS CHARACTER NO-UNDO.
DEFINE VARIABLE cPath AS CHARACTER NO-UNDO.

DEFINE TEMP-TABLE ttdata NO-UNDO
    FIELD GetName  AS CHARACTER 
    FIELD iValue   AS INTEGER.

ASSIGN
    icount = 2.

DO I = 1 TO icount:
    /* Using a CASE statement makes it easier to add in other values in the future */
    CASE I:
        WHEN 1 THEN cName = "David".
        WHEN 2 THEN cName = "Macavo".
    END CASE.

    CREATE ttdata.
    ASSIGN
        ttdata.GetName = cName
        ttdata.iValue  =  100.
END.

/** ttdata has two records now*/
I = 1.
FOR EACH ttdata NO-LOCK:

    cPath = ".\" + STRING(I) + ".txt".

    OUTPUT TO VALUE(cPath).
    PUT UNFORMATTED ttdata.GetName ttdata.iValue SKIP.
    OUTPUT CLOSE.

    I = I + 1.
END.
© www.soinside.com 2019 - 2024. All rights reserved.