Как в отчете СКД рассчитать разницу прихода и расхода в строке общий итог

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

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

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

Почему СКД складывает приход и расход в общем итоге

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

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

Настройка раздельного расчета ресурсов для общего итога

Для корректного получения конечного сальдо в строке итогов необходимо переопределить формулу расчета ресурса для уровня Общий итог. Рассмотрим пошаговый алгоритм решения задачи:

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

Посмотрим на пример правильного выражения для общего итога:


СУММА(ВЫБОР 
    КОГДА ВидДвижения = ЗНАЧЕНИЕ(ВидДвиженияНакопления.Приход)
        ТОГДА СуммаБУ
    ИНАЧЕ 0
КОНЕЦ) - СУММА(ВЫБОР
    КОГДА ВидДвижения = ЗНАЧЕНИЕ(ВидДвиженияНакопления.Расход)
        ТОГДА СуммаБУ
    ИНАЧЕ 0
КОНЕЦ)

Важный нюанс: в языке выражений СКД обращение к предопределенным значениям перечислений и системных типов выполняется через конструкцию ЗНАЧЕНИЕ(...). Сравнение вида движения со строковым литералом (например, ВидДвижения = "Приход") является ошибкой и приведет к тому, что условие не сработает и итог останется пустым или нулевым.

Особенности работы с нарастающими (накопительными) итогами

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


ВычислитьВыражение("Сумма(СуммаБУФакт)", "ДатаДвижения.ЧастиДат.НазваниеМесяца", , "Первая", "Текущая")

Если попытаться рассчитать итоговую строку для такого поля через стандартную функцию СУММА, платформа выполнит сложение всех накопленных сумм за каждый месяц (Январь + (Январь + Февраль) + (Январь + Февраль + Март)...), что приведет к неверным многократно завышенным значениям.

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

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

ВычислитьВыражение("Сумма(ВЫБОР КОГДА ВидДвижения = ЗНАЧЕНИЕ(ВидДвиженияНакопления.Приход) ТОГДА СуммаБУФакт ИНАЧЕ -СуммаБУФакт КОНЕЦ)", , , "Последняя", "Последняя")

Альтернативные архитектурные решения

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

  1. Формирование знаковых оборотов в запросе набора данных: на уровне SQL-запроса вычисляются явные поля прихода, расхода и итогового знакового оборота:
    
    ВЫБОР
        КОГДА Регистр.ВидДвижения = ЗНАЧЕНИЕ(ВидДвиженияНакопления.Приход) ТОГДА Регистр.Сумма
        ИНАЧЕ -Регистр.Сумма
    КОНЕЦ КАК ЗнаковыйОборот
    
    В этом случае нарастающий итог и общий итог строятся по полю ЗнаковыйОборот стандартным суммированием без условных конструкций в СКД.
  2. Использование виртуальной таблицы «ОстаткиИОбороты»: для регистров накопления оптимальным решением является выборка данных из виртуальной таблицы ОстаткиИОбороты с указанием периодичности (например, МЕСЯЦ). В настройках полей набора данных СКД достаточно назначить роли НачальныйОстаток и КонечныйОстаток, после чего платформа автоматически корректно рассчитает все промежуточные и общие итоги.
← На главную