Monday, December 26, 2011

Cool project on CodePlex

Here's a really cool project, creating an adapter for CSV files to BOF (Business Operation Framework) services.

Tuesday, December 20, 2011

Odd CIL compilation issue

I'd really like some input on this article, if anyone has experienced something similar.

I had a couple of CIL compilation errors today in an imported model. The errors all pertained to a new field that was added to a couple of tables. After setting a random LegacyId for the field, I was able to do a successful CIL compilation, and I was also able to compile successfully after removing the LegacyId again.

I don't know if it was the LegacyId change that did the trick, or just the fact that I made a change to the tables.

Please let me know if you have had similar issues and what ideas you may have to fix them.

(And of course we did, without luck, try all the usual stuff, restarting AOS'es, recompiling X++ etc)

Friday, December 16, 2011

Import CSV files using AIF

I was really happy back in January when I learned that you can now can import CSV, and other flat files, into AX using AIF with .NET transformations. Many proprietary file imports, and exports, can now be handled by AIF allowing you to focus on the business logic rather than the nitty-gritty file handling stuff.

But since then I have missed proper documentation on how you actually go about it. The article "Walkthrough: Creating a .NET Assembly Transform" on MSDN, doesn't quite get you to the finish line, where you have a file the AIF can actually read.

Today however I found a three part blog series where part 3 ends up in having a file that AIF will consume.

I recommend that you read all three parts you want to play with these transformations. Here's the link to part 1:

Monday, December 12, 2011

Color code forms in AX 2012, depending on environment/company

One thing that you might miss in the AX client is as a higher visibility of which company and environment that you’re working in. I have seen plenty of solutions where the entire background of forms is colored according to the current company, making each form look like something the cat has coughed up.

The least intrusive solution and the only one I have taken time to modify a bit and implemented at a customer is the one made by Arijit Basu. I have modified it, allowing you to choose your own color and a customer text per AOS. Since not all forms are designed entirely correct, the solution unfortunately doesn’t work as expected on all forms.

In AX 2012 the game has changed, because there is no background left on the forms to color. But the good folks at Microsoft has anticipated that we want to do some coloring still, and there’s a new method on FormRun which allows you to color the background of the statusbar; setStatusBarBackgroundColor.

I have made a solution using this method. The solution allows you to select a color per database server, database and company. If you don’t specify a company, the color works for all companies on the selected server and database.

I have included database server and name to support the scenario where you copy your production database to a test database. This way you can setup the indication for working in the test environment from your production system and you don’t need to add any information after having copied production data to test.

The solution is absolutely version 1, but I expect to add more features for the visualization in the time to come. One thing I’d like to add as soon as possible is some kind of identification in the infolog.
I have one known issue with the solution, which is that the lookups on database server and database don’t quite show all the servers and databases that I expected. I’ll look into that at some point, but any hints are welcome.

Example of form:

You can download the solution as an XPO or a model file from my SkyDrive.

Wednesday, November 30, 2011

Hiding a data member attribute from dialogs

When you use data contracts with for example the new Business Oprations Framework (BOF), it is smart that AX will generate the dialog for you. But what if you have a field in the data contract that you don't want exposed in the dialog?

Well, use the SysOperationControlVisibilityAttribute:
[DataMemberAttribute, SysOperationControlVisibilityAttribute(false)]
public int parmIntProperty(int _parmIntProperty = parmIntProperty)
    parmIntProperty = _parmIntProperty;

    return parmIntProperty;

Monday, November 28, 2011

Create ZIP files from AX

I recently had to write a solution to create ZIP files from within AX 2012. Apparently such functionality is not very well implemented in standard .NET.

But the free DotNetZip .NET library works like a charm. Here's a link to the library on CodePlex:

Friday, November 4, 2011

Call a BOF service with a caller record

If you need to call a Business Operations Framework (BOF) service with a caller record, like you'd often do for a RunBase job, you must create a custom SysOperationServiceController to get the record argument passes from the service controller to an applicable data contract.

A good example from standard AX can found in the PurchFinalizeServiceController class.

Another example can be found here:

Print images directly from AX without user interaction

I have written one other post on doing this by calling WinApi::ShellExecute directly, but here is a more elaborate sample using .NET.

The sample prints an image (in this case a TIFF image) to your default printer without prompting first. You need to add a reference to System.Printing in AX to use the sample.

static void PrintImage(Args _args)
    System.Printing.PrintServer         localPrintServer    = new System.Printing.LocalPrintServer();
    System.Printing.PrintQueue          printQueue          = System.Printing.LocalPrintServer::GetDefaultPrintQueue();
    System.Diagnostics.Process          printProcess        = new System.Diagnostics.Process();
    System.Diagnostics.ProcessStartInfo processStartInfo;
    str                                 arguments;
    Filename                            fileName            = @'C:\TESTFILE.TIF';

    processStartInfo = printProcess.get_StartInfo();


    arguments  = @'C:\WINDOWS\System32\shimgvw.dll,ImageView_PrintTo /pt ';
    arguments += @'"';
    arguments += filename;
    arguments += @'" ';
    arguments += @'"';
    arguments += ClrInterop::getAnyTypeForObject(localPrintServer.get_Name()) + @'\' + ClrInterop::getAnyTypeForObject(printQueue.get_Name());
    arguments += @'" ';
    arguments += @'"%3" "%4"';




Monday, October 24, 2011

AX 2012 editor extensions

I try to keep focus on original content in this blog, but yesterday I read a post that was so interessting that I'd like to point it out.

The post is about the new possibilities you have for creating editor extensions to the X++ editor, as it is now hosted by Visual Studio.

Here's the link:

Monday, October 10, 2011

Export and import labels for translation

If you develop solutions that need to be executed in several different languages you might need some external party to translate your label files, unless of course you are a linguistic genius.

I have written a small solution with a job that exports labels to a spreadsheet that you can send to an external party. When you get the spreadsheet back, you run a second job which based on the spreadsheet creates an XPO file. Now you can use the standard XPO import tool to analyze the changes and import the labels you want.

The jobs work on AX 2009. I have not tested them with other versions of AX.

You can find both jobs here:

Tuesday, October 4, 2011

Send invoices electronically

This is just a quick tip, as it seems to me that many are unaware of how easy it is to have Microsoft Dynamics AX 2009 and 2012 automatically send electronic customer invoices through AIF.

All you have to do is to setup AIF with a valid endpoint for the customer and the document. And you must select a print destination other than “Screen”. I’ll suggest you use “Print archive” as print destination if you don’t actually need the printed document. This will just add the documents to an internal queue that you delete later.

The \Classes\CustPrintOutInvoice\sendAsXML method will then take care of business, submitting the invoice to the AIF queue.

Monday, September 19, 2011

Bug in the training material for AX 2012 Development II

In chapter 1, Introduction to X++, under Jobs you can find the following statement:
"... Jobs are used primarily for testing code during development and running batch processes within Microsoft Dynamics AX that affect large amounts of data".

Jobs are not in any way related to the batch capabilities of AX, and due to that fact that they are executed on the client, you'd never use a job to work with large amount of data.

I think the author somehow confuses the RunBase(Batch) framework with the Jobs node in the AOT.

You can find the same error in the course material for AX 2009.

Tuesday, September 13, 2011

Querying printer queues from X++

For a client we need to print a page of an X++ report and then some attached files, like PDF or Word documents.

We need all the connected documents to be printed in one batch and we must not print the next X++ page before the attached documents are printed.

So we need to figure out if the shell and the printer are finished printing the attached documents before sending the next document from AX.

Luckily we can use the .NET library System.Printing to query the queue  and in particular we can call the NumberOfJobs to figure out if the attached documents have been printed.

Here's a few bits of code for querying the printer queues:
    System.Printing.PrintServer           printServer = new System.Printing.LocalPrintServer();
    System.Printing.PrintQueueCollection  printQueueCollection = printServer.GetPrintQueues();
    System.Printing.PrintQueue            printQueue;
    System.Collections.IEnumerator        enumerator;
    // Print the local server name
    print printServer.get_Name();
    // Enumerate and print names of all the queues on the server
    enumerator = printQueueCollection.GetEnumerator();
    while (enumerator.MoveNext())
        printQueue = enumerator.get_Current();
        print printQueue.get_FullName();
    // Get information for a particular print queue
    printQueue = new System.Printing.PrintQueue(printServer, "HP Color LaserJet 5550 PS");
    print printQueue.get_Description();
    print printQueue.get_NumberOfJobs();
    print ClrInterop::getAnyTypeForObject(printQueue.get_IsBusy());
    print ClrInterop::getAnyTypeForObject(printQueue.get_IsPrinting());


In AX 2012 I would probably have placed the supporting code in a Visual Studio project rather than calling these CLR objects from X++.

Thursday, September 8, 2011

Changing AOS service name

Sometimes in a development environment you may have an AOS serving a specific purpose or project and maybe the role of the AOS changes over time.

When the role changes it would be nice that the service name was changed, to correctly indicate what it serves. Here is the command line for changing the display name of the service:

sc config AOS50$01 DisplayName= "Dynamics AX Object Server 5.0$01_MyNewPurpose"

This of course doesn't change things like the name of the folder holding the binaries (which you probably shouldn't change if you want to be able to uninstall the service). To change everything you'd need to install a AOS service and possibly uninstall the old service.

