I'm new to progress and I'm trying to learn dynamic queries. As a Task I gave to myself I want to read a csv file and create a table based on the contents of said file. So far everything works but I can't really seem to find a way to display the contents properly. I have a temp-table created based on a csv input with the first line being the columns or fields of the table and everything after being the records. Field1,Field2,Field3,Field4,Fieldn... Value1.1,Value2.1,Value3.1,Value4.1,Valuen.1... Value1.2,Value2.2,Value3.2,Value4.2,Valuen.1... Value1.3,Value2.3,Value3.3,Value4.3,Valuen.1... Value1.4,Value2.4,Value3.4,Value4.4,Valuen.1... etc... How can I display a dynamic number of fields and their names properly? The following things are unknown: Number of fields Name of fields Values of records The following works and shows the data in the desired format (but it's hard coded): DO WHILE qMyTable:GET-NEXT(): DISPLAY bMyTable:BUFFER-FIELD(1):BUFFER-VALUE LABEL 'PK' bMyTable:BUFFER-FIELD(2):BUFFER-VALUE LABEL 'Field1' bMyTable:BUFFER-FIELD(3):BUFFER-VALUE LABEL 'Field2' bMyTable:BUFFER-FIELD(4):BUFFER-VALUE LABEL 'Field3' bMyTable:BUFFER-FIELD(5):BUFFER-VALUE LABEL 'Field4' WITH FRAME f DOWN. DOWN WITH FRAME f. END. I'm trying to loop over the buffer fields but I can't find a way to do it without redefining the DISPLAY command every iteration. Also I don't know how to display the labels of the fields in as a header row. I'm looking for something like this : /* This doesn't work */ DO WHILE qMyTable:GET-NEXT(): DO i = 1 to iNumFields: DISPLAY bMyTable:BUFFER-FIELD(i):BUFFER-VALUE LABEL cTitlerow. END. END. This would be the full code: /* Variables */ DEF VAR i AS INTEGER INITIAL 0 NO-UNDO. //Counter DEF VAR iEntry AS INTEGER INITIAL 0 NO-UNDO. //Counter2 DEF VAR cTitleRow AS CHARACTER NO-UNDO. //Fields csv DEF VAR cDataRow AS CHARACTER NO-UNDO. //Entries csv DEF VAR cFieldName AS CHARACTER NO-UNDO. //Field DEF VAR iNumFields AS INTEGER NO-UNDO. //Amount of Fields DEF VAR iNumLines AS INTEGER NO-UNDO. //Amount of records DEF VAR cTitleArray AS CHARACTER EXTENT NO-UNDO. //Fields Array /* Handles */ DEF VAR ttMyTable AS HANDLE NO-UNDO. //Temp table DEF VAR bMyTable AS HANDLE NO-UNDO. //Buffer DEF VAR qMyTable AS HANDLE NO-UNDO. //Query INPUT FROM 'C:\Path\To\CSV\mycsv.csv'. /* Get first row for fields and field names */ IMPORT UNFORMATTED cTitleRow. iNumFields = NUM-ENTRIES(cTitleRow) + 1. //Additional field for PK EXTENT(cTitleArray) = iNumFields. /* Dynamic table creation */ CREATE TEMP-TABLE ttMyTable. ttMyTable:ADD-NEW-FIELD('PK', 'integer'). cTitleArray[1] = 'PK'. DO i = 2 to iNumFields: iEntry = i - 1. cFieldName = ENTRY(iEntry,cTitleRow). ttMyTable:ADD-NEW-FIELD(cFieldName, 'character'). cTitleArray = cFieldName. END. /* Adding and defining indexes */ ttMyTable:ADD-NEW-INDEX('idx', TRUE, TRUE). ttMyTable:ADD-INDEX-FIELD('idx', 'PK', 'asc'). ttMyTable:TEMP-TABLE-PREPARE('myTable'). /* Creating buffer */ bMyTable = ttMyTableEFAULT-BUFFER-HANDLE. /* Populating data */ REPEAT: IMPORT UNFORMATTED cDataRow. bMyTable:BUFFER-CREATE. bMyTable:k = iNumLines. DO i = 2 to iNumFields: iEntry = i - 1. bMyTable:BUFFER-FIELD(i):BUFFER-VALUE = ENTRY(iEntry,cDataRow). bMyTable:BUFFER-FIELD(i):COLUMN-LABEL = cTitleArray. bMyTable:BUFFER-FIELD(i):LABEL = cTitleArray. END. iNumLines = iNumLines + 1. END. /* Creating query */ CREATE QUERY qMyTable. qMyTable:SET-BUFFERS(bMyTable). qMyTable:QUERY-PREPARE('for each myTable'). qMyTable:QUERY-OPEN(). /* /* This doesn't work */ DO WHILE qMyTable:GET-NEXT(): DO i = 1 to iNumFields: DISPLAY bMyTable:BUFFER-FIELD(i):BUFFER-VALUE. END. END. */ DO WHILE qMyTable:GET-NEXT(): DISPLAY bMyTable:BUFFER-FIELD(1):BUFFER-VALUE LABEL 'PK' bMyTable:BUFFER-FIELD(2):BUFFER-VALUE LABEL 'Field1' bMyTable:BUFFER-FIELD(3):BUFFER-VALUE LABEL 'Field2' bMyTable:BUFFER-FIELD(4):BUFFER-VALUE LABEL 'Field3' bMyTable:BUFFER-FIELD(5):BUFFER-VALUE LABEL 'Field4' WITH FRAME f DOWN. DOWN WITH FRAME f. END. qMyTable:QUERY-CLOSE(). DELETE OBJECT qMyTable. Continue reading...