Thursday 2 November 2017

AX 2012: Create a Simple Batch Job

In this post we’ll learn how to create a very basic custom Batch job using SysOperation framework. We’ll use the base controller class SysOperationServiceController and develop a custom service operation class to achieve the goal.
Requirement:
To create a Batch job to mark all the records as processed in a custom table MAKSalesTable.
Project overview:
Untitled
The project shows how simple yet powerful the SysOperation framework is for developing custom batch jobs as opposed to RunBase framework since the minimum development needed to create a fully functional batch job is to create a custom service operation class defining a single method giving the implementation for the batch operation to be performed.
Development steps:
1. Create a service operation class MAKSalesTableService having the following class declaration:
class MAKSalesTableService
{
}
2. Create a new method in the class giving a suitable name like processRecordshaving the following definition:
[SysEntryPointAttribute(false)]
public void processRecords()
{
    MAKSalesTable   makSalesTable;
    int             counter = 0;

    //Determines the runtime
    if (xSession::isCLRSession())
    {
        info('Running in a CLR session.');
    }
    else
    {
        info('Running in an interpreter session.');

        //Determines the tier
        if (isRunningOnServer())
        {
            info('Running on the AOS.');
        }
        else
        {
            info('Running on the Client.');
        }
    }

    //Actual operation performed
    while select forUpdate makSalesTable
    {
        ttsBegin;
        makSalesTable.Processed = NoYes::Yes;
        makSalesTable.update();
        ttsCommit;

        counter++;
    }

    info(strFmt("Successfully processed %1 records.", counter));
}
3. Create an action menu item MAKSalesTableService pointing to SysOperationServiceController.
4. Set the parameters of the action menu item to the service operation just created, MAKSalesTableService.processRecords.
Untitled
5. Compile the service operation class and generate incremental IL.
6. Click on the action menu item to run the batch job. Check the Batch processing checkbox to run the job in CLR runtime which is the batch server execution environment.
Untitled
Untitled
7. Click System administration > Inquiries > Batch jobs to view the status of the job. You may also click on the Log button to view the messages written to infolog during the job execution.
Untitled
Untitled
Preconditions:
Before running the batch job, all the records were unprocessed:
Untitled
Post conditions:
After running the batch job, the list page shows that all the records are now marked as processed:
Untitled

Thursday 26 October 2017

The formatter threw an exception while trying to deserialize the message Dynamics Ax 2012 R3 SSRS

The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter http://tempuri.org/:queryBuilderArgs. The InnerException message was ‘Element ‘http://tempuri.org/:queryBuilderArgs’ contains data from a type that maps to the name ‘http://schemas.datacontract.org/2004/07/XppClasses:SrsReportProviderQueryBuilderArgs’. The deserializer has no knowledge of any type that maps to this name. Consider using a DataContractResolver if you are using DataContractSerializer or add the type corresponding to ‘SrsReportProviderQueryBuilderArgs’ to the list of known types – for example, by using the KnownTypeAttribute attribute or by adding it to the list of known types passed to the serializer.’. Please see InnerException for more details.

2016-12-06_9-58-01

Solution:
  • Stop AOS service.
  • Stop Sql Server Service.
  • Start SQL server Service.
  • Restart SQL Server reporting services.

Tuesday 5 September 2017

Dynamics AX 2009 Report libraries to Dynamics AX 2012 SSRS Reports


Question:How can i convert my Dynamics AX 2009 reporting libraries to be usable in Dynamics AX 2012?Answer:In order to use the Reporting Libraries from 2009 in 2012 use the following steps,1- Use the upgrade reports command line that comes with AX 2012 , normally located at C:\Program Files\Microsoft Dynamics AX\60\tools, to upgrade the reporting libraries to current format.

2- Open the business logic project created after the step above , compile and add the business logic to AOT.

3- Open the reporting project and change the business logic to be using the new business logic.
    


4- Compile the project, add to AOT and deploy to SSRS.


Tuesday 25 July 2017

How to create a custom filter on list or inquiry form in Dynamics AX 2012

During development we have to create custom inquiry forms. Or Form where we can  search and filter records on different criteria.

Consider a scenario, where we have to build custom inquiry form for all saleline. In this inquiry or custom list form, we can filter on records on date, customer and amount or discount.
Lets do this,

Create a form with name custom Sales

From expend its designs and right click on design to open its property window

Design property

From property window set its design style to simplelist


Simple list

Now add new data source on form, and sets create and edit property to no, Because we did not want to insert , update and delete operation  on this form.

