RSS

Category Archives: Basics

Compile Whole AX Code in less than 30 min AX 2012 R2

Hi All,

With the release of cumulative update 7 for Microsoft Dynamics AX 2012 R2, Microsoft has launched a new command line tool to compile the complete X++ code. This tool has reduced the compilation time and 13 times faster. It can compile the whole AX in 30 mins.

For further details,

http://msdn.microsoft.com/library/d6da631b-6a9d-42c0-9ffe-26c5bfb488e3.aspx

 
Leave a comment

Posted by on November 10, 2013 in AX, Basics, X++

 

Tags: , , , ,

Dynamics AX2012 Fact boxes

Fact boxes in Dynamics AX2012 is another very pretty feature. Before writing anything see the below screenshot of the Customer Listpage.

The area in the red box are the fact boxes, which are new in AX2012. These fact boxes provides extra information of the selected record for example the related information fact box shows the quotation, invoices of the customer selected. By this feature user don’t need to move to other form to get the information. User can get the summarized view of extra information in the fact boxes.

On AOT, there is a new node called “Part”, which holds the fact box objects. The available type of fact boxes are,

  • Form part
  • Info part
  • Cue part
I will provide more detail about how to develop fact boxes and place it to any form. Fact boxes can be placed on on listpage or forms.
Wait for my new post to know more about fact boxes. Keep reading my posts.
 

Tags: , , , , , , , , , , ,

Delete Action

Cascade

A cascading delete action will delete all records in the related table, where the foreign key is equivalent to the primary key of the current table. That is, deleting the parent record will also delete the child record(s) in the related table. This cascading will take place whether the deletion is performed in code or directly by a user through the user interface.

Restricted

A restricting delete action will raise an error message if the user tries to delete a record, where records exist in the related table where the foreign key is equivalent to the primary key of the current table. This error will only appear if the deletion is performed through the user interface. A deletion from X++ code will be allowed to proceed and will not be cascaded to the related table. In this case the programmer should call .validateDelete() themselves prior to the call to .delete()

Cascade + Restricted

The delete action performs a restricted, if the record of the table will be deleted directly and performs a cascade, if the record of the table will be deleted through a cascade delete action of a other table.

 

Thanks for reading. keep visiting and giving feedback.

 
Leave a comment

Posted by on February 7, 2011 in AX, Basics, X++

 

Tags: , , , ,

Exceptions Inside Transactions

When an exception is thrown inside a transaction, the transaction is automatically aborted (a ttsabort operation occurs). This applies both for exceptions thrown manually and for exceptions thrown by the system.

If an exception is thrown inside a ttsBegin/ttsCommit block, it will be caught by the first matching catchlist that is outside the transaction block. If there is a catch block within the ttsBegin/ttsCommit, it will be ignored

 

Example

Example  shows how an exception in a ttsBegin/ttsCommit block is caught by the first catchlist outside the block rather than by the catch within the ttsBegin/ttsCommit block. If you run this code, “outside tts” will be printed before an Infolog displays “Message”.

try

{

ttsbegin;

try

{

throw error(“Message”);

}

catch

{

print “not here”;

pause;

}

ttscommit;

}

catch

{

print “outside tts”;

pause;

}

 

Source: http://msdn.microsoft.com/en-us/library/aa893385(AX.10).aspx

 
2 Comments

Posted by on January 20, 2011 in AX, Basics, Dynamics, SQL, Tables, X++

 

Tags: , , , , , ,

RecordSortedList and RecordInsertList

For those who are wondering, Is there any way in AX to reduce the client server call when inserting a bunch of records into the database. With no surprise Yes!, AX provides a way to do that. Two Collection classes are there in AX RecordSortedList and RecordInsertList for this purpose.

The RecordSortedList class inserts multiple records in a single database trip, and can hold a subset of data from a table, in a particular sort order that does not exist as an index. There are built-in methods in RecordSortedList which can be used to perform the insertion to database. You must provide the sort order in order to perform the insertion properly. The following code sample demonstrates how to insert multiple Student records in the same database trip, using RecordSortedList:

 
 

Student student;

RecordSortedList recordSortedList = new RecordSortedList(tablenum(Student));

recordSortedList .sortOrder(fieldname2id(tablenum(Student),’StudentId’));

 
 

student.clear();

student.StudentID=”123″;

