BobNoobGuy
BobNoobGuy

Reputation: 1645

Progress 4GL for each and select * from cust

I often do the following progress 4GL code

  output to /OUTText.txt.
  def var dRow as char.
  dRow = "cmpid|CustNum|Cur".
  put unformatted dRow skip.  
  for each Cust no-lock:
    dRow = subst("&1|&2|&3", Cust.CmpId, Cust.CustNum, Cust.Curr).
    put unformatted dRow skip.       
  end.
  output close. 

in order to mimic

select * from cust (in MS SQL)

my question is is there a way to make this block of code, even closely resemblance "select *" using 4GL. Such that I don't have to type each column name and it will print all values in all columns. my thinking is. something like this.

 output to /OUTText.txt.
  def var dRow as char.
  dRow = "cmpid|CustNum|Cur".
  put unformatted dRow skip.  
  for each Cust no-lock:
    if row = 1 then do:
      for each Column in Cust:
        **'PRINT THE COLUMN HEADER**
      end.
    end.
    else do:
      **'PRINT EACH CELL**
    end.
  end.
  output close. 

If there is such thing. then I don't have to keep explicit column name in dRow.

Upvotes: 0

Views: 1163

Answers (2)

Tom Bascom
Tom Bascom

Reputation: 14020

output to "somefile".

for each customer no-lock:  
  display customer.
end.

I wouldn't generally mention this as the embedded SQL-89 within the 4GL is the highway to hell (that dialect of SQL only works for the most basic and trivial of purposes and really shouldn't be used at all in production code), but as it happens:

output to "somefile".
select * from customer.

does just happen to work to the spec of the original question (although, like the DISPLAY solution, it also does not support a delimiter...)

Upvotes: 1

Jensd
Jensd

Reputation: 8011

You can do what you're after if you first output all field labels (or names) and then use EXPORT to output the table content.

To change to field name instead of label: change :LABEL below to :NAME

For instance:

DEFINE VARIABLE i AS INTEGER     NO-UNDO.

OUTPUT TO c:\temp\somefile.txt.

DO i = 1 TO BUFFER Customer:NUM-FIELDS.

    PUT QUOTER(BUFFER Customer:BUFFER-FIELD(i):LABEL).

    IF i < BUFFER Customer:NUM-FIELDS THEN 
        PUT UNFORMATTED ";".
    ELSE IF i = BUFFER Customer:NUM-FIELDS THEN 
        PUT SKIP.

END.

FOR EACH Customer NO-LOCK:
    EXPORT DELIMITER ";" Customer.
END.
OUTPUT CLOSE.

You could put the header part in a separate program to call dynamically every time you want to do something similar:

DEFINE STREAM str.

OUTPUT STREAM str TO c:\temp\somefile.txt.

RUN putHeaders.p(INPUT BUFFER Customer:HANDLE, INPUT ";", INPUT STREAM str:HANDLE).

FOR EACH Customer NO-LOCK:
    EXPORT STREAM str DELIMITER ";" Customer.
END.
OUTPUT STREAM str CLOSE.


putHeaders.p
============
DEFINE INPUT  PARAMETER phBufferHandle AS HANDLE      NO-UNDO.
DEFINE INPUT  PARAMETER pcDelimiter    AS CHARACTER   NO-UNDO.
DEFINE INPUT  PARAMETER phStreamHandle AS HANDLE      NO-UNDO.

DEFINE VARIABLE i AS INTEGER     NO-UNDO.

DO i = 1 TO  phBufferHandle:NUM-FIELDS.
    PUT STREAM-HANDLE phStreamHandle UNFORMATTED  QUOTER(phBufferHandle:BUFFER-FIELD(i):LABEL).

    IF i < phBufferHandle:NUM-FIELDS THEN 
        PUT STREAM-HANDLE phStreamHandle  UNFORMATTED pcDelimiter.
    ELSE IF i = phBufferHandle:NUM-FIELDS THEN 
        PUT STREAM-HANDLE phStreamHandle SKIP.
END.

Upvotes: 2

Related Questions