Code highlighting

Thursday, September 23, 2010

Tutorial: Undocumented behavior of kernel functions min()/max()

I was recently reviewing some code written to be shipped with AX6, and noticed an unfamiliar pattern being used in it. I investigated a bit deeper, and turns out it actually works fine on previous versions of AX as well.


I am talking about 2 kernel functions for finding the maximum or minimum of the specified values.
The signature of these methods is shown on the below image:


As you can see, it takes 2 arguments of anytype, and returns an anytype which is the largest of the two values. But it can accept much more than 2 arguments, even though it is not documented as such.

I wrote a small job to showcase this behavior. The code is provided below. You can also download it from my SkyDrive Dynamics AX share.

static void Tutorial_MinMaxFunctions(Args _args)
{
    #define.ArraySize(11)

    Random  rand = new Random();

    int     counter;
    int     arrayInt[#ArraySize];
    str     arrayIntAsString;
    int     arrayIntMaxValue;
    int     arrayIntMinValue;
    ;

    for (counter = 1; counter <= #ArraySize; counter++)
    {
        arrayInt[counter] = rand.nextInt();
        if (arrayIntAsString)
            arrayIntAsString += ', ';
        arrayIntAsString += int2str(arrayInt[counter]);
    }
    info("Generated array of integers: " + arrayIntAsString);

    info("The typical way to find a maximum is by looping through all the values one by one, calling the comparison function multiple times");
    arrayIntMaxValue = minint();
    arrayIntMinValue = maxint();
    for (counter = 1; counter <= #ArraySize; counter++)
    {
        arrayIntMaxValue = max(arrayIntMaxValue, arrayInt[counter]);
        arrayIntMinValue = min(arrayIntMinValue, arrayInt[counter]);
    }
    info(strfmt("Max.value: %1 and Min.value: %2", int2str(arrayIntMaxValue), int2str(arrayIntMinValue)));

    info("Using max and min with 11 arguments works just as well");
    arrayIntMaxValue = minint();
    arrayIntMinValue = maxint();
    arrayIntMaxValue = max(arrayInt[1], arrayInt[2], arrayInt[3], arrayInt[4], arrayInt[5], arrayInt[6], arrayInt[7], arrayInt[8], arrayInt[9], arrayInt[10], arrayInt[11]);
    arrayIntMinValue = min(arrayInt[1], arrayInt[2], arrayInt[3], arrayInt[4], arrayInt[5], arrayInt[6], arrayInt[7], arrayInt[8], arrayInt[9], arrayInt[10], arrayInt[11]);
    info(strfmt("Max.value: %1 and Min.value: %2", int2str(arrayIntMaxValue), int2str(arrayIntMinValue)));

    info("Note that comparing an integer and a real also works, as well as outputing the results straight into an infolog message");
    info(max(12, 12.001));
}


Another interesting point is that it can actually accept different types of arguments, for example, a real and an integer, as shown above. And it actually returns an anytype, which implicitly gets converted to a string when sent to the infolog.

Disclaimer: Since this is not a documented feature, it can theoretically change in the future releases, but I doubt it in this particular case.

Wednesday, July 07, 2010

Advertisement: MDCC is looking for talent!

Hello, all.

Microsoft Development Center in Copenhagen has a number of open positions for Software Development Engineers in Test (SDETs), to work in the team responsible for shipping the latest version of the Microsoft Dynamics AX product.

Below is a detailed description of one of the currently open positions (SDET II role). Salary level and title are based on your education, number of years of experience, etc., nothing new here. Dynamics AX background is, of course, a plus (I assume this applies to all my readers).
The Microsoft Dynamics AX product group has an open position for a Software Development Engineer in Test (SDET) within our supply chain management teams. The position provides unique opportunities for professionals with a diverse background of business acumen and software engineering to work on one of the fastest growing Enterprise Resource Planning (ERP) products in the market.

Responsibilities:
Write and review technical requirements and design documents
Plan, design, and write code for automated tests of features within the supply chain management features of Dynamics AX
Create and use test tools and processes to both increase effectiveness in the daily work and assure quality of the product
Collaborate with other engineers to ensure all feature areas achieve the desired high level of innovation and quality our customers demand.

Requirements:
We are looking for engineers with a strong background in object oriented development. Experience with business applications or ERP solutions are pluses.

Software development experience, particularly within C#, C++ or similar object oriented programming languages
Strong technical and analytical skills
Excellent problem solving and design skills
Ability to work independently - and in teams
An excellent command of written and spoken English
Experience with Microsoft Dynamics AX or ERP products is a plus
Experience with X++ (a Dynamics AX language) is a plus
Software testing experience with an organized and structured approach is also a plus

We are also looking for less experienced people for the IAESTE student program, so all you excellent Computer Science students, interested in developing business applications and working for one of the world's leading software companies, welcome!

If you are interested in applying for the positions, please e-mail me your up-to-date CV at ivan.kashperuk(@nospam)hotmail.com

An additional request I would like to make is to leave a comment here, if you are invited to an interview, describing how it went, how you were treated, and what your impression was of the entire process, the MDCC campus, the interviewers, etc. This will help us make improvements in our hiring process, so I am really waiting for your comments. Note that anonymous comments are allowed.

Some additional information about MDCC:
Microsoft Development Center Copenhagen (MDCC) was created in 2002 following the acquisition of the Danish company Navision. Today, it has grown to be Microsoft’s biggest development center in Europe and a spearhead in the European IT industry. MDCC is Microsoft’s Center of Excellence for Supply Chain Management and drives the development of several of the Microsoft Dynamics ERP (Enterprise Resource Planning) products. Our products enable companies throughout the world to optimize the planning of their resources – and increase their revenues.

Today, the development center gathers around 650 people from more than 40 different countries. Every third employee is a non-Dane and that makes MDCC to one of the most international companies in Denmark. MDCC has been widely awarded for its unique work culture and is a coveted career booster for top talents from all over the world.

Thursday, July 01, 2010

Tutorial: Brief description of ways to close a form in AX

We had this question asked on one of the internal AX forums, and Michael Fruergaard wrote a short description of each method you can use.

Re-posting it here with some extra comments, so that new developers can read and understand, when to use what method.

There are “only” 5 ways to close a form:
  • Close - close the form. Similar to the 'X' button.
  • CloseOK – close the form, and set the OK flag – called by the Commandbutton::Ok
  • CloseCancel – close the form, and set the Cancel flag – called by the Commandbutton::Cancel
  • CloseSelectRecord – close the lookup form, and set return record
  • CloseSelect – close the lookup form, and set return value

The below methods (note their names are in past-tense) are used to determine if or how a form was closed:
  • Closed – Returns true, if the form is no longer open
  • ClosedOK – Return true, if the form was closed by the user clicking ‘OK’
  • ClosedCancel – Returns true, if the form was closed by the user clicking ‘Cancel’

Finally, CanClose() is called inside super() of any of the close methods. If CanClose() returns false, the form is not allowed to close.

Tuesday, May 04, 2010

Tool: DEV_SysTableBrowser and DEV_CreateNewProject tools now on AX 2009

3 or so years ago I created a couple of tools that provide extra capabilities for AX developers, specifically, ease up the creation of a new project with a predefined structure and name pattern, and add functionality to the way we browse tables with the standard SysTableBrowser, allowing to specify the exact fields you want to see, browsing temporary tables. Both tools were also available as Tabax plugins

You can read more about the tools, as well as Tabax, on the following pages on Axaptapedia:
DEV_SysTableBrowser home page on Axaptapedia
DEV_CreateNewProject home page on Axaptapedia

You can download the new versions of these tools through the pages on Axaptapedia, or directly from my SkyDrive: DEV_SysTableBrowser, DEV_CreateNewProject
If you are unfamiliar with these tools, I suggest you go through Axaptapedia, as it also contains a detailed description of the features provided.

A couple of things I would like to note:
  • There is a kernel bug in AX 2009 that heavily impacts the SysTableBrowser user experience. It takes around 10 seconds each time you want to browse the contents of a specific table. This bug was fixed with a hotfix rollup 3, so users of AX 2009 without the hotfix might have problems enjoying the DEV_SysTableBrowser tool.
  • In AX 2009 the behavior of SysTableBrowser changed a bit. Instead of re-opening the browser window each time the user changes from All fields to AutoGroup only, now 2 grids with these fields are added from the beginning, and hidden/shown based on user selection. DEV_SysTableBrowser provides much more flexibility when selecting the fields to display, so I was not able to follow the same approach. Thus, see bullet 1
  • I have not added any new AOT nodes to the template in DEV_CreateNewProject tool (Data sets, Report Libraries, etc). I don't think AX developers will invest that much time into SSRS reports and EP, and in these cases they will be able to manually create the remaining group nodes in the project.

Let me know if you have comments, suggestions or ideas for these tools.
Thanks

Thursday, April 22, 2010

Tool: User preferred startup menu for Dynamics AX 2009

In AX 2009, the user has no control over which menu is opened in the navigation pane and address bar when AX client is started. Most of the time you simply get the Home page, which is frustrating for a number of users. Another thing that is frustrating for them is the company account the application opens with. The latter can actually be setup using standard application functionality in the User options form. Just set the 'Start company accounts' to the account you want for the user by default. I wrote a small tool, that allows the user to select a preferred startup menu, ensuring that this menu is the one open every time AX client is started. Something similar existed in Axapta 3.0 application. You can download the xpo for this tool from my SkyDrive. Note, that it contains minor changes to a number of existing application objects. I suggest that you compare the xpo from the import dialog and ensure that you don't override any of your changes during import - the best thing would be to re-implement these minor changes manually. Below is a list of changes that I am referring to above:
  • SysUserInfo table - 1 new field was added
  • SysUserSetup form - 1 new control was added. Lookup method on datasource field overridden
  • Info class - startupPost method changed
In order to enable the functionality, simply select one of the menus in the User options, as shown in the below screenshot. Next time you start AX, the selected menu will be open by default. Start Menu in User options, Microsoft Dynamics AX 2009 Below is a short listing of "code patterns" used in the project, that can serve as examples for your future projects:
  • SysTableLookup - for displaying a lookup form with a list of menus
  • infolog.globalCache() - for storing a global reference to the navigator class
  • TreeNode iteration - for finding all menu references in MainMenu
  • QueryBuild classes - for constructing and filtering a list of menu references in MainMenu, used in the lookup form
  • infolog.addTimeOut() method - for scheduling execution of another method in a set period of time