Как в отчете СКД вычесть общий итог из значения детальной записи?

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

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

Анализ механизма работы СКД

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

Решение через функцию ВычислитьВыражение

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

Синтаксис функции выглядит следующим образом:

ВычислитьВыражение(Выражение, Группировка, ТипРасчета)

Чтобы получить значение общего итога в каждой строке детальной записи, мы будем использовать следующую формулу:

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

Разберем параметры подробнее:

  1. Первый параметр: Мы указываем агрегатную функцию Сумма от нашего поля. Это то значение, которое мы обычно видим в подвале отчета в колонке «Итого».
  2. Второй параметр: Оставляется пустым. Это указывает системе, что расчет производится для текущей группировки (в данном случае — для всего набора данных).
  3. Третий параметр: Строка "ОбщийИтог". Это критически важный параметр. Он сообщает СКД, что выражение должно быть рассчитано не по текущей строке или текущей группе, а по всем записям, входящим в отчет.

Теперь, чтобы найти отклонение, мы просто вычитаем это выражение из значения текущей строки. Итоговая формула для вычисляемого поля будет выглядеть так:

ВремяВСекундах - ВычислитьВыражение("Сумма(ВремяВСекундах)", , "ОбщийИтог")

Пошаговая настройка в схеме компоновки данных

Теперь выясним, куда именно нужно вписать эти выражения, чтобы отчет заработал корректно. У нас есть два пути, и мы рассмотрим каждый из них.

Вариант 1: Использование вкладки «Вычисляемые поля»

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

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

Вариант 2: Настройка через вкладку «Ресурсы» (рекомендуемый)

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

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

Обработка пустых значений (NULL)

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

Модернизированная формула будет выглядеть так:


ЕСТЬNULL(ВремяВСекундах, 0) - ВычислитьВыражение("Сумма(ЕСТЬNULL(ВремяВСекундах, 0))", , "ОбщийИтог")

Расчет отклонения от итогов родительской группы

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

Рассмотрим пример, где нужно получить сумму по родительской группировке:


Сумма(ВремяВСекундах) - ВычислитьВыражение("Сумма(ВремяВСекундах)", "ИмяВашейРодительскойГруппировки")

Здесь во втором параметре указывается имя группировки, заданное в настройках СКД. Это позволяет делать отчеты более информативными и многоуровневыми.

Использование макетов оформления

В обсуждениях на форумах иногда упоминается работа с «адресами ячеек». Этот метод подразумевает создание собственного Макета для отчета. Мы можем создать макет области итогов и макет детальных записей, присвоить им имена параметров и затем программно или через выражения макета вычислять разницу. Однако, это путь максимального сопротивления. Использование встроенных функций языка выражений СКД (таких как ВычислитьВыражение) считается «лучшей практикой» (best practice), так как такой отчет гораздо проще поддерживать, и он сохраняет гибкость при изменении настроек пользователем.

Важные нюансы оформления

Посмотрим на финальные штрихи оформления отчета:

  1. Формат данных: Если результат вычисления отклонения получается дробным (например, при использовании среднего), настройте «Формат» в свойствах поля на вкладке «Наборы данных» или «Вычисляемые поля», ограничив количество знаков после запятой.
  2. Условное оформление: Очень полезно выделить отрицательные отклонения красным цветом. В настройках отчета на вкладке «Условное оформление» добавьте правило: если Отклонение < 0, то цвет текста — Красный.
  3. Порядок расчета: Помните, что СКД при использовании "ОбщийИтог" фактически делает дополнительный проход по данным. На очень больших объемах данных (миллионы строк) это может незначительно повлиять на производительность, но для большинства стандартных отчетов это влияние неощутимо.

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

← На главную