При разработке отчетов на системе компоновки данных (СКД) программисты часто сталкиваются с задачей расчета относительных показателей, таких как процент наценки, доля в выручке или прирост продаж. Типичная ошибка заключается в том, что в итогах по группировкам (например, по Контрагенту или Складу) система просто суммирует проценты, рассчитанные для детальных записей, что математически неверно. Рассмотрим, как настроить отчет так, чтобы на уровне группировок расчет производился по формуле, а не простым суммированием.
Представим ситуацию: у нас есть две позиции номенклатуры. Для первой прирост составил 50%, для второй — 100%. Если СКД просто сложит эти значения в группировке по контрагенту, мы получим 150%, что вводит пользователя в заблуждение. Правильный подход — сначала просуммировать продажи за оба периода по всем товарам контрагента, а затем применить формулу расчета прироста к этим итоговым суммам.
Попытка прописать формулу вида (СУММА(Продажа2) - СУММА(Продажа1)) / СУММА(Продажа1) * 100 непосредственно в Вычисляемых полях часто приводит к ошибке: "Использование вложенных агрегатных функций не допускается". Это происходит потому, что поле, уже содержащее агрегаты (СУММА), система пытается повторно агрегировать при создании ресурсов.
Начнем с настройки запроса. Для того чтобы СКД "видела" поле, по которому мы будем считать итоги, нам нужно либо добавить его в запрос, либо создать вычисляемое поле. Как показывает практика, более "чистым" методом является создание вычисляемого поля с пустым выражением или добавление поля-пустышки в запрос.
Проанализируем пример добавления поля в запросе:
ВЫБРАТЬ
Продажи.Контрагент КАК Контрагент,
Продажи.Номенклатура КАК Номенклатура,
Продажи.СуммаОборот1 КАК ПродажаЗаПериод1,
Продажи.СуммаОборот2 КАК ПродажаЗаПериод2,
0 КАК Прирост
ИЗ
РегистрНакопления.Продажи.Обороты(&Начало1, &Конец1, , ) КАК Продажи
Добавление 0 КАК Прирост позволяет нам определить типизацию поля и сделать его доступным в списке полей компоновки еще до настройки ресурсов.
Если мы не хотим менять запрос, перейдем на вкладку Вычисляемые поля. Здесь важно оставить колонку "Выражение" пустой или указать в ней просто имя поля. Основная магия будет происходить на следующей вкладке. Помните: не пишите формулы с агрегатными функциями (СУММА, СРЕДНЕЕ) в вычисляемых полях, если планируете использовать это поле в итогах.
Это самый важный этап. Переходим на вкладку Ресурсы. Именно здесь мы укажем системе, как именно нужно вычислять "Прирост" для каждого уровня группировки и для общего итога.
Добавим наше поле Прирост в список ресурсов. В колонке "Выражение" напишем формулу, используя агрегатные функции к исходным данным. Также крайне важно добавить проверку на деление на ноль, иначе отчет может завершиться с ошибкой при отсутствии продаж в первом периоде.
Рассмотрим правильное выражение для ресурса:
ВЫБОР
КОГДА СУММА(ПродажаЗаПериод1) = 0
ТОГДА 0
ИНАЧЕ (СУММА(ПродажаЗаПериод2) - СУММА(ПродажаЗаПериод1)) / СУММА(ПродажаЗаПериод1) * 100
КОНЕЦ
Обратите внимание: мы используем СУММА(ПродажаЗаПериод1). Это заставляет СКД сначала вычислить итог продаж по текущей группировке (например, по Контрагенту), а уже потом подставить этот итог в формулу расчета процентов.
В настройках ресурса есть колонка "Рассчитывать по...". По умолчанию расчет идет по всем доступным группировкам и общим итогам. Если вам нужно, чтобы на уровне детальных записей (номенклатуры) прирост считался иначе, или вы вообще хотите скрыть его для определенных уровней, вы можете добавить поле в ресурсы несколько раз.
Разберем ситуацию, когда нам нужны разные формулы:
Контрагент указываем общую формулу процента.Общего итога указываем ту же формулу (она рассчитает процент по всей компании).Детальных записей формула не нужна, просто не добавляйте их в список "Рассчитывать по".Поскольку процент прироста часто бывает отрицательным, полезно настроить Условное оформление. Выясним, как выделить отрицательные показатели:
Прирост Меньше 0.Цвет текста: Красный.Прирост.Также не забудьте настроить формат поля. Для процентов в ресурсах лучше указать ЧДЦ=2 (два знака после запятой) в колонке "Оформление" на вкладке "Наборы данных" или непосредственно в настройках отчета.
Если логика расчета прироста очень сложная (например, требует обращения к другим данным или специфических алгоритмов округления), мы можем вынести расчет в Общий модуль. Рассмотрим пример вызова серверной функции из ресурса СКД:
МойСерверныйМодуль.РассчитатьПроцент(СУММА(ПродажаЗаПериод1), СУММА(ПродажаЗаПериод2))
Важные условия для работы такого метода:
Экспортная.Сервер, Внешнее соединение.Для корректного вывода относительных показателей в группировках СКД:
СУММА, КОЛИЧЕСТВО) внутри формул ресурсов.ВЫБОР.Следуя этой методике, вы получите математически верные итоги, которые будут корректно пересчитываться при любом изменении структуры группировок пользователем в режиме "1С:Предприятие".