Thursday, December 30, 2021

selectForUpdate with fieldId in D365Fo using x++

selectForUpdate with fieldId in D365Fo using x++ . Just check below method.


static void update(Args _args) { CustTable custTable; TestCustomer testCustomer; void updateByField(FieldId _testCustomerFieldId, FieldId _custTableFieldId) { if (custTable.(_custTableFieldId)) { testCustomer.(_testCustomerFieldId) = custTable.(_custTableFieldId); } } void updateTable(Common _tableBuffer) { if (_tableBuffer.validateWrite()) { _tableBuffer.update(); } } while select testCustomer { custTable = CustTable::find(testCustomer.CustAccount); if (custTable) { ttsBegin; testCustomer.selectForUpdate(true); updateByField(fieldNum(testCustomer, CustGroupId), fieldNum(custTable, CustGroup)); updateByField(fieldNum(testCustomer, Currency), fieldNum(custTable, Currency)); updateByField(fieldNum(testCustomer, Name), fieldNum(custTable, InventSiteId)); updateByField(fieldNum(testCustomer, NoYesId),                                                                            fieldNum(custTable, InterCompanyDirectDelivery));

updateTable(testCustomer); ttsCommit; } } }

Before:

After run the method:

Output


Keep Daxing!!

Tuesday, December 28, 2021

Passing Temp table values from one form to other form in D365fo using X++

Hi guys, today post is for passing Temp table values from one form to other form using List in D365fo.

I got requirement like I need to pass the selected temp table values from one form to other form and I need to do some actions based on temp table values. 

For this we can use 

  • List
  • Set
  • Container
Examples: Use any one from this.
-----------------------------------------------------------------------------------------------------------------------------
List: 

//Parent Class Button Clicked method.

void clicked() {

    List myList; TempTable tmpLoc; ; myList = new List(Types::Record);     if (TempTable_ds.Anymarked())// check user selected the record or not. for (tmpLoc = getFirstSelection(TempTable_ds); tmpLoc; tmpLoc = TempTable_ds.getNext()) { myList.addStart(tmpLoc); }

//Calling child form: Any one we can use.

Way1: Args args; FormRun formRun; args = new Args(); args.parmobject(myList); args.name(formstr(Myform)); formrun = classfactory.formrunclass(args); formrun.init(); formrun.run(); formrun.wait();

Way 2:

    Args args;

    args.parmObject(myList);

    new MenuFunction(menuitemdisplaystr(menu item name), MenuItemType::Display).run(args);

}

 //Child class init method;

public void init() {

    List myList; ; if (element.args().parmObject()) { myList = element.args().parmObject(); } //Iterator ListIterator listterator = new ListIterator(myList); while (literator.more()) { tmpTable.data(literator.value()); } //Enumerator ListEnumerator enumerator = myList.getEnumerator(); while(enumerator.moveNext()) { tmpTable.data(enumerator.current()); }

}

-----------------------------------------------------------------------------------------------------------------------------

Set:

//Parent Class Button Clicked method.

void clicked() {

    Set records; TempTable tmpLoc; ; records = new Set(Types::Record); for (tmpLoc = getFirstSelection(TempTable_ds); tmpLoc; tmpLoc = TempTable_ds.getNext()) { records.add(tmpLoc); }

//Calling child form: Any one we can use.

Way1:

Args args; FormRun formRun; args = new Args(); args.parmobject(records); args.name(formstr(Myform)); formrun = classfactory.formrunclass(args); formrun.init(); formrun.run(); formrun.wait();

Way 2:

    Args args;

    args.parmObject(myList);

    new MenuFunction(menuitemdisplaystr(menu item name), MenuItemType::Display).run(args);

}

//Child class init method; 

public void init() {

    Set records; ; if (element.args().parmObject()) { records = element.args().parmObject(); } //Iterator SetIterator recordsIterator = new SetIterator(records);//element.args().parmObject() while (recordsIterator.more()) { tmpTable.data(recordsIterator.value()); //tmpTable.linkPhysicalTableInstance(recordsIterator.value()); recordsiterator.next(); } //Enumerator SetEnumerator enumerator= records.getEnumerator(); while (enumerator.moveNext()) { tmpTable.data(enumerator.current()); }

}

-----------------------------------------------------------------------------------------------------------------------------

Container:

