Wednesday, January 5, 2022

Web.config file in D365 FO

 Go to :

K:\AosService\WebRoot

look for web.config file

search for following

<add key="DataAccess.Database"

<add key="DataAccess.DbServer"

<add key="DataAccess.SqlPwd"

<add key="DataAccess.SqlUser"


These are for DB, Server, and SQL password and SQL User


Microsoft

Link

Tuesday, January 4, 2022

Round off in D365 FO X++

Round off to 3 decimals: return decRound(total, 3);



More examples are below:

decRound(1234.6574,2) returns the value 1234.66.

decRound(1234.6574,0) returns the value 1235.

decRound(1234.6574,-2) returns the value 1200.

decRound(12345.6789,1) returns the value 12345.70.

decRound(12345.6789,-1) returns the value 12350.00.

Tuesday, December 14, 2021

How to update record in validTimeState table

        LogisticsPostalAddress  LogisticsPostalAddress;

        select * from HCMWORKER

                where HCMWORKER.PERSONNELNUMBER == '002013'; //68719512003

        TransDate x= today(),y=dateMax();

        select forupdate validtimestate(x) * from LogisticsPostalAddress

                where LogisticsPostalAddress.PRIVATEFORPARTY == HCMWORKER.person;     

        LogisticsPostalAddress.ValidTo = today() -1;

        Info(strFmt("%1",HCMWORKER.Person));

        Info(strFmt("%1",LogisticsPostalAddress.RecId));

        ttsbegin;

        LogisticsPostalAddress.validTimeStateUpdateMode(ValidTimeStateUpdate::Correction);

        LogisticsPostalAddress.update();

        ttscommit;

Saturday, December 11, 2021

Full CIL, Incremental CIL in AX 2012

 Full CIL and Incremental CIL in AX2012


Compile: -The compile is to convert X++ source code into p-code, it is in 2009


Sync:-Checking each and every table defining the value of your EDT


Full CIL:-generate CIL is about to convert the p-code into CIL, referred to as the byte code which, at run time, is used by the CLR to convert into native code for execution on the computer. It is easier to understand that a full CIL generation involves converting all p-code into CIL finally, it converts to the binary Lang


Incremental CIL:-incremental CIL generation involves only the “changed” p-code artifacts that need to be converted into target CIL. Incremental CIL would compile only the objects that were modified since the last incremental compilation.


Some X++ batch jobs can now complete in much less time. All X++ code that runs on the AX32.exe client still runs as interpreted p-code. However, all batch jobs now run as Microsoft .NET Framework CIL, which is often much faster than p-code.


The X++ developer must now complete the extra step of compiling X++ p-code to CIL. To compile p-code to CIL, right-click AOT, and then click Add-ins > Incremental CIL generation from X++.


Next, if the installation uses multiple instances of Application Object Server (AOS), all AOS instances must be stopped and then restarted. This causes the AOS instances to load the updated assembly.


Finally, a service or a batch job must run the X++ code that was compiled to CIL. Services and batch jobs now run only as CIL

Friday, December 10, 2021

Change tracking in SQL

 Open SSMS in administrator mode

Run the following command


ALTER DATABASE DATABASENAME

SET CHANGE_TRACKING = ON

(CHANGE_RETENTION = 5 DAYS, AUTO_CLEENUP = ON)




Enable change tracking on the particular table :

ALTER TABLE custgroup

ENABLE CHANGE_TRACKING

WITH (TRACK_COLUMNS_UPDATED = ON)




To view the change-tracking history of a particular table :

select * from CHANGETABLE(CHANGES custGroup, 0) AS ChTbl


Tada!!

Disable HTTP2 for chrome

Open RUN (Window + R)

Run following command :

chrome.exe -disable-http2

This will open chrome in http2 disabled mode


Change the basic settings of D365 DEV server

Change following settings :

DB - Business Database Name, Default Company, Default Model For New Projects, Offline Authentication Admin Email


Go to the following path

K:\AosService\PackagesLocalDirectory\bin\

Open the below file :

