Общая информация про вычисления

Компонент «Вычисления» обеспечивает поддержку расчетов и работы с вычисленными значениями показателей.

Виды вычислений

В NetDB есть несколько видов вычислений:

Вычисления в отчете сводятся к независимым вычислениям для каждой клетки отчета. Источник значений и наложенные на него фильтры (фильтры данной строки, данного столбца и внешние фильтры отчета) определяют запрос на вычисление значения.

Интерпретация

Каждый показатель в системе можно интерпретировать как функцию, от своих аналитических признаков.

Допустим, у нас есть подневные данные по продажам товаров в сети магазинов (для простоты подразумеваем, что каждая запись - продажа одной единицы товара):

Сумма продажи - Товар - Магазин - Период

Тогда можно считать, что показатель Сумма продажи (S) - это функция от трех переменных Товар (p), Магазин (m), Период (t): S(p,m,t). В таком случае, если у нас есть объект вида

Сумма продажи = 50, Товар = «Товар1», Магазин = «Mагазин1», Период = «10.01.2019», то S(p = «Товар1», m = «Магазин1»,t = «10.01.2019») = 50.

В такой интерпретации, фильтр Товар = «Товар1» в заголовке столбца (строки) отчета, подставляет в переменную p значение «Товар1» во всех ячейках этого столбца (строки):

  Магазин = «Магазин1» Магазин = «Магазин1» Магазин = «Магазин2»
  Период = «10.01.2019» Период = «11.01.2019» Период = «10.01.2019»
Товар = «Товар1» S(«Товар1», «Магазин1», «10.01.2019») S(«Товар1», «Магазин1», «11.01.2019») S(«Товар1», «Магазин2», «10.01.2019»)
Товар = «Товар2» S(«Товар2», «Магазин1», «10.01.2019») S(«Товар2», «Магазин1», «11.01.2019») S(«Товар2», «Магазин2», «10.01.2019»)

По умолчанию, для того чтобы функция S был определена для каких-то значений переменных, должен существовать объект с этими значениями всех признаков.

Далее, рассмотрим пример формулы, вычисляющей процент продаж конкретного товара относительно всех остальных товаров в заданном магазине, в заданный период времени. Показатель Процент продаж товара (R) вычисляется по следующей формуле:

\[R(p,m,t) = 100 * S(p,m,t) / \sum_{i} S(p_i,m,t)\]

Как мы видим, в этой формуле переменные m и t одинаково используются во всех функциях. Поэтому в записи вычислений их можно опустить. Соответствующая формула в NetDB будет выглядеть следующим образом:

Процент продаж товара при Товар = X = 100 * Сумма продажи при Товар = Х / СУММА ( Сумма продажи )

В этой формуле мы использовали свободную переменную. То есть, мы в явном виде задали, как работать с признаком Товар для вычисления функции. Остальные переменные просто пробрасываются во все аргументы формулы автоматически.

Теперь представим что у нас есть показатель Закупочная цена товара (K(p)), по всем товарам. Можем вычислить Прибыль:

\[U(m,t) = \sum_{i} (S(p_i,m,t)-K(p_i))\]

И в терминологии NetDB:

Прибыль при Магазин = X и Период = Y = СУММА ( Сумма продажи при Магазин = X и Период = Y - Закупочная цена товара , Товар)

Здесь с помощью второго аргумента для функции СУММА мы в явном виде указали, что суммирование идет по признаку Товар.

Во всех вышеуказанных примерах подразумевается, что может быть только одна продажа товара в день. На практике же на самом деле необходимо будет либо обернуть аргументы Сумма продажи в дополнительную фунцию СУММА, либо (что более правильно) создать сначала показатель Общая сумма продаж = СУММА (Сумма продажи) и работать уже с ним.

Итого: с помощью формул в NetDB мы задаем способ вычисления значения показатели при определенном наборе значений его аналитических признаков. Все признаки, не указанные в формуле в явном виде, будут автоматически «пробрасываться» в аргументы формулы. В левой части формулы мы задаем область ее применимости, т.е. при каких условиях ее применять.

Порядок вычислений

