The minimum implementation of a RunBase class consists of the following components:
• ClassDeclaration
• pack
• unpack
• run
• description (static)
• main (static)
The following dialog methods are not explicitly required in a minimum implementation, but we will explore them as part of this example:
• dialog
• getFromDialog
If the dialog methods are not overridden, this provides a standard blank dialog.
ClassDeclaration
The classDeclaration consists of three types of definitions:
• Variables used to create fields in the dialog.
• Variables used within the data manipulation .
• Local macro to define which variables to pack (in other words, remember for next time, and/or use on the batch server).
In this example the class declaration is as follows.
public class DemoRunBase extends RunBase {
DialogField dialogAccount;
DialogField dialogFromDate;
DialogField dialogToDate;
CustAccount custAccount;
FromDate fromDate;
ToDate toDate;
fromDate, toDate #ENDMACRO }
The individual fields of the dialog will be initialized in the method dialog().
When the dialog is accepted by the user, the contents of the dialog fields are read in the method getFromDialog(). As both methods have to access the same variables, they are defined as members of the class.
The manipulation in the method run() uses the information from the dialog. This information is stored in variables with specific data types. These variables are initialized in the method getFromDialog() and read in the method run().
The information for the last used dialog values is packed into a container structure. The variables that should be packed are defined in the CurrentList macro in the classDeclaration.
Dialog
This method builds a dialog and initializes the fields that will be used to capture data from the user. These variables can be automatically initialized with the same data selected in the last run.
Typically, developers initialize the dialog object by a call to super() and then add fields and other controls, afterward. The dialog() method for this example has the following contents.
protected Object dialog() {
DialogRunBase dialog;
DialogGroup groupPeriod;
dialog = super();
dialogAccount =
dialog.addFieldValue(extendedTypeStr(CustAccount), custAccount);
groupPeriod = dialog.addGroup("Period");
dialogFromDate =
Visual elements are added to the dialog design using the add*() methods on the Dialog object. This code first adds one field of type CustAccount, and references the custAccount variable (the value of which will be used as the default for the field, if it has a value). Then, a group is added to the design, with a caption
"Period". The two fields added after that will be included in the just created group (by default). These two fields also reference class variables, and include a third text parameter to override the label on the fields.
When the dialog is rendered, it will appear as follows.
FIGURE 3.1 DIALOG FROM RUNBASE
GetFromDialog
This method is called immediately after the dialog is accepted by the user, and before the run() method is called. It is used to transfer the information from the dialog fields into the class variables.
The method has the following content.
public boolean getFromDialog() {
boolean ret;
ret = super();
custAccount = dialogAccount.value();
fromDate = dialogFromDate.value();
toDate = dialogToDate.value();
return ret;
}
Pack
The task for this method is to return a container with the information. This can be used to initialize a similar data manipulation on another computer and/or at another time. The information packed should be sufficient to communicate information from the dialog to the data manipulation in the run-method.
The container should contain a version number as the first element. This number should control how the rest of the container is structured. If you change the contents of the container, you should increment the version number.
The pack method frequently has the following basic contents. However, it cannot be inherited as it contains references to macros defined locally in the class declaration.
public container pack() {
return [#CurrentVersion,#CurrentList];
}
The pack/unpack method is used in the following situations:
• To save and restore the dialog between each use of the class. The information is usually saved on a per user/company basis.
• To save and restore the specification of the manipulation to execute on a batch server.
• To transfer the object from the client to the server. This is done to optimize both the user dialog and the data manipulation in an AOS environment.
Unpack
The unpack() method is the counterpart to the pack() method. It receives a container as a parameter and restores the type specific variables of the class. The method returns a Boolean with the value true if the information could be restored.
The unpack() method handles the current version number as a minimum, which is defined in the ClassDeclaration. You can select to support unpacking of older versions by extending the switch statement.
The unpack() method has the following content.
public boolean unpack(container _packedClass) {
Version version = RunBase::getVersion(_packedClass);
switch (version) {
case(#CurrentVersion) :
[version,#CurrentList] = _packedClass;
The run() method controls the data manipulation. The method can use the variables defined in the classDeclaration and initialized from the dialog. The method does not receive any formal parameters.
The content of the run() method is unique for each data manipulation, based on requirements. It will typically contain some local variables and a "try-catch"
statement with TTS calls that wrap all physical data manipulation into one logical transaction.
The method for our example has the following content.
public void run() {
CustTrans custTrans;
select sum(AmountMST) from custTrans where custTrans.AccountNum == ledgerAccount && custTrans.TransDate >= fromDate
&& custTrans.TransDate <= toDate;
info(strFmt("Sum equals %1", custTrans.AmountMST));
}
Description
The description() method returns a descriptive name for the data manipulation.
The value is used to identify the job in the batch queue and is used as the caption in the dialog.
The method for this example is as follows.
static client server ClassDescription description() {
return "Sum customer transactions";
}
This method is static, which means that it can be executed on the opposite tier of the object. In this case, because the method does not contain user interface or data interface, the specification of both client and server results in an execution of the method on the tier it is called from regardless of the settings on the class properties.
Main
The main() method is the entry point when the class is executed from a menu item. The method is static. It defines and initializes the object. Notice that new() should never accept any parameters. The main method receives one formal parameter that is an args() object. This object is described further.
The main() method is also responsible for calling prompt(), which executes the dialog, and then calling run() to perform the manipulation.
static void main(Args _args) {
DemoRunBase demoRunBase;
With a main() method in place, a RunBase class can now be called from a menu item in the AOT.