DynamicsDevConfig.xml

and there you may set any setting

Wednesday, December 8, 2021

How to synch DB in AX 2012

Go to 

SQL administration

Click System administration > Periodic > Database > SQL administration.

On the Table actions menu, click Synchronize database, or click Check/Synchronize.

Saturday, December 4, 2021

Debug Issue/Error in D365 FO

 1. Open the event viewer and right click and run as administrator. In the Event viewer go to the Microsoft folder expand it.

2. After expanding the Microsoft folder go to AX-SystemRuntime under Operational. Under Operational you will find the error message in the level column and Task category Column. In the below window you will find two tabs details and general.

In the General tab, you will get the error message.


Click on the Details tab to get the full view of the error message.





Thursday, December 2, 2021

Wednesday, November 10, 2021

Line break code in X++

str desc = 'Description :' + "\r\n" + 'This will be in Next line'

Overloading and overriding

Polymorphism means “Many Forms”. In Polymorphism, poly means “Many” and morph means “Forms.” Polymorphism is one of the main pillars in Object-Oriented Programming. It allows you to create multiple methods with the same name but different signatures in the same class. The same name methods can also be in derived classes.
 
There are two types of Polymorphism :
1. Method Overloading
2. Method Overriding


Method Overloading
Method Overloading is a type of polymorphism. It has several names like “Compile Time Polymorphism” or “Static Polymorphism” and sometimes it is called “Early Binding”. 
Method Overloading means creating multiple methods in a class with the same names but different signatures (Parameters). It permits a class, struct, or interface to declare multiple methods with the same name with unique signatures.
The compiler automatically calls the required method to check the number of parameters and their type which are passed into that method.

Sample Code

   public class Program  
    {  
        public int Add(int num1, int num2)  
        {  
            return (num1 + num2);  
        }  
        public int Add(int num1, int num2, int num3)  
        {  
            return (num1 + num2 + num3);  
        }  
        public float Add(float num1, float num2)  
        {  
            return (num1 + num2);  
        }  
        public string Add(string value1, string value2)  
        {  
            return (value1 + " " + value2);  
        }  
        static void Main(Args _args)  
        {  
            Program objProgram = new Program();  
           Info("Add with two int parameter :" + objProgram.Add(3, 2));  
           Info("Add with three int parameter :" + objProgram.Add(3, 2, 8));  
           Info("Add with two float parameter :" + objProgram.Add(3 f, 22 f));  
           Info("Add with two string parameter :" + objProgram.Add("hello", "world"));  
           
        }  
    }  


In the above example, you can see that there are four methods with the same name but the type of parameters or number of parameters is different. When you call Add(4,5), complier automatically calls the method which has two integer parameters and when you call Add(“hello”,” world”), complier calls the method which has two string parameters. So basically in method overloading complier checks which method should be called at the time of compilation.
Note: Changing the return type of method does not make the method overloaded. You cannot create method overloaded vary only by return type.



Method Overriding
Method Overriding is a type of polymorphism. It has several names like “Run-Time Polymorphism” or “Dynamic Polymorphism” and sometimes it is called “Late Binding”. 
Method Overriding means having two methods with the same name and same signatures [parameters], one should be in the base class and another method should be in a derived class [child class]. You can override the functionality of a base class method to create the same name method with the same signature in a derived class. You can achieve method overriding using inheritance. Virtual and Override keywords are used to achieve method overriding.

class BaseClass  
    {  
        public virtual void Add(int num1, int num2)  
        {  
           // your logic will be here 
        }  
    }  
    class ChildClass: BaseClass  
    {  
        public override void Add(int num1, int num2)  
        {  
          // your logic will be here
            ;  
        }  
    }  
    class Program  
    {  
        static void Main(Args _args)  
        {  
            BaseClass baseClassObj;  
            baseClassObj = new BaseClass();  
            Info("Base class method Add :" + baseClassObj.Add(-3, 8));  
            baseClassObj = new ChildClass();  
            Info("Child class method Add :" + baseClassObj.Add(-2, 2));  
          
        }  
    }  

