Когда возникает задача по отображению иерархических данных из справочника в отчетах 1С, основанных на Системе Компоновки Данных (СКД), мы сталкиваемся с необходимостью правильно настроить группировки и связи. Давайте разберем различные подходы к решению этой распространенной проблемы, начиная от самых простых и переходя к более сложным.
Представим ситуацию: у нас есть справочник «Группы контрагентов», который является иерархическим по элементам. В другом справочнике — «Контрагенты» — добавлен реквизит, ссылающийся на наш справочник групп. Обороты по продажам фиксируются в дополнительном оборотном регистре накопления, где в качестве измерения хранится ссылка на «Группу контрагентов» и указывается количество продаж. Наша цель — построить отчет по этому регистру, но так, чтобы вся иерархия «Групп контрагентов» была красиво представлена.
Это самый простой и часто используемый способ, который применим, если ваш справочник имеет иерархию элементов или иерархию групп и элементов. Система Компоновки Данных предоставляет встроенные механизмы для работы с такими структурами.
Шаг 1: Добавляем поле для группировки.
В настройках отчета, на вкладке «Настройки», мы переходим к структуре отчета. Создаем новую группировку и в качестве поля для группировки выбираем наш реквизит ГруппаКонтрагента, который содержится в основном наборе данных отчета (например, из регистра накопления).
Шаг 2: Устанавливаем тип группировки «Иерархия».
После того как мы выбрали поле ГруппаКонтрагента, необходимо установить для этой группировки специальный тип. Для этого мы нажимаем на кнопку «Дополнительные настройки» или открываем свойства группировки. В открывшемся окне мы находим опцию «Тип группировки» и устанавливаем значение «Иерархия».
Что это означает? При выборе типа «Иерархия» СКД автоматически будет пытаться построить дерево из элементов, используя стандартные поля иерархических справочников (Ссылка и Родитель). В результате в отчете будут последовательно выводиться родительские элементы, а под ними — их подчиненные.
Важные нюансы:
Таким образом, самым первым шагом всегда является попытка использования стандартной иерархической группировки. В большинстве случаев она решает задачу вывода иерархии достаточно элегантно.
Бывают ситуации, когда стандартная иерархическая группировка не подходит. Например, когда иерархия строится по каким-то нестандартным правилам, или когда мы хотим контролировать вывод родительских элементов, или когда иерархия должна быть построена на основе данных, не являющихся стандартным иерархическим справочником (например, из внешней таблицы или другого регистра). В таких случаях на помощь приходит механизм произвольной иерархии через связи наборов данных в СКД.
Давайте рассмотрим этот подход подробнее.
Шаг 1: Создаем два набора данных.
Нам потребуется как минимум два набора данных:
ГруппуКонтрагента (отладить текст запроса поможет управляемая консоль запросов). Например:
ВЫБРАТЬ
ПродажиОбороты.ГруппаКонтрагента КАК ГруппаКонтрагента,
ПродажиОбороты.КоличествоОборот КАК Количество
ИЗ
РегистрНакопления.Продажи.Обороты КАК ПродажиОбороты
Ссылка или Код, Наименование), и второе, идентифицирующее его родителя. В нашем случае, это будет справочник «Группы контрагентов»:
ВЫБРАТЬ
ГруппыКонтрагентов.Ссылка КАК Группа,
ГруппыКонтрагентов.Родитель КАК РодительГруппы
ИЗ
Справочник.ГруппыКонтрагентов КАК ГруппыКонтрагентов
Обратите внимание на названия полей: Группа (идентифицирует сам элемент иерархии) и РодительГруппы (идентифицирует родителя). Упростить написание таких запросов может интерактивное формирование текста запроса для получения родителей всех уровней справочника.
Шаг 2: Устанавливаем связи между наборами данных.
Теперь нам нужно связать эти два набора данных:
Группа = РодительГруппы (или Ссылка = Родитель, в зависимости от выбранных имен полей). Это позволяет СКД понять структуру иерархии.ГруппаКонтрагента = Группа. Эта связь сообщает СКД, как данные из основного отчета соотносятся с элементами иерархии.Шаг 3: Настраиваем группировку с проверкой иерархии.
Возвращаемся к настройкам отчета, на вкладку «Настройки». Создаем группировку по полю ГруппаКонтрагента. Теперь самое важное: в свойствах этой группировки (обычно через кнопку «Дополнительные настройки») нам нужно установить флажок «Проверка иерархии» и указать набор данных, который описывает иерархию (в нашем случае, это «ИерархияГрупп»). Также указываем поля, обозначающие иерархический уровень (Группа и РодительГруппы). СКД будет использовать связи, которые мы настроили, чтобы построить иерархическое представление.
Этот подход дает нам гораздо больше гибкости, позволяя строить иерархию практически на любых данных, где можно выделить связь «родитель-потомок».
Как мы уже упоминали, при использовании иерархических группировок иногда возникает ситуация, когда родительский элемент выводится дважды: один раз как заголовок группы, и еще раз как отдельная детальная запись, если он сам имеет данные в регистре. Чтобы избежать такого дублирования, мы можем использовать пользовательское поле и отбор.
Шаг 1: Создаем пользовательское поле-выражение.
На вкладке «Наборы данных» в СКД, в основном наборе данных, мы можем добавить новое вычисляемое поле. Например, назовем его РодительГруппыКонтрагента. Выражение для этого поля будет простым:
ГруппаКонтрагента.Родитель
Это поле будет хранить ссылку на непосредственного родителя текущей группы контрагента.
Шаг 2: Настраиваем отбор для группировки.
В настройках отчета, на вкладке «Настройки», для нашей иерархической группировки по ГруппаКонтрагента добавляем отбор. Условие отбора будет следующим:
ГруппаКонтрагентаНЕ РАВНОРодительГруппыКонтрагента (наше вычисляемое поле)Самое главное здесь — это правильно установить «Применение отбора». Для этой цели выбираем значение «После группировки или для иерархии». Это гарантирует, что отбор будет применен после того, как СКД построит иерархию, и не отфильтрует родительские элементы, которые должны отображаться как заголовки групп.
Такой отбор позволяет нам вывести только те записи, которые не являются родителями для самих себя на данном уровне иерархии, эффективно устраняя дублирование.
Конструкция В ИЕРАРХИИ в запросах 1С позволяет нам получить все подчиненные элементы (включая группы и подгруппы) для заданного иерархического объекта. Это может быть полезно, если вы хотите получить иерархически связанные данные уже на этапе формирования запроса к базе данных, а не только на этапе компоновки отчета в СКД.
Например, если нам нужно получить обороты не просто по одной группе, а по заданной группе и всем ее дочерним группам и элементам, мы можем модифицировать запрос следующим образом:
ВЫБРАТЬ
ПродажиОбороты.ГруппаКонтрагента КАК ГруппаКонтрагента,
ПродажиОбороты.КоличествоОборот КАК Количество
ИЗ
РегистрНакопления.Продажи.Обороты КАК ПродажиОбороты
ГДЕ
ПродажиОбороты.ГруппаКонтрагента В ИЕРАРХИИ &ПараметрГруппы
Здесь &ПараметрГруппы — это параметр, в который мы передаем ссылку на родительскую группу. Запрос вернет все данные, относящиеся к этой группе и всем элементам, находящимся в ее иерархии. Этот механизм удобен для формирования динамических отчетов, где пользователь может выбрать верхний уровень иерархии.
СКД также предоставляет возможность выводить иерархию детальных записей. Это происходит, когда набор данных имеет ссылку на самого себя, и СКД автоматически распознает и рекурсивно выполняет эту связь для построения вложенных записей. Это более продвинутый механизм, который чаще используется для вывода иерархических справочников как таковых, без агрегации по ним данных. Однако, понимание его принципов может быть полезно для создания очень гибких иерархических представлений.
Сообщение 6 в исходной теме предлагает интересный подход: если есть возможность, можно избежать создания отдельного справочника для групп контрагентов, а использовать стандартные группы самого справочника «Контрагенты». Это значительно упростит работу с иерархией в отчетах.
Если справочник Контрагенты является иерархическим (что характерно для большинства типовых конфигураций), и вы добавили в нем группы, то реквизит ГруппаКонтрагента в вашем регистре накопления мог бы ссылаться непосредственно на элемент или группу справочника Контрагенты. В этом случае:
Контрагент (или ГруппаКонтрагента, если это измерение регистра), и установить для нее тип «Иерархия».Контрагенты, без необходимости настройки сложных связей наборов данных или вычисляемых полей.Этот подход уменьшает сложность конфигурации и упрощает построение отчетов, делая их более типовыми и легкими в сопровождении. Перед тем как приступать к сложным настройкам СКД, всегда полезно рассмотреть, можно ли решить задачу на уровне архитектуры данных.
Для глубокого понимания всех возможностей Системы Компоновки Данных, включая работу с иерархиями, мы настоятельно рекомендуем обратиться к классическим источникам. Например, книга Е.Ю. Хрусталевой «Разработка сложных отчетов в "1С:Предприятии 8". Система Компоновки Данных» является настольной книгой для многих разработчиков 1С. В ней подробно рассматриваются все аспекты построения отчетов, включая тонкости работы с иерархиями на странице 323 и далее. Изучение этих материалов позволит вам не только решить текущую задачу, но и успешно справляться с любыми вызовами, связанными с отчетностью в 1С.
Мы рассмотрели несколько ключевых методов вывода иерархии в отчетах СКД. Выбор конкретного подхода зависит от вашей текущей архитектуры данных и требований к отчету. Начните с самого простого (стандартная иерархическая группировка) и переходите к более сложным, если это необходимо. Помните, что СКД — это мощный, но гибкий инструмент, и знание его возможностей поможет вам создавать эффективные и информативные отчеты.