Blog

Name is Anant Dubey and the intent to create this blog is to discuss the problems and issues that developer face in the dynamics AX development and to share the new things that come up with the new version of AX.

Thursday, 22 May 2014

Get Employee email with X++

public Email GetEmployeeEmailFromEmplId(EmplId emplId)
{
    Email       email;
    UserId      userId;
    ;
   
    if(!emplId)
        return '';

    userId = SysCompanyUserInfo::emplId2UserId(emplId);
    email = SysUserInfo::find(userId, false).Email;
   
    return email;
}

Wednesday, 14 May 2014

Import new Worker through code in ax 2012

Firstly create an excel file that contains some fields like name, searchname, personnal no and worker type.
then create a record and run this job
static void importRecord(Args _args)
{
    SysExcelApplication xlsApplication;
    SysExcelWorkBooks xlsWorkBookCollection;
    SysExcelWorkBook xlsWorkBook;
    SysExcelWorksheets xlsWorkSheetCollection;
    SysExcelWorksheet xlsWorkSheet;
    SysExcelRange xlsRange;
    SysExcelCells Cells;
    SysExcelCell RCell;
    CommaIO inFile;
    int nRow,i;
    DialogField dialogPath;
    Dialog dialog;
    Filename filename;
    Name Name;
    LegalEntity LegalEntity;
    HcmPersonnelNumberId PersonnelNo;
    HcmEmploymentType WorkerType;
    HcmWorker hcmWorker;
    DirPerson dirPerson;
    DirPartyTable DirPartyTable;
    HcmEmployment HcmEmployment;
    DirPersonName DirPersonName;
    HcmPersonPrivateDetails HcmPersonPrivateDetails;
    importworker importworker;
    NameAlias SearchName;
    LogisticsElectronicAddressLocator Telephone;
    LogisticsElectronicAddress LogisticsElectronicAddress;
    DirAddressBookPartyAllView DirAddressBookPartyAllView;
    HcmPositionDuration HcmPositionDuration;
    ;
    dialog = new Dialog("Import");
    dialogPath = dialog.addField(extendedTypeStr(Filenameopen), "File Name");
    dialog.run();
    if (dialog.run())
    {
    filename = (dialogPath.value());
    }
    inFile = new CommaIO (filename, 'R');
    if (!inFile || infile.status() != IO_Status::Ok )
    {
    throw error (strfmt("@SYS19312",filename));
    }
    try
    {
    xlsApplication = SysExcelApplication::construct();
    xlsWorkBookCollection = xlsApplication.workbooks();
    xlsWorkBookCollection.open(filename);
    xlsWorkSheetCollection = xlsApplication.worksheets();
    xlsWorkSheet = xlsWorkSheetCollection.itemFromNum(1);
    Cells = xlsWorkSheet.Cells();
    nRow = 2;
    RCell = Cells.Item(nRow, 1);
    while (RCell.value().bstr() != "")
    {
    Name = RCell.value().bStr();
    RCell = Cells.item(nRow,2);
    SearchName = RCell.value().bStr();
    RCell = Cells.item(nRow,3);
    PersonnelNo = RCell.value().bStr();
    RCell = Cells.item(nRow,4);
    WorkerType = str2enum(WorkerType,RCell.value().bStr());
    RCell = Cells.item(nRow,5);
    Telephone = RCell.value().bStr();
    DirPerson.Name=Name;
    hcmWorker.PersonnelNumber = PersonnelNo;
   // DirPartyTable.name = Name;
    HcmEmployment.EmploymentType = WorkerType;
    dirpersonname.FirstName =  Name;
    dirperson.NameAlias = SearchName;
    LogisticsElectronicAddress.Locator =  Telephone;
    //hcmWorker.Person=dirPerson.RecId;
    //exportImportRecords.income = income;
    //importworker.insert();
    //dirPerson.RecId=DirPartyTable.RecId;
    DirPerson.insert();
   // DirPartyTable.RecId=dirPerson.RecId;
    //DirPartyTable.insert();
    DirPersonName.Person=dirPerson.RecId;
    dirpersonname.insert();
    LogisticsElectronicAddress.insert();
    hcmWorker.Person=DirAddressBookPartyAllView.Party;
    hcmWorker.Person=dirPerson.RecId;
   // HcmEmployment.insert();
    hcmWorker.insert();
     HcmEmployment.LegalEntity = 5637148640;
     HcmEmployment.ValidFrom=2007-05-05T23:22:21;
    HcmEmployment.ValidTo = 2015-05-05T23:22:21;
    HcmEmployment.Worker=hcmWorker.RecId;
    HcmEmployment.insert();
    //hcmWorker.update();
    nRow++;
    RCell = Cells.Item(nRow, 1);
    }
    xlsApplication.quit ();
    xlsApplication.finalize ();
    info("Import completed");
    }
    catch( Exception::Error)
    {
    xlsApplication.quit ();
    xlsApplication.finalize ();
    ttsabort;
    info("Unable to process the excel import ");
    }
    }

