Operations Maintenance in Microsoft Dynamics AX

Recently I have got a requirement of having a possibility to update several values for selected Operation in AX 2012. This is not an inbuilt feature of AX 2012 but this was a client requirement for providing the possibility to update several values for selected Operation according to given parameter settings.

In my requirement, it was required to create two forms which include a setup form known as Data Maintenance Setup Form where we can specify the tables and fields of selected table to be updated. This form is basically a Parameter settings form to control what can be updated. The form should look like this.


As you can see we have two sections of form .In first section you can choose the name of Table which you want to update and in second section you will have all the fields of above selected table which is required to be updated with new value on the basis of some criteria.

The second form is Operation Maintenance Form where we will define the condition on basis of which the mentioned new value will be updated in the fields that has been selected in Data Maintenance Form. This Operation Maintenance Form will update RouteOpr Table. Since I am talking about Operations here this RouteOpr table is taken into consideration but we can add other tables also and extend the functionality for other Tables as well. This Form 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 data source:
  • I have written following code on modified method of my Table Name Control
To get the lookup of Field name on Fieldname Control from above selected Table , I have used following code :
Creation of Operation Maintenance Form:

This form is a dialog Form and is created with the help of dialog class. Following are the methods created 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 table which are 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 setup 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 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(); } } }

This is how we can update the field of any table with new value on certain condition using this code.

Hope you all have understood the concept. Feel free to ask any questions related on Microsoft dynamics AX development please contact us.