Как реализовать нарастающий итог или сумму соседних строк в системе компоновки данных (СКД)

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

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

Использование функции ВычислитьВыражение в ресурсах

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

Сценарий 1: Сумма двух соседних строк

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

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

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

Сценарий 2: Нарастающий итог с начала отчета

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

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

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

Где прописывать выражение: в вычисляемых полях или ресурсах?

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

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

Совет: Если вы хотите, чтобы нарастающий итог отображался и в строках с товаром, и в общих итогах по складу, всегда указывайте формулу на закладке Ресурсы.

Важность правильной сортировки данных

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

Чтобы отчет работал стабильно, рекомендуется использовать шестой параметр функции — Сортировка. Рассмотрим пример:


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

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

Особенности работы с группировками

Часто требуется, чтобы нарастающий итог не шел «сквозняком» через весь отчет, а сбрасывался при переходе к новой группе (например, к новому складу). Для этого используется второй параметр функции — Группировка. Если оставить его пустым, расчет идет в рамках текущей группировки. Если указать конкретное имя (например, "Склад"), расчет будет ограничен рамками этого измерения.

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

ВычислитьВыражение("Сумма(ЕстьNull(Количество, 0))", , , "Первая", "Текущая")

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

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

Реализация в запросе обычно строится на соединении таблицы самой с собой:


ВЫБРАТЬ
    Т1.Номенклатура,
    Т1.Количество,
    СУММА(Т2.Количество) КАК НарастающийИтог
ИЗ
    ВТ_Данные КАК Т1
ЛЕВОЕ СОЕДИНЕНИЕ ВТ_Данные КАК Т2
    ПО Т1.Дата >= Т2.Дата
СГРУППИРОВАТЬ ПО
    Т1.Номенклатура,
    Т1.Количество

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

Резюме по шагам

Подведем итог, как быстро настроить такой отчет:

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

Таким образом, мы получаем мощный и гибкий механизм для создания аналитических отчетов со сложными расчетами, полностью используя потенциал платформы 1С:Предприятие 8.

← На главную