RSS

Model, Model store, Importing, Compilation, IL generation and Upgrade scripts.


Nice post can I reblog it on my blog if you do not having problem.

Raziq AX's Blog

I prepared this post from different sources which would give you clear cut picture on Importing & Compilation objects and IL generation. So, let’s begin withModel and Model store.

What is Model?
A model is a set of elements in a given layer. Each layer consists of one or more models. Each layer contains one system-generated model that is specific to that layer. Every element in a layer belongs to only one model. In other words, no element can belong to two models in the same layer, and every element must belong to a model.

A default model owned by Microsoft exists in each layer. Default models cannot be modified.

A model is permanently associated with the layer that the model was created in. If you need to move one of your models from one layer to another, you must create a project from the model in the Application…

View original post 804 more words

Advertisements
 
Leave a comment

Posted by on September 14, 2016 in Uncategorized

 

AIF–handling related incoming records


I had to being able to handle HRM applicants and applications from a corparate website. In basics the customer wanted to have a webform where the applicant could enter his/her personal data and attach files like eg. a CV, the application or any other relevant stuff.

To handle that scenario I created two tables in AX – one to handle the applicant and application related stuff and another to handle the file attachments. One application should be able to have many attachments. Therefore the first attachment should relate to one application and the second attachment to the same application and so on…

Having the datamodel set, I created a document service.

I created a simple webform in c# that consumed the AIF service and I was soon able to send data into AX. Then it occured to me, that I wasn’t able to create the relation between attachments and applications from the webclient because I needed the RecID og the Application in order to put in onto the attachments.

Inside ax i found the PrepareForSaveExtended method of my AXD class to be useful. Here I could make sure that applications would be processed before attachments. And once the applications were processed I could fetch the RecId and put in on each attachment.

I ended up with this:

Class declaration:

 

class Axdegf_HRMWebRecruitment extends AxdBase

{

#define.WebRecruitment_DataSourceName(‘WebRecruitment’)

#define.Attachments_DataSourceName(‘Attachments’)

 

 

HRMWebRecruitment            axbc_WebRecruitment;

HRMWebRecruitmentAttachments axbc_Attachments;

 

}

PrepareForSaveExtended:

public boolean prepareForSaveExtended(

AxdStack                    _axBcStack,

str                         _dataSourceName,

AxdRecordProcessingContext  _recordProcessingContext,

AxInternalBase              _childRecord)

{

//TODO: Add code here to ensure that required fields specified in the initMandatoryFieldsMap method are sent in by the service caller.

switch (_dataSourceName)

{

// ———————————————————————-

// Process WebRecruitment records

// ———————————————————————-

case #WebRecruitment_DataSourceName:

 

axbc_WebRecruitment = _axBcStack.top();

switch (_recordProcessingContext)

{

 

case AxdRecordProcessingContext::BeforeChildRecordProcessed:

switch(_childRecord.dataSourceName())

{

case #Attachments_DataSourceName:

if(!axbc_WebRecruitment.isProcessed())

{

return true;

}

break;

}

return false;

 

// Ensure WebRecruitment record is saved

case AxdRecordProcessingContext::AfterAllChildRecordsProcessed:

if (!axbc_WebRecruitment.isProcessed())

{

return true;

}

return false;

}

return false;

// ———————————————————————-

// Process Attachments records

// ———————————————————————-

case #Attachments_DataSourceName:

 

axbc_Attachments = _axBcStack.top();

//axbc_Attachments.parmDescription(“dudelidut”);

switch (_recordProcessingContext)

{

 

// Propagate parent’s key

case AxdRecordProcessingContext::BeforeAnyChildRecordsProcessed:

axbc_WebRecruitment = axbc_Attachments.parentAxBC();

axbc_Attachments.parmHRMWebRecruitmentRecIdRef(axbc_WebRecruitment.currentRecord().RecId);

return false;

 

// Ensure Attachments record is saved

case AxdRecordProcessingContext::AfterAllChildRecordsProcessed:

if (!axbc_Attachments.isProcessed())

{

 

return true;

}

 

return false;

}

return false;

 

// ———————————————————————-

// Unsupported data sources

// ———————————————————————-

default:

error(strfmt(“@SYS88979”,classId2Name(classidget(_axBcStack.top()))));

return false;

}

return false;

}

 

 
Leave a comment

Posted by on July 29, 2016 in AIF, Uncategorized

 

Deadlocks show up in AIF exception log when CRM synchronizes multiple companies.


