I came across this issue with adding dates to negative integers. Basically the issue is that you cant add a negative value to a date variable (but you can subtract a positive integer).
i.e. if x = -5, and date1 is 01/01/2012,
and you do date1 = date1 + x,
this results in a runtime error which says “Error executing code”. This error is not even caught by the catch block.

The need for logging in Ax for me came from the .Net world of using Debug.Writeline , and then looking up the debug values from sysInternals dbgview.
However, to make a very quick and just basic configurable logging, i went to write the logs into a file.
This is a quick and dirty way to add logging capabilities into Dynamics ax.

The Macro values define if the logging capability is turned on, and also the filename (So it can be configured from the usr layer / production site)

I have tested this with Ax 2012 and it has worked pretty well so far, and i do not think Ax2009 should have an issue with it. This logging is so far restricted to file based logging, but I am looking at incorporating other forms like Debug.WriteLine, and will further look into incorporating log4Net (however i have a strong suspicion that this will be limited to server side, and only for Ax 2012).

Hope this brings enough joy to you out there.
Happy Logging

NOTE: before you run the test class in the project, please make sure to edit the Macro to specify the folder path (This can be set to a local directory, but please be advised, this method is “called from”)

UPDATE:

I have now updated the code to include 2 more logging features. Along with that made changes to the method to include the type of message being passes (i.e. warning, information or error. We shall see why)

1. Windows Event logging. – This enables you to you write into the Windows Event log directly. The log type (info , error, warning) will correlate directly to the log icons in the event viewer 🙂

2. Debug log: The most simplistic logging with .Net’s System.Diagnostics.Debug.WriteLine is now included. Although i have seen that this also writes to the event log 😦 (as information only, probably something that is handled from x++ itself, so may not be a good idea to have it in a production server where it manages to clutter the event viewer)

I came across this piece of code which was required to check the AOT elements for certain things.
This iteration should work fine as long as all the developments done show up in your session.
The best way is to restart the AOS and run it to make sure the utilElements have all new objects

So i have found a bug in Ax relating to join statement.
Based on the Image, you can see that i am joining 2 tables, and setting a where statement for the first one to a tableId
All 3 should give me the same result.
However i get a compile error in the 3rd statement. It involves around checking the RefTableId field of Table 2, and comparing it to a tablenum method.

Ax X++ select statement join bug

The 1st method uses the same functions, but all the where clauses are after the join statements. This however can get ugly (unreadable) when there are a lot of where clauses as you would like to have them grouped up.//Join scenario 1
select firstonly table2
join table1
where table2.MyRefTableId == tablenum(Table2)
&& table1.SomeId == "ID00001";

The 2nd method of select statements groups the where clauses nicely. However to do that, I have to use the tablename2Id function instead.//Join scenario 2
select firstonly table2
where table2.MyRefTableId == global::tableName2Id(tablestr(Table2))
join table1
where table1.SomeId == "ID00001";

The 3rd method is the culprit, for which i have no explanation at the moment. Anyone want to shed some light on this?//Join scenario 3
select firstonly table2
where table2.MyRefTableId == tablenum(Table2)
join table1
where table1.SomeId == "ID00001";
This gives me a “Syntax error”

This is a code snippet I use to validate a record created in X++. I do not have to manually go and check if the group I am adding exists in the reference table. The validateField method does this, but is only called from the UI. This topic has been added by me previously here

The following code goes through each line and validates the field, and then the record itself. Any error messages are populated in the infolog (just like the UI)
It could be placed as a static method and can be used application wide with one line of code

When an Ax environment is setup for version control with MorphX, there are times when the database needs to be restored, or another database is required to be used instead. This causes the loss of all version control data. Ax has some standard tables where it stores all this data which can be backed up and restored.
The tables used by Ax for MorphX version control are:

SYSVERSIONCONTROLMORPHXITE2541

SYSVERSIONCONTROLMORPHXLOC2542

SYSVERSIONCONTROLMORPHXREV2543

SYSVERSIONCONTROLPARAMETERS

SYSVERSIONCONTROLSYNCHRONI1982

However due to certain Ax frameworks its just not a straight copy.

The Backup procedure:

In this procedure, i create an SSIS task and add it to a Job that runs nightly backing up data from the tables specified above to a seperate database, which is then completely backed up. This is a simple “export data” functionality within SQL, and saved in the SSIS and attached to a job.

The restore procedure:

This is where a similar export data from the backup database is done to the Ax database. There are a couple of things that need to be done before importing the data. Assuming that a different database has been restored, and Ax is compiled and syncronized.

Ax does not create the tables defined above on syncronization. The parameters for MorphX need to be turned on.

After setting up MorphX version control, go to Tools –> Development tools –> Version Control –> Setup –> System Settings –> click Ok.
This creates the version control XML file definition and checks it out (Resources\SysVersionControlSystemMorphXDefFile). Check this file in and we are ready to

Shut down the AOS to avoid any conflicts

Import the data from the 5 tables defined above into the Ax database

Now this is where we need to reset the record Id’s of Ax. To do so open SQL and run the following commands on the Ax databaseUpdate systemSequences Set nextval = (select max(RecId) + 1 from SYSVERSIONCONTROLMORPHXREV2543) Where tabid = 2543;Update systemSequences Set nextval = (select max(RecId) + 1 from SYSVERSIONCONTROLMORPHXITE2541) Where tabid = 2541;

After starting the AOS the version control should be restored

Update 26/10/2015: For 2012 application the table names are used in full and not terminated by the string limit

To show an example of how this looks, here is a form, with an empty group, and a button to select the query values

The button “Select values” is calling queryRun.Prompt for the queryrun variable defined within the form object.

Once the user selects the fields (user can even leave certain ranges empty, and add more range fields) the query is passed to a class along with the forms group control (i.e. “My Query Group”)

The class will then clear existing controls within the group and then add the ranges from the query.

Multiple data sources can be added by the user and they all show up in the group.

A shortcoming of this is that every time the class arranges the fields in the group, it first hides any existing controls. This is because, controls cannot be removed when added. So a lot of selects can cause a large memory footprint for this form

Sometimes running a batch job may depend on another one completing before it runs. To ensure that can happen, and to set it up involves some development work.

To add a batch job to an existing batch task list, lets first set up a batch job

For this example i have created a batch job, and added the class InventTransferMultiPick (Transfer order – Picking list) to the list.

I have created my own batch job called MyBatchClass. This class needs to run only after the InventTransferMultiPick class has finished executing.

When I try to insert another record into the Batch tasks, it does not show this class there. For reasons, there is a setting required in the class called canGoBatchJournal. This method by default returns false, and needs to be explicitly overridden and set to true.