Friday, April 27, 2018

Creating lookup control in D365

The easiest way to do lookup on your form control in D365 can be achieved by following the steps mentioned below.

  1. Go to your field where lookup needs to be created 
  2. Expand the Events node of form control
  3. Right click OnLookup event and select "Copy event handler method"
  4. Create a new class and name it appropriately (Naming convention "FormName"+"EventHandler")
  5. In newly created class press Ctrl + V
          [FormControlEventHandler(formControlStr(SalesTable, LC_AssetGroup_LC_AssetId), FormControlEventType::Lookup)]
    public static void LC_AssetGroup_LC_AssetId_OnLookup(FormControl sender, FormControlEventArgs e)
    {
        
    }
Do your lookup code inside the handler, as shown below

FormControlEventHandler(formControlStr(SalesTable, LC_AssetGroup_LC_AssetId), FormControlEventType::Lookup)]
public static void LC_AssetGroup_LC_AssetId_OnLookup(FormControl sender, FormControlEventArgs e)
{
    Query                   query = new Query();
    QueryBuildDataSource    queryBuildDataSource;
    SysTableLookup          sysTableLookup;

    sysTableLookup = SysTableLookup::newParameters(tableNum(AssetBook), sender);
    queryBuildDataSource = query.addDataSource(tableNum(AssetBook));

    queryBuildDataSource.addRange(fieldNum(AssetBook, Status)).value(strFmt('((Status == %1) || (Status == %2))', any2int(AssetStatus::Open), any2int(AssetStatus::Closed)));

    sysTableLookup.addLookupField(fieldNum(AssetBook, AssetId), true);
    sysTableLookup.addLookupMethod(tableMethodStr(AssetBook, assetName));

    sysTableLookup.parmQuery(query);
    sysTableLookup.performFormLookup();
}

Output




More than one form was opened at once for the lookup control

After implementing lookup in D365 I encountered an error "More than one form was opened at once for the lookup control" while interacting with control as shown below.



Lookup Code

FormControlEventHandler(formControlStr(SalesTable, LC_AssetGroup_LC_AssetId), FormControlEventType::Lookup)]
public static void LC_AssetGroup_LC_AssetId_OnLookup(FormControl sender, FormControlEventArgs e)
{
    Query                   query = new Query();
    QueryBuildDataSource    queryBuildDataSource;
    SysTableLookup          sysTableLookup;

    sysTableLookup = SysTableLookup::newParameters(tableNum(AssetBook), sender);
    queryBuildDataSource = query.addDataSource(tableNum(AssetBook));

    queryBuildDataSource.addRange(fieldNum(AssetBook, Status)).value(strFmt('((Status == %1) || (Status == %2))', any2int(AssetStatus::Open), any2int(AssetStatus::Closed)));

    sysTableLookup.addLookupField(fieldNum(AssetBook, AssetId), true);
    sysTableLookup.addLookupMethod(tableMethodStr(AssetBook, assetName));

    sysTableLookup.parmQuery(query);
    sysTableLookup.performFormLookup();
}

In order to fix this issue we need to make sure of following things:
  • No super() call in lookup code
  • FormControlCancelableSuperEventArgs must be used to cancel super()
FormControlCancelableSuperEventArgs event = e as FormControlCancelableSuperEventArgs;

event.CancelSuperCall();

Lookup Code with Fix

[FormControlEventHandler(formControlStr(SalesTable, LC_AssetGroup_LC_AssetId), FormControlEventType::Lookup)]
public static void LC_AssetGroup_LC_AssetId_OnLookup(FormControl sender, FormControlEventArgs e)
{
    Query                   query = new Query();
    QueryBuildDataSource    queryBuildDataSource;
    SysTableLookup          sysTableLookup;

    FormControlCancelableSuperEventArgs event = e as FormControlCancelableSuperEventArgs;

    sysTableLookup = SysTableLookup::newParameters(tableNum(AssetBook), sender);
    queryBuildDataSource = query.addDataSource(tableNum(AssetBook));
    queryBuildDataSource.addRange(fieldNum(AssetBook, Status)).value(strFmt('((Status == %1) || (Status == %2))', any2int(AssetStatus::Open), any2int(AssetStatus::Closed)));
    sysTableLookup.addLookupField(fieldNum(AssetBook, AssetId), true);
    sysTableLookup.addLookupMethod(tableMethodStr(AssetBook, assetName));

    sysTableLookup.parmQuery(query);
    sysTableLookup.performFormLookup();
    event.CancelSuperCall();
}


Hope you find this post useful :)