AX2012 : Understanding Attributes

Hi Friends,
I would like to discuss about the concept of attributes with an example of how we use them in AX2012. This post will be interesting to those who are new to Attributes concept. It is important to understand that Attributes come from .NET platform they are not simply implemented as language elements.To summarize the general introduction of attributes:

  • Attributes are declarative information used to add metadata information to the code.
  • Attributes are stored as metadata in an assembly. They are NOT part of executable code.
  • Attributes information can be extracted through reflection at run time/compile time/design time.
  • Attributes are extensible, you can create you own custom attributes.
An attribute can be attached by simply typing the name of the attribute enclosed in square bracket before the declaration of class/function where it needs to be applied.

In AX 2012, SysAttribute class is an abstract base class for all attribute classes. So if you have to create your own attribute class then it should be a non abstract class and must inherit from SysAttribute class. 
Attributes can be used in many different scenarios, one of the common practice is to use them in creating batch jobs through SysOperation framework.

Let\’s jump into some practical way to use attributes, I\’ll use SysObsoleteAttribute in the below example to get a feel of using attributes:

I created a new class \”SampleCalculator\” and a method to add two numbers:
Then I created a job to call this method
This is simple, nothing interesting till now. 
In the current method, there is a limitation that it accepts only 2 integers, there can be situations where a person wants to add n number of integers, so to improve the design and usability I thought to create a new function which accepts a list as a parameter so that we can add any number of integers, the new method looks  like below:
We test this method through job, it works good:
Now I want that if any other developer is using the class \”SampleCalculator\”  to perform the addition calculations, he should prefer using the new function \”addMultipleNum()\” instead of the old function \”add2Num()\”.
Also, I do not want to delete the previous function as it may lead to compilation errors in system in case the previous function is used somewhere. So what do I do ??? The answer in such situation is use ATTRIBUTES. 
AX2012 provides us with an Attribute class SysObsoleteAttribute for such situations.
I can decorate my first function add2Num() with SysObsoleteAttribute and to do this I simply have to add the attribute in function definition as shown below:
Now the question is how does it impacts the overall process, to know this just compile the job and you will notice that the compiler gives a warning and immediately tells me that this function which I am using in my job is Obsolete.
This is Okay but does it tells me what to do if this function is Obsolete? No not now. 
Can I add some more information to the attribute I attached? YES 🙂
While defining SysObsoleteAttribute you can see that we can define two optional parameters:
So now I added the explanation in the first parameter for the attribute, notice that value in second boolean parameter \”_isError\” is passed as false for now.
Now if I compile the job, the warning is more informative, it tells me which function should I use:
This is cool. Now I can inform someone other developers to use the new function, when the try to use the old one.
Now let us change second Boolean parameter \”_isError\” value to true, compile the code and see what happens:
You will notice that compiler gave an error instead of warning. This is quite helpful in situations where we want to avoid use of some function. This is an example of attributes behavior at compile time.  
This attribute class \”SysObsoleteAttribute\” is also helpful for ISV\’s when they release new hot fixes  versions of there product and want there partners to start using new functions when they customize the solution.
An example of SysObsoleteAttribute can also be found in SysDictClass 
There are many attribute classes provided by default in AX. You can get the list by simply looking the type hierarchy browser of SysAttribute class and start playing with them :).
Thanks for reading the post!!!!!


AX2012 : Move label file between environments

Hi Friends,
Recently, I moved label file from one environment to another environment.I referred to various sources before doing this activity and found the below as most recommended method:

  • Create a dummy model.
  • Move the existing label file to dummy model.
  • Delete the dummy model using Axutil commands.
  • Restart AOS.
  • Import the label file.
  • Restart AOS.

However even after performing the above mentioned steps, I was still not able to view the updated labels. While playing around I found the following solution which I want to share with you all:

  • Delete the *.ali file for the specific label Id, from the folder \”C:\\Program Files\\Microsoft Dynamics AX\\60\\Server\\\”Your Application name\”\\bin\\Application\\Appl\\Standard\”
  • Restart AOS
When I reopened the client, I was able to see the updated labels.
P.S. –> The above information is based on my experience and does not guarantee the results in general. Please take essential backups before performing the above task in your environment.
Thanks for your time.

Ax2012: View map for addresses

Hi Friends,
Just came across feature in AX2012, ability to view maps for a address.
e.g: On customer master form you will notice a new button “map” under the fast tab of addresses.

When you click this system will open the map in explorer using bing!!! Cool isn’t it J
How it is done: Check the code below. This is also an example of CLR Interop. You can find the standard code using .net function to encode URL.
This feature is also available in AX2009 as shown below:

AX2012 : X++ code to update picking list for sales order

Hi Friends,

