Thursday, July 14, 2011

X++ : lockWindowUpdate() vs. lock()/unlock()

There are two method pairs in X++, that are used throughout the application by everyone writing some processing on application forms. These are:


element.lock();
element.unLock();


and

element.lockWindowUpdate(true);
element.lockWindowUpdate(false);


Now, not that many people know the difference between the two methods, and only very few think about why and when should each of them be used.
I will try to describe the behavior of these methods and at the end give some recommendations on how to use them. I have done some kernel code reading (with help of kernel dev. Andy Stach, who I would like to mention here), so what I write below is more or less backed up by code.
If you disagree with some of the recommendations though, please share your experience in using these methods through comments for this post.

FormRun.lockWindowUpdate()

is basically a wrapper around the LockWindowUpdate Win32 function. What it does is pretty simple:
When a window is locked, all attempt to draw into it or its children fail. Instead of drawing, the window manager remembers which parts of the window the application tried to draw into, and when the window is unlocked, those areas are invalidated so that the application gets another WM_PAINT message, thereby bringing the screen contents back in sync with what the application believed to be on the screen.
Note, that according to MSDN, it should not be used for general purpose suppression of redraw operations, but only when dealing with drag&drop operations. This does not hold true for AX, where this method is used all over the place to prevent redraw of controls on the form.
Another interesting point is that only one window can be locked at the same time. So, any nested calls tolockWindowUpdate will be ignored, but when unlocking, only the outer-most unlock will actually invoke the Win32 counterpart. Now, I have not seen this used in X++, which is for the better.

FormRun.lock()

is internally invoking lockWindowUpdate to prevent the redraw of the window, and then also prevents the IntelliMorph control layout engine from running. This is commonly used in scenarios where control properties affecting control arrangement are being set in a loop, which provides a performance optimization as it avoids redundant arrange calls being processed. On the other hand, when calling FormRun.unlock, more work will need to be done, compared to usinglockWindowUpdate(false), where the control layout changes were actually processed by the layout engine, but simply not displayed.

So, based on my investigation, I would suggest to use the following recommendations when doing form development:

  • When formRun.resetSize() is used, specifically, when some controls become visible, increasing the form size, always use formRun.lock()/unlock(), otherwise the change in the size of the form might not get reflected on the screen correctly.
  • When changing multiple layout properties (Left, Width, etc.) on one or more controls, use lock/unlock
  • When you modify the properties that do not impact the layout of controls on the form, useformRun.lockWindowUpdate(), or, if there are only very few control properties being modified, do not lock the form window at all.

Monday, June 20, 2011

Microsoft Dynamics AX 2012 - Type Hierarchy





With the upcoming release of Microsoft Dynamics AX 2012, one of the rather interesting new elements about this release, is the introduction of table type hierarchies.

When you glance at this, just from a data layer level, it seems to be super normalization. That is actually correct, however, you must look at the total picture. That means, you must take and look at this from the data + application layers, together.

That is the only way, that this concept then actually works. In order to help understand this concept, and how the new data structures live within Microsoft Dynamics AX 2012, there is a new tool called the Type hierarchy browser.

You can get to this tool, from any object within AX actually. Classes, tables, etc. For this post, we will focus on tables, and how the tool can help us better understand the data structure.

Lets pick a new structure in Microsoft Dynamics AX 2012, EcoResProduct. This is part of the new Master Data Management (MDM) / Product Data Management (PDM), that will exists out of the box for this release of AX.

Once we have selected the EcoResProduct table, within the AOT, simply right click, add-ins, and then click on the 'Type hierarchy browser' menu item.



Once we do this, we then see the hierarchy that exists for the EcoResProduct table, which extends from the Common table object.



You will notice, that both Common and the EcoResProduct tables have RecId, revVersions & relationType. You will also notice that, DataAreaId is no longer listed. We will save that for another post.

In here we can see as well that the EcoResProduct table inherits methods, from the Common table object. Fields that exists at the EcoResProduct table, are marked with blue blocks, that exist beyond the Common table. We can also see that, in the tree view on the right hand side of the screen, that the hierarchy make up, that EcoResProduct is a part of.

Extending from the EcoResProduct table object, is the EcoResDistinctProduct, and the EcoResProductMaster. Extending from the EcoResDistinctProduct, is the EcoResDistinctProductVariant table object.

Now, if we step forward in the tree, and select the EcoResDistinctProduct, in the tree view, we should see something that looks like the following.



Now you will notice, that for the EcoResDistinctProduct table, the only fields it has, is the three system fields that we listed above. If you look at the data for this table, sure enough that's all that is there, from the data layer perspective.

