Sunday, October 31, 2021

How to debug an SSRS report

Sometimes when you place a breakpoint in a data provider class to debug an SSRS report and exercise the report to hit the breakpoint it works and sometimes it doesn't. So the trick to always make the hit is to inherit from the SrsReportDataProviderPreProcess class instead of the SRSReportDataProviderBase class

public class SalesInvoiceDP extends SrsReportDataProviderPreProcess



Macros in D365 FO

A macro is a variable known to the precompiler. The variable can have a value that is a sequence of characters, but it is not required to have a value.

class GITS_Test
    public static void main(Args _args)
        HcmWorker   HcmWorker;
        select * from HcmWorker

        where %1.PersonnelNumber == %2


Overriding in D365 FO

 class Point


    // Instance fields.

    real x;

    real y;

    // Constructor to initialize fields x and y.

    void new(real _x, real _y)


        x = _x;

        y = _y;


    void write()


        info("(" + any2Str(x) + ", " + any2Str(y) + ")");



class ThreePoint extends Point


    // Additional instance fields z. Fields x and y are inherited.

    real z;

    // Constructor is overridden to initialize z.

    void new(real _x, real _y, real _z)


        // Initialize the fields.

        super(_x, _y);

        z = _z;


    void write()


        info("(" + any2Str(x) + ", " + any2Str(y) + ", " + any2Str(z) + ")");



// Code that creates Point objects and calls the write method.

Point point2 = new Point(1.0, 2.0);

Point point3 = new ThreePoint(3.0, 4.0, 5.0);


// Output is "(1.0, 2.0)".


// Output is "(3.0, 4.0, 5.0)".


Saturday, October 30, 2021

Error while exporting data in excel D365 FO


You can start the Azure storage emulator by following the steps below:

On OneBox VM, run command prompt as administrator.

Navigate to “C:\Program Files (x86)\Microsoft SDKs\Azure\Storage Emulator\”

Run “AzureStorageEmulator.exe start”

This should resolve the issue reported above which surfaces while exporting data through data entities in Dynamics 365 for Operations.

List page interaction class and methods

Interaction class of list pages extends SysListPageInteractionBase class. Some handful methods of this class are as follows:

initializing: Called when the form is initializing – Similar to the form init method

intializeQuery: Also called when the form is initializing – Similar to the datasource init method

selectionChanged: Called when the active record changes – Similar to the datasource active method.

setButtonEnabled: Should be overridden to dynamically enable/disable buttons based on the current selection. This is called from the selectionChanged method.

setButtonVisibility: Should be overridden to show/hide buttons when the form first opens. This is used more to do a one-off layout adjustment based on system configuration/parameters, as well as the menu-item used to open the form. eg If you have a menu-item that opens a form based on status, you may want to hide the relevant ‘status’ field to reduce clutter.

Friday, October 29, 2021

Run a class from browser

open browser and just type in

here class name is "GITS_Test"

Cache lookup property in D365 FO

Types of Cache Lookup :






For the master table - EntireTable

For static tables(Like unit tables) - Found

For transaction table - NotInTTS

For static tables (record exists or not example discount table) - FoundAndEmpty

 CacheLookup  Property :-

None :-

No data is cached or retrieved from the cache for this table.

This property value should be used for tables that are heavily updated or where it's unacceptable to read outdated data.

NotInTTS :-

All successful caching key selects are cached.

When in a transaction (after ttsBegin), no caches made outside the transaction are used. When inside a transaction, the record is read once from database and subsequently from cache. The record is select-locked when read in a transaction, which ensures that the record cached is not updated while the transaction is active.

A typical example of the NotInTTS property is the CustTable in the Microsoft Dynamics AX standard application. It's acceptable to read outdated data from the cache outside a transaction, but when data is used for validation or creating references, it is ensured that the data is real-time.

Found :-

All successful caching key selects are cached. All caching key selects are returned from the cache if the record exists there. A selectforUpdate in a transaction forces reading from the database and replaces the record in the cache.

This is typically used for static (lookup) tables, such as Unit, where the record usually exists.

FoundAndEmpty :-

All selects on caching keys are cached, including selects that are not returning data.

All caching key selects are returned from caching if the record exists there, or the record is marked as nonexistent in the cache. A selectforUpdate in a transaction forces reading from the database and replaces the record in the cache.

