QAD 2017 Enterprise Edition > User Guides > System Administration > Customizing Business Logic > Elements of Customization
  
Elements of Customization
The following section describes the code elements used in non-intrusive customization.
Parameters
The parameters of all business methods are stored in the temporary table t_Parameter. To access a parameter, you use the field of the same name in t_Parameter table. The t_Parameter table always contains exactly one available record, which means that you do not need to use find or for each when using the table. When you assign a value to a field in the table, this value is retrieved at runtime by the standard business code.
You typically assign a value to an input parameter in a before event, and assign a value to an output parameter in an after event. A value assigned to an output parameter in an before event can be overwritten by the standard business logic.
Example: The following example uses the input parameter icPkeys.
 
/**/
PROCEDURE BItem.DataLoad.before:
if t_Parameter.icPkeys <> ""
then t_Parameter.icPkeys = t_Parameter.icPkeys + chr(4) + "MyKey".
/* load something extra */
END PROCEDURE.
/**/
Datasets
All datasets available to the standard business logic are also available to the customization code. These are not just copies of these datasets, but are direct bindings, which means that any dataset changes you make go directly to the standard business logic.
Class Datasets
Each business component has a set of class tables grouped in a class dataset. These tables are used to update the application database. Database updates are first prepared in the class tables, then validated, and when correct, are written to the application database.
Each business component has three class datasets:
<classname>O (tables t_o<databasetablename>)
Records in this dataset are updated by the business logic. These values are written to the application database.
<classname>I (tables t_i<databasetablename>)
Records in this dataset represent values read from the database (used for optimistic lock checking), and must not be modified.
<classname>S (tables t_s<databasetablename>)
Records in this dataset represent the input data of business functions that use the class dataset for input parameters (for example, SetPublicTables). These records are first validated and, when correct, are copied into the <classname>O dataset. This means that all business validation rules are written to use this dataset.
A buffer t<databasetablename> is available in all components that represents the t_o<databasetablename>. This makes programming easier and more readable. Since the code is working with the t_o data in most methods, it can be used in most cases, except for the Validate* methods, in which the t_s data is worked on.
Class Tables
Each class table contains the fields tc_Rowid and tc_ParentRowid. They are used to define a generic relation between tables of the class dataset:
<childtable>.tc_ParentRowid = <parenttable>.tc_Rowid.
Important: You must not change the value of these fields. Check the documentation of each business component individually to establish the relations between class tables.
Each class table also contains the field tc_Status. The value of this field defines the kind of update that is performed on the database, and can be one of the following:
(empty)
The record is identical to the record in the database. It is ignored when the database is updated. If you do make changes to the record but forget to set the value of tc_Status, your changes are not written to the database.
'N' (new)
Records with this status are created in the database. Do not use a create statement to add records in the class dataset. Instead, use the business function AddDetailLine which assigns correct default values to the newly created record.
'C' (change)
Records with this status are updated in the database. The record to update is retrieved using the value of tc_Rowid, instead of the primary key fields. This does not mean that primary key fields can be modified, as these fields may be copied into related tables, and by modifying them, you break the link to those tables.
'D' (delete)
Records with this status are deleted in the database. The record to delete is retrieved using the value of tc_Rowid. If the table is the parent of table relations with delete constraint 'cascaded', related records are deleted as well.
Class Data Items
Each class also contains a set of data items, which are used in the internal business logic of the component. You can examine and update these data items using the generic Get<DataType>Item and Set<DataType>Item methods, where <DataType> is one of the following:
Character
Decimal
Integer
Int64
Logical
Memptr
Longchar
Raw
Recid
Rowid
Handle
ComHandle
These methods are only generated when at least one class data item of the respective data type is defined for the component.
The logic includes a preprocessor variable called &USEDDATAITEMS, which is available to all code. This preprocessor is a comma-separated list of data item names, and is passed in the include file reference definition/<component include file name> in the custom code program. For example:
{definition/bsaf.i &USEDDATAITEMS = “viDataItem”}
It is the responsibility of the custom code developer to populate the &USEDDATAITEMS variable with custom code. Data items not added to the preprocessor will not be available in the custom code.
The following conditional code defines a variable to mirror a data item:
&IF LOOKUP("viDataItem","{&USEDDATAITEMS}") > 0
&THEN
DEFINE VARIABLE viDataItem AS INTEGER NO-UNDO.
&ENDIF
The following conditional code calls the setDataItem and getDataItem methods:
Procedure GetDataItems:
Define variable vc as character no-undo.
&IF LOOKUP("viDataItem","{&USEDDATAITEMS}") > 0
&THEN
Run GetIntegerItem (input “viDataItem”, output viDataItem).
&ENDIF
End procedure.
Procedure SetDataItems:
Define variable vc as character no-undo.
&IF LOOKUP("viDataItem","{&USEDDATAITEMS}") > 0
&THEN
Run SetIntegerItem (input “viDataItem”, input viDataItem).
&ENDIF
End procedure.