При вычислении значения при заданных фильтрах и источнике производится:

  1. Поиск значения в базе. Если значения в базе нет, =>
  2. Поиск продолженного значения (только введенного). Если продолженного нет, =>
  3. Вычисления в порядке, заданном пользователем для этого показателя. Сначала применяется первая формула, или агрегация. Если есть формула, левая часть которой совместима с фильтрами клетки, то вычисляются все ее аргументы, вызывая рекурсивно те же три пункта, но уже для других значений фильтров и источника – с учетом фильтров и источника аргумента формулы. Если вычислить эту формулу не получилось (нет данных), то осуществялется переход к следующей формуле. Для агрегации все происходит также – последовательный спуск вниз по каждому из параметров агрегации, начиная с последнего параметра.

Таким образом, введенные значения имеют больший приоритет (см. Корректировка), а сам процесс вычисления значения для показателя может быть достаточно сложным – вычисления и агрегация могут перемежаться, постепенно спускаясь вниз. Но для каждой клетки значение всегда получено понятным образом – по одной из формул или агрегацией через значения в других клетках, соответствующих аргументам формулы или ниже расположенным по одному из деревьев узлам. Здесь под клеткой понимается некоторый набор фильтров и источник – эта клетка не обязательно присутствует в отчете.

Расслоения

Расслоение может возникнуть только в одном случае, в пункте (1) выше описанного алгоритма – если условиям фильтров удовлетворяет несколько введенных значений. При самих вычислениях расслоение возникнуть не может - даже если есть несколько формул, всегда берется первая из них, по которой получилось что-то посчитать. А если есть введенное значение, то формулы не применяются.

В результате нет необходимости обращать внимание на признаки значения, если они не приводят к расслоению. У вычисленного значения не будет всех признаков введенных значений - только те признаки, которые необходимы в силу фильтров.

Расслоения можно избежать двумя способами:

  1. Добавить фильтры, чтобы «уточнить» объект.

    Например, есть реестр с показателями «Организация», «Сумма по контракту» и «Период».

    _images/stratification_1.PNG

    В столбце отчета задан показатель-источник «Сумма по контракту», в заголовках строк - фильтры по показателю «Организация». В строке, соответствующей организации «Организация 1», происходит расслоение по показателю «Период»:

    _images/stratification_2.PNG

    Чтобы избавиться от расслоения, нужно добавить фильтр по показателю «Период».

    _images/stratification_3.PNG

    Теперь в отчете отображаются только данные за определенный отчетный период:

    _images/stratification_4.PNG
  2. Использовать «жадные» функции, чтобы «свернуть» несколько объектов в одно значение.

    Чтобы избежать расслоения, нужно создать и вывести в отчет новый показатель «Общая сумма по контракту», который будет суммировать значения показателя «Сумма по контракту» за несколько отчетных периодов.

    _images/stratification_8.PNG

    Теперь в отчете отображаются данные об общих объемах финансирования, освоенных организациями за несколько лет выполнения контракта.

    _images/stratification_7.PNG

Агрегация

Агрегация показателя задает, как он вычисляется по древовидным аналитическим признакам или по периодам, если задан для дочерних узлов, но не задан для родительского.

В простейшем случае агрегация – это суммирование, однако часто есть необходимость агрегировать с помощью других функций, которые могут иметь разные значения в зависимости от того, в каком порядке их применять (например, функция «среднее»).

Допустим у нас есть показатель A, с аналитическими признаками период и структура_вуза. При этом структура_вуза это показатель, берущий значения из древовидного справочника, вида

- вуз
- - факультет 1
- - - кафедра 1.1
- - - кафедра 1.2
- - факультет 2
- - - кафедра 2.1
- - - кафедра 2.2

Данные в него вводятся по месяцам, для каждой кафедры.

