Как правильно использовать функцию ВычислитьВыражение() для вывода нарастающего итога в отчете СКД

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

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

Разбор основной ошибки: ресурсы против вычисляемых полей

Рассмотрим ситуацию, с которой столкнулся автор темы. В схеме компоновки данных было создано вычисляемое поле, но его выражение в списке полей было оставлено пустым. При этом в закладке Ресурсы была прописана магическая формула с использованием ВычислитьВыражение(). Логика разработчика понятна: "Я хочу итог, значит, иду в ресурсы". Однако здесь кроется фундаментальная особенность работы СКД.

Проанализируем, как СКД обрабатывает данные. Система разделяет вывод на два уровня:

  1. Детальные записи: это самые нижние строки отчета, где выводятся значения напрямую из полей набора данных или вычисляемых полей.
  2. Группировки и итоги: здесь работают агрегатные функции, и именно здесь СКД обращается к закладке Ресурсы.

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

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

Пошаговая настройка нарастающего итога

Рассмотрим по шагам правильный процесс настройки на примере расчета прибыли (Доход - Расход) с накоплением:

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

ВычислитьВыражение("Сумма(Доход - Расход)", , , "Первая", "Текущая")

2. Перейдем на закладку Ресурсы. Выберем наше поле ПрибыльНарастающимИтогом. В выражении ресурса укажем точно такое же выражение или просто Сумма(ПрибыльНарастающимИтогом), если вы хотите, чтобы в итогах группировок выводилось последнее накопленное значение.

3. На закладке Настройки добавим это поле в Выбранные поля. Теперь в отчете данные появятся и в строках, и в итогах.

Глубокое погружение в параметры функции ВычислитьВыражение()

Для свободного владения инструментом разберем параметры функции более подробно. Синтаксис выглядит так: ВычислитьВыражение(Выражение, Группировка, ТипРасчета, Начало, Конец, Упорядочивание).

Параметр 1: Выражение. Здесь мы указываем, что именно нужно считать. Важно понимать, что внутри этой функции можно использовать другие агрегатные функции, такие как Сумма(), Количество(), Максимум().

Параметр 2: Группировка. Если оставить его пустым, расчет идет в контексте текущей группировки. Если написать "Общая", расчет пойдет по всему отчету без учета иерархии групп. Если указать имя конкретной группировки (например, "Номенклатура"), нарастающий итог будет сбрасываться при переходе к новой группе.

Параметры 3 и 4: Начало и Конец (Границы окна). Для классического нарастающего итога мы используем значения "Первая" и "Текущая". Это заставляет систему суммировать значения от самой первой записи в выборке до текущей строки включительно.

Параметр 6: Упорядочивание. Это критически важный параметр, о котором часто забывают. Нарастающий итог напрямую зависит от порядка записей. Если пользователь в настройках отчета изменит сортировку, математический смысл нарастающего итога может нарушиться. Чтобы этого избежать, в шестом параметре рекомендуется явно указывать поле сортировки, например:


ВычислитьВыражение("Сумма(СуммаОборот)", , , "Первая", "Текущая", "ПериодСекунда Возр")

Проблема пустых значений (NULL)

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

Посмотрим на безопасный вариант написания выражения:


ВычислитьВыражение("Сумма(ЕстьNULL(Доход, 0) - ЕстьNULL(Расход, 0))", , , "Первая", "Текущая")

Использование функции ЕстьNULL гарантирует, что отсутствие данных в одной из колонок не "обнулит" весь нарастающий итог строки.

Альтернативы и производительность

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

Если вы заметили падение производительности, проанализируем альтернативные варианты:

  1. Расчет в запросе: Использование временных таблиц и соединения таблицы самой с собой по условию Т1.Период <= Т2.Период. Это перенесет нагрузку на СУБД, что зачастую работает быстрее.
  2. Системные поля: Если вам нужна просто нумерация строк, не используйте сложные выражения. Для этого в СКД предусмотрены функции ПорядковыйНомер() или НомерВГруппировке(), которые работают значительно эффективнее.

Особенности работы с иерархией

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

В таких случаях при вычислении выражения стоит проверять тип записи. Рассмотрим пример, где мы исключаем иерархические уровни из расчета:


ВычислитьВыражение("Сумма(Выбор Когда СистемныеПоля.Уровень = 0 Тогда СуммаОборот Иначе 0 Конец)", , , "Первая", "Текущая")

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

← На главную