In the above example, I have created two same name methods in the BaseClass as well as in the child class. When you call the BaseClass Add method with less than zero value as parameters then it adds successfully. But when you call the ChildClass Add method with less than zero value then it checks for a negative value. And the passing values are negative then it asks for a new value.
 
So, here it is clear that we can modify the base class methods in derived classes.
 
Points to be remembered,
The method cannot be private.
The only abstract or virtual method can be overridden.
Which method should be called is decided at run time.

Sunday, November 7, 2021

Define Concept of Extensions

 An extension is a way to add functionality to an object in D365FO without modifying the base code of that object.  

Your extensions are compiled into their own DLLs, which are separate from the D365 base system libraries. It also makes it easier for Microsoft to patch their sys layer code.

Microsoft has added to allow customizations without allowing the base code to be changed because they plan to not allow any overlaying of SYS layer code.

Reference

Difference between Container, List, Map and Set

 Containers:

Containers are dynamic and have no limits. They can contain elements of

almost all data types: boolean, integer, real, date, string, container,

arrays, tables, and extended data types. However, objects may not be stored

in containers.

Containers in AX are used very often. It’s easy to work with them. But…

data in containers are stored sequentially and thus retrieved sequentially.

This means that containers provide slower data access if you are working with

_large numbers_ of records. In case of large numbers of records use temporary

tables.


List:

Lists are structures that may contain any number of elements that are

accessed sequentially. Lists may contain values of any X++ type. All the

values in the list must be of __the same__(this is the main difference

between lists and containers) type, given in the creation of the list. The

implementation of lists is such that the traversal of the list elements is __very

fast.

Take a look for example at the class Dialog addControl() method.

Their controls are stored in ctrls List.


Map:

A map is a data type that associates one (key) value with another value [An

analog – a small table in memory with two fields: Keys, Values]. Both the key

and value values may be of any valid X++ type, including objects. The types

of the key and the value are given in the declaration of the map. The

implementation of maps is such that access to the values is _very fast_.

Don’t confuse map X++ types with Map objects in AOT, which are used for

mapping tables with similar structures of fields


Set:

The functionality of Sets is similar to the list.  A Set is just an unordered list of items, while a list of items held by a Map

are indexed via a key.

Take look at

\Classes\sysLabel\LabelModuleId()

How to get label, name and data type of all fields of any table

 static void JobTableLabel(Args _args)

{


    DictTable       dt=new SysDictTable(tableNum(HcmWorker));

    FieldId       _fieldId=  dt.fieldNext(0);

    DictField     _dictField;

    

while(_fieldId)

    {

      _dictField  =dt.fieldObject(_fieldId);

 info(strFmt("Field Name %1 , Field Lable %2 and Field Type %3", _dictField.name(),_dictField.label(),_dictField.type()));

     _fieldId=  dt.fieldNext(_fieldId);

    }

}

BYOD (Bring your own database) in D365 FO



What is BYOD?

BYOD feature lets administrators configure their own database, and then export one or more data entities that are available in Finance and Operations into it.

The BYOD feature allows you to push data into a database you manage on Azure or on-premises.

This is done with the use of data entities. This means you can use existing entities or build your own entities to structure the data you need for your external database. Currently, more than 1700 Data entities are available.


Objective

You have data in D365 running in the cloud but you still have other applications that you run on-premise or elsewhere. 

So you need to get data from D365 into another environment so other applications can use the data. 

The most common use of BYOD is for data analysis and long-running reporting (Long-running reports are the pain point of AX)


Reference

Link

How-to search system logs for BYOD (and other) errors in D365 F&O : Link

Create DB > Configuration > Publish : Link

How to override form control Lookup using extensions in D365 FO

In D365FO we have a bunch of events to subscribe to on a form control level:

right-click on lookup event of control to subscribe to the event and paste in class.


[FormControlEventHandler(formControlStr(PayrollEmployerTaxRegion, Overview_StateId), FormControlEventType::Lookup)]

    public static void Overview_StateId_OnLookup(FormControl sender, FormControlEventArgs e)

    {

                  // Logic here

    }