Changing the service name is just a quick way to indicate the changed purpose of the service.

Monday, September 5, 2011

Fun observation about BOF dialogs

After reading the Client User Experience Guidelines for dialog boxes, I noticed that the automatically generated dialogs from the Business Operation Framework (BOF) doesn't quite meet the guidelines.

According to the guidelines you need to display a "Main instruction":

But if you take a look at the dialog generated by BOF, theres is no "Main instruction" section, and I haven't really figured out how I can add it myself:

The Dialog form which is the base for all RunBase dialogs has a StaticText control for this main instruction, but the SysOperationTemplateForm, which is the base for BOF dialogs, dosn't have a control for displaying the main instruction.

Not a big deal, but still a bit fun...

Tuesday, August 30, 2011

Validate dialog input in the Business Operation Framework

A number of good community articles have been written on the new Business Operation Framework (BOF) in Microsoft Dynamics AX 2012, for example these series:
And then there is of course MSDN.

However the documentation from Microsoft in this area currently is not yet comprehensive, so here is my first article on a small area of the framework.

If you need to validate the input of the dialog for a data contract, you need to add code to the data contract. Your data contract must implement the SysOperationValidatable interface:
public class BOFDataContractA implements SysOperationValidatable
    int     parmIntProperty;
    str     parmStrProperty;