student.FirstName=”DOM”;

student.LastName=”FED”;

recordSortedList.ins(student);

 
 

student.clear();

student.StudentID=”456″;

student.FirstName=”TOM”;

student.LastName=”GED”;

recordSortedList.ins(student);

 
 

student.clear();

student.StudentID=”789″;

student.FirstName=”ROM”;

student.LastName=”TED”;

recordSortedList.ins(student);

 
 

recordSortedList.insertDatabase();

 
 

The RecordInsertList class provides array insert capabilities in the kernel. This allows you to insert more than one record into the database at a time, which reduces communication between the application and the database.

RecordInsertList is similar to RecordSortedList, but it has built-in client/server support (it automatically packs data from one tier to another when needed), and it lacks the sort order features available in RecordSortedList.

 
 

The following is an example using RecordInsertList

Student student;

RecordInsertList insertList = new RecordInsertList(student.TableId, True);

int i;

 
 

for ( i = 1; i <= 100; i++ )

{

student.StudentrId = “F”+int2str(i);

insertList.add(student);

}

insertList.insertDatabase();

 
 

Let me know if you guys have any queries. I will appreciate your comments and feedback.

 
2 Comments

Posted by on December 30, 2010 in AX, Basics, Dynamics, Framework, Tables, X++

 

Tags: , , ,

Read XML file in AX

This post will not take your lots of time, just giving you one example to make you understand how can we read XML file. This post will enable you to read a file that is in the same format as the example in the previous post. You can try on your own to create a Job that reads an XML file that uses attributes such as the second example in the

previous post.

 

static
void ReadXml(Args _args)
 