//Parent Class Button Clicked method. 

void clicked() {

    container                   packed;
    Set                         records;
    TempTable                   tmpLoc;
    ContainerClass              containerClass;// For container we need to use this.
    ;
    
    records = new Set(Types::Record);
    for (tmpLoc = getFirstSelection(TempTable_ds); tmpLoc; tmpLoc = TempTable_ds.getNext())
    {
        records.add(tmpLoc);
    }

    packed          = records.pack();
    containerClass  = new ContainerClass(packed);
    

//Calling child form: Any one we can use.

Way1:

    Args           args;
    FormRun        formRun;

    args = new Args();
    args.parmobject(containerclass);
    args.name(formstr(Myform));

    formrun = classfactory.formrunclass(args);

    formrun.init();
    formrun.run();
    formrun.wait();

Way 2:

    Args args;

    args.parmObject(myList);

    new MenuFunction(menuitemdisplaystr(menu item name), MenuItemType::Display).run(args);

}

//Child class init method:

public void init() {
    ContainerClass containerClass; ; if (element.args().parmObject()) { containerClass = element.args().parmObject(); } SetIterator recordsIterator; container packed = containerClass.value(); ; recordsIterator = new SetIterator(Set::create(packed)); while (recordsIterator.more()) { tmpTable.data(recordsIterator.value()); //tmpTable.linkPhysicalTableInstance(recordsIterator.value()); recordsiterator.next(); }
}
--------------------------------------------------------------------------------------------

Keep Daxing!!

Container function in D365fo

Hi guys, today our topic is Container function in D365fo      

Container: It will stores the multiple values with multiple data types.


    container  myContainer= ['Hi',1,2,'Hello'];

    anytype    value;
 
    ConIns:
        Insert the values into container.
    
        myContainer = conIns(myContainer,1,'test1');
    
    ConPeek:
        Get the value from container.

        value  = conPeek(myContainer,1);//your container name, position.

    ConPoke:
        Update the value in container.

        myContainer = conpoke(myContainer,1,'test2');
    
    Condel:
        Delete the values from Container.
    
        secondContainer =conDel(secondContainer,2,1);

    ConNull:    
        clear all the value from container.
    
        myContainer = conNull() ;

    ConLen:
        Find the length of the container.

        int lenght= conLen(myContainer);

    Confind:
        This function is return the Position of searched value. 
            if value is not found it will return 0.

        int position = conFind(secondContainer,'Hello');

 
    Con2Str:
        This function is used to convert container to string. 

        str     string= con2Str(secondContainer);

    Con2List:

        This function converts the container into list.

        List myList = con2List(secondContainer);
    
    Con2Buf: converts container into record. con2Buf(myContainer, mytable); ConView: It will show the container values. conView(myContainer); str2Con: It converts string into container. str2Con(string); str2Con(string, '/');// It will separate the values upon '/'.

    Convert Set into container:
    
        Set         records = new Set(Types::Int64);
        container   packed  = records.pack();
    
    Convert Set into container:
    
        SetIterator     recordsIterator = new SetIterator(Set::create(container));
                                            
 

     Loop the container:

    for (int i = 1; counter <=conLen(secondContainer); i++)
    {
        info(conPeek(secondContainer, i));
    }


 Keep Daxing!!

Filter records in form in D365fo

Hi guys, Today we see how to filter the records in form using X++.

  • If it's a new form directly write the below code.
  •  If it's a standard form. create extension class.
Here we have 2 ways. Follow anyone.

Way 1:

    public QueryBuildRange qbr;//declare this variable globally. public void init()// dataSource init method { super(); qbr = this.query().dataSourceTable(tableNum(InventSite)).addRange(
                                                        fieldNum(InventSite, IsActive)); } public void executeQuery()// dataSource { FormRun formRun = element; if (formRun.args().menuItemName() == menuItemDisplayStr(InventSite)) { qbr.value(queryValue(NoYes::Yes)); } next executeQuery(); 

} 


Way 2:

    public void executeQuery()// dataSource { FormRun formRun = element; if (formRun.args().menuItemName() == menuItemDisplayStr(InventSite)) { this.initializeQueryFromType(); } next executeQuery(); } public void initializeQueryFromType() { QueryBuildDataSource qbDataSource; ; qbDataSource = this.query().dataSourceTable(tableNum(InventSite)); qbDataSource.clearDynalinks(); qbDataSource.addRange(fieldNum(InventSite,                                              isActive)).value(SysQuery::value(NoYes::Yes));

}

