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

How to export a text file in for each loop?

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

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 个文件,但调用另一个文件的想法很糟糕 procedure.Please 有助于解决这个问题。

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

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

您可能应该使用 "FOR EACH ttdata:" 而不是旧样式的 "FOR EACH ttdata."。

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

中的代码

假设代码来自 CallProc,您打开的文件名为 cPath。 (我不明白为什么要写两个文件。)如果你想把文件命名为“*******”,你必须写 value(cPath) 而不是 cPath,但是“**** ***" 无论如何都是 Windows 中的无效名称。

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

而且你打开文件时没有附加,这意味着你每次都在覆盖它,所以只有最后一条记录被写入。

至于不使用过程,这应该是微不足道的,特别是因为您不使用传递给过程的参数。您目前正在输出 ttdata.GetName 两次,这可能是一个错误。此外,由于未格式化不添加任何 space,因此您在 put 语句末尾缺少一个 SKIP,并且在它们之间缺少一个 space。我想你应该写 PUT UNFORMATTED getName " " iValue skip.

我想这是某种作业?

如果您想要两个(或更多)单独的导出文件,则需要为它们指定唯一的名称。我在这里通过重复使用您的 '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.

我将在示例中使用 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.