Search This Blog

Saturday, September 3, 2022

Import data using data entity from x++ in dynamics 365 F&O

This is quite common requirement we receive that we need to import the data using data entity with the x++. 

so to Import the data using data entity, we need to make sure that Definition group should be created and we will going to use it in the code. 

I have tested with the CustCustomerGroupEntity data entity and it was working fine. 

Runnable class to import the customer related data 

internal final class TestReadFileWithDataEntity

{

    /// <summary>

    /// Class entry point. The system will call this method when a designated menu

    /// is selected or when execution starts and this class is set as the startup class.

    /// </summary>

    /// <param name = "_args">The specified arguments.</param>

    public static void main(Args _args)

    {

        DMFDefinitionGroup  definitionGroup = DMFDefinitionGroup::find("Import customer group");//Sepcify definition group name

        DMFExecutionId      executionId     = DMFUtil::setupNewExecution(definitionGroup.DefinitionGroupName);

        FileUploadTemporaryStorageResult        storageResult = File::GetFileFromUser() as FileUploadTemporaryStorageResult;

        SharedServiceUnitFileID fileId;

 

        if (storageResult && storageResult.getUploadStatus())

        {

            fileId = storageResult.getFileId();

            DataFileImportExportUtils_W::importDataFromFileToAX(fileId,definitionGroup.DefinitionGroupName,"CustCustomerGroupEntity",true);

        }

 

    }

 

}


We can check the history as well. Navigate to the data definition group that we have created. As per below 












Click on the Job history and we can see the recently some new customer group has been updated.












We can see the staging data as per below 



How to get the selected records of a form in class in Dynamics 365 F&O

Get the selected records of a form datasource

Sometime we have requirement that we need to do some operation on the selected records of a form. 

on the below code, we may have button on the CustTable form and datasource property should be custTable in this case to access the record from CustTable table. when we select multiple record on the custTable form and click that menu item button then in the below class, we can get the selected records by using the standard class MultiSelectionHelper. 

if only single record is selected then still it will work.


    public static void main(Args    _args)

    {

        MultiSelectionHelper            selectionHelper;

        CustTable                       custTable;

 

        if (_args.caller() && _args.dataset() == tableNum(CustTable))

        {

            selectionHelper = MultiSelectionHelper::createFromCaller(_args.caller());

 

            custTable = selectionHelper.getFirst();

 

            while (custTable)

            {

                info(strFmt("Select account number is %1",custTable.AccountNum));

 

                custTable = selectionHelper.getNext();

            }

        }

    }


Refresh the caller datasource of form using x++ in Dynamics 365 F&O

 Refresh the caller datasource of a form from class

Sometime, we have requirement that after completion of the certain process we need to refresh the caller form or may be we need to execute the query of the caller form. 

You can use the below code to refresh the caller datasource. 

There are many method or combination of the method of the datasource you can execute. So it is all based on the customer requirement

internal final class FOTestAccessCallerRecord extends Runbasebatch

{

    public static void main(Args    _args)

    {

        if (_args.caller() && _args.dataset() == tableNum(CustTable))

        {

            FormDataSource fds = FormDataUtil::getFormDataSource(_args.record());

            //you can use the various method over here like execute query or combination of the reread and refresh or if you wanted to execute the currenct query of the caller form

            fds.research(true)

        }

 

 

    }

 

}


Called another form using x++ Dynamics 365 F&O

There are many ways to call the form in Dynamics 365 Finance and Operation. if need to run the form and form should show the detail of the specified record then in that case we can use the below code to call the form. 

In the below code, I am calling the sales order form and it will show the the SalesId specfieid. 


        SalesTable      salesTable = SalesTable::find("SalesId");

        Args            args = new Args(formStr(salestableDetails)); //Specify the form name here

        FormRun         formRun;

   

        //Specify the record

        args.lookupRecord(salesTable);

       

        formRun = classFactory.formRunClass(args);

        formRun.init();

        formRun.run();

        FormRun.detach(); //you can call the wait method overhere as well. it is completed based on the requirement

 


Override the jumpRef method in dynamics 365 F&O

Override the jumpRef method in Dynamics 365 F&O

Show view detail button on a field when we right click

To show the view detail button, there are many ways.  By overriding jumpRef method is one way to show the view detail button.

JumpRef method is used when we click on the any form and wanted to move the respective detail page of it .

Like we have a sales order field on any other form and by right clicking we wanted to see the view detail button so that we can move the detail page of the sales order. 

you can find the below sample code.  There are some other ways as well to override the jumpRef method

    public void jumpRef()

    {

        SalesTable      salesTable = SalesTable::find("SalesId");

        Args            args = new Args(This);

        MenuFunction    mf;

   

        //Specify the record

        args.record(salesTable);

        args.caller(element);

        //Specify the menuitem name that is going to be called.

        mf = new MenuFunction(menuItemDisplayStr(SalesTableDetails), MenuItemType::Display);

        mf.run();

 

    }

 


Tuesday, August 23, 2022

Create display method on the existing table using Extension in Dynamics 365 Finance and Operation

Display method used to create when we need to do some calculation on numeric or some string operation and then we need to display it on the form. Try to avoid creating display method as it causes performance overhead. 

