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

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

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

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

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

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

По умолчанию агрегатные функции для числовых ресурсов рассчитываются снизу вверх — от записей-листьев к родительским узлам. Если в наборе данных присутствует строка, где в качестве статьи указана группа справочника (с признаком ЭтоГруппа = Истина), платформа воспринимает ее как непосредственную детальную запись. Чтобы показать ее значение, СКД строит узел иерархии с именем папки, а внутрь помещает саму запись. В результате в отчете отображается строка-папка, а под ней — вложенная строка с точно таким же наименованием и выведенной суммой.

Способ 1. Объединение запросов вместо соединений

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

Наиболее надежный архитектурный подход — построение единого набора данных с помощью конструкции ОБЪЕДИНИТЬ ВСЕ, где плановые показатели по группам и фактические показатели по элементам разделяются по отдельным ресурсным колонкам.

Посмотрим на пример текста запроса:


ВЫБРАТЬ
    ПланЗатратСписокОпераций.СтатьяЗатрат КАК СтатьяЗатрат,
    ПланЗатратСписокОпераций.Сумма КАК СуммаПлан,
    0 КАК СуммаФакт
ИЗ
    Документ.ПланЗатрат.СписокОпераций КАК ПланЗатратСписокОпераций
ГДЕ
    ПланЗатратСписокОпераций.Ссылка.Проект В(&Проект)

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
    Авансы.СтатьяЗатрат КАК СтатьяЗатрат,
    0 КАК СуммаПлан,
    Авансы.Сумма КАК СуммаФакт
ИЗ
    Документ.Авансы КАК Авансы
ГДЕ
    Авансы.Проект В(&Проект)

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

Способ 2. Настройка вычисления ресурсов по группировкам

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

Разберем по шагам настройку выражений:

  1. Добавим поле СуммаПлан на вкладку Ресурсы.
  2. В колонке Рассчитывать по... укажем конкретную группировку: СтатьяЗатрат Иерархия.
  3. Для суммирования планового значения по группе применим формулу с проверкой на пустые значения: Максимум(ЕстьNull(СуммаПлан, 0)) или Сумма(ЕстьNull(СуммаПлан, 0)) в зависимости от того, размножаются ли строки в выборке.
  4. Создадим вычисляемое поле СуммаИтоговая и настроим для него ресурс с выражением, которое будет на уровне иерархии объединять групповой показатель и сумму детальных записей: Сумма(ЕстьNull(СуммаФакт, 0)) + Максимум(ЕстьNull(СуммаПлан, 0)).

Способ 3. Исключение детальных дублей через отбор по родителю

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

Рассмотрим подробнее логику настройки отбора:

  1. Дублирующая строка возникает тогда, когда детальная запись выводится под родителем, совпадающим с ней самой (или когда запись группы выводится на детальном уровне).
  2. Для группировки по иерархии накладываем условие отбора на поле СтатьяЗатрат.Родитель или используем признак СтатьяЗатрат.ЭтоГруппа.
  3. Если необходимо скрыть вывод детальной строки самой группы, установим условие отбора для детальных записей группировки: СтатьяЗатрат.ЭтоГруппа Равно Ложь. При этом на уровне папки сохранятся агрегированные данные, а вложенная дублирующая строка с именем группы отображаться не будет.
  4. Чтобы пользователь не видел системную строку отбора в шапке отчета, перейдем на вкладку Настройки, откроем Другие настройки и для параметра Расположение отборов выберем значение Не выводить.

Способ 4. Использование пользовательских полей и функции Вычислить

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

Проанализируем синтаксис функции в СКД:

  1. В платформе 8.1 используется функция Вычислить("ИмяПоля", "Группировка"), а в версиях 8.2 и 8.3 — расширенная функция ВычислитьВыражение("ИмяПоля", "Группировка").
  2. При создании пользовательского поля необходимо строго следить за точным наименованием полей. Если поле в наборе данных названо СтатьяЗатрат, передавать его имя в функцию необходимо в кавычках с соблюдением регистра. Ошибки в синтаксисе приводят к сообщению Поле не найдено.
  3. Получив значение родительского узла через пользовательское поле, на уровне отчета устанавливается отбор, исключающий строки, у которых идентификатор текущей записи совпадает с идентификатором родительского узла контекста расчета.

Применение разделения наборов через ОБЪЕДИНИТЬ ВСЕ в сочетании с раздельной настройкой ресурсов по группировкам является наиболее универсальным и производительным решением, полностью исключающим появление артефактов и дублей в иерархических отчетах 1С.

← На главную