An example of FoundAndEmpty record caching is in the Discount table in the Microsoft Dynamics AX standard application. By default, the Discount table has no records. By using a FoundAndEmpty cache on this table, the keys that are queried for but not found are stored in the cache. Subsequent queries for these same non-existent records can be answered from the cache without a round trip to the database.

EntireTable :-

Creates a set-based cache on the server. The entire table is cached as soon as at least one record is selected from the table.

The Found and FoundAndEmpty caches cross transaction boundaries. The NotInTTS cache is newly created inside a transaction. This example, modified for the purposes of this topic, demonstrates how records are retrieved from the cache when the table's CacheLookup property is set to NotInTTS, and the PrimaryIndex property is set to a unique index on the AccountNum field.

Table level best practices D365 FO

Set Title fields

Create primary index

Create basic methods like find, findRecId, exist.

Add method documentation in every method.

Method name should be camel casing

Add BP deviation comment on every display or edit method.

Create groups containing relevant fields.

Run the BP check on your table (right-click on table -> Add-ins -> Check Best Practices) and it will show the most crucial BP deviations you might have there.

Index and Key in Dynamics 365 FO

Cluster Index

The ClusterIndex value is given to the underlying Microsoft SQL Server database system as a performance tuning choice. This choice generally controls the physical sequence in which the records are stored in the underlying database.[Let's just say we have 100 fields in a table and we need to fetch 3 fields from different locations, then we use cluster index to make it quick]

Primary Index

The drop-down list contains the surrogate key plus every index on the table that has its AlternateKey property set to Yes.

Surrogate key

In AX 2012, a surrogate key is the auto-generated primary key for a table in the database. The surrogate key is linked to the already existing RecId field within any table. This means that the surrogate key is a unique 64-bit integer value that is mandatory for the table and cannot be changed or have duplicates. The fact that it is a 64-bit integer (int64) value means table operations normally perform faster than other types of field such as string fields. This is the main strength of surrogate keys.

Replacement key Index

While a surrogate key is great for lookup and database performance, it is not useful for the end-user because it gives no indication of the table’s purpose, or what related tables it is linked to. For this reason, AX 2012 has added the ‘Replacement Key’ index property for tables. The replacement key index is a dropdown of alternate keys that have been specified for the table. There can be any number of alternate keys for a table but only a single replacement key. More than one field can be specified under a replacement key, and it is these fields that will be displayed to the end-user on a form instead of the surrogate key field.

A replacement key is an alternate key that the system can display on forms instead of a meaningless numeric primary key value. Each table can have a maximum of one replacement key.

Alternate key

A table can have any number of alternate keys. An alternate key may be a natural key or a single field primary key used in foreign or primary key relations with other tables. In either case, to set one, the user must create a new index and then set AllowDuplicates to “No” and AlternateKey to “Yes”. If AllowDuplicates is not set to “No” then AlternateKey should be greyed out and uneditable Reference


This property controls whether the system creates a unique index on the RecId field. The default value is Yes. This is the basis of the surrogate key.

No other field is added to this index, not even DataAreaId.

Replacement Key

The drop-down list contains every index that has its AlternateKey property set to Yes.

You might change the default blank value to an index whose field values within each record provide a name or other moniker that is meaningful to people. If a ReplacementKey is chosen, its fields can appear on forms to help identify each record.

The ReplacementKey should be a set of fields that represent the natural key.

Alternate Key

Yes means that other tables can create foreign key relations that reference this key, as an alternative to referencing the primary key.

Indexes with two or more fields cannot have their AlternateKey property value set to Yes.

Configuration key

Configuration keys allow administrators to enable or disable features in the application for all users. Disabling features help to minimize the attack surface against potential attacks.

Configuration keys are applied to:






Menu items

Form controls,

Report controls

Extended data types


Security key

Security keys allow administrators to set security on a user group level. Minimizing access on a user group level helps to reduce the attack surface against potential attacks.

The main reasons to apply user-level security are to:

Allow users to do only their designated tasks.

Protect sensitive data in the database.

Prevent users from inadvertently breaking an application by changing code or objects on which the application depends.

You need to apply a security key to:




Menu items

Form controls

Report controls

Difference between COC(Chain of commands) and Event Handler in D365

Post Event Handler is static, does not allow you to have access to protected members of a class.

Also, you cannot add new method or class state via event handler, so CoC is way more powerful.

The advantage of chain of command is you can share the same method variables in the pre and post (before/after next() call) or share the same TTS block inside your COC method.

COC also supports return value and parameter modification of the extended method in a much more readable manner.

COC is nearly the same as pre and post-handlers, pre being before the next call and post after it.

Exist method in D365 FO

 static boolean exist(CustGroupId custGroupId)


    return custGroupId 

        && (select firstOnly RecId from custGroup

            where custGroup.custGroup == custGroupId).RecId != 0;


Wednesday, October 27, 2021

Var in x++

Usually, it's just a shortcut, so you don't have to declare the type if it would make the code less readable. For example, often the type is obvious or not important, and specifying it would make code less readable.

You're welcome to use var where it makes sense, but make sure that you don't make your code less readable by omitting important type information. That the type is obvious to the compiler doesn't mean it's obvious to developers.

In C#, it's also necessary for variables of anonymous types, because there is no way how to declare such a type. For example, you have a LINQ query returning two fields and the framework returns an object with these two fields, but it doesn't have any named type.

Anonymous types are going to be supported in X++ in the future.

Tuesday, October 26, 2021

All methods in D365 FO

 Table Methods

Modified Field : Each time the value of a field is changed ,this method is called.

Init Value : It is used to set a default value for the fields.If we create a new record from the table browser “initvalue” is executed(runs when we create a new record).

Validate Field : It is used for validation only and will return true or false.Each time the value of a field is changed the method ValidateField() is called.

Validate Write : It works like mandatory field(setting) (runs when you save the record).

Validate Delete : while deleting a method if we want to put any validation we can use this method.


//Insert update find exist


Form Methods

Activate : When a form receives focus.Returns boolean data type that specifies whether a form has focus.

CanClose : When aform is closed.specifies whether you can close the form.The call to the super in the method checks whether closing the form is a valid action.

Closed : The form is closed.use this method to check whether the form has been closed.

Close : The form is closed.the call to the super in this method closes the form window,manages database updates and sets the closed method to true.

CloseCancel : Use this method to check whether the form has been closed by a cancel action.the method is set to true if the form is closed by a cancel action.

CloseOk : The user presses an ok button.specifies whether the form wasa closed by clicking the ok button.the call to the super method sets the boolean flag closedok and calls the close method.

InIt : The form is opened.use the method to initialize a form.the init method I started immediately after the new method and creates the run time image of the must call the super method if you override this methpd and you should add your code before the super call.

Run : The form is opened.Call the run method immediately after the init method.The call to the super method makes the form window appear on the screen and performs a database search for the data to be displayed in the form.

Form Control Methods

Validate : The user exists a control after entering data.

Lookup : The user uses the lookup facility.

Modified : The user exits an edit field after changing it.The user changes a value in a checkbox,combobox,listbox or radio button control.The super call manages the table update.


Form Datasource Methods

Active : The user selects a new record.Retrieves data from joined datasource when a user moves to a new record.

Create : The user creates a new record in the datasource.If you use this method to specify field values,the new value are saved to the database when you leave the form.

Delete : the user deletes a record in the datasource.Deletes the current reord from the datasource.

ExecuteQuery : The form is opened for data display.Executes the datasource query and displays the retrieved records.

Filter : The user starts one of the filter commands on the form shortcut menu.Filter records in the datasource.

FindRecord : Activated by the find value method.Finds the specified record in the database and makes it the current one.

InIt : The form is opened.Creates a datasource query based on the datasource properties.

InItValue : A new record is created.The purpose is to fill in initial values in the record.Initializes field values in a new record.If you use this method to specify field values,the new values are not automatically saved to the database when you leave the form.To specify values that you want to save when you leave the form,use the created method.

LinkActive : The user selects a new record in a form that has a datasourcelinked to another datasource.Calls the FormDataSource.executeQuery method on data sources that are linked to the current data source.

Refresh : Not sgtarted by the system.Updates the form by refreshing the view of all records in the datasource.WILL NOT REREAD THE RECORD FROM THE DATASOURCE.IT BASICALLY JUST REFRESHES THE SCREEN WITH WHATEVER IS STORED IN THE FORM FROM THE CACHE.



SelectionChanged() : The user selects or unselects one or morerecords in the datasource.Enables youo to change the property values of control when the selected record changes.

ValidateWrite() : A new or updated record is to be written determines whether data is valid and ready to be written.

Write() : The user inserts a new record or updates an existing one.Calls the FormDataSource.validateWrite method and manages the database write operation.

Methods called while modification closing opening deletion saving runbase


Field modification

Form closing

Form opening

Record deletion

Record saving


Monday, October 25, 2021

Cardinality and RelatedTable Cardinality

Specifically, the Cardinality property corresponds to the notation on the child table (SalesLine in this case). So it should be ZeroMore (0…*).

RelatedTableCardinality property corresponds to the notation on the parent table (SalesTable). So it should be ExactlyOne (1:1).

Semantically, Cardinality specifies how many instances of SalesLine row can be related to a single instance of SalesTable row. ZeroMore means that for every sale order, there can be zero, or more sales lines related to it. If the business requirement dictates that you need to have at least one sales line to be able to create a sales order, the Cardinality would be OneMore (1:*).

RelatedTableCardinality specifies how many instances of SalesTable row can be related to a single instance of SalesLine row. ExactlyOne means that every sales line should belong to one and only one sales order.

Automatically generated batch retryable

Microsoft introduced a BatchRetryable interface to cover unexpected failures on batch jobs.

The problem is that this interface is not implemented automatically, you need manually specify it on all classes. 

To fix this issue, I extended my Runbase class builder tool to automatically generate this property(interface and isRetryable() method)

Saturday, October 23, 2021

Difference between SysOperation Framework and Runbasebatch Framework

Difference between batchprocessing and runbasebatch Framework

The purpose of the SysOperation framework is to provide the same capabilities as the RunBase framework but with base implementations for common overrides. 4 functions are below :

Service: Service class extends from the SysOperationServiceBase class and contains the business logic for the batch operation. Developers often tend to add the business logic in controller classes, which violates the Single responsibility principle[The single-responsibility principle is a computer-programming principle that states that every module, class or function in a computer program should have responsibility over a single part of that program's functionality, and it should encapsulate that part.]

Data Contract: Data contract class is the model class defining attributes needed for batch operations. These attributes are provided by the user, in a dialog. DataContractAttribute attribute is needed for the class and the properties methods requires DataMemberAttribute attribute.

Controller: Controller class extends from the SysOperationServiceController class. It holds information about the batch operation like execution mode, show dialog or progress bar etc. and directs the batch operation.

UI Builder: UI Builder class extends from SysOperationAutomaticUIBuilder class and is used for adding custom behavior to dialog / dialog fields dynamically constructed by the SysOperation framework.

SysOperation framework Classes:

Contract class - SysOperationDataContractBase 

Service - SysOperationServiceBase

UI Builder class - SysOperationAutomaticUIBuilder

Controller - SysOperationServiceController

Here are the main differences between the two:


Legacy framework: RunBaseBatch is an older framework available in earlier versions of Dynamics AX (before AX 2012). It's still supported in Dynamics 365 F&O, but Microsoft encourages the use of the SysOperation framework for new development.

Object-oriented: RunBaseBatch uses an object-oriented approach, which allows developers to create classes that inherit from the RunBaseBatch class.

Serialization: RunBaseBatch requires manual serialization of class members using the pack and unpack methods. This can lead to errors and inconsistencies if not implemented correctly.

Limited support for user interface (UI) controls: The RunBaseBatch framework has limited support for UI controls, such as dialog boxes, which may require additional customization.

SysOperation Framework:

Modern framework: SysOperation was introduced in Dynamics AX 2012 and is the recommended framework for background processing and batch tasks in Dynamics 365 F&O.

Attribute-based: SysOperation uses attributes to define the class and its methods, making it easier to understand and manage.

Automatic serialization: SysOperation automatically handles serialization, reducing the chances of errors and inconsistencies.

Better UI support: The SysOperation framework provides better support for UI controls, such as dialog boxes, making it easier to create user-friendly interfaces for batch processing tasks.

Integration with Application Object Tree (AOT): SysOperation integrates with AOT, which provides an organized way to access and manage application objects.

In conclusion, while both frameworks can be used for batch processing and background tasks in Dynamics 365 F&O, the SysOperation framework is the recommended choice due to its modern architecture, automatic serialization, better UI support, and integration with AOT. RunBaseBatch is still supported, but it is considered a legacy framework and should only be used for maintaining existing implementations or when specific requirements demand its use.

Monday, October 18, 2021

Interface in X++


An interface is an empty shell. There are only the signatures of the methods, which implies that the methods do not have a body. The interface can't do anything. It's just a pattern.

All interfaces are public regardless of whether you explicitly write the keyword public in front of the keyword interface in the class declaration. The methods on an interface are also public, and again the explicit inclusion of the keyword public is optional.

Abstract classes:

Abstract classes, unlike interfaces, are classes. They are more expensive to use because there is a look-up to do when you inherit from them.

Abstract classes look a lot like interfaces, but they have something more: You can define behavior for them. It's more about a person saying, "these classes should look like that, and they have that in common, so fill in the blanks!".

Abstract classes are classes that contain one or more abstract methods.

An abstract method is a method that is declared but contains no implementation.

When we declare a class as abstract, this class cannot initiate in X++ code. To use this class or its method we have to first extend this class than only we are able to use this class or its method.

Interface IDrivable


    int getSpeed(){}

   void setSpeed(int newSpeed){}


class Automobile implements IDrivable


    int speed;

   public int getSpeed()


        return speed;


    public void setSpeed(int newSpeed)


        speed = newSpeed;



class UseAnAutomobile


    void DriveAutomobile()


        IDrivable drivable;

        Automobile myAutomobile = new Automobile();

        str temp;

        myAutomobile = new Automobile();

        if (myAutomobile is IDrivable)


            drivable = myAutomobile;


            temp = int2str(drivable.getSpeed());




            temp = "Instance is not an IDrivable.";





----------------------------------------Abstract class----------------------------------------

To understand the abstract class consider the following example

We have three classes

     1.      absClass  (it’s an abstract class)

     2.      normal class (another class that will use the absClass methods)

     3.      extendAbsClass (this class will extend the absClass)

    1.abstract class absClass



    void printName()


    ;    info("AbsClass... Deepak");


    2. class extendAbsClass extends absClass



    3.class normalClass



  void accessAbsClass()


    absClass        absClass;

    extendAbsClass  extendAbsClass;

 //   absClass = new absClass();    // this declaration will throw error “Object could not be created because class absClass is abstract” so first we extend absClass into extendsAbsClass and further use extendsAbsClass to access absClass methods.

    extendAbsClass  = new extendAbsClass();



----------------------------------------Abstract class----------------------------------------

----------------------------------------Abstract method----------------------------------------

When we declare a method as abstract, this method should be overloaded in child class or we can say, this method should be declared/initiated in the child class then only we can use this class or its method.


a.      Abstract methods may only be declared in abstract classes.

b.      No code or declarations are allowed in abstract methods.

We have three classes

i.                    absMethodClass

ii.                  extendAbsClass

iii.                NormalClass

1.      abstract class absMethodClass



abstract void absPrintName()


                        // we cannot declare any code in the abstract method


2.      class extendAbsClass extends absMethodClass



void absPrintName()


    ; // we have to initiate the abstract method here as this class extends the abstract class.

    info("abstract method declaration in derived class");


3.      class childClass_1



void accessAbsClass()


    extendAbsClass  extendAbsClass;


    extendAbsClass  = new extendAbsClass();



Conclusion : 

Abstract classes can't be instantiated

they're explicitly intended to be extended. 

They also usually contain abstract methods, i.e. methods without any implementation that must be implemented by any non-abstract child. 

It allows you to define high-level concepts and provide some common functionality and leave details for concrete implementations. 

----------------------------------------Abstract method----------------------------------------

How to repair a DB using SSMS

Open SSMS and run the following command








If this didn't work then try this one








Saturday, October 16, 2021

How to create a Display method in D365 F&O

Create a class extension of the table you want to add display method to and then add the display method


final class CustTable_Extension


public static class CustTable_Extension



 public static display Name custGroupName(CustTable _this)


 return  CustGroup::find(_this.CustGroup).Name;




How to make Ledger Dimension lookup in form

Create an int64 field(Dimension Default) EDT in the source table

Put EDT as DimensionDefault

Now drag and drop the field in form and set ControllerClass setting of the field as "LedgerDefaultDimensionEntryController"

How to see open process and kill processes SSMS DB

Open SSMS :

Run the following command :

exec sp_who

i.e this will show all the processes in the SSMS

To kill the process select PID and write the following command

kill 52        [In this case PID is 52]

Set database from SINGLE USER mode to MULTI USER :




How to debug error in D365 F&O

Open event viewer (Run as administrator)

Go to "Application and Services Logs"

Expand "Microsoft"

Go to "AX System Runtime"

Go to "Operational"

Now check the General and Detailed error

Data Source Join Types(Link type) in D365 F&O

Form data source link type is a property of the form data source. We can add more than one table as a data source to the form. Those data sources should have the table level relation, So, then the developer does not need to work on the coding part to find the related records.

Passive Join Type

Passive form data source link type won't update the child data source automatically. For example, if we select the parent table order then order details child data source won't update. If we need to update the child data source we need to call the child data source to execute the query method by the program (code).

Active Join Type

Active link type updates the child data sources without any delay when you select the parent table record. When you deal with more records it will affect application performance.

Delay Join Type

Delay form data source link type is also same as active method the different is delay method won't update immediately when you select the parent record. It will update the child data source when you select the parent table, Ax uses a pause statement before update the child data source. 

Inner join Type

Inner join form data source link type displays the rows that match with parent table and child table. 

Outer join Type

Outer join form data source link type will return all parent records and matched child records. It will return all rows in the parent table. 

Exists Join Type

Exist join form data source link type return matched rows of the parent table. It behaves like an inner join but the difference is once the parent row is matched with child records then stops the process and updates in the grid, Ax won't consider how many records are in the child table for the parent row.

Not Exists Join Type

Not exist join form data source link type is a totally opposite method to exist join. It will return the not-matched parent records with child records.


None: There is no link between the data sources.

Delayed: The linked data source is not queried until it's needed. This can improve form performance by reducing initial load times.

Passive: A relation exists between the data sources, but changes in one do not affect the other.

InnerJoin: Only records that have corresponding records in the joined data source are displayed.

OuterJoin: All records from both data sources are displayed, even if there's no corresponding record in the joined data source.

ExistJoin: Only records from the primary data source for which there are corresponding records in the joined data source are shown.

NotExistJoin: Only records from the primary data source for which there are no corresponding records in the joined data source are shown.

Active: Filters records in a form data source to only show those relevant to the current active record in another linked data source.

How to refresh Data entity list in D365 FO

In order to use the data entities in Dynamics 365 for Finance and Operations, for example through OData or the Data import/export framework, you need to refresh the entity list. The entities need to be refreshed in a new environment, and/or if you have added, deleted, or modified a data entity. In order to refresh the data entities, you click 

Data management workspace > 

Framework parameters > 

Entity settings > 

Refresh entity list in D365FO

Please Note: The refresh usually takes approximately a minute, and it's done in the background. However, the notifications only appear during page refreshes.

Tada !

Saturday, October 9, 2021

Data validation method on table level








Wednesday, October 6, 2021

Different joins in X++ (Inner ,outer ,exist, not exist)

Take 2 tables A & B.

Table A :

Name        Num

Atul             1

Anju            2

Amit            3

Akshay        4

Ritu             5

Table B :

Class        Department        Num

first           accounts            1

second      HR                     2

third          Finance             3

fourth        Technical          4

Fifth          Solution            4

1. Inner join: The common records of both the tables

2. Outer join: All records of table A and common records of Table B

3. Exist join: common records from Table A

4. Not Exist join: The not common record of Table A


Types of temp tables in D365

InMemory tables :

1. Holds data temporarily in client or server tier

2. These tables can't be stored in Database

3. Can't apply security

4. We cannot use InMemory table buffers

5. InMemory temporary table is used when the data set is small

TempDB tables :

1. Holds data temporarily in database till the scope is valid

2. These tables are stored in the database

3. Can apply security

4. TempDB table buffer can be used in coding

5. TempDB is normally used for larger datasets to improve performance