Компонент «Вычисления»

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

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

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

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

  • Вычисленные значения не зависят от отчета в том же смысле, что и данные в отчете без вычисления не зависят от отчета, т.е. отчет – это по-прежнему запрос к базе, где как-то виртуально живут и вычисленные объекты.
  • Но бывают вычисления, которые зависят от отчета – это спец-функции (экстраполяции, «прочее»), и вычисления в клетках отчета (как в Excel)
  • Агрегация и вычисление производятся только в отчетах. В реестрах возможны только простейшие вычисления в одной строчке, см. Формулы в реестрах).
  • Агрегация производится по деревьям и периодам.
  • То, как вычисляется значение данного показателя, определяется свойствами этого показателя – формулами, параметрами агрегации и продолжением по времени.

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

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

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

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

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

Пользователь при записи формул для показателя может указать, какие будут посчитаны до агрегации, а какие после. Примеры, когда агрегацию имеет смысл делать до вычисления формул:

  • Агрегация количества. Например, мы можем при помощи формулы посчитать количество элеваторов в каждом районе. А дальше хотим узнать количество элеваторов в регионе и по всей стране. Для этого нужно агрегировать результат вычислений.
  • Пусть есть показатель «Число статей», который задается функцией КОЛИЧЕСТВО от, например, строкового показателя «Название статьи». Число статей = КОЛИЧЕСТВО (Название статьи). На каждой кафедре (элемент дерева) Ni статей (i – индекс кафедры). Хочется посчитать число статей по факультету (узел того же дерева выше узлов «кафедры»). Агрегировать сразу не получится, т.к. этот показатель расчетный, поэтому необходимо сначала вычислить, а потом уже считать агрегацию.
  • Пусть у нас есть данные по количеству коров (К) и общему надою (Н) для сельхозпредприятий. Мы хотим оперировать вычисляемым показателем удельный надой (УН). УН = Н / К. Применив эту формулу на уровне области, мы будем делить общий надой области на общее количество коров области. Но что, если мы хотим узнать средний надой сельхозпредприятия по области? Тогда нам нужно будет поставить агрегацию в начало – чтобы применять формулу в самом низу дерева.

Расслоения

Расслоение может возникнуть только в одном случае, в пункте (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

Агрегация

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

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

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

  1. Хотим считать А за год как среднее по месяцам (на всех уровнях вуза), потом А для факультета как сумма по кафедрам, А для вуза как сумма по факультетам (для всех периодов).
  2. Хотим считать А для факультета как сумма по кафедрам, А для вуза как сумма по факультетам, потом А за год как сумма по месяцам.
  3. Хотим считать А для вуза за год как среднее по кафедрам и месяцам. А для факультета за год как среднее по кафедрам и месяцам. А для года и кафедры – как среднее по месяцам, а А для вуза и месяца – как среднее по кафедрам, А для факультета и месяца – как среднее по кафедрам.
  4. Хотим считать А за месяц как среднее по дням, А за год как среднее по месяцам.
  5. Хотим считать А за месяц как среднее по дням, А за год как среднее по дням.

Таким образом параметры агрегации можно представить как упорядоченный набор формул вида (<П.i=уровень.i>+) = функция(<П.j=уровень.j>+), например (период=месяц, структура_вуза=вуз) = сумма(период=день, структура_вуза=кафедра), (период=день) = сумма(период=время). При этом наборы показателей справа и слева должны совпадать, т.е. такое запрещено: (структура_вуза=вуз) = среднее(структура_вуза=кафедра, период=месяц). Если один из показателей, по которым идет агрегация, опущен, то считается, что формула задана для всех уровней этого показателя. Т.е. выражение (период=год) = среднее(период=месяц) эквивалентно набору выражений (период=год,структура_вуза=вуз) = среднее(период=месяц,структура_вуза=вуз), (период=год,структура_вуза=факультет) = среднее(период=месяц,структура_вуза=факультет), (период=год,структура_вуза=кафедра) = среднее(период=месяц,структура_вуза=кафедра).

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

Формулы в реестрах

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

Формулы вычисляются без анализа зависимостей и использования только что вычисленных значений.

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

Так сделано из соображений производительности – чтобы вычислять формулы уже после разбивки реестра на страницы.