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