Sunday, December 8, 2013

AX 4.0, 2009 and 2012 Table Synchronization issue. 

Commonly I find that AX 4.0 and AX 2009 users complain about synchronization issues. Whether it is a Dynamics Administrator, Developer or Business user they struggle to get fields synchronized across their AOS servers. 

Be it a simple field or Table properties, its going to cause problems when your users would say 'This field suddenly disappeared today' 

What's causing this,
When you have multiple AOS servers connected, this issue is common. Lets say the field was added in AOS 1. This would show up normally for all users logged into AOS 1. 

Now, after some time lot of users are logging, AX routes some of the users to AOS 2 for load balancing. This server would not recognize this field and the changes wont be visible. 

How to fix this,
; It is recommended to manually synchronize all AOS servers to update the changes. 

Its very easy indeed,

Step 1: Log into the AOS server where you have the fields available. Go to the table you want and click synchronize. [This would push changes back to SQL Server].
Note down the AOS server ID you are logged on to. 

Step 2: Go to Administration -> Online Users -> Server instances. Now we have to synchronize other server's in order to update them. So choose the next server and block other servers by selecting them and clicking 'Reject clients'. 

Note: Make sure at least one server is accepting clients. 

Step 3: Close AX and open it back again. You would be logged back in to other AOS Server

Step 4: Now go to the Table you want to synchronize [If you have added a new field, it might show as UNKNOWN here, newly added table properties and subgroups are usually not visible ] 

      Step 4.1: Right click and Compile the table 
      Step 4.2: Right click and Restore the table. Now you can see the changes back. 

Do the same for other AOS Servers. After you are done mark other AOS server to accept clients. 

Commonly asked questions
Why should you compile the table, why cant you just restore it ? 
Reason is it would rebuild the cache and then restore it back from SQL server. If you just do a restore, the cache is not marked and the changes would not be brought down. 

How can I automate this ? 
There are some floating scripts on the internet to do this. Would update this Job shortly. You can convert this to a periodic job. 

I have a batch server running and should I close them and open back ?
Yes it is advised. 

Faster SSRS Reports Development

Dynamics AX SSRS Reports Development using Report Builder & VS

I am a personal fan of Report Builder with its capabilities of allowing users or [Developers] to quickly create and modify reports. 

When developing or modifying Dynamics AX Model Reports using Visual Studio I always feel its kind of slow when compared to Report builder. [In AX 2012 Visual Studio is the defacto for SSRS development.]

Why VS is slow when deploying reports ? 
It primarily does a lot of things like validation of the existing reports with the modified ones, then deploying all the localized reports (even when you don't want it to) and finally generating the model files for AOT deployment. 

In Report builder if you want to change a field or expression or layout it takes a minute to change it and preview it from Report viewer or AX which is fast in every sense [without having to wait for 5 minutes]. 

This post focusses on how to make the best use of Report builder and then using VS to deploy it. 

Lets take an example of doing some UI changes like adding 

  • adding new fields
  • adding expressions to these fields 
  • doing some layout changes and styling your report 

Step 1. Do all these changes in Report builder. Once done download the RDL file and open in notepad.

Step 2. Go to VS, open the same Report and edit using the built in designer. Right click the designer tab and click 'Open containing folder'. This would provide the location of the RDLC file which would be in a temporary folder. 

Note: Now don't worry about the file extensions for now.

Step 3: Open the RDLC file in another notepad. 

Step 4: Now focus on the Body and Page elements which primarily contains your layout, field properties and so on. So just copy the Body element and replace it in the RDLC file. 

This is the High level blocks of a RDL file [which is similar to RDLC] 


         [All your layout (Tablix,etc) and design (Groups, expressions, etc) elements are here]
        [Header report items here]
        [Footer report items here]
       [Do not modify this section as this differs between the tools] 
      [self explanatory]  
   <Code />

Note: If you have done changes in the Page header or footer then just copy and replace them as well. 

Step 5 :You are almost there. Now deploy the Report from VS and you should have the latest changes deployed to AOT and SSRS. 

Note: After you deploying your changes, all matching SSRS reports would be overwritten. [Meaning the current report you are editing in Report builder would be changed] This is not a problem because now your VS has the latest changes

This would allow you to develop SSRS reports quickly in Report builder and then finally deploy them to AOT. 

Limitations in Report Builder
Cannot connect to AX datasources, only VS can do it. So any Model changes like adding new fields, changing field properties, adding new datasets do it in VS. 

Works In
Visual Studio 2010 [2012],  SQL Sever 2008 [2012], AX 2012 [2009]
;square brackets mean not checked but would work

Sunday, July 28, 2013

Record Level Security in Dynamics AX 2009

Looks like accessing record level security programatically in Dynamics AX 2009 is not that easy, mainly to mention about retrieval of restrictions. 

Before going into deep into this, I assume you might know basics of record level security configured in AX 2009. 

I would show you here on how to access the queries (Record level securities) defined in the Record Level security form. 

Finding it the hard way :

1. The Starting point is the Sys table - SysRecordLevelSecurity.
2. I quickly created a view to see what's in the table. 
    GroupId  tabId companyId  restriction RecId

But if you see here the restriction field does not show up. This is because it is a ranged query that is set in a container assigned to the Datasource as a Query when you setup using the form. When you debug it would show as a binary data type (BLOB) . 

So how to access this, 

There is no straight forward way to access this. Since its a query range attached in the datasource, you have to retrieve it by accessing from the datasource itself .  

Check out my code below. 

Query query = new Query();
SysQueryRun queryRun;
SysRecordLevelSecurity   sysRecordLevelSecurity;
anytype d;


while select  * from sysRecordLevelSecurity {

        queryRun = new SysQueryRun(sysRecordLevelS0ecurity.Restriction);

        info(strFmt('Sec params: %1 Group name:%2 Table Name:%3',
                        queryRun.query().dataSourceNo(1).range(1).value() ,

        /* clear the obj to release blob */

This would give you the permission as a string delimited by periods. 

On how to create/ setup the record level security by code, there is a lot of code floating on the net.