Dynamics AX Blog - Dynamics AX 2012 - Financial dimensions - Dynamics AX 2009 - ssrs

In Dynamics AX 2012, the handling of financial dimensions has changed. Both on the surface and the underlying data model.
In earlier versions you find one field - usually named dimension - of type array. Now you'll find a field derived from RecId called DefaultDimension (or similar).
In this series I want to specifically address these changes and present one or the other piece of code.
Show entriesRSS-Feed of this blog series

RSS-Feed of this version
AX 2012: How to change the value of a default dimension of a recordThe following job will give you an example, of how to change the value of a dimension within the default dimensions of a record (the example-job changes the value of the dimension costcenter of a customer). In this way and manner individual dimension values can be removed also.
static void changeDimensionValue(Args _args)
{
DimensionAttributeValueSetStorage dimensionAttributeValueSetStorage;
DimensionAttribute dimensionAttribute;
CustTable custTable = CustTable::find("US-014");
DimensionValue oldDimensionValue;
DimensionValue newDimensionValue = "011";
DimensionDefault newDimensionDefault;
#define.dimensionName("CostCenter")
DimensionValue getDimensonValue(DimensionDefault _dimensionDefault)
{
DefaultDimensionView defaultDimensionView;
select firstonly DisplayValue
from defaultDimensionView
where defaultDimensionView.Name == #dimensionName
&& defaultDimensionView.DefaultDimension == _dimensionDefault;
return defaultDimensionView.DisplayValue;
}
// Get current value
oldDimensionValue = getDimensonValue(custTable.DefaultDimension);
// Build DimensionAttributeValueSetStorage
dimensionAttributeValueSetStorage = DimensionAttributeValueSetStorage::find(custTable.DefaultDimension);
// Remove old dimension value
dimensionAttribute = DimensionAttribute::findByName(#dimensionName);
dimensionAttributeValueSetStorage.removeDimensionAttributeValue(
DimensionAttributeValue::findByDimensionAttributeAndValue(dimensionAttribute, oldDimensionValue).RecId);
// Set new dimension value
if(newDimensionValue != "")
{
dimensionAttribute = DimensionAttribute::findByName(#dimensionName);
dimensionAttributeValueSetStorage.addItem(
DimensionAttributeValue::findByDimensionAttributeAndValue(dimensionAttribute, newDimensionValue));
}
newDimensionDefault = dimensionAttributeValueSetStorage.save();
ttsbegin;
custTable.selectForUpdate(true);
custTable.DefaultDimension = newDimensionDefault;
custTable.update();
ttscommit;
}
Screenshot before job Screenshot after job |
AX 2012: Building a DefaultDimension/LedgerDimensionBelow you'll find a code example of how to generate a RecId of type DefaultDimension for several dimensions.
static void buildDefaultAndLedgerDimension(Args _args)
{
DimensionAttributeValueSetStorage dimensionAttributeValueSetStorage;
DimensionAttribute dimensionAttribute;
DimensionAttributeValue dimensionAttributeValue;
DimensionDefault dimensionDefault;
LedgerDimensionAccount ledgerDimensionAccount;
dimensionAttributeValueSetStorage = new DimensionAttributeValueSetStorage();
// BusinessUnit
dimensionAttribute = DimensionAttribute::findByName('BusinessUnit');
if(dimensionAttribute)
{
dimensionAttributeValue = DimensionAttributeValue::findByDimensionAttributeAndValue(dimensionAttribute, '069', false, true);
dimensionAttributeValueSetStorage.addItem(dimensionAttributeValue);
}
// CostCenter
dimensionAttribute = DimensionAttribute::findByName('CostCenter');
if(dimensionAttribute)
{
dimensionAttributeValue = DimensionAttributeValue::findByDimensionAttributeAndValue(dimensionAttribute, '010', false, true);
dimensionAttributeValueSetStorage.addItem(dimensionAttributeValue);
}
// Department
dimensionAttribute = DimensionAttribute::findByName('Department');
if(dimensionAttribute)
{
dimensionAttributeValue = DimensionAttributeValue::findByDimensionAttributeAndValue(dimensionAttribute, '024', false, true);
dimensionAttributeValueSetStorage.addItem(dimensionAttributeValue);
}
dimensionDefault = dimensionAttributeValueSetStorage.save();
// Merge main account and source dimension values and return RecId which can be used as ledgerDimension
ledgerDimensionAccount = DimensionDefaultingService::serviceCreateLedgerDimension(DimensionStorage::getDefaultAccountForMainAccountNum("110110"),
dimensionDefault);
info(strFmt("Default dimension recId: %1", dimensionDefault));
info(strFmt("DefaultDimension (Source RecId): %1 LedgerDimension (Merged RecId): %2", dimensionDefault, ledgerDimensionAccount));
} |
AX 2012: Show RecId of type LedgerDimension as Display valueIn the following code-example a record is selected from table LedgerJournalTrans, than the value of the field LedgerDimension respectively the field OffsetLedgerDimension is converted in the display value, which is display in a so called Segemented entry control.
static void GetLedgerDimensionDisplayValue(Args _args)
{
DimensionStorage dimensionStorage;
DimensionDisplayValue DimensionDisplayValue;
ledgerJournalTrans ledgerJournalTrans = LedgerJournalTrans::findRecId(5637169330, false);
// LedgerDimension
dimensionStorage = DimensionStorage::findById(ledgerJournalTrans.LedgerDimension);
DimensionDisplayValue = dimensionStorage.getComboDisplayValue();
info(DimensionDisplayValue);
// OffsetLedgerDimension
dimensionStorage = DimensionStorage::findById(ledgerJournalTrans.OffsetLedgerDimension);
DimensionDisplayValue = dimensionStorage.getComboDisplayValue();
info(DimensionDisplayValue);
}
Output for example: |
AX 2012: Show financial dimension using display methodFollowing display-method (created in the datasource of the form custtable) shows the financial dimension Costcenter.
public display DimensionValue showCostCenter(CustTable _custTable)
{
DimensionAttributeValueSet dimensionAttributeValueSet;
DimensionAttributeValueSetItem dimensionAttributeValueSetItem;
DimensionAttributeValue dimensionAttributeValue;
DimensionAttribute dimensionAttribute;
#define.CostCenterDimensionName("CostCenter");
if( !_custTable || !_custTable.DefaultDimension)
{
return '';
}
dimensionAttributeValueSet = DimensionAttributeValueSet::find(_custTable.DefaultDimension);
select firstOnly RecId
from dimensionAttributeValueSetItem
where dimensionAttributeValueSetItem.DimensionAttributeValueSet == dimensionAttributeValueSet.RecId
join DimensionAttributeValue
where DimensionAttributeValue.RecId == dimensionAttributeValueSetItem.DimensionAttributeValue
join RecId from dimensionAttribute
where dimensionAttribute.RecId == DimensionAttributeValue.DimensionAttribute
&& dimensionAttribute.Name == #CostCenterDimensionName
if(dimensionAttributeValue && dimensionAttribute)
{
return dimensionAttributeValue.getValue();
}
return '';
}
Simpler version (see comments)
public display DimensionValue showCostCenter(CustTable _custTable)
{
#define.CostCenterDimensionName("CostCenter");
return ((select firstOnly DisplayValue from DefaultDimensionView
where DefaultDimensionView.Name == #CostCenterDimensionName
&& DefaultDimensionView.DefaultDimension == _custTable.DefaultDimension).DisplayValue);
}
|
AX 2012: Enter financial dimension based on an form inputSometimes you have the requirement that a certain financial dimension is to be set on the basis of an input in a form. The following code example is something relatively easy to implement. In the example, whenever a particular field is changed - queried on the method modified() of the field of a DataSource, the financial dimension Costcenter will be filled with the value 25. If the value to be entered an invalid, nothing happens (error message or similar).
public void modified()
{
DimensionAttribute DimensionAttribute = DimensionAttribute::findByName("Costcenter");
DimensionValue newValue = '25'; // New dimension value
super();
dimensionDefaultingController.setDimensionAttributeValue(
DimensionAttribute,
DimensionAttributeValue::findByDimensionAttributeAndValue(DimensionAttribute, newValue).RecId,
newValue);
}
In the example, an existing instance of DimensionDefaultingController used. |
AX 2012: Selecting the values of a financial dimensionThe following job demonstrates how to display the values of a financial dimension - in the example Department - via X++.
static void getValues4Dimension(Args _args)
{
DimensionValueService dimensionValueService;
DimensionContract dimensionContract;
List dimensionValueContractList;
ListEnumerator listEnumerator ;
DimensionValueContract dimensionValueContract;
DimensionValue dimensionValue;
dimensionValueService = new DimensionValueService();
dimensionContract = new DimensionContract();
dimensionContract.parmDimensionName('Department');
dimensionValueContractList = dimensionValueService.getDimensionValues(dimensionContract);
listEnumerator = dimensionValueContractList.getEnumerator();
setPrefix(strFmt("Dimension %1: ", dimensionContract.parmDimensionName()));
while(listEnumerator.moveNext())
{
dimensionValueContract = listEnumerator.current();
dimensionValue = dimensionValueContract.parmValue();
info(dimensionValue);
}
} |
|
|
|
|
|
|
Hide entries

If you only want to display data records of a table that contain certain financial dimensions in a form, you can do this by overwriting the init() of the FormDataSource as follows:
public void init() { super(); SysQuery::addDimensionAttributeRange(salesTable_ds.query(), salesTable_ds.name(), fieldStr(Salestable, DefaultDimension), DimensionComponent::DimensionAttribute, '1001', 'CostCenter'); }You can also call addDimensionAttributeRange() multiple times, so you can filter for multiple dimensions simultaneously.
clearDimensionRangesFromQuery() removes such filters: