Recently I need to have the possibility to update multiple values for selected operations in AX 2012. It is not an inbuilt feature of AX 2012, but this was a client requirement for providing the possibility to update several values for selected Operations according to given parameter settings.
In my requirement, there was a need to create two forms that include a setup form referred to as the Data Maintenance Setup Form, where we can specify the tables and fields of the chosen table to be updated. It is the Parameter settings form to control what can be updated. The form should look like this.
As you can see, we have two sections of the form. In the first section, you can choose the name of the Table, which you want to update, and in the second section, you will have all the fields of the above-selected that we have to update with a new value based on some criteria.
The second form is the Operation Maintenance Form, where we will define the condition based on which the mentioned new value will be updated in the fields that have been selected in the Data Maintenance Form. This Operation Maintenance Form will update RouteOpr Table. Since I am talking about Operations here, this RouteOpr table is taken into account, but we can also add other tables and extend the functionality for other tables. It should look like this:
Development:
Creation of Data Maintenance Setup Form:
-
I have created two Tables :
- AAFTableStoreOperations :TableIDNumber ,TableName(uses enum AAFTableNameOperations where you can add n no. of tables in case you want to extend the functionality other than for operations.)
- AAFFieldStoreOperations: FieldName, TableIDNumber, TableName
I have used a Splitter form to create my Data Maintenance Setup Form, which has two tables in the data source:
- I have written the following code on the modified method of my Table Name Control.
To get the lookup of Field name on Fieldname Control from the above-selected Table, I have used the following code:
Creation of Operation Maintenance Form:
This form is a dialog Form, and we can create it with the help of the dialog class. Following are the created methods and code behind it:
I am attaching the code below for this class:
public boolean canGoBatch()
{
return true;
}
This method dialog() gives desired user interface fields for use:
public Object dialog()
{
FormStringControl fieldNamecontrol,tableNameControl;
;
dialog = super();
dlgTableName = dialog.addFieldValue(enumStr(AAFTableNameOperations),tableEnum);
namefield = dialog.addField(extendedTypeStr(Name),"@SYS8498");
dlgvalueUpdate = dialog.addField(extendedTypeStr(Name),"@SYS68002");
fieldNamecontrol = namefield.control();
tableNameControl = dlgTableName.control();
fieldNamecontrol.registerOverrideMethod(methodStr(FormStringControl,lookup),methodStr(AAFOperationsMaintain,lookup),this);
tableNameControl.registerOverrideMethod(methodStr(FormStringControl,modified),methodStr(AAFOperationsMaintain,fld3_1_modified),this);
dialog.allowUpdateOnSelectCtrl(true);
return dialog;
}
This method allows you to select the table which is set in Data Maintenance Form:
public void dialogSelectCtrl()
{
tablename = enum2Symbol(enumNum(AAFTableNameOperations),dlgTableName.value());
super();
}
public void fld3_1_modified(FormStringControl _control)
{
boolean isFieldModified;
Query query;
QueryBuildDataSource qbds;
;
isFieldModified = _control.modified();
tablename = enum2Symbol(enumNum(AAFTableNameOperations),dlgTableName.value());
this.parmselectedTable(tablename);
if(isFieldModified)
{
namefield.value('');
query = new Query();
if(tablename == enum2str(AAFTableNameOperations::RouteOpr))
{
qbds = query.addDataSource(tableNum(RouteOpr));
}
else if(tablename == enum2str(AAFTableNameOperations::RouteOprTable))
{
qbds = query.addDataSource(tableNum(RouteOprTable));
}
queryRun = new QueryRun(query);
}
}
public boolean getFromDialog()
{
selectedTable = enum2Symbol(enumNum(AAFTableNameOperations),dlgTableName.value());
fieldName = namefield.value();
newValue = dlgvalueUpdate.value();
return super();
}
public void initParmDefault()
{
Query query;
QueryBuildDataSource qbd;
super();
query = new Query();
qbd = query.addDataSource(tableNum(RouteOpr));
queryRun = new QueryRun(query);
}
This method will give the lookup of Fields for the table selected and set up in Data Maintenance Form:
public Types ListFields(TableName _tableName, str _fieldName)
{
DictField dictField;
DictTable dictTable;
Types type;
;
dictTable = new dictTable(tableName2Id(_tableName));
fieldId = dictTable.fieldName2Id(_fieldName);
if (fieldId)
{
dictField = new DictField(tableName2Id(_tableName), fieldId);
if (dictField && !dictField.isSystem())
{
type = dictField.baseType();
}
}
return type;
}
public void lookup(FormStringControl _control)
{
SysTableLookup sysTableLookup = SysTableLookup::newParameters(Tablenum(AAFFieldStoreOperations),_control,true);
Query query = new Query();
QueryBuildDataSource QBDS;
SysTableLookup.addLookupfield(fieldnum(AAFFieldStoreOperations,FieldName),true);
QBDS = query.addDataSource(Tablenum(AAFFieldStoreOperations));
QBDS.addRange(fieldnum(AAFFieldStoreOperations,TableName)).value(queryvalue(tablename));
sysTableLookup.parmQuery(query);
systableLookup.performFormLookup();
}
public container pack()
{
return [#CurrentVersion, #CurrentList, queryRun.pack()];
}
public str parmselectedTable(str _selectedTable = selectedTable)
{
selectedTable = _selectedTable;
return selectedTable;
}
public QueryRun queryRun()
{
return queryRun;
}
Here in the run (), we are writing the logic for the value update of any type:
public void run()
{
RouteOprTable routeOprTable;
RouteOpr routeOpr;
Types type;
DictEnum dictEnum;
DictField dictField;
super();
type = this.listFields(selectedTable,FieldName);
while(queryRun.next())
{
ttsBegin;
if(selectedTable == enum2str(AAFTableNameOperations::RouteOpr))
{
routeOpr = queryRun.get(tableNum(RouteOpr));
routeOpr.selectForUpdate(true);
switch (type)
{
case Types::String:
routeOpr.setFieldValue(FieldName,newValue);
break;
case Types::Enum:
dictField = new DictField(tableName2Id(selectedTable), fieldId);
dictEnum = new DictEnum(dictField.enumId());
routeOpr.setFieldValue(FieldName,dictEnum.name2Value(newValue));
break;
case Types::Integer:
routeOpr.setFieldValue(FieldName,str2int(newValue));
break;
case Types::Real:
routeOpr.setFieldValue(FieldName,str2num(newValue));
break;
case Types::Date:
routeOpr.setFieldValue(FieldName,str2date(newValue,123));
break;
case Types::Int64:
routeOpr.setFieldValue(FieldName,str2int64(newValue));
break;
}
routeOpr.doUpdate();
}
if(selectedTable == enum2str(AAFTableNameOperations::RouteOprTable))
{
routeOprTable = queryRun.get(tableNum(RouteOprTable));
routeOprTable.selectForUpdate(true);
switch (type)
{
case Types::String:
routeOprTable.setFieldValue(FieldName,newValue);
break;
case Types::Enum:
dictField = new DictField(tableName2Id(selectedTable), fieldId);
dictEnum = new DictEnum(dictField.enumId());
routeOprTable.setFieldValue(FieldName,dictEnum.name2Value(newValue));
break;
case Types::Integer:
routeOprTable.setFieldValue(FieldName,str2int(newValue));
break;
case Types::Real:
routeOprTable.setFieldValue(FieldName,str2num(newValue));
break;
case Types::Date:
routeOprTable.setFieldValue(FieldName,str2date(newValue,123));
break;
case Types::Int64:
routeOprTable.setFieldValue(FieldName,str2int64(newValue));
break;
}
routeOprTable.doUpdate();
}
ttsCommit;
}
info(strFmt("ABC",FieldName,newValue));
}
boolean showQueryValues()
{
return true;
}
public boolean unpack(container _packedClass)
{
Version version = runbase::getVersion(_packedClass);
Container packedQuery;
switch (version)
{
case #CurrentVersion:
[version, #CurrentList, packedQuery] = _packedClass;
if(packedQuery)
queryRun = new QueryRun(packedQuery);
break;
default:
return false;
}
return true;
}
public boolean validate(Object _calledFrom = null)
{
if (!selectedTable || !fieldName || !newValue)
{
return checkFailed("ABC”);
}
return true;
}
server static AAFOperationsMaintain construct()
{
return new AAFOperationsMaintain();
}
public static void main (Args _args)
{
AAFOperationsMaintain dataMaintain;
dataMaintain = AAFOperationsMaintain::construct();
if(dataMaintain.prompt())
{
if (box::yesNo("ABC", dialogButton::Yes, "@SYS114651") == dialogButton::Yes)
{
dataMaintain.run();
}
}
}
Thus we can update the field of any table with new value on certain conditions by using this code.
I hope you all have understood the concept. Feel free to ask any questions related to Microsoft dynamics AX development Contact us to know more.