Как вывести всю иерархию справочника в отчет на Системе Компоновки Данных (СКД) 1С:Предприятия?

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

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

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

Подход 1: Стандартная иерархическая группировка в СКД

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

Шаг 1: Добавляем поле для группировки.

В настройках отчета, на вкладке «Настройки», мы переходим к структуре отчета. Создаем новую группировку и в качестве поля для группировки выбираем наш реквизит ГруппаКонтрагента, который содержится в основном наборе данных отчета (например, из регистра накопления).

Шаг 2: Устанавливаем тип группировки «Иерархия».

После того как мы выбрали поле ГруппаКонтрагента, необходимо установить для этой группировки специальный тип. Для этого мы нажимаем на кнопку «Дополнительные настройки» или открываем свойства группировки. В открывшемся окне мы находим опцию «Тип группировки» и устанавливаем значение «Иерархия».

Что это означает? При выборе типа «Иерархия» СКД автоматически будет пытаться построить дерево из элементов, используя стандартные поля иерархических справочников (Ссылка и Родитель). В результате в отчете будут последовательно выводиться родительские элементы, а под ними — их подчиненные.

Важные нюансы:

  1. Если ваш справочник имеет иерархию групп и элементов (т.е., элементы находятся внутри папок), и вы хотите видеть и папки, и элементы, то просто установите тип «Иерархия».
  2. Если вы выберете тип «Только иерархия», то в отчете будут отображены только группы (папки), без детальных элементов, подчиненных этим группам напрямую. Это полезно, если вам нужна агрегированная информация только по родительским группам.
  3. Если же справочник имеет иерархию только элементов (когда один элемент является родителем для другого элемента, а не для группы), стандартная иерархическая группировка также будет работать. Однако, иногда возникает проблема дублирования: элемент может отображаться и как родитель для своих подчиненных, и как самостоятельная детальная запись. Об этом мы поговорим чуть позже.

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

Подход 2: Произвольная иерархия через связи наборов данных

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

Давайте рассмотрим этот подход подробнее.

Шаг 1: Создаем два набора данных.

Нам потребуется как минимум два набора данных:

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

    Обратите внимание на названия полей: Группа (идентифицирует сам элемент иерархии) и РодительГруппы (идентифицирует родителя). Упростить написание таких запросов может интерактивное формирование текста запроса для получения родителей всех уровней справочника.

Шаг 2: Устанавливаем связи между наборами данных.

Теперь нам нужно связать эти два набора данных:

  1. Связываем набор данных иерархии сам с собой: Открываем вкладку «Связи наборов данных» в СКД. Здесь мы создаем связь, где источник и приемник — наш набор данных иерархии (например, «ИерархияГрупп»). Устанавливаем связь по полям: Группа = РодительГруппы (или Ссылка = Родитель, в зависимости от выбранных имен полей). Это позволяет СКД понять структуру иерархии.
  2. Связываем основной набор данных с набором данных иерархии: Создаем еще одну связь. Источник — наш основной набор данных (например, «ПродажиОбороты»), Приемник — набор данных иерархии («ИерархияГрупп»). Связь устанавливаем по полям: ГруппаКонтрагента = Группа. Эта связь сообщает СКД, как данные из основного отчета соотносятся с элементами иерархии.

Шаг 3: Настраиваем группировку с проверкой иерархии.

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

Этот подход дает нам гораздо больше гибкости, позволяя строить иерархию практически на любых данных, где можно выделить связь «родитель-потомок».

Избегаем повторения родительских элементов в отчете

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

Шаг 1: Создаем пользовательское поле-выражение.

На вкладке «Наборы данных» в СКД, в основном наборе данных, мы можем добавить новое вычисляемое поле. Например, назовем его РодительГруппыКонтрагента. Выражение для этого поля будет простым: ГруппаКонтрагента.Родитель Это поле будет хранить ссылку на непосредственного родителя текущей группы контрагента.

Шаг 2: Настраиваем отбор для группировки.

В настройках отчета, на вкладке «Настройки», для нашей иерархической группировки по ГруппаКонтрагента добавляем отбор. Условие отбора будет следующим:

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

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

Использование конструкции «В ИЕРАРХИИ» в запросах

Конструкция В ИЕРАРХИИ в запросах 1С позволяет нам получить все подчиненные элементы (включая группы и подгруппы) для заданного иерархического объекта. Это может быть полезно, если вы хотите получить иерархически связанные данные уже на этапе формирования запроса к базе данных, а не только на этапе компоновки отчета в СКД.

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


ВЫБРАТЬ
    ПродажиОбороты.ГруппаКонтрагента КАК ГруппаКонтрагента,
    ПродажиОбороты.КоличествоОборот КАК Количество
ИЗ
    РегистрНакопления.Продажи.Обороты КАК ПродажиОбороты
ГДЕ
    ПродажиОбороты.ГруппаКонтрагента В ИЕРАРХИИ &ПараметрГруппы

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

Иерархия детальных записей

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

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

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

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

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

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

Рекомендации по изучению и дальнейшему развитию

Для глубокого понимания всех возможностей Системы Компоновки Данных, включая работу с иерархиями, мы настоятельно рекомендуем обратиться к классическим источникам. Например, книга Е.Ю. Хрусталевой «Разработка сложных отчетов в "1С:Предприятии 8". Система Компоновки Данных» является настольной книгой для многих разработчиков 1С. В ней подробно рассматриваются все аспекты построения отчетов, включая тонкости работы с иерархиями на странице 323 и далее. Изучение этих материалов позволит вам не только решить текущую задачу, но и успешно справляться с любыми вызовами, связанными с отчетностью в 1С.

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

← На главную