Now to cancel parent event, D365FO provide a class FormControlCancelableSuperEventArgs


You can cancel the parent(Original event with below code)


        FormControlCancelableSuperEventArgs ce = e as FormControlCancelableSuperEventArgs;


        //cancel super() to prevent error.

        ce.CancelSuperCall();





//Code

[FormControlEventHandler(formControlStr(PayrollEmployerTaxRegion, Overview_StateId), FormControlEventType::Lookup)]

    public static void Overview_StateId_OnLookup(FormControl sender, FormControlEventArgs e)

    {

        SysTableLookup      sysTableLookup  = SysTableLookup::newParameters(tableNum(LogisticsAddressState), sender);

        Query               query           = new Query();


        // Filter lookup to only show US states

        query.addDataSource(tableNum(LogisticsAddressState)).addRange(fieldNum(LogisticsAddressState, CountryRegionId)).value(LogisticsAddressCountryRegion::findByISOCode(SysCountryRegionCode::countryInfo(curext())).CountryRegionId);


        // Sort the lookup by state Id

        query.dataSourceTable(tableNum(LogisticsAddressState)).addOrderByField(fieldNum(LogisticsAddressState, StateId), SortOrder::Ascending);


        // Add fields

        sysTableLookup.addLookupfield(fieldNum(LogisticsAddressState, StateId));

        sysTableLookup.addLookupfield(fieldNum(LogisticsAddressState, Name));


        // Run lookup

        sysTableLookup.parmQuery(query);

        sysTableLookup.performFormLookup();

        FormControlCancelableSuperEventArgs ce = e as FormControlCancelableSuperEventArgs;


        //cancel super() to prevent error.

        ce.CancelSuperCall();

    } 

Reference

Monday, November 1, 2021

Get Number sequence by code in D365 FO

NumberSeq   num;

        num = NumberSeq::newGetNum(NumberSeqReference::findReference(extendedTypeNum(DAPTransNum)));

info(num.num());

num.used();

Class basic code concept in D365 FO X++

Class GITS_Test_AY

{

    public static GITS_Test_AY construct()

    {

        return new GITS_Test_AY();

    }


    public void PrintName(str _Name)

    {

        info(strFmt("%1",_Name));

    }


    public static void withoutReference()

    {

        info(strFmt("Hello"));

    }


}






----------------Calling class----------------

class GITS_Runnable_AY

{

    public static void main(Args _args)

    {

        GITS_Test_AY    obj = GITS_Test_AY::construct();

        obj.PrintName("Jyoti");

        obj.PrintName("Atul");

        GITS_Test_AY::withoutReference();

    }


}

Difference between Index and Index hint

When you use the index keyword in a select statement the kernel will translate this to the "order by" command and the database optimizer will choose the best index to actually use. When you chose to use the index hint keyword in your select statement, Ax will force the database to use the chosen index.


Index:

When you use the index keyword in a select statement the kernel will translate this to order by command and the database optimizer will choose the best index to actually use. 

Example: select * from InventTable index GroupItemIdx will generate the following SQL statement to the database:

SELECT A.ITEMGROUPID, A.ITEMID, A.ITEMNAME,.... FROM INVENTTABLE A ORDER BY A.ITEMGROUPID, A.ITEMID

The Index ItemGroupIdx of the InventTable exactly contains the two fields ItemGroupID and ItemId (in that order). Using "index", you still give the control of which index to use to the database optimizer. So, if the optimizer finds a better index to use, it will use it.

Index hint:

When you chose to use the index hint keyword in your select statement, Ax will force the database to use the chosen index.

Example: select * from InventTable index hint GroupItemIdx will generate the following SQL statement to the database:

SELECT /*+ INDEX(A I_175GROUPITEMIDX) */ A.ITEMGROUPID, A.ITEMID, A.ITEMNAME,.... FROM INVENTTABLE A

Using "index hint", you take away the control of which index to use from the database optimizer. So, if there may be a better index, the database will not use it.