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.