And you need to add the validate method of the interface:
public boolean validate()
    if (this.parmIntProperty() <= 25)
        return checkFailed("The number must be higher than 25");
    return true;

Monday, August 22, 2011

Working with files that are supplied by or generated for clients

When you have jobs that require clients to upload a file to AX, or you have a job requiring AX to create a file for client, you earlier had to place the file in a folder with an UNC path available to both the client and the server.

In AX 2012 you can use the class SysFileStoreManager to move the file between server and client, so the client doesn’t need to know about or deal with UNC paths.

Thursday, July 7, 2011

Upper- / lowercase oddity in AIF

Have you ever wondered why the name of batch id tag must start with a capital letter, i.e. , when using the InventDim table in an AIF service? The field in the table starts with a lowercase i.

Well, the reason is that AIF uses the names of the methods in the AX class (AxInventDim in this case) for the naming in the schema and of other artifacts it generates. On the AX class the method for this field is named “parmInventDimId”. So here the name starts with a capital letter.

Okay, that’s not really very odd and you could probably have figured this out just by making a qualified guess.

But then, why must the tag for the Serial Id start with a lower case s? The field name in the table starts with a lowercase s, and the method name is “parmInventSerialId”. So according to the logic above, the Serial Id tag should also start with an uppercase character.

This is where it gets interesting. In the \Classes\AxInternalBase\parmMethods method AX generates a list of fieldnames based on the parm methods of the AX class. The underlying class handing out the names is DictClass.
DictClass actually returns a wrong name, or at least not what you see in the AOT, for the parmInventSerialId method. It returns the name as parminventSerialId, which matches the casing of the table field and, voila, the tag can be named exactly as the table field.

Here is a job showing the names handed out by (Sys)DictClass:
static void AIF(Args _args)
    SysDictClass            dc = new SysDictClass(5790);
    Map                     methods;
    MapEnumerator           me;

    methods = dc.objectMethods2ClassId(true);
    me      = methods.getEnumerator();

    while (me.moveNext())
        if (substr(me.currentKey(),1,strlen('parm')) == 'parm')
            info (me.currentKey());

Sunday, July 3, 2011

Find your SID

If you restore the demodatabase for an AX 2012 image, you might need to know you SID in order to change your login in the AX database.

This vbs script displays your SID and copies it to your clipboard:

strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")

Set objAccount = objWMIService.Get _
Wscript.Echo objAccount.SID

Set WshShell = WScript.CreateObject("WScript.Shell")
WshShell.Run "cmd.exe /c echo " + objAccount.SID + " | clip", 0, TRUE