Drop down


Now drag and drop following fields form  data source to grid.

ItemId,CustNumber,SalesQty,SalesPrice,

selected fields

Now right click on grid and set its datasource to salesline.
Datasource for grid
Now run the form its look like similar

Grid with data
Now above grid, add  group control and set its column property to 2, also set its visible property to true.
Add String Edit control, and button here.
Right click on String Edit control and set its auto delecaration to true, so we can access this control in x++. Set its name as “txtCustomerNum”. And set its lookup property to always.


ControlName


lookup always

Now we are going to create Unbound control with lookup,
Right lock on methods under stringEditcontrol and add lookup method.
Add following code to fill the lookup to customer and Name which belongs to current legal entity.
public void lookup()
{
Query query = new Query();
QueryBuildDataSource queryBuildDataSource, qbds, dsView;
QueryBuildRange queryBuildRange;

SysTableLookup sysTableLookup = SysTableLookup::newParameters(tableNum(CustTable), this);

sysTableLookup.addLookupField(fieldNum(CustTable, AccountNum));
sysTableLookup.addLookupField(fieldNum(CustTable, Party), false);

queryBuildDataSource = query.addDataSource(tableNum(CustTable));

qbds = queryBuildDataSource.addDataSource(tableNum(DirPartyTable));
qbds.joinMode(JoinMode::InnerJoin);
qbds.addLink(fieldNum(CustTable, Party), fieldNum(DirPartyTable, RecId));

dsView = qbds.addDataSource(tableNum(DirPartyPostalAddressView));
dsView.joinMode(JoinMode::InnerJoin);
dsView.addLink(fieldNum(DirPartyTable, RecId), fieldNum(DirPartyPostalAddressView, Party));


sysTableLookup.parmQuery(query);

sysTableLookup.performFormLookup();


}

Now run the form lets see the how behave the lookup control.
Lookupdisplay
Man its working. Now check that selected value from this textbox is accessible, then we move to filter the records
Add Click event/ method on button we just added with this string edit button.

And right following code.
void clicked()
{
super();
info(  txtCustomerNumber.text());
}


Now run the form, select customer and click on button.
dd


Now right click on Salesline datasource and over rights its execute Query method.
And add following lines to filter it.
public void executeQuery()
{
QueryBuildRange QcustomerFilter;
QcustomerFilter = SysQuery::findOrCreateRange(SalesLine_q.datasourceTable(tableNum(SalesLine)),fieldNum(SalesLine,CustAccount));
if (txtCustomerNumber.text()!=””)
{
QcustomerFilter.value(queryValue(txtCustomerNumber.text()));

}
else
{
QcustomerFilter.value(SysQuery::valueUnlimited());
}
super();
}

In button click even add this line code
void clicked()
{
super();
SalesLine_ds.executeQuery();

}



Now run the form, select the customer and click on button, you will find the filter records on form
Column

An export format or a method of payment with an export format must be specified



 
An export format or a method of payment with an export format must be specified.


To reolve the error I had to move the current execution point from the CustVendSumForPaym class, constructor method “custVendSumForPaym.getLast();” Line to avoid looking in the cache (SysLastValue) and retrieving a payment method format that does not exist. I was asked to rename a file format method text that I had created, and had referenced this class during my testing. I tried both clearing the cache and restarting the AOS but was unsuccessful attempting to remove the reference to the previously selected payment settings.
 
The source of my woes.

Thursday 2 February 2017

Error while synchronizing AOT

 Error: While doing Synchronization system throw below error
SQL error description: [Microsoft][SQL Server Native Client 11.0][SQL Server]Error: The new name ” is already in use as a COLUMN name and would cause a duplicate that is not permitted.


Solution: By doing followed steps the error got resolve for me:

1) Renamed the table name "PAYMENTTYPE_ES" to "PAYMENTTYPE_ES_Old" in SQL server.

2) Switched to AX and synchronized the "PAYMENTTYPE_ES" table.

3) Switched to SQL Server and refreshed the database, this will pop up two tables with names- i) PAYMENTTYPE_ES and ii) PAYMENTTYPE_ES_Old

4) Now renamed both the tables PAYMENTTYPE_ES to PAYMENTTYPE_ES_New and PAYMENTTYPE_ES_Old to PAYMENTTYPE_ES

5) Again switched to AX and synchronized the PAYMENTTYPE_ES table, error got resolved.

6) Dropped table "PAYMENTTYPE_ES_New" from SQL server.