The following code example provides a FUNCTION to emulate a dynamic EXPORT statement, (currently missing from the 4GL in releases prior to 12.8)
FUNCTION dynExport RETURNS CHARACTER
(INPUT hRecord AS HANDLE,
INPUT cDelim AS CHARACTER):
DEFINE VARIABLE hFld AS HANDLE NO-UNDO.
DEFINE VARIABLE iCnt AS INTEGER NO-UNDO.
DEFINE VARIABLE iExtnt AS INTEGER NO-UNDO.
DEFINE VARIABLE cTmp AS CHARACTER NO-UNDO.
DEFINE VARIABLE cArray AS CHARACTER NO-UNDO.
DEFINE VARIABLE cResult AS CHARACTER NO-UNDO.
DEFINE VARIABLE cLobname AS CHARACTER NO-UNDO.
IF hRecord:TYPE <> "BUFFER" THEN
RETURN ?.
DO iCnt = 1 TO hRecord:NUM-FIELDS:
ASSIGN hFld = hRecord:BUFFER-FIELD(iCnt).
/* Handle EXPORT for large objects by writing them out to .blb files. Omit this section in Progress 9
* EXPORT adds extra "" for output compatible with the INPUT statement.
* Names for blobs are not guaranteed the same as the static EXPORT statement, IMPORT handles them correctly.
*/
IF hFld:DATA-TYPE = "clob" OR hFld:DATA-TYPE = "blob" THEN DO:
IF hFld:BUFFER-VALUE = ? THEN DO:
cResult = cResult + "?" + cDelim.
END.
ELSE DO:
cLobname = hFld:NAME +
(IF hFld:DATA-TYPE = "clob" THEN "!" + GET-CODEPAGE(hFld:BUFFER-VALUE) + "!" ELSE "")
+ hRecord:TABLE + "_" + STRING(hRecord:RECID) + ".blb".
COPY-LOB FROM hFld:BUFFER-VALUE TO FILE cLobname NO-CONVERT.
cResult = cResult + QUOTER(cLobname) + cDelim.
END.
NEXT.
END.
IF hFld:EXTENT = 0 THEN DO:
IF hFld:BUFFER-VALUE = ? then cTmp = "?".
ELSE
CASE hFld:DATA-TYPE:
WHEN "character" THEN cTmp = QUOTER(hFld:BUFFER-VALUE).
WHEN "raw" THEN cTmp = '"' + STRING(hFld:BUFFER-VALUE) + '"'.
WHEN "datetime" OR
WHEN "datetime-tz" THEN
cTmp = string(year(hFld:BUFFER-VALUE),"9999")
+ "-" + string(month(hFld:BUFFER-VALUE),"99")
+ "-" + string(day(hFld:BUFFER-VALUE),"99")
+ "T" + substring(string(hFld:BUFFER-VALUE),12).
OTHERWISE cTmp = STRING(hFld:BUFFER-VALUE).
END CASE.
cResult = cResult + cTmp + cDelim.
END.
ELSE DO:
cArray = "".
DO iExtnt = 1 TO hFld:EXTENT:
IF hFld:BUFFER-VALUE(iExtnt) = ? THEN cTmp = "?".
ELSE
CASE hFld:DATA-TYPE:
WHEN "character" THEN cTmp = QUOTER(hFld:BUFFER-VALUE(iExtnt)).
WHEN "raw" THEN cTmp = '"' + STRING(hFld:BUFFER-VALUE(iExtnt)) + '"'.
WHEN "datetime" OR
WHEN "datetime-tz" THEN
cTmp = string(year(hFld:BUFFER-VALUE(iExtnt)),"9999")
+ "-" + string(month(hFld:BUFFER-VALUE(iExtnt)),"99")
+ "-" + string(day(hFld:BUFFER-VALUE(iExtnt)),"99")
+ "T" + substring(string(hFld:BUFFER-VALUE(iExtnt)),12).
OTHERWISE cTmp = STRING(hFld:BUFFER-VALUE(iExtnt)).
END CASE.
cArray = cArray + cTmp + cDelim.
END.
cResult = cResult + RIGHT-TRIM(cArray,cDelim) + cDelim.
END.
END.
RETURN RIGHT-TRIM(cResult,cDelim).
END.
This dynExport function can be invoked to: 1. Export the record content to a variable:
DEFINE VARIABLE myVar AS CHARACTER.
FIND FIRST customer.
ASSIGN myVar = dynExport(INPUT BUFFER customer:HANDLE, " ").
MESSAGE myVar VIEW-AS ALERT-BOX.
2. Emulate a dynamic EXPORT statement for a single record:
FIND FIRST customer.
OUTPUT TO test.txt.
PUT UNFORMATTED dynExport(INPUT BUFFER customer:HANDLE, " ") SKIP.
OUTPUT CLOSE.
3. Dynamically dump an entire table, when the table name is unknown at design time:
DEFINE VARIABLE f-table AS CHARACTER FORMAT "X(30)":U. /* table name */
DEFINE VARIABLE f-folder AS CHARACTER FORMAT "X(30)":U. /* directory name */
DEFINE VARIABLE hQuery AS HANDLE NO-UNDO.
DEFINE VARIABLE hBuffer AS HANDLE NO-UNDO.
DEFINE VARIABLE cExportData AS CHARACTER NO-UNDO.
CREATE BUFFER hBuffer FOR TABLE f-table.
CREATE QUERY hQuery.
hQuery:SET-BUFFERS(hBuffer).
hQuery:QUERY-PREPARE("FOR EACH " + f-table).
hQuery:QUERY-OPEN().
OUTPUT TO VALUE(f-folder + "\" + f-table + ".d").
hQuery:GET-FIRST().
DO WHILE NOT hQuery:QUERY-OFF-END:
cExportData = dynExport(INPUT hBuffer, INPUT " ").
PUT UNFORMATTED cExportData SKIP.
hQuery:GET-NEXT().
END.
OUTPUT CLOSE.
hQuery:QUERY-CLOSE().