显示动态字段数

时间:2019-05-29 14:05:50

标签: openedge progress-4gl

我是新手,我正在尝试学习动态查询。作为一项任务,我想阅读一个csv文件并根据该文件的内容创建一个表。到目前为止,一切正常,但是我似乎还找不到真正正确显示内容的方法。

我有一个基于csv输入创建的临时表,第一行是表的列或字段,之后的所有内容都是记录。

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...

如何正确显示动态数量的字段及其名称?
以下是未知的事情:

  • 字段数
  • 字段名称
  • 记录值

以下内容可以工作并以所需的格式显示数据(但它是硬编码的):

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.

我试图遍历缓冲区字段,但是在不每次迭代都重新定义DISPLAY命令的情况下,我无法找到一种方法。另外,我也不知道如何在标题行中显示字段的标签。

我正在寻找这样的东西:

/*
This doesn't work
*/
DO WHILE qMyTable:GET-NEXT():    
    DO i = 1 to iNumFields:
        DISPLAY bMyTable:BUFFER-FIELD(i):BUFFER-VALUE LABEL cTitlerow[i].
    END. 
END.

这将是完整的代码:

/*
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[i] = 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 = ttMyTable:DEFAULT-BUFFER-HANDLE.

/*
Populating data
*/
REPEAT:
    IMPORT UNFORMATTED cDataRow.
    bMyTable:BUFFER-CREATE.
    bMyTable::pk = 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[i].
        bMyTable:BUFFER-FIELD(i):LABEL = cTitleArray[i].
    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.

3 个答案:

答案 0 :(得分:1)

我认为您可能只有一些框架问题。您的代码基本上应该可以工作。

此较小的更改将显示您的数据,但它将全部显示在一列中。

DO WHILE qMyTable:GET-NEXT():      
    DO i = 1 to iNumFields:
        DISPLAY bMyTable:BUFFER-FIELD(i):BUFFER-VALUE WITH FRAME f2 DOWN TITLE "Dynamic" .
        DOWN  WITH FRAME f2 .
    END.  
END.

所以输出基本上是

row1column1
row1column2
row1column3
...
row1columnN
row2column1
row2column2
row2column3
...
row2columnN
etc

代替

row1column1    row1column2    row1column3    ...    row1columnN
row2column1    row2column2    row2column3    ...    row2columnN

获得相同结果的一个想法是也动态创建框架小部件...

答案 1 :(得分:1)

我会这样做。它将在名称旁边显示字段值,并且一次显示一条记录。我希望这会有所帮助:

DO WHILE qMyTable:GET-NEXT():    
   DO i = 1 to iNumFields:
      DISPLAY bMyTable:BUFFER-FIELD(i):NAME
              bMyTable:BUFFER-FIELD(i):BUFFER-VALUE LABEL cTitlerow[i] WITH FRAME f DOWN.
      DOWN WITH FRAME f.
   END. 
   CLEAR FRAME f ALL.
END.

答案 2 :(得分:1)

这应该使您开始动态创建框架和“文本”小部件:

define variable f as handle no-undo.
define variable t as handle no-undo.

define variable r as integer no-undo initial 1.
define variable c as integer no-undo initial 1.

create frame f.
assign
  f:row           = 4
  f:column        = 1 
  f:width-chars   = 132
  f:box           = no
  f:top-only      = false
  f:overlay       = true
  f:name          = "something"
no-error.

create text t.
assign
  t:frame        = f
  t:name         = "text1"
  t:format       = substitute( "x(&1)", max( 1, 20, length( t:name )))
  t:row          = r
  t:col          = c
  t:screen-value = "value1"
  f:height-chars = max( r, f:height-chars )
.

f:visible = yes.

在您的情况下,您可能只想在顶部创建一次框架,然后为每个字段创建2个文本小部件-一个用于标签,一个用于数据值。