Структура данных финансовых аналитик в DAX 2012 значительно изменилась по сравнению с предыдущими версиями. В DAX 2009 и более ранних версиях каждая таблица, содержащая финансовые аналитики должна была включать поле ‘Dimension’ (массив размерности n). Это применимо к основным таблицам, таким как CustTable, VendTable и т.д., так же как и к таблицам с проводками ГК (LedgerTrans). Аналитики, указанные в CustTable копируются в заголовок заказа (SalesTable), далее в строки заказа (SalesLine), далее при обработке заказа они переносятся в проводки ГК.
В DAX 2012 концепция сохранилась, но реализация сильно отличается. Теперь есть понятие ‘Аналитики по умолчанию’(Default dimensions), которые хранятся в основных таблицах, но не в проводках. Аналитики по умолчанию соответствуют значениям аналитик в проводках ГК, но они хранятся в разных таблицах
Структура таблиц
Ниже приведен пример кода, который отображает аналитики по умолчанию, которые указаны для поставщика (VendTable)
static void ShowVendDefaultDimensions(Args _args)
{
VendTable vendTable;
DimensionAttributeValueSet dimAttrValueSet;
DimensionAttributeValueSetItem dimAttrValueSetItem;
DimensionAttributeValue dimAttrValue;
DimensionAttribute dimAttr;
Common dimensionValueEntity;
;
vendTable = VendTable::find(‘1001’);
//Поиск значения набора аналитик (DimensionAttributeValueSet),
//на которое указывает значение аналитик по
//умолчанию в таблице поставщиков.
//Эта таблица используется в качестве своего рода заголовка, к которому относятся
// записи в таблице DimensionAttributeValueSetItem
dimAttrValueSet = DimensionAttributeValueSet::find(vendTable.DefaultDimension);
// поиск значений всех аналитик
while select dimAttrValueSetItem
where dimAttrValueSetItem.DimensionAttributeValueSet == dimAttrValueSet.RecId
{
//Поиск значения аналитики
dimAttrValue = DimensionAttributeValue::find(dimAttrValueSetItem.DimensionAttributeValue);
//
dimAttr = DimensionAttribute::find(dimAttrValue.DimensionAttribute);
// используем хэлпер класс для получения ссылки на источник
// из которого берутся данные для атрибута
dimensionValueEntity = DimensionDefaultingControllerBase::findBackingEntityInstance(
curext(),
dimAttr,
dimAttrValue.EntityInstance);
info(tableId2name(dimensionValueEntity.TableId));
info(dimAttr.Name + ‘ ‘ + dimAttrValue.getValue());
}
}
Очевидно, это не особенно эффективный код, он расширен ради демонстрации структуры данных.
Ниже представлена диаграмма основных таблиц и отношений между ними
Очень много таблиц. Если раньше мы просто обращались к элементу массива Dimension, то теперь нужно выбирать данные из нескольких связанных таблиц. Причина тому – способ, которым аналитики определены и структурированы в DAX 2012. Если раньше мы имели фиксированное число аналитик, и для добавления новой нужно было изменить значительное количество кода, то теперь достаточно просто добавить новый атрибут, который может ссылаться практически на любые данные (контрагенты, группы номенклатур, данные из структуры компании, склады и т.д.).
В случае, если источником данных для атрибута используется существующая таблица (контрагенты и т.п.) то для такого источника создается view. Например, если создан атрибут ItemGroup и он использует данные из InventItemGroup, будет создан view DimAttributeInventItemGroup
Также существует view, включающий в себя таблицы DimensionAttributeValue и DimensionAttributeValueSetItem. С учетом этого оптимальный код для вывода значение аналитик по умолчанию следующий:
static void ShowVendDefaultDimensions(Args _args)
{
VendTable vendTable;
DimensionAttributeValueSetItemView dimAttrValueSetItem;
DimensionAttributeValue dimAttrValue;
DimensionAttribute dimAttr;
;
vendTable = VendTable::find(‘1001’);
//выборку из таблицы DimensionAttributeValueSet можно пропустить, а напрямую использовать
// vendTable.DefaultDimension
// поиск значений всех аналитик
while select DisplayValue from dimAttrValueSetItem
where dimAttrValueSetItem.DimensionAttributeValueSet == vendTable.DefaultDimension
//выборка атрибута
join Name from dimAttr
where dimAttr.RecId == dimAttrValueSetItem.DimensionAttribute
//значение атрибута
join dimAttrValue
where dimAttrValue.RecId == dimAttrValueSetItem.DimensionAttributeValue
{
info(dimAttr.Name+ ‘ ‘ + dimAttrValue.getValue());
}
}
А для поиска значения конкретной аналитики:
static void ShowVendDefaultDimensions(Args _args)
{
VendTable vendTable;
DimensionAttributeValueSet dimAttrValueSet;
DimensionAttributeValueSetItemView dimAttrValueSetItem;
DimensionAttributeValue dimAttrValue;
DimensionAttribute dimAttr;
Name dimAttributeBU =”BusinessUnit”;
;
vendTable = VendTable::find(‘1001’);
//выборку из таблицы DimensionAttributeValueSet можно пропустить, а напрямую использовать
// vendTable.DefaultDimension
// поиск значений всех аналитик
select DisplayValue from dimAttrValueSetItem
where dimAttrValueSetItem.DimensionAttributeValueSet == vendTable.DefaultDimension
//выборка атрибута
join RecId from dimAttr
where dimAttr.RecId == dimAttrValueSetItem.DimensionAttribute
&& dimAttr.Name == DimAttributeBU
//значение атрибута
join dimAttrValue
where dimAttrValue.RecId == dimAttrValueSetItem.DimensionAttributeValue;
info(dimAttr.Name+ ‘ ‘ + dimAttrValue.getValue());
}
Для установки значения аналитик по умолчанию можно воспользоваться следующим кодом:
//в метод передается старое значанеи аналитик по умолчанию, имя аттрибута который нужно установить и иго //значение
public DimensionDefault CreateDefaultDimension(DimensionDefault _oldDimension, str _dimensionName, str _dimensionValue)
{
DimensionAttributeValueSetStorage valueSetStorage;
DimensionAttribute dimensionAttribute;
DimensionAttributeValue dimensionAttributeValue;
;
//инициализируем экземпляр класса DimensionAttributeValueSetStorage
//старым значением аналитики по умолчанию
valueSetStorage = DimensionAttributeValueSetStorage::find(_oldDimension);
//поиск атрибута по имени
dimensionAttribute = dimensionAttribute::findByName(_dimensionName);
if (dimensionAttribute)
{
if (_dimensionValue != “”)
{
//поиск значения атрибута, если его не существует, то он будет создан
dimensionAttributeValue = dimensionAttributeValue::findByDimensionAttributeAndValue(dimensionAttribute,_dimensionValue,false,true);
//добавим новое значение атрибута в набор
valueSetStorage.addItem(dimensionAttributeValue);
}
}
//сохраним набор значений атрибутов и вернем новое значение аналитики по умолчанию
return valueSetStorage.save();
}
Формы
Класс DimensionDefaultingController используется во всем приложении для обработки отображение аналитик по умолчанию на основных таблицах (клиент, поставщик и т.д.). Если вы посмотрите на код в следующей трассировке стека, вы увидите логику, аналогичную примеру в начале этого поста.
DimensionDefaultingController создается в форме, принимая источник данных и поле (которое в большинстве случаев будет DimensionDefault). На событии active источника данных, контроллер перебирает соответствующее значение набора аналитик и обновляет элементы управления.
Добавить комментарий
Для отправки комментария вам необходимо авторизоваться.