Mastering Default Dimensions in D365 F&O: X++ Helper Methods to Create, Read, and Update
One of the most common yet complex tasks in X++ development for Dynamics 365 Finance and Operations is manipulating Financial Dimensions. Whether you are importing data, integrating with external systems, or simply updating a record based on business logic, interacting with the DimensionAttributeValueSet framework is inevitable.
To save you time, I have put together a set of static helper methods that handle the "heavy lifting" of the DimensionAttributeValueSetStorage class.
Below are three essential methods to Create, Read, and Update Default Dimensions.
1. Creating a New Default Dimension
If you have a list of dimension names and their corresponding values (for example, coming from a CSV import or an integration), you need to generate a new RecId for the DefaultDimension field.
This method accepts two containers: one for dimension names (e.g., Department, CostCenter) and one for values.
public static DimensionDefault createDefaultDimension(container _attributes, container _values)
{
DimensionAttributeValueSetStorage valueSetStorage = new DimensionAttributeValueSetStorage();
DimensionDefault ret;
int itemsCounter;
DimensionAttribute dimensionAttribute;
DimensionAttributeValue dimensionAttributeValue;
str dimValue;
for (itemsCounter = 1; itemsCounter <= conLen(_attributes); itemsCounter++)
{
// 1. Find the Dimension Attribute by Name (e.g., "Department")
dimensionAttribute = dimensionAttribute::findByName(conPeek(_attributes, itemsCounter));
if (dimensionAttribute.RecId == 0)
{
continue;
}
// 2. Get the value from the container
dimValue = conPeek(_values, itemsCounter);
if (dimValue != "")
{
// 3. Find the Value record.
// The last two parms (false, true) ensure we don't create new names, but we create values if missing.
dimensionAttributeValue = dimensionAttributeValue::findByDimensionAttributeAndValue(dimensionAttribute, dimValue, false, true);
// 4. Add to storage
valueSetStorage.addItem(dimensionAttributeValue);
}
}
// 5. Save and return the RecId
ret = valueSetStorage.save();
return ret;
}
2. Reading a Specific Dimension Value
Sometimes you don't need to change anything; you just need to know: "What is the Cost Center on this Sales Order?"
This method takes the DefaultDimension RecId and the name of the dimension you want to inspect, returning the display string.
public static str getDimensionDisplayValue(RecId _defaultDimension, Name _dimName)
{
DimensionAttributeValueSetStorage dimStorage;
// 1. Load the existing dimension set
dimStorage = DimensionAttributeValueSetStorage::find(_defaultDimension);
// 2. Return the value specific to the Dimension Name provided
return dimStorage.getDisplayValueByDimensionAttribute(DimensionAttribute::findByName(_dimName).RecId);
}
3. Updating an Existing Dimension
A common requirement is to take an existing record (like a Customer or Vendor) and update just one specific dimension while keeping the others distinct.
This method loads the existing set, adds (or overwrites) the specific dimension value, and returns the new DefaultDimension RecId.
public static DimensionDefault updateDimensionValue(DefaultDimension _currentDim, Name _dimName, DimensionValue _dimValue)
{
DimensionAttributeValueSetStorage dimStorage = new DimensionAttributeValueSetStorage();
DimensionAttribute dimAttribute;
DimensionAttributeValue dimAttributeValue;
DimensionDefault defaultDimension;
ttsBegin;
// 1. Load the existing dimension set
dimStorage = DimensionAttributeValueSetStorage::find(_currentDim);
// 2. Find the attribute to update
dimAttribute = DimensionAttribute::findByName(_dimName);
if (dimAttribute)
{
// 3. Find or Create the new value
dimAttributeValue = DimensionAttributeValue::findByDimensionAttributeAndValue(dimAttribute, _dimValue, true, true);
}
if (dimAttributeValue)
{
// 4. Add item (this overwrites the existing value for this attribute if it exists)
dimStorage.addItem(dimAttributeValue);
// 5. Save to get the new RecId
defaultDimension = dimStorage.save();
}
ttsCommit;
return defaultDimension;
}
Summary
createDefaultDimension: Great for data migration or creating new master data records.getDimensionDisplayValue: Useful for reporting or conditional logic based on dimensions.updateDimensionValue: Essential for patching specific values on existing transactions or records.
Feel free to wrap these in a utility class (e.g., GlobalDimensionHelper) to make them accessible across your project!
No comments:
Post a Comment