Wscript.Echo "Your SID is copied to the  clipboard"
You may need to change the values for the user account name and the domain.

And this is the script you can use in the database:
update userinfo
networkdomain = 'YourDomain',
networkalias = 'YourAlias',
SID = 'YourSID'
where ID = 'Admin'

Wednesday, June 29, 2011

Unable to create project with project filtering, for example, for a certain layer in AX 2009 RU-7?

This hotfix from PartnerSource should fix the issue:
You can find a bit more information on the partner support forum:

Please note that the hotfix description does not mention this issue directly. The description for the hotfix is about access to LedgerTrans...

Tuesday, June 7, 2011

Not enough rights to use table 'Common' (Common) error i Purchase Totals (PurchTotals)

You can get this error from Purchase Totals if the user does not have Edit permissions to Administration / Tables. Here's is how you can fix it by changing you security setup:

You can also fix the issue by modifying the form. All you need to do is to change the "AllowCheck" property of the Common data source of the PurchTotals form. Change the value from "Yes" to "No".

Monday, May 23, 2011

Book review: Microsoft Dynamics Sure Step 2010

This book is really helpful if you work with Dynamics and need to use Microsoft Dynamics Sure Step for your implementations. It’s a beautiful match for the material you can pick up online from Microsoft, adding background information, going into depth in relation to the online material and adding practical information to get going.
The first chapters of the book provides excellent background information if you are not too familiar with project management and ERP or CRM implementations using a model like Sure Step.
The middle of the book goes into depth with each of the Sure Step project phases and goes into depth with the Sure Step optimization offerings as well as areas around upgrade projects and project change management.
Finally the books gives you a practical guide to adopt Sure Step in your organization.
One of the authors have experience from with Microsoft, working with different aspect of developing the model. So the stuff in this book comes straight from the horse’s mouth.
If you’re quick the book is on sale from the publisher, Packt Publishing, for the rest of the month. Their other excellent Dynamics book are also on sale just now. Click this link to get to the campaign.

Monday, April 11, 2011

Microsoft Dynamics AX 2012 White Papers: Code Upgrade

A whole bunch of white papers related to Microsoft Dynamics AX 2012 upgrade has been released in Microsoft Download Center. Download them here.

Click here to search for other Micosoft Dynamics AX 2012 stuff available in Microsoft Download Center.

Thursday, April 7, 2011

Create your own shortcuts in AX forms

In AX it is virtually impossible to control the shortcuts of buttons. Even though button properties like KeyTip indicate that you should be able to have some control, nothing really works.
Here is a tip on how you can catch special keyboard combinations yourself, and thus create your own shortcuts.

First you need to call a method from USER32.DLL to figure out if a certain key is pressed. You could for example implement this on the WinAPI class:

static boolean getKeyPressed(int _keyCode)
    DLL winApiDLL = new DLL('USER32');
    DLLFunction getKeyState = new DLLFunction(winApiDLL, 'GetAsyncKeyState');
    int result;


    result =;

    if ((result & 0x8000) == 0x8000)
        return true;
        return false;
The method is called with what’s called a virtual key code, which is the code of the key you want to know is pressed or not. You can find a list of these keyboard codes on MSDN:

On your form you need to implement a method that is executed again and again while the form is idle. The method needs to check if your special key combination is pressed, do the action associated with the key and set the method up for next iteration.
It could look like this:

void myKeyboardCheck()

    // Check if this form is the foreground window of Windows
    if (winApi::getForegroundWindow() == this.hWnd())
        // Check if ALT + O is pressed
        if (WinApi::getKeyPressed(#ALT) && WinApi::getKeyPressed(#O))
            // Check if the button is enable
d            if (MyVerySpecialButton.enabled())
    // Reset timer
    this.setTimeOut('myKeyboardCheck', #timeOut, true);

In the run method of the form, I set the above method up for the first iteration, and I change the label of the button to reflect the desired shortcut:

MyVerySpecialButton.text(MyVerySpecialButton.labelText() +' (o)');

If you need to implement this in more forms, you might want to build a small supporting framework in order to avoid repeating much of the same code over and over. The class DocuFileWatchDog could be a good pattern to look at.

If you need to catch keyboard combinations at a global level, you should hook into the Info.OnEventGoingIdle() method. Global reserved keys are defined under \Application Documentation\Global\Shortcutkeys.

I want to give a big thank you to Microsoft support for pointing me in the right direction. I can only wonder why Microsoft haven't gotten this stuff correctly wired up in the first place.

Tuesday, March 29, 2011

Run the Microsoft Dynamics® AX 2012 Hyper-V pre-release image without a Hyper-V server

With the latest version of VirtualBox from Oracle, you can run Hyper-V images from a PC without Windows Server 2008 R2 Hyper-V - for example a box with Windows 7.

There are a few special things you must do in order to make the Dynamics 2012 image work with VirtualBox:
  • Setup the disks as IDE disks. It won't work as SATA disks.
  • Setup two network cards:
  • - Adapter 1 should be configured for "NAT"
  • - Adapter 2 should be configured for "Internal Network"
When the virtual server is started you need to change the TCP/IPv4 network setting for the first adapter:
  • Select "Use the following IP address"
  • IP address:
  • Subnet mask:
  • Select "Use the following DNS server addresses"
  • Preferred DNS server:
(UPDATE April 12th: It seems like you don't need to do these tcp/ip network changes in the new Beta image)

I'm not too sure about the network card settings, as to why they have to be configured like this, but this configuration works and resemble the Hyper-V settings as closely as I could figure it out. If anyone has some actual knowledge about this, I'd love to hear about it.

You can safely diable all the Hyper-V related services on the machine if you want to save the extra overhead. VirtualBox is not using them.

I have tried the image with only 2 GB of RAM for the virtual server. It runs (except for Enterprise Portal), albeit very slow. 4 GB or more gives you a more acceptable performance.

Check the license requirements for VirtualBox. In most cases it is free. But if you, for example, roll it out as part of your business operations you might have to buy a license.

Please share your experiences running the image this way.

Oh - and the Dynamics AX 2012 image itself!? Well, if you don't have it already - you're unfortunately not eligible to get it yet and you'll have to wait for coming releases.
Try the links mentioned here though:

UPDATE: Also check out this step-by-step guide, including a great tip to make SharePoint work as expected:

Sunday, March 13, 2011

Book review: Microsoft Dynamics AX 2009 Administration

This book is written for anyone engaged in planning, deploying, configuring and maintaining a Microsoft Dynamics AX 2009 installation.
It takes you through topics like system planning, installation, configuration of Enterprise Portal and Role Centers, configuration of Workflow, configuration of Application Integration Framework (AIF), data migration, Security and User Administration, Setup of Kerberos Authentication, setup and maintenance of alerts and general maintenance and backup.
Every topic is described in a way so the reader gets a good overview and lots of details for each task covered by the topic. A lot of screen clippings accompanies the tasks described in each chapter, making it easy to follow the necessary steps.  The publisher could however have done a better job implementing the screen clippings. The quality varies a lot, and some of the clippings are barely readable.
The only chapter where I find a bit weak information, is the System Planning and Hardware Sizing chapter. The sizing part has some generic information about what you need to consider for your sizing, but not much in actual numbers to work with. I’ll give the author that Microsoft is equally reluctant to disclose actual numbers in their sizing guides.     So just don’t expect this chapter to be a “next-next-finish” guide to get your right sizing.
Other chapters have excellent tips, some can save you money directly on licenses, others can save you money in shorter implementation cycles. A good hint is the description on what you need to do if you want to deploy Enterprise Portal and don’t have the AX language license for “EN-US”. This tip alone more than pays for the book.  
It pleases me to see a few pages about automated batch jobs. Given the very technical design of this feature it often ends up in a gray area between developers and application consultants. Application consultants would surely benefit from reading this chapter.
I’m also very happy to see the pages about Consistency Check. Not what you’d consider as a very sexy topic, but a lot of issues with data not being correctly migrated to Microsoft Dynamics AX could be caught in an early stage, just by running the consistency checks.
Given the book title, I would have expected more information about regular Application Life Cycle management, for example something about how to deploy new versions of modifications. I feel the book, for most parts, stops when the initial system is installed and configured. 
Also it would have been great to see more Troubleshooting information for each topic, especially for Workflow and Enterprise Portal. And it would have been nice with a few pages about the Intelligent Data Management Framework (IDMF), even though it’s not yet part of the standard Microsoft Dynamics AX package.
So should you buy this book? 
Yes - This book is ensured a prominent place in my bookshelf and it’ll be an important tool in my toolbox. It gives you much value for your money.

More information about the book here: Microsoft Dynamics AX 2009 Administration