Skip to main content

Notifications

Announcements

No record found.

Community site session details

Community site session details

Session Id :
Microsoft Dynamics AX (Archived)
Answered

How to set default dimension values on creating a new Customer/Vendor etc

(0) ShareShare
ReportReport
Posted on by 504

I have a requirement to customise a few forms that display financial dimensions. There is a preference to pre-populate the financial dimension values and save the user from having to do it. Also, validation that certain dimensions have been populated is another requirement.

e.g. for CustTable form in our system, the FastTab "Financial Dimensions" is displayed with 11 Financial Dimension such as Customers, FixedAsset, Sector, etc. 

So when a new record for Customer is created the user sets the Customer name and Customer group and clicks "Save and open" > "Customer" which launches the CustTable form.

The Edit button needs to be clicked to allow changes.

At this point the user needs to see these dimension values already populated with various default values. 

Each default may have its own rule (not yet defined) which in theory I should be able to write in X++.

I can see the form's init() method uses DimensionDefaultingController to dynamically create the form controls to represent dimension values but would like to know how and where best to do this customisation.

Thanks.

*This post is locked for comments

  • Vilmos Kintera Profile Picture
    Vilmos Kintera 46,149 on at
    RE: How to set default dimension values on creating a new Customer/Vendor etc

    I am not too deeply involved with financials development and you are right. The backing entity should be referred indeed, so you could only do that in a post- event handler subscription of the insert() method, and update with your value. I have found this post explaining that the customer master must exist before the default dimension could be filled in: community.dynamics.com/.../180355

  • _MGP Profile Picture
    _MGP 504 on at
    RE: How to set default dimension values on creating a new Customer/Vendor etc

    Thanks Vilmos for the help.

    I am still stuck though.

    Do you know if it is possible to get around the problem with the code (at the bottom of this reply) which is depending on the existence of the Dimension value (AccountNum) before insert super() is called?

    At the moment, 

    dimAttrCustTable.RecId


    is empty when calling the custom logic before the insert which means the Dimension value is not created.

    However, if I call the custom logic after the super(), the dimAttrCustTable buffer does exist but then the following call fails:-

    MCRFullTextSearch::insert(this);

    Hope you can help - thanks again for your advice.

    //Get the backing entity type for the dimension value to process
        select firstOnly dimAttrCustTable
            where dimAttrCustTable.Value == this.AccountNum;
    
        //Find the required Dimension Attribute Value record
        //Create if necessary
        dimAttrValue = DimensionAttributeValue::findByDimensionAttributeAndEntityInst(dimAttr.RecId, dimAttrCustTable.RecId, false, true);
    


  • Verified answer
    Vilmos Kintera Profile Picture
    Vilmos Kintera 46,149 on at
    RE: How to set default dimension values on creating a new Customer/Vendor etc

    RecId has nothing to do with it.

    You would put the dimension value defaulting before the super() call in the insert() method of CustTable, if you always want to fill it in when a new customer is created. I would only do that if the user has not already provided a value manually (or came from customer group, or any other standard source for filling in the dimensions automagically).

    In fact, the nicest solution would be not to change the standard method at all, but create a pre- event handler subscription for the insert method, and put your dimension defaulting validation and update logic in your custom class.

  • _MGP Profile Picture
    _MGP 504 on at
    RE: How to set default dimension values on creating a new Customer/Vendor etc

    Thanks Vilmos for the useful info - you have made it clearer for me :)

    I've been asked whether I can set the Financial Dimension for Customers irrespective of the path the user takes from the first form when entering Customer data.

    e.g. The User may fill in Name and select the CustGroup and then decide to "Save and close" or maybe "Save and Open" > "Sales order".

    I have managed to update the default dimension in a separate Job when the Customer already exists. However, not when it doesn't exist during CustTable.initValue() or CustTable.modifiedField().

    I believe it is failing here because there is no RecId at the point in time and so the Customer Account Number cannot be a valid Financial Dimension value.

    What is the best table method to use which will allow me to only set the default dimension when the user saves the Customer for the first time and I have my Customer RecId to hand?

    Please let me know if you need anymore info.

    Btw I've put the table method I intend to use below (maybe it is *too* much code to do the most simple thing??)

    private void setDefaultFinancialDimension()

    {

       #LedgerSHA1Hash

       DimensionSHA1Hash               hash; //To store the calculated hash for DimensionAttributeValueSet

       HashKey                         valueKeyHashArray[]; //To store the has key of dimension in question

       Map                             dimAttrIdx; //to store the dimension index and backing entity type

       DimensionAttributeSetItem       dimAttrSetItem; // Contains the number of dimensions active for a account structure ledger

       DimensionAttribute              dimAttr; // Contains the financial dimensions records

       DimensionAttributeValue         dimAttrValue; // Contains used financial dimension values

       DimensionAttributeValueSet      dimAttrValueSet; //Contains default dimension records

       DimensionAttributeValueSetItem  dimAttrValueSetItem; //Contains individual records for default dimensions

       DimAttributeCustTable           dimAttrCustTable; //Backing entity view for Customer type dimension

       DimensionEnumeration            dimensionSetId; //Record id for table that contains active dimensions for current ledger

       CustTable                       custTable;

       int dimAttrCount, i;

       int custBackEntityType; //Stores the backing entity type for Employee type dimension

       ;

       //The customer backing entity will be the view DimAttributeCustTable

       custBackEntityType = tableNum(DimAttributeCustTable);

       //Initialize the map to store the backing entity types

       dimAttrIdx = new Map(Types::Integer, Types::Integer);

       //Get the record Id (dimension set id) for current ledger to find active dimensions

       dimensionSetId = DimensionCache::getDimensionAttributeSetForLedger();

       //Find all the active dimensions for current ledger except main account and store there

       //backing entity type in the map

       while select * from dimAttr

           order by Name

               where dimAttr.Type != DimensionAttributeType::MainAccount

           join RecId from dimAttrSetItem

               where dimAttrSetItem.DimensionAttribute == dimAttr.RecId &&

                   dimAttrSetItem.DimensionAttributeSet == dimensionSetId

       {

           dimAttrCount++;

           dimAttrIdx.insert(dimAttr.BackingEntityType, dimAttrCount);

       }

       //initialize hash key array to null

       for (i = 1; i<= dimAttrCount; i++)

           valueKeyHashArray[i] = emptyGuid();

       //Find the Dimension attribute record for the dimension to work on

       dimAttr.clear();

       select firstonly dimAttr

           where dimAttr.BackingEntityType == custBackEntityType;

       //Get the backing entity type for the dimension value to process

       select firstOnly dimAttrCustTable

           where dimAttrCustTable.Value == this.AccountNum;

       //Find the required Dimension Attribute Value record

       //Create if necessary

       dimAttrValue = DimensionAttributeValue::findByDimensionAttributeAndEntityInst(dimAttr.RecId, dimAttrCustTable.RecId, false, true);

       //Store the required combination hash keys

       valueKeyHashArray[dimAttrIdx.lookup(custBackEntityType)] = dimAttrValue.HashKey;

       //Calculate the hash for the current values

       hash = DimensionAttributeValueSetStorage::getHashFromArray(valueKeyHashArray, dimAttrCount);

       //Null hash indicates no values exist, which may occur if the user entered an invalid value for one dimension attribute

       if (hash == conNull())

       {

           throw error("Wrong value for Customer Dimension");

       }

       // Search for existing value set

       dimAttrValueSet = DimensionAttributeValueSet::findByHash(hash);

       // This value set does not exist, so it must be persisted

       if (!dimAttrValueSet)

       {

           ttsbegin;

           // Insert the value set with appropriate hash

           dimAttrValueSet.Hash = hash;

           dimAttrValueSet.insert();

           //Insert Employee dimension set item

           dimAttrValueSetItem.clear();

           dimAttrValueSetItem.DimensionAttributeValueSet = dimAttrValueSet.RecId;

           dimAttrValueSetItem.DimensionAttributeValue = dimAttrValue.RecId;

           dimAttrValueSetItem.DisplayValue = dimAttrCustTable.Value;

           dimAttrValueSetItem.insert();

           ttscommit;

       }

       custTable = CustTable::find(this.AccountNum);

       if(custTable)

       {

           custTable.selectForUpdate(true);

           custTable.DefaultDimension = dimAttrValueSet.RecId;

           custTable.update();

       }

    }

  • Suggested answer
    Vilmos Kintera Profile Picture
    Vilmos Kintera 46,149 on at
    RE: How to set default dimension values on creating a new Customer/Vendor etc

    That is just using CustTable.DefaultDimension field.

    So when you actually create the customer account, you have to add the logic to populate this value depending on what other information do you want to base it on. If you know it before creating the custom (ie. it is determined by which AX user account is creating the custom, or in what legal entity your user is currently in), you could add it to CustTable.initValue(). You could also tie it to changing a specific field when creating the customer, you can already see that in CustTable.modifiedField() for the CustGroup, it does the initialization of the financial dimensions based on that in Standard AX.

    Alternatively you could overwrite the dimensions based on your custom logic when you insert/update your customer account in those two methods.

    It also has a nice feature of mergeDimension if you want to apply them in multiple steps and layers on top of each other.

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Announcing Our 2025 Season 1 Super Users!

A new season of Super Users has arrived, and we are so grateful for the daily…

Vahid Ghafarpour – Community Spotlight

We are excited to recognize Vahid Ghafarpour as our February 2025 Community…

Tip: Become a User Group leader!

Join the ranks of valued community UG leaders

Leaderboard

#1
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 292,494 Super User 2025 Season 1

#2
Martin Dráb Profile Picture

Martin Dráb 231,305 Most Valuable Professional

#3
nmaenpaa Profile Picture

nmaenpaa 101,156

Leaderboard

Featured topics

Product updates

Dynamics 365 release plans