Example :

suppose we wanted to display new field on the customer group form which will show the customer group id with the desciption. To achieve the same, we need to create the display method. We can create by creating extension of the form or of the table. 

I have created code extension of the CustGroup table and created the below code.

/// <summary>

/// Extension of the CustGroup table has been created to add some display method

/// </summary>

[ExtensionOf(tableStr(CustGroup))]

final class CustGroup_FOTraining_Extension

{

    /// <summary>

    /// Display method

    /// </summary>

    /// <returns>Customer group with name</returns>

    [SysClientCacheDataMethodAttribute(true)]

    public display TRNGroupWithName displayGroupWithName()

    {

        //your logic goes here

        return this.CustGroup + this.Name;

    }

 

}


And now we will create the extension of the CustGroup form to add the new field which will display the above values

so we can create the new string type field with the below properties. 






and the output will be as per below 


















How to create label or label file in Dynamics 365 Finance and Operation

In the Dynamics 365 Finance and Operation, for each hard code string, we need to create the label for that like Label on the Extended data type, Base enums, Menu items, Caption on the forms or any other string used to create the info, warning or error in the code. There are more scenario, where we need to create label instead of hard code. 

Label support language translation as well so that when user change the language so that user can see all the labels on the front end in respective language. 

To create the label, first we need to create the label file. Every model should a label file. 

How to create label file

To create label file, Just right click on your project and click add new time and select the label file as per below screenshot. 

Click next 


Click next 



By default en-us will be selected. you can select the multiple language based on your requirement and click on next. 

it will show you the summary



click next and label file has been created.

when you double click the created label file, it will show you the below grid. 
here you can create the new label id and copy it and paste in your code or on the object properties. for example, below label id will be 

@FOTraining:NewLabel0






Every time while creating the label, we should search the existing label and we can use it. 


Monday, August 15, 2022

Read excel file using x++ in Dynamics 365 F&O

 How to read excel file using x++ in Dynamics 365 Finance and operation

Below is the Runnable class we can use to read the excel file. 

internal final class TestReadExcelFile

{

    FileUploadTemporaryStorageResult        fileUploadResult;

    int                                     totalRows;

 

    /// <summary>

    /// Parm method for the file upload storage

    /// </summary>

    /// <param name = "_fileUplaodResult">File upload storage</param>

    /// <returns>File upload storage</returns>

    public FileUploadTemporaryStorageResult parmFileUploadResult(FileUploadTemporaryStorageResult   _fileUplaodResult = fileUploadResult)

    {

        fileUploadResult = _fileUplaodResult;

 

        return fileUploadResult;

    }

 

    /// <summary>

    /// Class entry point. The system will call this method when a designated menu

    /// is selected or when execution starts and this class is set as the startup class.

    /// </summary>

    /// <param name = "_args">The specified arguments.</param>

    public static void main(Args _args)

    {

        TestReadExcelFile       readExcelFile = new TestReadExcelFile();

        try

        {

            FileUploadTemporaryStorageResult    tempStorageResult = File::GetFileFromUser() as FileUploadTemporaryStorageResult;

 

            if (tempStorageResult && tempStorageResult.getUploadStatus())

            {

                readExcelFile.parmFileUploadResult(tempStorageResult);

                readExcelFile.readExcelFile();

            }

        }

        catch

        {

            Error("Error");

        }

    }

 

    /// <summary>

    /// Get the excel ranges to read the excel

    /// </summary>

    /// <returns>Excel range</returns>

    private OfficeOpenXml.ExcelRange getRange()

    {

        int                             firstRow, lastRow;

        System.IO.Stream                stream;

        OfficeOpenXml.ExcelPackage      excelPackage;

        OfficeOpenXml.ExcelRange        range;

        OfficeOpenXml.ExcelWorksheet    excelWorksheet;

 

 

        stream = fileUploadResult.openResult();

 

        excelPackage = new OfficeOpenXml.ExcelPackage(stream);

        excelPackage.Load(stream);

        //get the first worksheet. here you can specify the sheet name as well

        excelWorksheet = excelPackage.get_Workbook().get_Worksheets().get_Item(1);

        firstRow  = excelWorksheet.Dimension.Start.Row;

        lastRow   = excelWorksheet.Dimension.End.Row;

        totalRows = lastRow - firstRow + 1;

        range     = excelWorksheet.Cells;

        return range;

    }

 

    /// <summary>

    /// Read excel file

    /// </summary>

    public void readExcelFile()

    {

        int                     recordsUpdated;

        CustGroup               custGroup;

        OfficeOpenXml.ExcelRange range = this.getRange();

 

        //First row is header so we we reading the values from second row.

        for (int i = 2; i <= totalRows; i++)

        {

           

            CustGroupId                custGroupLocal           = range.get_Item(i,1).Value;

            Description                custGroupName            = range.get_Item(i,2).Value;

 

            custGroup.clear();

            custGroup.CUstGroup = custGroupLocal;

            custGroup.Name      = custGroupName;

            custGroup.insert();           

        }

        Info(strFmt("Record %1 created", totalRows-1));

    }

 

}