What this suggests then, and shows, is that the actual field data that lives for a Distinct Product, vs. a Product, still lives within the EcoResProduct table. The EcoResDistinctProduct table inherits the fields for:SearchName, ProductType, InstanceRelationType, and DisplayProductNumber.

When the table is referenced within a form, or code, the EcoResDistinctProduct table has these fields as possible uses, becomes of the new way AX handles, allowing table structure hierarchy.

This does a lot of things for such structures, it cuts down, big time, on the amount of repeat data, size of databases, and enables the application layer, to be the only true way, of working with the data that lives within a Microsoft Dynamics AX 2012 instance.

With using the Type hierarchy browser, provided out-of-the-box for Microsoft Dynamics AX 2012, one can better understand the new data structures, and be able to connect all the new dots, that will exists with this release.

This is very powerful, and through the use of the application layer, the statement of Powerfully Simple, which is the tag term being used to describe Microsoft Dynamics AX 2012, is true!

Source : http://dynamics-ax.blogspot.com/2011/06/microsoft-dynamics-ax-2012-type.html

Wednesday, June 15, 2011

Tips & Tricks - Number Sequence


When you are using a Number Sequence, keep in mind that a Continuous Number Sequence is slower than a non-continuous. The reason is that the system creates a record in the table NumberSequenceList (with the status Active) and cleans it up later during TTSCOMMIT.
Performance tip: You can improve the performance of a process that creates many numbers of one Number Sequence by using number pre-allocation. This loads a set of numbers into the memory and provides faster access. You can do this by using the NumberSeqGlobal, witch means that once it is instantiated, it is available until the session is closed. This function is only available for non-continuous Number Sequences. The numbers can only be retrieved from the cache by calling the getNumInternal() method in the NumberSeq_Fast class.

List of mandatory fields on a table

Hi,
   The Following Code will let you know the List of Mandatory Fields in a table :-


static void CheckMandatoryFieldsOnTable(Args _args)
{
    DictTable dictTable;
    DictField dictField;
    int i;
    TableId tableId = tablenum(custtable);
    ;
    dictTable = new DictTable(tableId);
    for (i=1 ; i<=dictTable.fieldCnt() ; i++)
    {
        dictField = new DictField(tableId, dictTable.fieldCnt2Id(i));
        if (dictField.mandatory())
        {
            info(dictField.name());
        }
    }
}

Enjoy DAX !!!

AX 2012 Unleashed


On Amazon.com I found the first paperback concerning Ax 2012 ‘Microsoft Dynamics Ax 2012 Unleashed’. The book will be released Ocober/November this year. There is not much info availible at the moment, but if you’re intrested in pre-ordering go to Amazon.com
Details:
Author:David Weiner, Ivan Cole
Format:Paperback
Publish Date:October 2011
ISBN-10:0672335484
ISBN-13:9780672335488
Edition:1st


Cheers !!!

Tuesday, June 14, 2011

Migration Tool in Dynamics AX

"The Migration Tool is a .NET application with client/server architecture. The client provides a user interface for managing data migration tasks such as configuring a project, staging data, managing exceptions, loading data, and reviewing results.

It also provides features such as comparing the schema of the current Microsoft Dynamics AX 2009 database to the standard schema of Microsoft Dynamics AX 2009 (RTM). The client can be disconnected from the server during the execution of a pre-existing configured project.

The migration process is managed using:
- Groups of Microsoft® SQL Server 2005 Integration Services (SSIS) packages, combined into prerequisite check, source, target, and validation adaptors.

- A staging database.

- AxMT classes. These are X++ classes that are used to validate and to migrate transactional data from the staging database to the Microsoft Dynamics AX 2009 database."


You can Download the Migration Tool from Partner Source using the below link
Click Here for Download Migration Tool for Dynamics AX



Friday, June 3, 2011

Non admin debugging in Dynamics AX 2012


1.) Add the admin to the roles that you want to test. Note that it is ok to leave the admin user in the system administration role. 
2.) Open a dev workspace and close the application work spaces.
3.) Set applicable breakpoints.
4.) Create a job with the following line of code and execute:SecurityUtil::sysAdminMode(false);
5.) So at this point the current session is in “non-admin mode”.
6.) Use Ctrl+W to open the application work space. You should notice that few menus / menu items are available
7.) Run the test and any break points set will be hit.

Current constraints / limitations

When SecurityUtil::sysAdminMode(…) is invoked, it is only applicable to the current session. So you must use CTRL+W to open the app workspace; launching a new client will not work.
Since this is scoped to the current session scenarios like run-as are not supported and also services / EP is not supported at this point.

Enjoy Axapta !!!