如何为每个循环导出文本文件?
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.
我写了一个将文件导出到特定目录的程序,我觉得我写了一些不需要的逻辑。所以我想知道导出文件的简短和最佳方法。让我分享一下我的尝试
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.