Keep Daxing!!

Tuesday, December 21, 2021

How to add Records to include option on sys operation dialog in D365FO

 Hi guys, Today we see how to add records to include option to sys operation.




While running the batch we have to filter the data based on requirements. Instead of writing while loops. We can use query. Just follow the below steps.


Step 1: Create a static query and add data sources based on your requirement. Here I have added Vendatable.


Required fields drag to Ranges node those will be displayed in the dialog.

Sometimes we need the same data from the query. Instead of selecting the values from the front end, we can define in value property.



Step 2: Create a Contract class, add parm methods for your parameters and we have to add a few methods to get that option.

[DataContractAttribute] class TestSysOperationContract { Name name; str packedQuery; [DataMemberAttribute] public Name parmName(Name _name = name) { name = _name; return name; }

    //SysOperationControlVisibilityAttribute(false)// Hide control

[DataMemberAttribute, AifQueryTypeAttribute('_packedQuery', querystr(TestVendorQuery)) ] public str parmQuery(str _packedQuery = packedQuery) { packedQuery = _packedQuery; return packedQuery; } public Query getQuery() { return new Query(SysOperationHelper::base64Decode(packedQuery)); } public void setQuery(Query _query) { packedQuery = SysOperationHelper::base64Encode(_query.pack()); } //public void initQuery() //{ // Query query = new Query(querystr(TestVendorQuery)); // this.setQuery(query); //} }

Step 3: Create a Controller class for calling the service class.

class TestSysOperationController extends SysOperationServiceController
{
    public static void main(Args args)
    {
        TestSysOperationController      controller;
        ;

        controller =  new TestSysOperationController();
        controller.startOperation();
    }
    public void new()
    {
        super(classStr(TestSysOperationService),
                methodStr(TestSysOperationService, process));//,
                    //  SysOperationExecutionMode::Synchronous);
        this.parmDialogCaption("Dialog Title");
    }
} 

Step 4: Create a service class to write our business logic.

class TestSysOperationService extends SysOperationServiceBase
{
    //[SysEntryPointAttribute]
    public void process(TestSysOperationContract _contract)
    {
        QueryRun    queryRun;
        VendTable   vendTable;
        ;

        // create a new queryrun object
        queryRun = new queryRun(_contract.getQuery());

        while(queryRun.next())
        {
            vendTable = queryRun.get(tableNum(VendTable));
            // Your logic.
            info(strFmt('Account - %1 , Name - %2',vendTable.AccountNum,vendTable.name()));
        }
    }

} 

Ends.............

------------------------------------------------------------------------

Sys operation :

If we need to run this batch based on the caller record.


We need to change the logic in the Controller class.

class TestSysOperationController extends SysOperationServiceController { public static void main(Args args) { TestSysOperationController controller; ; controller = TestSysOperationController::newFromArgs(args); controller.startOperation(); } public static TestSysOperationController newFromArgs(Args _args) { TestSysOperationController testController; TestSysOperationContract contract; testController = new TestSysOperationController(); //controller.initializeFromArgs(_args); //contract.initQuery(); if(_args && _args.dataset() == tableNum(VendTable)) { VendTable vendTable; Query query;

            //controller.getDataContractObject()//// for sys operation             //controller.parmReportContract().parmRdpContract() // For Report
contract = testController.getDataContractObject('_contract');
                      // '_contract' this name is from service class method parameter buffer. vendTable = _args.record(); if (vendTable) { query = new query(queryStr(TestVendorQuery));                 //query = contract.getQuery();
//query.clearQueryFilters(); query.dataSourceTable(tableNum(VendTable)).clearRanges(); query.dataSourceTable(tableNum(VendTable)).addRange(fieldNum(VendTable, VendGroup)).value(queryValue(vendTable.VendGroup)); query.dataSourceTable(tableNum(VendTable)).addRange(fieldNum(VendTable, AccountNum)).value(queryValue(vendTable.AccountNum)); contract.setQuery(query); } } return testController; } public void new() { super(classStr(TestSysOperationService), methodStr(TestSysOperationService, process));//, // SysOperationExecutionMode::Synchronous); this.parmDialogCaption("Dialog Title"); } }

multiple records
protected void initContract(Args _args)
{
    MyContract   contract;
    Query        q;
    ;
    contract = this.getDataContractObject('_contract'); 
    q = contract.getQuery();
    
    MultiSelectionHelper multiSelectionHelper;

    multiSelectionHelper = MultiSelectionHelper::createFromCaller(_args.caller());
    multiSelectionHelper.createQueryRanges(q.dataSourceTable(tableNum(MyTable)), 
                                                        fieldStr(MyTable, JournalId));
    
    qbr = findOrCreateRange_W(q.dataSourceTable(tableNum(MyTable)), 
                                                        fieldNum(MyTable, JournalId));

    contract.setQuery(q);
}





Keep daxing!!





Tuesday, December 7, 2021

How to get Default Dimension value for the Record in D365FO

 How to get Default Dimension value for the Record in D365FO using x++.


Way 1: by class

public DimensionValue getDimensonValue(LedgerDimensionValueSet     _defaultDimension)
{
    DimensionAttributeValueSetStorage   dimensionAttributeValueSetStorage;
    DimensionAttribute                  dimensionAttribute;
    DimensionValue                      dimensionValue;
    ;

    #define.DimensionName("CostCenter")// 'DimensionName'

    dimensionAttributeValueSetStorage = dimensionAttributeValueSetStorage::find(_defaultDimension);

    dimensionAttribute  = dimensionAttribute::findbyname(#DimensionName);
    dimensionValue      = dimensionAttributeValueSetStorage.getDisplayValueByDimensionAttribute(
                                                                    dimensionAttribute.recId);
    return dimensionValue;
}

Way 2: by View

Public DimensionValue getDimensonValue(LedgerDimensionValueSet _defaultDimension) { DefaultDimensionView defaultDimensionView; ; select firstonly DisplayValue from defaultDimensionView where defaultDimensionView.Name == 'dimensionName' && defaultDimensionView.DefaultDimension == _defaultDimension; return defaultDimensionView.DisplayValue; }



Keep daxing!!



How to remove the value of a default dimension of a record in D365FO

 How to remove the value of a default dimension of a record in D365FO.


public void removeDimension(LedgerDimensionValueSet _defaultDimension) { DimensionAttributeValue dimAttrValue; DimensionAttribute dimAttr; DimensionAttributeValueSetStorage dimensionAttributeValueSetStorage; dimensionAttributeValueSetStorage = DimensionAttributeValueSetStorage::find(_defaultDimension); dimAttr = DimensionAttribute::findByName('DimensionName'); dimensionAttributeValueSetStorage.removeDimensionAttributeValue( DimensionAttributeValue::findByDimensionAttributeAndValue(dimAttr, 'DimensionValue').RecId); } 


Keep daxing!!

How to change the value of a default dimension of a record in D365FO

Today, we see how to change the value of a default dimension of a record in D365FO using X++.


public LedgerDimensionValueSet updateDimension(LedgerDimensionValueSet _defaultDimension) { DimensionAttributeValue dimAttrValue; DimensionAttribute dimAttr; DimensionAttributeValueSetStorage dimensionAttributeValueSetStorage; LedgerDimensionValueSet defaultDimension; dimensionAttributeValueSetStorage = DimensionAttributeValueSetStorage::find(_defaultDimension); dimAttr = DimensionAttribute::findByName('DimensionName'); dimAttrValue = DimensionAttributeValue::findByDimensionAttributeAndValue(dimAttr,                         'DimensionValue', false, true);

if(dimAttrValue) { dimensionAttributeValueSetStorage.addItem(dimAttrValue); defaultDimension = dimensionAttributeValueSetStorage.save(); } return defaultDimension; } 


Keep daxing!!

Monday, December 6, 2021

Get label for table using x++ in D365FO

 Hi, guys today we see how to get a table, fields label value using x++.


Info(strfmt('Table name : %1, Lable : %2 ', tablestr(VendTable), tablePName(VendTable)));



tablestr --> It will retun table name. O/P -> VendTable.

tablePName--> It will retun lable name of table. O/P -> Vendors.


Field label:

info(fieldPName(VendTable, AccountNum));


Label, Name, and Data type of all fields of any table:

DictTable dt=new SysDictTable(tableNum(CustTable)); 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); }


Keep Daxing!!