Ниже преведены несколько примеров различных вариантов агрегации показателя А по периоду и древовидной структуре вуза:

  1. Чтобы считать А за год как среднее по месяцам (на всех уровнях вуза), потом А для факультета как сумма по кафедрам, А для вуза как сумма по факультетам (для всех периодов):

    А (период=год) = СРЕДНЕЕ (A (период=месяц)); A (структура_вуза=x) = СУММА (A (структура_вуза.родитель=x));

  2. Чтобы считать А для вуза за год как среднее по кафедрам и месяцам. А для факультета за год как среднее по кафедрам и месяцам. А для года и кафедры – как среднее по месяцам, а А для вуза и месяца – как среднее по кафедрам, А для факультета и месяца – как среднее по кафедрам:

    А (период=год, структура_вуза=вуз) = СРЕДНЕЕ (A (период=месяц, структура_вуза.родитель.родитель=вуз)); А (период=год, структура_вуза=x) = СРЕДНЕЕ (A (период=месяц, структура_вуза.родитель=x)); A (период=год) = СРЕДНЕЕ (A (период=месяц)); A (структура_вуза=x) = СРЕДНЕЕ (A (структура_вуза.родитель.родитель=x)); A (структура_вуза=x) = СРЕДНЕЕ (A (структура_вуза.родитель=x));

Таким образом параметры агрегации можно представить как упорядоченный набор формул. Обратите внимание, что если не указать аналитический признак в левой части формулы, то формула будет считатся подходящей для любого значения этого признака и он «пробросится» в правую часть.

Т.е. выражение (период=год) = среднее(период=месяц) эквивалентно набору выражений

(период=год,структура_вуза=вуз) = среднее(период=месяц,структура_вуза=вуз);

(период=год,структура_вуза=факультет) = среднее(период=месяц,структура_вуза=факультет);

(период=год,структура_вуза=кафедра) = среднее(период=месяц,структура_вуза=кафедра).

Раскрытие вычислений

По любому вычисленному значению в отчете, форме или реестре, можно кликнуть и получить информацию о вычислении данного значения. При раскрытии видно по какой формуле, из каких показателей вычислено данное значение а также значения всех этих показателей. Если в свою очередь они являются вычисленными, то можно «провалиться» в вычисления дальше, вплоть для исходных объектов. Для «жадных» функций также доступен реестр с перечнем всех объектов, на основании которых вычислено исходное значение.

Корректировка значений

Если в NetDB существует фактическое значение, удовлетворяющее фильтрам отчета, но для показателя задана формула, позволяющая вычислить это значение - система воспринимает это как корректировку вычисленного значения. При этом, такая ячейка с двумя значениями будет подсвечена желтым цветом, а при наведении на нее курсора мыши будет появляться подсказка о том, что значение было откорректировано и будет указываться вычисленное значение. Если вычисленное и откорректированное значения совпадают, ячейка будет подсвечена бледно-желтым цветом, если различаются — ярко-желтым. Если в форме в ячейке присутствует вычисленное значение, пользователь может ввести вместо него другое, тогда в системе появится соответствующий фактический объект. Если же введенное значение в точности совпадает с вычисленным - отдельный объект не сохранится. Этот функционал называется корректировкой, т.к. веденное значение имеет приоритет над вычисленным и во всех вычислениях, где скорректированный показатель является аргументом, будет использовано введенное значение. Например, если взять такие значения показателя A (см. Агрегация):

А(период=январь 2019 г., структура_вуза=кафедра 1.1) = 7
А(период=январь 2019 г., структура_вуза=кафедра 1.2) = 5
А(период=январь 2019 г., структура_вуза=кафедра 2.1) = 14

И устновить для него формулу агрегации:

A (структура_вуза=x) = СУММА (A (структура_вуза.родитель=x));

Тогда вычисленное значени:

А(период=январь 2019 г., структура_вуза=вуз) = 26

Но если дополнительно ввести значение:

А(период=январь 2019 г., структура_вуза=факультет 1) = 30

То, это же вычисленное:

А(период=январь 2019 г., структура_вуза=вуз) = 44

Этот эффект возникает, потому что согласно заданной формуле мы спускаемся по одному уровню по структура_вуза за итерацию. Обратите внимание, что здесь очень важен порядок вычислений. Если при тех же фактических данных мы зададим для А такие формулы:

A (структура_вуза=x) = СУММА (A (структура_вуза.родитель=x));
A (период=год) = СУММА (A (период=месяц));

То:

А(период=2019 г., структура_вуза=вуз) = 26

Если же формулы будут в другом порядке:

A (период=год) = СУММА (A (период=месяц));
A (структура_вуза=x) = СУММА (A (структура_вуза.родитель=x));

То:

А(период=2019 г., структура_вуза=вуз) = 44