Axaptapedia is now maintained by AgileCadence For more information please click here.

Dialog macro

From Axaptapedia
Jump to: navigation, search

Abstracts[edit]

I often need a quick dialog to check or moify some data.

Sometimes the customer doesn't know exactly what select critera he or she needs, so the dialog needs a lot of criteria fields (from .. to).

What I have to do is creating a dialog object with up to 10 dialog fields - or more. This is very hard, because I have to repeat the ist of variables several times:

  1. declare dialog fields
  2. declare working fields
  3. create dialog fields objects, and add them to the dialog
  4. restore last saved values
  5. set values to the dialog fields
  6. after prompting and running the dialog: save values
  7. move dialog fields to the working fields.

Especially if you need more variables, you can easily make some mistakes.

So I decided to create a macro (using Abstract macro) to do the hard work.

Example[edit]

I have to check some invoices - depending on customer groups, customer or invoice accounts, invoice date and invoice id.

<xpp> static void CheckInvoices(Args _args) {

   CustInvoiceTable    custInvoiceTable;
  1. define.DialogMacroId("CheckInvoice") // <- define a unique id
   Dialog          dialog = new Dialog("Check Invoice");

// define fields

  1. localmacro.DialogMacroFields
   #dialogMacroField(CustGroupId,   fromCustGroupId,    "from customer group")
   #dialogMacroField(CustGroupId,   toCustGroupId,      "to customer group")
   #dialogMacroField(CustAccount,   fromOrderAccount,   "from customer account")
   #dialogMacroField(CustAccount,   toOrderAccount,     "to customer account")
   #dialogMacroField(CustAccount,   fromInvoiceAccount, "from invoice account")
   #dialogMacroField(CustAccount,   toInvoiceAccount,   "to invoice account")
   #dialogMacroField(TransDate,     fromInvoiceDate,    "from invoice date")
   #dialogMacroField(TransDate,     toInvoiceDate,      "to invoice date")
   #dialogMacroField(CustInvoiceId, fromInvoiceId,      "from invoice")
   #dialogMacroField(CustInvoiceId, toInvoiceId,        "to invoice")

// #dialogMacroField(NoYes, update, "change data")

  1. endmacro
  1. macrolib.DialogMacro


   while select custInvoiceTable
       where
       (! fromCustGroupId || custInvoiceTable.CustGroup >= fromCustGroupId) && // long version
       (! toCustGroupId   || custInvoiceTable.CustGroup <= toCustGroupId  ) &&
       #DialogMacroRange(fromOrderAccount,   custInvoiceTable.OrderAccount,   toOrderAccount)   &&  // short version
       #DialogMacroRange(fromInvoiceAccount, custInvoiceTable.InvoiceAccount, toInvoiceAccount) &&
       #DialogMacroRange(fromInvoiceDate,    custInvoiceTable.InvoiceDate,    toInvoiceDate)    &&
       #DialogMacroRange(fromInvoiceId,      custInvoiceTable.InvoiceId,      toInvoiceId)
   {
       // do some check ...
   }

} </xpp>

Advantages

  * You have to code the variables only once
  * dialog fields and variables match
  * the program code is very short

goodies[edit]

In some cases you don't want to insert the last values. Instead values from an active record should be used. In this case you can use a special macro: <xpp> static void rgg(Args _args) {

   CustInvoiceTable    custInvoiceTable;
  1. define.dialogMacroAfterLastValueGet
  2. localMacro.dialogMacroAfterLastValueGetBlock
  fromCustGroupId = 'value from a buffer';
  1. endMacro
  1. define.DialogMacroId("CheckInvoice")

... </xpp> I often use this for buttons in forms, to insert values from the active record.

Source of dialog macro[edit]

<xpp> // DialogMacro // // Version 1.0 2010 creation

   int version = 1;
  1. define.dialogMacroName('DialogMacro')

// declare dialog fields and variables

  1. localMacro.dialogMacroField
   %1 %2;
   DialogField %2_dialogField;
  1. endMacro
  2. dialogMacroFields
   container   dialogMacroCon;
   int         dialogMacroCount;
   ;

// count variables

  1. localMacro.dialogMacroField
   dialogMacroCount++;
  1. endMacro
  2. dialogMacroFields

// get last stored values

   dialogMacroCon = classFactory.lastValueGet(, curUserId(), UtilElementType::Class, #dialogMacroName, #DialogMacroId);
   while (conLen(dialogMacroCon) < 1+dialogMacroCount)
       dialogMacroCon += ;
   [version
  1. localMacro.dialogMacroField
   , %2
  1. endMacro
  2. dialogMacroFields
       ] = dialogMacroCon;

// addin: overwrite some values

  1. if.dialogMacroAfterLastValueGet
   #dialogMacroAfterLastValueGetBlock
  1. endif

// add dialog fields to dialog

  1. localMacro.dialogMacroField
   %2_dialogField = dialog.addFieldValue(typeId(%1), %2, %3);
  1. endMacro
  2. dialogMacroFields


// call the dialog

   if (! dialog.run())
       return;
   dialog.wait();

// set variables

  1. localMacro.dialogMacroField
   %2 = %2_dialogField.value();
  1. endMacro
  2. dialogMacroFields

// store values

   classFactory.lastValuePut([1
  1. localMacro.dialogMacroField
   , %2
  1. endMacro
  2. dialogMacroFields
   ], , curUserId(), UtilElementType::Class, #dialogMacroName, #DialogMacroId);

// a useful macro for while-selects:

  1. localMacro.DialogMacroRange
   (! %1 || %1 <= %2) &&
   (! %3 || %2 <= %3)
  1. endMacro

// end of dialog macro </xpp>