Skip to content

Loading cCJGrid Data

Simple grids (cCJGrid) are designed to enable loading data from any source. For example, your data might come from a CSV file, an XML file, an SQL query, or any programmatic method for fetching data.

To load data into a grid, you must populate the grid's datasource. A datasource is populated by loading data into its internal datasource array. This is represented as an array of type tDataSourceRow, where each array element represents a row of data to be displayed in the grid.

Column objects (cCJGridColumn) are connected to both the grid and the datasource (cCJGridDataSource). Each column represents an element in a datasource row’s value array (tDataSourceRow.sValue). The element position of a column in that array is determined by the order that grid column is created, which is stored in the column's piColumnId property.

In simple grids, data is loaded manually by creating a tDataSourceRow array and sending the InitializeData message to the grid object.

When to Initialize the Grid

Most often, you will want to initialize your Grid when it is being activated. You must do that after the COM control has been created. The grid object's Activating event is a good place to load data.

Procedure Activating
    Forward Send Activating
    Send LoadData // Assume this creates the data and calls InitializeData
End_Procedure

InitializeData and cCJGrids

Before you call InitializeData, you must create and fill your array. The mechanism for doing this is entirely up to you.

The following example declares a grid object with three columns and fills the grid with data from a customer table.

Object oCJGrid1 is a cCJGrid
    Object oCustomer_Customer_Number is a cCJGridColumn
        Set piWidth to 46
        Set psCaption to "Number"
    End_Object

    Object oCustomer_Name is a cCJGridColumn
        Set piWidth to 231
        Set psCaption to "Customer Name"
    End_Object

    Object oCustomer_Status is a cCJGridColumn
        Set piWidth to 52
        Set psCaption to "Status"
        Set pbCheckbox to True
        Set psCheckboxTrue to "Y"
        Set psCheckboxFalse to "N"
    End_Object

    Procedure LoadData
        Handle hoDataSource
        tDataSourceRow[] TheData
        Boolean bFound
        Integer iRows
        Integer iNum iName iStatus

        Get phoDataSource to hoDataSource
        // Get the datasource indexes of the various columns
        Get piColumnId of oCustomer_Customer_Number to iNum
        Get piColumnId of oCustomer_Name to iName
        Get piColumnId of oCustomer_Status to iStatus

        // Load all data into the datasource array
        Clear Customer
        Find ge Customer by 1
        Move (Found) to bFound

        While bFound
            Move Customer.Customer_Number to TheData[iRows].sValue[iNum]
            Move Customer.Name to TheData[iRows].sValue[iName]
            Move Customer.Status to TheData[iRows].sValue[iStatus]
            Find gt Customer by 1
            Move (Found) to bFound
            Increment iRows
        Loop

        // Initialize Grid with new data
        Send InitializeData TheData
        Send MoveToFirstRow
    End_Procedure

    Procedure Activating
        Forward Send Activating
        Send LoadData
    End_Procedure
End_Object

The data is loaded when the grid is first activated. The LoadData procedure loops through the customer table; for each customer record, a tDataSourceRow array element is populated. This represents a single grid row.

The column values are stored in the tDataSourceRow.sValue member. The sValue member is also an array where each sValue element corresponds to a grid column. The connection between a column object and the corresponding array element in sValue is stored in the column's piColumnId property. Each column is assigned a sequential column id as it is created; this id is used to bind the column to the datasource's data.

Using piColumnIDs when populating the tDataSource.sValue array is good practice. It means that your code will be self-adjusting when columns are repositioned, added, or removed from the grid.

The example below shows how to populate the datasource of a three-column grid with two rows of data.

Procedure LoadData
    tDataSourceRow[] DataSourceArray

    Move "First Choice" to DataSourceArray[0].sValue[0]
    Move "A" to DataSourceArray[0].sValue[1]
    Move "100" to DataSourceArray[0].sValue[2]

    Move "Second Choice" to DataSourceArray[1].sValue[0]
    Move "B" to DataSourceArray[1].sValue[1]
    Move "101" to DataSourceArray[1].sValue[2]

    Send InitializeData DataSourceArray
End_Procedure

In this example, we are hard-coding the column ids when setting the sValue array member of each row. This technique is vulnerable to design changes in the grid's column layout. For example, if a column was inserted before the first column, then all of the sValue array indexes in the above code would need to be adjusted; otherwise, the data would appear in the wrong columns.

If you reference an element in the sValue array that does not correspond to any grid column, then a runtime error will occur when InitializeData is called.

Loading Grid Data and Displaying Grid Data

It is important to note that loading grid data into the datasource does not mean that the data is immediately loaded into the grid's rows and columns. The grid object will request pages of data from the datasource at a time when it needs that data.

You should not make any assumption about when a particular row of data is displayed in the grid. More specifically, you should not make any assumption about the states of global variables or record buffers when a grid row is being displayed.

For more information, see: Customizing the Display for Each Cell and Using Hidden Columns.

See Also