Как в СКД добавить реквизиты к произвольной иерархии

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

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

Почему реквизиты иерархического набора не отображаются в группировках

Проанализируем механику работы СКД при построении пользовательской иерархии с двумя наборами данных:

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

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

Способ 1. Синхронизация полей в обоих наборах и настройка ресурсов

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

Разберем по шагам реализацию этого метода:

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

Посмотрим на пример программного заполнения флага цикличности и реквизитов в обеих таблицах значений перед передачей их в СКД:


Для каждого Элемент Из ЗацикленныеСтатьи Цикл

    // Заполняем реквизит во вспомогательной таблице иерархии
    Строки = ТаблицаЗависимостей.НайтиСтроки(Новый Структура("Ссылка", Элемент.Значение));
    Для каждого СтрокаИерархии Из Строки Цикл
        СтрокаИерархии.ЕстьЦикл = Истина;
    КонецЦикла; 

    // Заполняем реквизит в базовой таблице конечных элементов
    Строка = ПоследнийУровень.Найти(Элемент.Значение, "Ссылка");
    Если Строка <> Неопределено Тогда
        Строка.ЕстьЦикл = Истина;
    КонецЕсли; 

КонецЦикла;
  1. Настройка на вкладке «Ресурсы»: Переходим на вкладку Ресурсы схемы компоновки данных. Добавляем наше поле ЕстьЦикл. В колонке Выражение указываем агрегатную функцию или само поле. Для булевых и строковых реквизитов безопаснее и корректнее использовать выражения вида: Максимум(ЕстьЦикл) или для строковых представлений: Минимум(ДополнительныйРеквизит)
  2. Ограничение области расчета (при необходимости): В колонке Рассчитывать по... можно указать конкретное поле группировки с иерархией, например Ссылка Иерархия, чтобы расчет значения выполнялся строго на уровнях группировки.

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

Способ 2. Связь набора данных с самим собой (Self-link)

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

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

При такой схеме все реквизиты изначально находятся в едином пространстве полей СКД. В настройках отчета достаточно вывести группировку Ссылка Иерархия и добавить требуемые реквизиты в выбранные поля — они будут автоматически доступны на каждом уровне вложенности.

Важные особенности и ограничения при работе с произвольной иерархией

При настройке нестандартных иерархических структур в СКД обратите внимание на следующие нюансы:

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

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

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

← На главную