I was working on a case where some issues occured when trying to synhronize data between MS dynamics ax 2012 and MS CRM.

Scenario description:

In MS CRM the following maps have been set up for synchronization in two integrations.

CRM_maps

Each integration uses its own AX user for connection.

From the CRM point of view, the synchronization seems to succeed. However going through the exception log in AX it seems that quite a few deadlocks have occurred, please see screendump below:

AX_deadlocks

And here’s a screendump from the “general” tab showing the error message – “Cannot select a record in Change Tracking Version (AifSqlCtVersion). Change Tracking Version: 0.
Deadlock, where one or more users have simultaneously locked the whole table or part of it.
”:

AX_deadlock_general

The deadlocks seems to have disappeared by themselves.
From this blog post this issue seems to be a known issue – https://community.dynamics.com/ax/f/33/t/160640 – however the ax database had not recently been updated.

 

The cause:

The cause seems to be the SQL optimiser doing a clustered index scan (RecId) in the query below, resulting in blocking:

SELECT T1.CTVERSION,T1.CREATEDDATETIME,T1.RECVERSION,T1.RECID FROM AIFSQLCTVERSION T1 WITH ( UPDLOCK) WHERE (CTVERSION<@P1)

 

The solution:

  • Login to Dynamics AX –> Open a Development workspace, and navigate to AOT –> Dictionary -> tables,
    Find the table AIFSQLCTVERSION , and create a new non-unique index for CTVERSION field
  • Login to SQL server Management studio, and create a new plan guide for the query adding index hint
    EXEC sp_create_plan_guide @name = N'[PlanGuide-AIFSQLCTVERSION]’, @stmt = N’SELECT T1.CTVERSION,T1.CREATEDDATETIME,T1.RECVERSION,T1.RECID FROM AIFSQLCTVERSION T1 WITH ( UPDLOCK) WHERE (CTVERSION<@P1)’, @type = N’SQL’, @module_or_batch = N’SELECT T1.CTVERSION,T1.CREATEDDATETIME,T1.RECVERSION,T1.RECID FROM AIFSQLCTVERSION T1 WITH ( UPDLOCK) WHERE (CTVERSION<@P1)’, @params = N’@P1 bigint’, @hints = N’OPTION (TABLE HINT (T1, INDEX( I_100021KOO_CTVERSIONIDX), UPDLOCK))’
    GO(replace the index name I_100021KOO_CTVERSIONIDX with the actual name of the newly created index)
 
 

AIF–duplicate types with name Dynamics.Ax.Application…


I had to redeploy an AIF http document service several times due to changes. Ocassionally the below error would occur when opening the inbound ports form. The error indicated that the classes related to my document service somehow would conflict because they were already registered. In the current state it would not be possible to activate a new inbound port.

DuplicateType

Fortunateley a colleague of mine had experienced something similar and here is our guide that in the end solved my issue:

  • Create a job that deletes everything  from the SysXppAssembly

static void Job1(Args _args)
{
SysXppAssembly sysxppassembly;
ttsBegin;
delete_from SysXppAssembly;
ttsCommit;
}

  • Stop the AOS.
  • Delete all files (and folders) from the “C:\Program Files\Microsoft Dynamics AX\60\Server\[instancename]\bin\XppIL” folder
  • Start the AOS and go to Systemadministration/setup/services and application integration framework/inbound ports to check if the error has gone.

In most cases that would solve the problem. In one situation I experienced that the above gude was not enough. I also had to do the following:

  • compile the entire application
  • Perform full CIL
  • Restart the AOS
Reference :https://philippsen.wordpress.com/2015/05/11/aifduplicate-types-with-name-dynamics-ax-application/
 
Leave a comment

Posted by on July 29, 2016 in AIF, Uncategorized

 

Enumerator and Iterator in Dynamics AX 2012


Difference between Enumerator and Iterator(use for list, Maps or Sets element’s traversing)

  • We can traverse our List, Map or Set collections by using either an enumerator or an iterator
  • We can’t add/Delete elements in the List or Maps or Set using Enumerator class but we can do it via iterator class
  • It is a best practice to use the Enumerator class instead of the Iterator class, because enumerators are automatically created on the same tier as the map (when calling the List.getEnumerator method)
  • Enumerators require less code than iterators to initiate there instance, they perform slightly better.

For more information please refer to following link

Difference between Enumerator and Iterator in AX 2012

 
Leave a comment