{

XmlDocument xmlDoc;

XmlElement xmlRoot;

XmlElement xmlField;

XmlElement xmlRecord;

XmlNodeList xmlRecordList;

XmlNodeList xmlFieldList;

CarTable carTable;

DictTable dTable = new DictTable(tablenum(CarTable));


int i, j, fieldId;

#CarsXmlTags


// Create an XmlDocument object to hold the


// contents of the xml-file

xmlDoc = new XmlDocument();


// Load the content of the xml-file


// into the XmlDocument object

xmlDoc.load(@”c:\temp\cars.xml”);


// Get the root node

xmlRoot = xmlDoc.getNamedElement(#CarRootNode);


// Get all child nodes (records)

xmlRecordList = xmlRoot.childNodes();


// Loop through the list of records


for (i=0; i<xmlRecordList.length(); i++)

{

carTable.clear();


// Get the current record from the


// record list

xmlRecord = xmlRecordList.item(i);


// Get all child nodes (fields)

xmlFieldList = xmlRecord.childNodes();


// Loop through the list of fields


for (j=0; j<xmlFieldList.length(); j++)

{


// Get the current field from the


// field list

xmlField = xmlFieldList.item(j);


// Set the matching field in the carTable


// to be equal to the inner text


// (the text between the tag and end tag).

carTable.(dTable.fieldName2Id(xmlField.name())) =

xmlField.innerText();

}


// Insert the record into the carTable

carTable.insert();

}

}


 
Leave a comment

Posted by on December 27, 2010 in AX, Basics, Dynamics, Tables, X++, XML

 

Tags: , ,

Playing with data

In this post, I am going to discuss about how the data can be retrieved, created, updated or deleted using data access and manipulating functionality provided by Dynamics AX framework. In DAX, developer doesn’t need to worry about opening the database connection, make transaction or fetching data, and close the connection. Rather doing these steps DAX framework requires only the table buffer variable to make transaction or manipulating data. What is table buffer? Hmmm, a table buffer is a variable of any Table which stores complete records, for example you can access any field of the table using that variable. Let’s take a simple example. In the Table node of the AOT, we have a table called “CustTable”, now we can declare a table buffer as,

 
 

CustTable custTable; ///table buffer variable of table type “CustTable”

 
 

A table buffer must be declared before using the select statement to retrieve data. The select statement is based on the SQL standard and quite similar to SQL server query statement except the fact that joining is little different for example there is no “ON” keyword in X++. The developer having experience in LINQ won’t have a problem in understanding the working of data access implementation in DAX. See the below simple job and its result.

 
 

static void Select_Statement(Args _args){

CustTable custTable;

select firstOnly custTable;

print custTable.AccountNum + ” ” + custTable.CustGroup;

pause;

}

And the result after running this job is, 
 


 

Now lets analyze the job, firstly a table buffer of table CustTable is declared, and in the 2nd line a select statement is written with the keyword “firstonly” which retrieves only one record based on the primary index defined on the Table. The “firstonly” keyword called the find option in DAX. The other find option keywords are “forUpdate”, “noFetch”, “firstFast”, and “reverse”. You can also define multiple find option keyword within a single select statement. A field list can also be provided with the select statement with the keyword “from”, for example,  
 

select firstoOnly AccountNum, CustGroup from custTable;  
 

Note: its now the BP error if not define the field list in the select statement in the AX 6.0 version.

Can we fetch multiple records? Yes, we can fetch multiple records using the “while” keyword with the select statement. The while loop will continue until all the records is fetched based on the condition in the where clause of the select statement. If now condition is defined, the loop will execute till the last record. 
 

See and observe the output of the following job. 
 

static void Select_Statement(Args _args){CustTable custTable;

while select AccountNum, custGroup from custTable

where custTable.CustGroup == “40”

{

print custTable.AccountNum + ” ” + custTable.CustGroup;

}

pause;

}

 
 

Aggregate functions like sum, count, avg etc. can be used in the select statement like,  
 

select count(AccountNum) from custTablegroup by custTable.CustGroupwhere custTable.CustGroup == “40”;

print custTAble.AccountNum;

 

Lets talk about “joins” in DAX, how we can join multiple tables in the select statement. See the below simple example of join, which joins custTable with custGroup table. 
 

static void Select_Join_Statement(Args _args){CustTable custTable;

CustGroup custGroup; 
 

while select * from custTable

join * from custGroup

where custTable.CustGroup == custGroup.CustGroup

&& custGroup.Name == “Wholesalers”

{

print custTable.AccountNum + ” ” + custTable.Currency + ” ” + custGroup.PaymTermId;

}

pause;

}

Instead of “On” keyword “where” keyword is used to join the same field of the tables that needs to be joined. The Join can be of type “Inner”, “outer”, “exists”, and “not exists”. There is no inner keyword so if the keyword join is written without the other keyword is referred to as inner join. See the below explanation of join types,

Join Type Explanation
join Fetches the records that matches on both the table. It is the inner join.
outer join Fetches the records whether or not records matches on both the table.
exists join Fetches record from the table define before the exists keyword that matches with the records in the 2nd table. No records will be fetched from thesecondary table using exists join.
notexists join Opposite of exists join. Will fetch records from the primary table, where norecords in the secondary table match the join expression.

 

Try and observe the join type result by creating a job. 

Now lets talk about insert, update, and delete records from the table. These will also be done by using the table buffer. In the table buffer, we have methods, of insert, update , and delete. To insert a record into table, declare table buffer, set values of the fields and call insert method of that table buffer. For example, 

static void Insert_Job(Args _args){

CustTable custTable;

custTable.AccountNum = “4444”;

custTable.Currency = “USD”;

custTable.insert();

}

Similarly, to update the record, update method will be called, but first records need to be fetched using the select statement with the keyword “forupdate”. 
 

static void Update_Job(Args _args){

CustTable custTable;

select forupdate * from custTable where custTable.AccountNum == “4444”; 

custTable.Currency = “EUR”;

custTable.update();

}

You can also update the record using the statement “update_recordset

update_recordset custTablesetting currency = “EUR”where custTable.AccountNum ==”4444″;

 

Now to delete the record, you can delete the record in two ways, either fetch the record using the forupdate keyoword and call the delete method of table buffer or using the delete_from statement.

static void Delete_Job(Args _args){

CustTable custTable;

select
forupdate * from custTable where custTable.AccountNum == “4444”;

custTable.delete();

}

Or using delete_from like,

delete_from custTablewhere custTable.AccountNum ==”4444″;

Inserting, updating, and deleting records are placed under the ttsbegin; and ttscommit; block. These keywords are usually placed to make sure that the transactions to database have been done successfully. If any failure occurs during the transaction then the state will be roll back to position before the ttsbegin keyword. ttsabort; keyword is also used when any exception occurs and transaction needs to be aborted.

 Thanks for reading.

 
2 Comments

Posted by on April 16, 2010 in Basics

 

Tags: , , , ,