Thursday, 1 May 2014

How to generate CIL(Common Intermediate Language) in Ax 2012

CIL
(Common Intermediate Language)

What is CIL?
CIL stands for Common Intermediate Language and it works together with the CLI or Common Language Infrastructure, which is basically a set of rules on programming languages that will compile with the CIL. 
CIL (Common Intermediate Language), formerly known as MSIL (Microsoft Intermediate Language) or sometimes simply IL is a low-level language used by .NET Framework.
The runtime (CLR) doesn’t work directly with high-level languages like C#, it works with CIL and compilers of high-level languages simply generate CIL. The runtime handles CIL in the same way regardless it was generated from C#, Visual Basic, IronPython or from X++.
We have two types of CIL compilations, the incremental CIL and the full CIL compilation. The major difference between the two of them is that the incremental CIL would compile only the objects that were modified since the last incremental compilation.
Compile: -The compile is to convert x++ source code into p-code.

Synchronization:- 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 Language.
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.





How does it work?



How to Generate CIL?
By AX 2012:-



                                      “OR”
By cmd:-

"C:\Program Files (x86)\Microsoft Dynamics AX\60\Client\Bin\Ax32.exe" \\server\share\yourconfigfile.axc -startupcmd=CompileIL


Classes, tables, and enums are types in the X++ language. X++ types can be compiled to CIL. The queries and forms in the AOT are not X++ types, and they cannot be compiled to CIL. This means there are a few minor cases where calls from CIL to X++ p-code can cause an exception.
Suppose a method that is running as CIL calls a method on a query. The query method calls the ClassFactory system class of Microsoft Dynamics AX. This case causes an exception to be thrown. The problem is that the CIL session does not have access to all the system classes, yet the query method makes a call to a system class.

On the XppIL folder, there is a bunch of files. These files are NetModule type files and they only contain type metadata and compiled code. 

There is a folder named “source”, and within this folder we find a bunch of files with the .xpp extension, which have x++ source code and are used to debug CIL code when working with services and batches. 
The “existence” of the source folder is directly related to our server configuration when choosing to enable debugging on the server. 









Sometimes while Generating we Got an error like this:-

For resolving this error firstly compile the full application & then Generate full CIL again. If error still exists do this step
Step 1: Stop the AOS

Step 2: Delete all of the source in the C:\Program Files\Microsoft Dynamics AX\60\Server\MicrosoftDynamicsAX\bin\XppIL directory


Step 3: Start the AOS
Step 4: Perform a full compile
Step 5: Perform a full CIL generation




After a FULL CIL compilation I got the following errors:


I just went to the object in question and compiled them separately.





The  error will be resolved.


How to Duplicate company in ax 2012

https://community.dynamics.com/ax/b/dynamicsnavax/archive/2013/07/29/duplicate-a-company-in-ax-2012.aspx

How to debug Batch jobs in ax 2012

All batch jobs and service operations now run in managed code (IL) and require different debugging steps.  Rather than setting breakpoints within X++, you need to set them within the IL code that corresponds to the X++ code and debug in Visual Studio.




  1. Open AX 2012 or R2.
  2. Open Visual Studio as 'administrator' and attach the debugger to the Ax32Serv.exe process. in VS: Debug->Attach to Process.
  3.  Note that it may also be necessary to change the ‘Attach to’ selection to ‘Managed (v4.0) code’ and make sure “just my code” is unchecked in VS: tools->options->debugging->General
  4. Once done, open up the file you want to debug in Visual Studio. All of the X++ code is compiled into IL and can be found in the following directory after deployment: ..\Program Files\Microsoft Dynamics Ax\6.0\Server\AxaptaDev\Bin\XppIL\source\                                                      (NOTE:- make sure that your ax server configuration and local configuration in breakpoint enabled and in the source folder it contains all of AX classes with methods this is created when you generate CIL. If you done any modifications then you have to generate CIL).
  5. Set a breakpoint in the file you opened in Visual Studio.
  6. Go to Ax and run the process in batch mode, or execute the service operation. This will end up hitting your breakpoint, provided you set it in the right place.