Posted by on July 29, 2016 in Uncategorized

 

Adding custom filter on a list page


Imagine you want a filter on a list page say planned orders list page. Filter works on the order date and shows order due today or all. It has two values in the selection Today/All. Its not that straightforward as it may seem as it is a list page. On a normal AX form, its much easier.

A number of steps required to achieve this.

1. Add the custom filter to the list page. Note the filterExpression, its a call to method we create in next step. Also you need an enum and an EDT based off the enum, EDT is selected in the properties as well.

2. SysQueryRangeUtil
Add a method to the SysQueryRangeUtil.

3. Interaction class
List pages use the interaction classes for logic. We need to customize 2 methods in the ReqTransPOListPageInteraction.
In method initializing, after super(), add this
   customFilter = SysEPCustomFilter::construct(formStr(ReqTransPOListPage));  
   customFilter.load();  
   customFilter.setInitialFilterControlValue(formControlStr(ReqTransPOListPage, yourFilter), 0);  
Note: customFilter.load() will reload the last saved selection in your filter. In case, you want a specific enum selection everytime, comment out this line.
In method initializeQuery, before super(), add this
Note the call to method in SysQueryRangeUtil
   if (this.listPage().listPageArgs().parameters())  
   {  
     reqPOFilterEnum = customFilter.getFilterControlValue(formControlStr(ReqTransPOListPage, yourFilter));  
     SysQuery::findOrCreateRange(_query.dataSourceTable(tableNum(ReqPO)), fieldNum(ReqPO, ReqDateOrder)).value(SysQueryRangeUtil::xxxReqPOFilter(reqPOFilterEnum));  
   }  
4. Your list page
 
Leave a comment

Posted by on July 16, 2016 in AX 2012

 

Capturing infolog messages


Retrieve the content of infolog and store it in log tables, made to track the progress of a batch job and take action on any errors. I used the below method in a catch statement handling all unexpected errors and at the same time updating error log tables. The while loop retrieves all the infolog errors using SysInfologEnumerator and SysInfologMessageStruct infolog classes and concatenating a string with the error messages.

 private str getErrorStr()  
 {  
   SysInfologEnumerator enumerator;  
   SysInfologMessageStruct msgStruct;  
   Exception exception;  
   str error;  
   enumerator = SysInfologEnumerator::newData(infolog.cut());  
   while (enumerator.moveNext())  
   {  
     msgStruct = new SysInfologMessageStruct(enumerator.currentMessage());  
     exception = enumerator.currentException();  
     error = strfmt("%1 %2", error, msgStruct.message());  
   }  
   return error;  
 }  

And the catch statement calling the above method.

   catch (Exception::Error)  
   {  
     ttsbegin;  
     mmsStagingPurchImport.selectForUpdate(true);  
     mmsStagingPurchImport.Error = true;  
     mmsStagingPurchImport.ErrorLog = this.getErrorStr();  
     mmsStagingPurchImport.update();  
     ttscommit;  
     retry;  
   }  
 
Leave a comment

Posted by on July 16, 2016 in AX 2012

 
 
AXAPTA Hut

AxaptaHut ax = new AxaptaHut();

All About Dynamics 365

Dynamics 365, D365, Implementor

Syed Rafay Ali

This blog contains information about Functional techniques and guidelines in Microsoft Dynamics AX, including tips, tricks, tutorials, tools and upcoming news enhancement in Microsoft Dynamics Ax

Philippsen's Blog

Everyday findings in my world of .net and related stuff

Microsoft Dynamics AX

A great WordPress.com site

Xalentis

All things Blockchain, ERP and IoT

Dynamics Ax

Technical Knowledge

timsaxblog

A blog about implementing Microsoft Dynamics AX and Dynamics 365 for Operations

Microsoft Dynamics 365 Blog

Start your organization's digital transformation with Dynamics 365, A Blog by Sandeep Chaudhury

DEVSerra - Dynamics AX development blog

Your official Microsoft Dynamics AX blog.

OrganicAX

Discovering Dynamics

AX

A blog by Hai Nguyen

Learn Dynamics Ax with Johnkrish

Live as if you were to die tomorrow. Learn as if you were to live forever - Mahatma Gandhi ****** The more I learn, the less I know - Albert Einstein

Twisted Untwirled

Just another WordPress.com site

ramdynamicsax

Just another WordPress.com site

guyterry's Dynamics AX blog

Just another Dynamics AX blog