Структура данных аналитик по умолчанию (Default dimension) в DAX 2012

Category: Статьи Post Date: 01.04.2020

Структура данных финансовых аналитик в DAX 2012 значительно изменилась  по сравнению с предыдущими версиями. В DAX 2009 и более ранних версиях каждая таблица, содержащая  финансовые аналитики должна была включать поле ‘Dimension’ (массив размерности n). Это применимо к основным таблицам, таким как CustTableVendTable и т.д., так же как и к таблицам с проводками ГК (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 источника данных, контроллер перебирает соответствующее значение набора аналитик  и обновляет элементы управления.

Подписывайтесь на канал @d365neti в Telegram

Подписаться

Добавить комментарий