X++Posted by Studio Erudit team 2008-11-06 23:28
The X++ job below shows how to find all tables in the AOT where the SaveDataPerCompany property is set to No.
static void se_findAOTObjectByProperty(Args _args)
TreeNode treeNodeTables = TreeNode::findNode(#TablesPath);
str strPropertyName = 'SaveDataPerCompany';
str strPropertyValue = 'No';
// first table
treeNode = treeNodeTables.AOTfirstChild();
while (treeNode != null)
if (treeNode.AOTgetProperty(strPropertyName)== strPropertyValue)
// next table
treeNode = treeNode.AOTnextSibling();
X++Posted by Studio Erudit team 2008-10-19 16:10
The X++ job below shows the top most layer of an AOT object (in this example it is the Address table).
static void se_topLayer(Args _args)
str strAOTObjectPath = #TablesPath + '\\' + tablestr(Address);
TreeNode treeNode = TreeNode::findNode(strAOTObjectPath);
for (i = 0; i <= 0xf; i++)
if (bitTest(treeNode.applObjectLayerMask(), 1 << i))
topLayer = max(topLayer, i);
X++Posted by Studio Erudit team 2008-04-22 22:31
Overriding the event methods (e.g. modify, validate, selectionChange) on dialog controls is not as straight forward as it is on form controls, but the good news is that it is possible!
In order to override the event methods on dialog controls, the following needs to be done (for simplicity we assume that your class extends RunBase class) :
1) The method dialogPostRun() should be overridden and following two lines are added after the super() call:
This will allow to call the event methods of your class.
2) The actual event methods should be added.
The format of the event method name is as follows: fld<ID>_1_<event name>
Please see the example below.
This method is called whenever a value of the dialog control with ID 900 is modified. In our case it is Employee ID field.
public boolean fld900_1_modified()
FormStringControl control = dialog.formRun().controlCallingMethod();
isFieldModified = control.modified();
// every time the employee id is changed, update the employee name
You will also need to make sure that the control “Employee ID” gets the same control ID as used in the event method name (ID 900). This should be done at the time of adding the control to the dialog. Please see below:
protected Object dialog(DialogRunbase _dialog, boolean _forceOnClient)
dialog = super(_dialog, _forceOnClient);
// Add a new field by explicitly specifying the field id.
// This field id is used to create the field event methods (e.g. fld900_1_modified()).
dlgFldEmplId = new DialogField(dialog, typeid(EmplId), #dlgFlgEmplIdFieldNo);
As you can see the macro #dlgFlgEmplIdFieldNo is used to assign the ID to the dialog control. The macro is defined in the classDeclaration and it equals 900.
That’s all what you need to do to be able to override the events on the dialog controls.
Here you can download a complete class which has the code used in the examples above.
AIFPosted by Studio Erudit team 2008-03-24 19:47
This is the second part of the article about import and export data in XML format.
In the first post we have shown how to import and export data in XML format using Axd classes and it was mostly oriented to X++ developers.
In this post, we will use data generated in the first post (AxBc and Axd classes) and will explain how to import and export data in XML format, but using Application Integration Framework (AIF) features and batch framework. This article is mostly oriented to end-users.
Setup part consists of two parts: AIF setup and Batch framework setup.
Before starting AIF setup, please import the xpo file with all required objects from here. Even if you have generated these objects before as a part of the first article, you still need to import it because some objects were slightly modified in order to implement Send functionality which will be used in this article.
The path to the AIF setup forms is: Basic > Setup > Application Integration Framework.
Figure 0. AIF setup forms location.
1) Open Local endpoints form and create a new local endpoint for the company where you want to import data to or to export data from. In our case, it is company DAT.
Figure 1. Local endpoints form
2) Open Transport adapters form and create a new transport adapter for the file system. Set Direction field to "Receive or Send" and select Active checkbox.
Figure 2. Transport adapters form
3) Open Channels form and create two new channels - Outbound and Inbound. The channes simply specify where the files should be taken from or put in.
At first, create an outbound channel and then create an inbound one and assign the outbound channel to it. For the outbound channel, create a folder C:\AIF\Outbound and for the inbound one - C:\AIF\Inbound.
Figure 3. 1. A new outbound channel
Figure 3.2. A new inbound channel with the assigned to it outbound one.
4) Open Actions form and click "Scan and register" button in order to find new documents and generate new actions for them. In our case, the system will be looking for AxdMyTable document and will be generating Create, CreateList, FindEntityKeyList, FindList, Read and ReadList actions for that document. For all these actions, we need to manually select "Enabled" checkbox.
Figure 4.1. Actions form before new actions were generated.
Figure 4.2. Actions form - searching AOT for new documents
Figure 4.3. Actions form - new actions CreateMyTable and CreateListMyTable for AxdMyTable document.
Figure 4.4. Actions form - new actions FindEntityKeyListMyTable and FindListMyTable for AxdMyTable document.
Figure 4.5. Actions form - new actions ReadMyTable and ReadListMyTable for AxdMyTable document.
5) Open Endpoints form and create a new endpoint. The endpoint is used to define rules for import and export of documents (where to export, who can export, which table fields to export or to import, etc.).
Figure 5.1. Endpoints form, Overview tab
Figure 5.2. Endpoints form, General tab
Figure 5.3. Endpoints form, Constraints tab
Figure 5.4. Endpoints form, Users tab
6) In the Endpoints form, click Action policies button. In the Endpoint Action Policies form, you need to add all 6 actions generated in the Actions form in order to be able to apply these actions for the AxdMyTable document. For each action, you need to set the Status field to "Enabled" and Logging Mode to "Log All".
Figure 6.1. Endpoint Action Policies form - action selection
Figure 6.2. Endpoint Action Policies form - all actions added
7) The last step of the AIF setup part is to enable fields that can be imported or exported for each action. For that, select an action and click "Data policies" button and enable following four fields: DocPurpose, MyFieldInt, MyFieldStr, Sender as shown on the picture below. Repeat it for each action.
Figure 7. Data policies selection for createListMyTable action.
Batch framework setup:
8) The path to the Batch setup forms is: Basic > Setup > Application Integration Framework.
Figure 8. Batch setup forms location.
9) Open Batch groups form and create a new batch group.
Figure 9. Batch group form with a new batch group 'AIF'.
10) Open Journal types form and create a new batch journal type. On the General tab, add four following classes that will be run by batch framework in order to import or export data: AifGatewayReceiveService, AifInboundProcessingService, AifOutboundProcessingService, AifGatewaySendService. The sequence in which you add them is not important at this point.
Figure 10.1. Batch journal type form.
Figure 10.2. AIF RunBaseBatch based classes added to the batch journal type.
11) Open Journal names form and create a new journal name. Give it a name 'AIF' and in the Journal type field, select 'AIF' journal type created in the previous step.
Figure 11. Batch journal name form.
12) In the Batch journal name form, click Jobs button. In the Batch journal line form, click Ctrl+N and select a class name from the lookup form. Repeat it for each class name. After all four classes are added, sort them using Up and Down buttons so that they are listed in the following order:
Figure 12.1. Batch journal line form - class name selection.
Figure 12.2. Batch journal line form - classes are in the correct positions.
That's it with the setup part.
Let's go to execution phase.
1) Import from XML file.
1.1) Copy the createListMyTable.xml file to the C:\AIF\Inbound folder.
1.2) Go to Basic > Periodic > Batch and open Batch journal execution form. Specify a journal name, a batch group and recurrence if necessary, and select the batch processing checkbox and click OK button.
Figure 1.1. Batch execution forms
Figure 1.2. Batch journal execution form - the journal name selection
Figure 1.3. Batch journal execution form - the batch processing, the batch group and the recurrence selection.
1.3) Open Processing form, select 'AIF' batch group and click OK.
Figure 1.4. Batch processing form
Now the createListMyTable.xml file should be imported into MyTable table and if you open the form MyTable form (it is a part of the xpo project imported in the beginning of AIF setup) you should be able to see two records:
Figure 1.5. Two records imported from the XML file
2) Export into XML file
2.1) Open MyTable form (select the form in AOT and click Open icon), select the first record and click Send electronically button. Now the job is added to the gateway queue and as soon as you run the batch jobs this document will be exported.
2.2) Repeat the steps 1.2 and 1.3 from the Import part. This will run the batch jobs.
2.3) Now the first record from the MyTable table should have been exported into XML file and you should be able to find it in C:\AIF\Outbound folder.
Figure 1.6. The exported 20083624_213604_2113008_00001.xml file.
If you have a problem and don't know why data was not imported or exported, look at the Basic > Periodic > Application Integration Framework > Exceptions form. This form has a log of all errors occurred during AIF processes and an explanation why they occurred.
More info regarding AIF you can find in MSDN: http://msdn2.microsoft.com/en-us/library/aa570087.aspx
AdministrationPosted by Studio Erudit team 2008-03-21 19:03
The installation of Dynamics AX 4 consists of three main parts:
1) Server installation
2) Client installation
3) Application installation
The path to the installation folders may be changed in the Dynamics AX Setup Wizard. However, if the default paths are used and all three parts are installed on the same machine, then the folder structure will look like below:
Figure 1. Microsoft Dynamics AX 4 folder free.
Application\Appl - contains the application files (business logic) and label files (.ald) for each language. The main application file is Ax<Layer ID>.aod containing the entire application (X++) code per layer.
Application\Appl\Standard\Db - MSDE database files.
Application\Appl\Standard\Tmp - Temporary files generated by the system.
Application\Appl\Standard\Old - during an upgrade the old application files are copied here.
Client\Bin - executable, dll files used on the client side and language dependent text files (.ktd) used by executables.
Server\DynamicsAX\Bin - executable, dll files used on the server side and language dependent text files (.ktd) used by executables. Note, 'DynamicsAX' here is an instance name specified during the Dynamics AX setup. By default it is 'Company1', but it can be changed to something more meaningful.
AIFPosted by Studio Erudit team 2008-03-03 16:11
We often receive questions regarding import and export data in XML format in Dynamics AX 4.
We have decided to post two articles:
1) (this article) Import and export data in XML format using Axd classes (end-user and X++ developer oriented).
2) (next article) Import and export data in XML format using AIF framework (end-user oriented).
This article explains how to use Axd-classes in order to import XML files into Dynamics AX and export Dynamics AX data into XML files. The setup part could be useful for both end-users and developers, however the execution part is mostly concerning X++ developers.
In order to import or export Dynamics AX data in XML format the following objects need to exist:
a) A table - where the data will be imported to or exported from.
b) An AxBC class - which is a wrapper for the table and it is used by Axd-framework to default data into the table fields and update the related tables.
c) A query - which is used by Axd-framework to select data from the table or from the XML file.
d) An Axd-class - which represents the XML document and it is used by Axd-framework to import or export data from and to Dynamics AX.
All these objects except the table and the query can be generated automatically using the Axd Wizard.
Let's create a table MyTable, insert several records into it and generate all the objects mentioned above using Axd Wizard. Afterwards, in the execution part, we will export the records from MyTable table into XML file and import the data from the XML file into MyTable table.
1) Create a new table MyTable.
Figure 1. A new table MyTable.
2) Using Table browser, insert two records into MyTable table. Later these records will be exported into an XML file.
Figure 2. Path to the Table browser menu item.
Figure 3. Insert two new records into MyTable table.
3) Create a new query that will be used to export the data from MyTable table into XML file and import the data from the XML file into MyTable table. The query name should start with Axd in order to easily distinguish betwean standard queries and Axd queries.
Figure 4. A new query AxdMyTable.
4) Go to Tools - Development tools - Wizards - and select Axd Wizard.
Figure 5. Path to the Axd Wizard menu item.
5) Axd Wizard will start. In the Welcome page, click Next button.
Figure 6. The Welcome page of the Axd Wizard.
6) Select the AxdMyTable query created in the step 3 and click Next button.
Figure 7. The Select query page of the Axd Wizard.
7) Select all actions to be able to import and export multiple records of the document (in our case multiple records of the MyTable table). Actually for import and export using Axd classes you don't need Find actions, but they will be needed later for the AIF import article where we will use the data from this setup.
Specify a document description in the Label field and click Next button.
Figure 8. The Select a label and methods page of the Axd Wizard.
8) Click Generate button in the Generate code tab page.
Figure 9. The Generate code page of the Axd Wizard.
9) After all required objects have been generated, the final page appears. Click Finish button.
Figure 10. The final page of the Axd Wizard.
10) If you look at Compiler output window, most likely you will find several errors in the AxMyTable class.
Figure 10. The Compiler output window after the Axd Wizard has completed.
11) In order to fix the compiler errors you need to go to the newly created project AxdMyTable, delete two methods cacheObject and cacheRecordRecord from the AxMyTable class and recompile the entire project.
Figure 11. The AxdMyTable project generated by Axd Wizard.
Figure 12. Deletion of the failing methods cacheObject and cacheRecordRecord.
Figure 13. Recompilation of the entire project.
Now all required objects have been created by Axd Wizard and we are ready to export and import the data in XML format.
1) Export data from MyTable table into XML file using AxdMyTable class.
The X++ job below exports records from MyTable table into XML file C:\Temp\AxdMyTable_Outbound.xml. Please make sure the C:\Temp directorty exists before running this job.
static void exportAxdMyTable(Args _args)
AxdMyTable axdMyTable = AxdBase::newClassId(classnum(AxdMyTable));
AifEntityKeyList aifEntiryKeyList = new AifEntityKeyList();
// convert a record to the entity key
AifEntityKey getEntityKey(Common _record)
AifEntityKey aifEntityKey = AifEntityKey::construct();
List keyFields = SysDictTable::getUniqueIndexFields(_record.TableId);
Map keyMap = SysDictTable::mapFieldIds2Values(keyFields,_record);
// add all records to be exported into the entity key list
while select myTable
// create an xml document containg the records
aifDocumentXml = axdMyTable.readList(aifEntiryKeyList,
xmlDocument = XMLDocument::newXML(aifDocumentXML);
// save the xml document on the disk
The generated XML file will look like this:
Figure 14. AxdMyTable_Outbound.xml file created by exportAxdMyTable X++ job.
2) Import data from the XML file into MyTable table using AxdMyTable class.
For testing purposes you can use the XML file AxdMyTable_Outbound.xml created by the exportAxdMytable job and simply rename it to axdMyTable_Inbound.xml.
static void importAxdMyTable(Args _args)
// create an xml document from file
xmlDocument = XmlDocument::newFile("C:\\Temp\\axdMyTable_Inbound.xml");
xml = xmlDocument.xml();
axdMyTable = AxdBase::newClassId(classnum(AxdMyTable));
// insert data from the xml document into Dynamics AX
The entire X++ project can be dowloaded from here.
Accounts receivablePosted by Microsoft Dynamics AX question 2007-10-08 19:16
Is there any possibility to reverse a packing slip updated sales order?
Yes, this can be done using 'Deliver now' field on the sales order line, Quantity tab page.
You need to specify a negative quantity value in the 'Deliver now' field and then post the packing slip for the sales order again (remember to set the Quantity parameter to 'Deliver now' on the posting packing slip dialog). This will revert the sales order's inventory transactions with status 'Deducted' to the status 'On order'.
Figure 1. 'Delivery now' field on the sales order line
Figure 2. 'Quantity' parameter in the posting packing slip dialog.
The same functionality exists for purchase orders, but the field where the negative quantity is to be specified in order to revert a packing slip updated purchase order is called 'Receive now'.
ProductionPosted by Microsoft Dynamics AX question 2007-10-07 21:24
How would I go about setting up the following.
A specific product can be manufactured on machine 1. (this being the preferred
machine). However it could also be manufactured on machine 2 or machine 3.
What I would like to be able to do if the Machine 1 has reached capacity,
then the demand must be moved to machine 2, then to machine 3 whilst I am
planning. (MPS should do this for me)
Is there a way of doing this?
Yes, this can be achieved using task groups by assigning one of them to the production order's operation.
A task group has a list of work centers which should be used when the best possible work center is being searched for performing the operation. The best work center means - the one that can do job faster(earlier).
Each line in the task group has a sorting criteria (it is called Requirement) where you can specify a number which will be used if there are equaly fast work centers and you need to define which one should be used first. The lowest number is used first.
Here is how you can set this up in AX:
1) Create an item of type BOM
2) Add one operation to the route (Items > Route button) and set the Work center field to e.g. "Machine 1".
3) Go to tab page Setup, do right click on the Task group field and go to the Main table form.
4) Create a new task group and on the tab page Work centers add two lines for the two alternative work centers - "Machine 2" and "Machine 3". Set the Requirement field to 10 for "Machine 2" and to 20 for "Machine 3". This will assure the sequence of how the machines will be used.
5) Assign the newly created task group to the operation.
6) Make sure all machines (1, 2, 3) have parameter "Finite capacty" set. (Work centers - tab page General).
7) Create a production order for the item created at the step 1 and do Update > Job scheduling. Check results in the Production > Jobs form. You can see that the selected work center is "Machine 1".
8) Do the same as on the step 7 (create another production order and run job scheduling for it) and you will see that now system has selected the work center - "Machine 2" for the same time interval (because "Machine 1" is booked).
9) If you repeat the step 7 again (create the third production order and job schedule it), then the time interval will be the same, but the selected work center will be - "Machine 3"(because "Machine 2" was booked on the step 8).
10) If you do it one more time, then there is no more alternative work centers and system will book a later time and the selected work center will be "Machine 1" again and if you continue creating production orders you will get the same results - all alternative work centers will be used.
Graphically it looks like below:
Figure 1. Production job scheduling on alternative work centers.
For simplicity production orders on the figure have only one operation and only one job of type Process, so they look like one bar.