Как в СКД поделить итоговое значение на детальное и использовать итоги в расчетах строк

Программист 1С v8.3 (Управляемые формы) Управленческий учет
← На главную

При разработке отчетов на базе Системы компоновки данных (СКД) часто возникает задача, когда в каждой детальной строке необходимо оперировать данными, которые еще только будут рассчитаны в итогах. Типичный пример: расчет доли каждой строки в общем объеме или, как в нашем случае, умножение количества из детальной записи на среднюю цену, вычисленную по всему отчету (общая выручка / общее количество). Рассмотрим детально, как реализовать этот механизм, используя встроенные функции СКД.

Разбор основной проблемы и выбор инструмента

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

Многие начинающие разработчики пытаются добавить такие поля на вкладку Вычисляемые поля. Однако это ошибка: вычисляемые поля на этой вкладке работают на уровне записей набора данных и «не знают» об итогах. Правильный подход — использование вкладки Ресурсы.

Реализация расчета через ресурсы

Рассмотрим пошагово, как настроить формулу, чтобы получить нужный результат. Допустим, у нас есть поля Выручка и Количество. Нам нужно новое поле, назовем его РасчетныйПоказатель.

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


Количество * ВычислитьВыражение("Сумма(Выручка) / Сумма(Количество)", "ОбщийИтог")

Разберем параметры функции ВычислитьВыражение, которые мы применили:

Почему может выводиться пустое поле и как это исправить

Проанализируем ситуацию, когда вместо ожидаемых цифр отчет выдает пустые значения. Это происходит из-за особенностей обработки NULL и деления на ноль в 1С. Если в какой-то из дат не было продаж (количество равно 0), результат всего выражения может стать неопределенным.

Чтобы избежать этой проблемы, применим функцию ЕСТЬNULL и добавим проверку на нулевой делитель. Модифицируем нашу формулу в ресурсах следующим образом:


ЕСТЬNULL(Количество, 0) * ВычислитьВыражение("Выбор Когда Сумма(Количество) = 0 Тогда 0 Иначе Сумма(Выручка) / Сумма(Количество) Конец", "ОбщийИтог")

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

Настройка области расчета ресурса

Важным нюансом является настройка колонки Рассчитывать по... в таблице ресурсов. Для корректной работы нашего механизма:

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

Использование контекста родительских группировок

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

Выясним, как это выглядит на практике. Если у вас есть группировка по полю Склад, формула будет выглядеть так:

Количество / ВычислитьВыражение("Сумма(Количество)", "Склад")

Система найдет итоговую сумму количества именно по тому складу, в который входит текущая детальная запись, и произведет деление. Это мощный инструмент для создания аналитических отчетов со структурным анализом.

Продвинутый метод: ВычислитьВыражениеСГруппировкойМассив

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

Посмотрим на пример, где нам нужно найти среднюю выручку среди всех магазинов и вывести ее в каждой строке:

Среднее(ВычислитьВыражениеСГруппировкойМассив("Сумма(Выручка)", "Магазин"))

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

← На главную