Use the following code to generate the picking list for a sales order. This will give you the same results when you do Sales Order –> Pick and Pack –> Generate picking list.

static void SalesOrder_UpdatePickingList(Args _args)
    SalesFormLetter_PickingList salesFormLetter;
    SalesTable      salesTable = salesTable::find(\’SO-101292\’);

    salesFormLetter = SalesFormLetter_PickingList::newPickingList();

AX2012 : The function InventDim::dim2dimParm has been called with an unknown inventory dimension.

Hi Friends,
Recently i started working on my first customization in AX 2012 which was to add a new inventory tracking dimension in the system. I would like to share the following problem which I faced. After doing the basic setup modifications in the system, i was able to see the new dimension in tracking dimensions form, but when i tried to create a sales order , on entering the item itself i was greeting with this following long error message :

The function InventDim::dim2dimParm has been called with an unknown inventory dimension.

Microsoft.Dynamics.Ax.Xpp.ErrorException: Exception of type \’Microsoft.Dynamics.Ax.Xpp.ErrorException\’ was thrown.

at Dynamics.Ax.Application.InventDim.dim2dimParm(Int32 _dimField) in InventDim.dim2dimParm.xpp:line 31

at Dynamics.Ax.Application.InventDim.Clearnotselecteddim(InventDimParm _inventDimParm) in InventDim.clearNotSelectedDim.xpp:line 10

at Dynamics.Ax.Application.CustVendExternalItemDescription.findExternalItemDescription(ModuleCustVend _moduleType, String _itemId, InventDim _inventDim, String _custVendAccountId, String _custVendItemGroupId) in CustVendExternalItemDescription.findExternalItemDescription.xpp:line 31

at Dynamics.Ax.Application.CustVendExternalItemDescription.Findexternaldescription() in CustVendExternalItemDescription.findExternalDescription.xpp:line 34

at Dynamics.Ax.Application.PurchLine.Initfromvendexternalitemdescription(InventDim _inventDim, Boolean ) in PurchLine.initFromVendExternalItemDescription.xpp:line 5

at Dynamics.Ax.Application.PurchLine.Initfromvendexternalitemdescription()

at Dynamics.Ax.Application.PurchLineType.Initfrominventtable(InventTable inventTable) in PurchLineType.initFromInventTable.xpp:line 40

at Dynamics.Ax.Application.PurchLine.initFromInventTableIL(Object[] _inputContract) in PurchLine.initFromInventTableIL.xpp:line 20

at PurchLine::initFromInventTableIL(Object[] )

at Microsoft.Dynamics.Ax.Xpp.ReflectionCallHelper.MakeStaticCall(Type type, String MethodName, Object[] parameters)

at Dynamics.Ax.Application.SysDictTable.invokeStaticMethod(Object[] _params) in SysDictTable.invokeStaticMethod.xpp:line 26

at SysDictTable::invokeStaticMethod(Object[] )

at Microsoft.Dynamics.Ax.Xpp.ReflectionCallHelper.MakeStaticCall(Type type, String MethodName, Object[] parameters)

at Microsoft.Dynamics.Ax.Xpp.PredefinedFunctions.runAsInvoke(String className, String staticMethodName, Object[] parms, Object[]& exportInfolog)\”

Wondering what went wrong I put debugger in the method from where the error was originating i.e. InventDim::dim2dimParm, to my surprise debugger was not stopping in the code.

On further troubleshooting, I came to know that some IL code is getting executed because of which the debugger is not stopping in AX client.

As we know that AX2012 there is a powerful capability that X++ code is compiled as IL code.
This IL code resides in the following location \”C:\\Program Files\\Microsoft Dynamics AX\\60\\Server\\MicrosoftDynamicsAX\\bin\\XppIL\\source\”.
I checked the Xpp file InventDim.Dim2DimParm by opening in Notepad and to my surprise the modifications which i did for new inventory dimension were not in this code.

To update this XPP file , we need to use generate incremental IL tool which can be found under build menu of Ax 2012 work space, there is also a shortcut for this (ctrl + shift + F7).

I generated incremented IL and then checked the XPP file and found that it is updated with the modification.

Now I was able to define item in sales line and system allowed me to proceed ahead.

so the catch was to \”Generate incremental IL code\” for your modifications before testing them.

Post a pick list journal through X++ code

Many times we are required to post a pick list journal through X++ code. Sometimes developers fear about how lengthy the code will be to post a journal but it\’s just a 3 lines code.
The following code can be used to posts a pick list journal.
You should have JournalId which is required to be posted. in this case i have used table object _record which holds journalId

ProdJournalCheckPostBOM prodJournalCheckPostBOM;
ProdJournalCheckPostBOM = ProdJournalCheckPostBOM::newPostJournal(_record.JournalId,false);;