Dynamic filtered lookup fields in Dynamics AX 2009 report dialog
22. August 2018 Leave a comment
I recently faced a customer requirement in Dynamics AX 2009 where a customer needs two lookups in report dialog. Depending what was selected on the first lookup (InventLocation), the content of the second lookup should be filtered (WMSLocationId). Michael has already documented in his blog how to overwrite a lookup in dialog. In order to override the lookup methods a RunBaseReport class is needed to call the the report.
class WarehouseReportRun extends RunBaseReport
{
Dialog dlg;DialogField fieldInventLocationId;
DialogField fieldWMSLocationId;InventLocationId inventLocationId;
WMSLocationId wmsLocationId;
}
Overwrite the dialog and getFromDialog methods as usual
public Object dialog(DialogRunbase dialog, boolean forceOnClient)
{
dlg = super(dialog, forceOnClient);
fieldInventLocationId = dlg.addField(typeId(InventLocationId));
fieldWMSLocationId = dlg.addField(typeId(WMSLocationId));return dlg;
}
public boolean getFromDialog()
{
boolean ret;ret = super();
inventLocationId = fieldInventLocationId.value();
wmsLocationId = fieldWMSLocationid.value();return ret;
}
Create two parm methods for the lookup variables
public InventLocationId parmInventLocationId(
InventLocationId _inventLocationId = inventLocationId)
{
;
inventLocationId = _inventLocationId;return inventLocationId;
}
public WMSLocationId parmWmsLocationId(
WMSLocationId _wmsLocationId = wmsLocationId)
{
;
wmsLocationId = _wmsLocationId;return wmsLocationId;
}
Implement the abstract method lastValueElementName and provide the name of the report to start. In my case the report is called WarehouseReport.
public identifiername lastValueElementName()
{
return reportStr(WarehouseReport);
}
Create a menu item and start the class. Right click the lookup fields and from the setup form note the name of the lookup fields. In my case the system generated name for the first lookup field is Fld6_1 (InventLocation) and the name for the second is Fld7_1 (WMSLocation)
According to michaels blog overwrite the dialogPostRun method. Here you can defined that you want to overwrite methods and link an object with the overwritten methods.
public void dialogPostRun(DialogRunbase dialog)
{
super(dialog);dialog.dialogForm().formRun().controlMethodOverload(true);
dialog.dialogForm().formRun().controlMethodOverloadObject(this);
}
Next implement the code for the lookup on the second lookup field in the dialog. In my case it will only show WMSLocations for the selected InventLocation in the first lookup.
void Fld7_1_lookup()
{
FormStringControl ctr;
SysTableLookup lookup;
Query q;
QueryBuildDataSource qbds;
QueryBuildRange qr;
;q = new Query();
qbds = q.addDataSource(tableNum(WMSLocation));
qr = qbds.addRange(fieldNum(WMSLocation,InventLocationId));
qr.value(fieldInventLocationId.value());ctr = dlg.formRun().controlCallingMethod();
lookup = SysTableLookup::newParameters(tableNum(WMSLocation),ctr);
lookup.addLookupfield(fieldNum(WMSLocation,WMSLocationId),true);
lookup.addLookupfield(fieldNum(WMSLocation,InventLocationId));
lookup.addLookupfield(fieldNum(WMSLocation,checkText));
lookup.parmQuery(q);
lookup.performFormLookup();
}
Test the class. It will only show WMSLocations for the selected InventLocation.
In the last step overwrite the init method in the report and set the range according to the values from the lookup fields. In my report I have a InventSum datasource linked with an InventDim datasource. I use the parm methods to set the InventDim ranges on the InventLocation and WMSLocation
public void init()
{
QueryBuildDataSource qbds;
QueryBuildRange rinv;
QueryBuildRange rwms;
WarehouseReportRun wrr = element.args().caller();
;super();
qbds = this.query().dataSourceTable(tableNum(InventDim));
rinv = qbds.addRange(fieldNum(InventDim,InventLocationId));
rinv.value(wrr.parmInventLocationId());rwms = qbds.addRange(fieldNum(InventDim,WMSLocationId));
rwms.value(wrr.parmWMSLocationId());
}
The report works as required and shows only data from InventLocation 22 and WMSLocation 01-01-01-1