简体   繁体   中英

How to export a text file in for each loop?

I have written a program for export file to a specific directory and I feel I have written some unwanted logic. so I would like to know short and best way to do export the files. Let me share what I tried

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.

From my logic its working well and exporting 2 files as I expected but its poor idea to call another procedure.Please help this case.

The program doesn't look too bad at first glance, but there are several issues.

The DEFINE TEMP-TABLE could use a NO-UNDO.

You should probably use "FOR EACH ttdata:" instead of "FOR EACH ttdata." which is old style.

You are running CallProc.p which is an external program and not the internal procedure included in your example. If your code actually runs you would have to show us the code in CallProc.p.

Assuming the code from CallProc, the file you open is named cPath. (I don't get why are saying two files are written.) If you want the file to be named "*******" you have to write value(cPath) instead of cPath, but "*******" is an invalid name in Windows anyway.

It doesn't hurt too much to run a procedure for every line. The bigger issue is that you open and close the file every time. Open the file before the for each and close it afterwards. If you are using a current OpenEdge version you should close it inside a finally block.

Also you are opening the file without APPEND which means that you are overwriting it every time, so only the last record gets written.

As for not using a procedure this should be pretty trivial, especially since you don't use the parameters you pass to the procedure. You are currently outputting ttdata.GetName twice though, which is probably an error. Also you are missing a SKIP at the end of the put statement and a space in between since UNFORMATTED doesn't add any spaces. I suppose you should have written PUT UNFORMATTED getName " " iValue skip.

I suppose this is some kind of homework?

If you want two (or more) separate export files, you'll need to give them unique names. I did that here by reusing your 'I' variable and reassigning cPath each time. And although I don't agree that calling a separate procedure to write the file is a poor idea, I've incorporated it into the single FOR-EACH loop. I've also fixed some of the points that idspispopd made.

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.

I am going to use the sports2000 db in my example. Everyone has a copy so it is easy to run the sample.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM