Как в СКД рассчитать и вывести разницу между иерархическими группами статей в итогах?

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

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

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

Метод 1. Использование флагов в запросе и настройка ресурсов

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

Шаг 1. Модификация текста запроса

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


ВЫБРАТЬ
    Продажи.СтатьяДДС КАК СтатьяДДС,
    Продажи.СуммаОборот КАК СуммаОборот,
    ВЫБОР
        КОГДА Продажи.СтатьяДДС В ИЕРАРХИИ (&СписокСтатей1)
            ТОГДА ИСТИНА
        ИНАЧЕ ЛОЖЬ
    КОНЕЦ КАК ЭтоГруппа1,
    ВЫБОР
        КОГДА Продажи.СтатьяДДС В ИЕРАРХИИ (&СписокСтатей2)
            ТОГДА ИСТИНА
        ИНАЧЕ ЛОЖЬ
    КОНЕЦ КАК ЭтоГруппа2
ИЗ
    РегистрНакопления.ДенежныеСредства.Обороты(&НачалоПериода, &КонецПериода, Авто, ) КАК Продажи

Здесь &СписокСтатей1 и &СписокСтатей2 — это параметры отчета, в которые пользователь (или разработчик) может передать группы или конкретные элементы справочника статей.

Шаг 2. Настройка ресурсов СКД

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

СУММА(ВЫБОР КОГДА ЭтоГруппа1 ТОГДА СуммаОборот ИНАЧЕ 0 КОНЕЦ) - СУММА(ВЫБОР КОГДА ЭтоГруппа2 ТОГДА СуммаОборот ИНАЧЕ 0 КОНЕЦ)

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

Метод 2. Использование функции «ВычислитьВыражение»

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

Рассмотрим алгоритм настройки:

  1. Создадим вычисляемое поле, например, ИтогРазница.
  2. В выражении ресурса для этого поля (в строке «Общий итог») пропишем следующую конструкцию:

ВычислитьВыражение("Сумма(СуммаОборот)", , "ОбщийИтог", "СтатьяДДС В ИЕРАРХИИ (&СписокСтатей1)") 
- 
ВычислитьВыражение("Сумма(СуммаОборот)", , "ОбщийИтог", "СтатьяДДС В ИЕРАРХИИ (&СписокСтатей2)")

Разберем параметры функции:

Метод 3. Добавление «фиктивной» группировки для результата

Часто заказчик хочет видеть не замену общего итога, а отдельную строку в самом низу отчета с названием, например, «Чистый денежный поток». Для этого проанализируем ситуацию и применим метод объединения запросов.

В схеме компоновки данных в основном запросе можно добавить секцию ОБЪЕДИНИТЬ ВСЕ, где мы выберем пустую ссылку на статью, а в поле наименования запишем строку «ИТОГ РАЗНИЦА». Однако более изящный способ — использование «Группировки по полю-константе» в настройках компоновки.

  1. В запросе создадим поле-пустышку: "Разница" КАК ТипСтроки.
  2. В настройках СКД добавим новую группировку по полю ТипСтроки.
  3. Разместим эту группировку в самом низу структуры отчета.
  4. Для этой конкретной группировки на закладке «Ресурсы» зададим ту же формулу разности, что мы рассматривали в первом методе.

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

Метод 4. Работа с характеристиками (для большого количества статей)

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

Проанализируем шаги:

  1. В конфигурации (или через дополнительные сведения) добавим для статей свойство «Категория для итога».
  2. Присвоим группам статей нужные значения: «Группа А» (для уменьшаемого) и «Группа Б» (для вычитаемого).
  3. В СКД подключим эти свойства через механизм характеристик.
  4. Тогда выражение в ресурсах станет максимально лаконичным:

СУММА(ВЫБОР КОГДА КатегорияДляИтога = "Группа А" ТОГДА СуммаОборот КОГДА КатегорияДляИтога = "Группа Б" ТОГДА -СуммаОборот ИНАЧЕ 0 КОНЕЦ)

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

Особенности вывода по месяцам

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

Важно: Если вы отключаете стандартные итоги (например, через настройки компоновки), убедитесь, что вы не скрыли саму область «Общий итог», где должна выводиться ваша формула. Если стандартные итоги не нужны, потому что они просто суммируют все статьи (включая обороты внутри групп, что приводит к двойному счету), лучше использовать метод с отдельной группировкой внизу или настроить расчет ресурса так, чтобы он игнорировал элементы определенного уровня.

Рассмотрим пример использования системного поля Уровень для исключения дублирования:

СУММА(ВЫБОР КОГДА Уровень = 1 ТОГДА СуммаОборот ИНАЧЕ 0 КОНЕЦ)

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

Подводя итог, можно сказать, что наиболее гибким и визуально понятным решением является сочетание флагов в запросе (через В ИЕРАРХИИ) и переопределение выражений ресурсов для группировки «Общий итог».

← На главную