Как настроить иерархию справочников и использовать её в документах и отчётах

· 9 мин

Содержание

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

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

Два вида иерархии: группы и элементы или только элементы

1С предлагает ровно два варианта, и выбирают их один раз при проектировании справочника:

  • Иерархия групп и элементов. Дерево строят из групп (папок), а элементы лежат внутри них как «листья». Элемент не может быть родителем другого элемента — родителем бывает только группа. У каждого объекта есть признак ЭтоГруппа. Так устроена, например, Номенклатура: папки «Материалы», «Товары», «Услуги», а внутри — конкретные позиции.
  • Иерархия элементов. Группы отсутствуют, родителем выступает обычный элемент. Такую схему применяют к классификаторам, где сам элемент является и узлом, и значением: Подразделения (отдел входит в департамент), СтатьиЗатрат, виды контактной информации, регионы.

Как выбрать — зависит от того, нужны ли вам «пустые папки» для группировки или сами значения образуют дерево:

Какой вид иерархии выбрать для справочника?

Вид иерархии задаётся при проектировании. Сменить «иерархию элементов» на «группы и элементы» на заполненной базе без потери или ручного переноса данных не получится — выбирайте осознанно.

Как включить иерархию справочника в конфигураторе

Настройка целиком живёт в конфигураторе, в свойствах объекта. Порядок такой:

  1. Откройте конфигуратор (Конфигуратор), найдите нужный справочник в дереве метаданных.
  2. В палитре свойств перейдите на закладку Данные.
  3. Установите флажок Иерархический. Появится поле Вид иерархии — выберите Иерархия групп и элементов или Иерархия элементов.
  4. При необходимости ограничьте глубину: свойство Количество уровней иерархии. Значение 0 означает «без ограничений».
  5. Флажок Размещать группы сверху управляет только отображением в списках — группы показываются над элементами.
  6. Обновите конфигурацию базы данных (F7).

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

Проверка перед включением иерархии
Выполнено: 0 / 5

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

Работа с группами в режиме «1С:Предприятие»

В пользовательском режиме дерево строится прямо в списке справочника:

  • Создать группу — команда Создать группу в командной панели списка (отдельная от обычного Создать). Группа доступна только для иерархии групп и элементов.
  • Поместить элемент в группу — при создании укажите значение в поле Группа (или Родитель), либо перетащите запись мышью в нужную папку в дереве слева.
  • Перенести ветку — выделите элементы и воспользуйтесь командой перемещения в группу из командной панели списка; можно перетаскиванием.
  • Переключить отображение — иконка режима просмотра позволяет показать список деревом, только текущей группой или сплошным списком без учёта групп.

Для иерархии элементов папок нет: подчинённость задаётся полем Родитель в самой карточке. Например, в карточке подразделения указываете вышестоящее подразделение — так собирается оргструктура.

Если в списке не видно вложенности, проверьте режим просмотра и снимите активные отборы: отбор по реквизиту может «разворачивать» дерево в плоский список, и структура визуально пропадает.

Иерархия в документах, запросах и отчётах

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

Это видно в подборе: когда в документе поступления или реализации нажимаете Подбор, открывается тот же справочник деревом — вы сворачиваете и разворачиваете папки, а в документ попадают только конечные элементы. На форме списка самого справочника дерево включает свойство динамического списка Режим просмотра; отдельного кода для этого не нужно, достаточно, чтобы основной таблицей списка был иерархический справочник.

В запросах за отбор по дереву отвечает оператор В ИЕРАРХИИ. Он возвращает элемент и всех его потомков на любую глубину:

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

Здесь &Группа — ссылка на папку: в результат попадут продажи по всем товарам внутри неё и во вложенных папках. Обычное условие = &Группа так не работает — оно сравнит с конкретным значением и вложенность проигнорирует.

В отчётах на СКД иерархию дают два механизма:

  • тип группировки Иерархия или Только иерархия в настройках структуры отчёта — строки сворачиваются в дерево с подытогами по каждому уровню;
  • в запросе набора данных — ИТОГИ ... ПО ... ТОЛЬКО ИЕРАРХИЯ, если отчёт строится без системы компоновки.

Благодаря этому в отчёте «Продажи по номенклатуре» сумма по папке «Товары» автоматически собирает все подчинённые позиции, а пользователь разворачивает нужную ветку.

Права доступа и производительность больших классификаторов

На объёмных справочниках (десятки тысяч позиций, номенклатура, адресный классификатор ) структура влияет и на права, и на скорость.

Права доступа . Через RLS (ограничение доступа на уровне записей) можно выдавать доступ к ветке справочника. Условие в шаблоне строят с тем же оператором В ИЕРАРХИИ: сотруднику видна только его группа номенклатуры со всеми вложениями. Схема рабочая, но помните — RLS с иерархией добавляет подзапрос к каждому обращению, и на больших данных это ощутимо нагружает СУБД.

Производительность. Несколько практичных правил:

СитуацияЧто делать
Глубина дерева «на всякий случай»Ограничьте Количество уровней: контроль целостности дешевле неконтролируемой вложенности
Отбор по ветке в динамическом спискеИспользуйте В ИЕРАРХИИ, а не выборку всех родителей в цикле
Частые отчёты по группамГруппировку Иерархия стройте на регистрах, а не на обходе справочника кодом
Справочник реально плоскийНе включайте иерархию — лишний реквизит Родитель и индекс не нужны

Если по справочнику регулярно крутятся тяжёлые отчёты с группировкой по дереву, надёжнее опираться не на обход справочника в коде, а на итоги регистров: в регистрах уже лежат готовые ссылки на номенклатуру, и запрос с В ИЕРАРХИИ по регистру работает на порядок быстрее рекурсивного прохода по справочнику. Плоский справочник с отбором по дополнительному реквизиту-категории иногда оказывается быстрее глубокого дерева — ветка сравнения = &Категория проще для СУБД, чем раскрытие иерархии.

Массовое изменение Родитель у тысяч элементов (реструктуризация классификатора) — тяжёлая операция. Запускайте её в нерабочее время: пока идёт перенос, пользователи будут видеть «переезжающие» между папками позиции, а обмен данными — ловить конфликты.

Программная работа с иерархией

Когда структуру нужно строить или перестраивать кодом — например, при загрузке классификатора из файла, — пригодятся несколько приёмов.

Определить родителя и признак группы:

Выборка = Справочники.Номенклатура.Выбрать();
Пока Выборка.Следующий() Цикл
    Если Выборка.ЭтоГруппа Тогда
        Сообщить("Группа: " + Выборка.Наименование);
    Иначе
        Сообщить("Элемент в папке: " + Выборка.Родитель.Наименование);
    КонецЦикла;
КонецЦикла;

Создать группу программно (для иерархии групп и элементов):

НоваяГруппа = Справочники.Номенклатура.СоздатьГруппу();
НоваяГруппа.Наименование = "Канцтовары";
НоваяГруппа.Записать();

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

Перенести ветку в другую папку кодом — тот же приём: получаете объект, меняете Родитель, записываете. Чтобы перенести сразу содержимое группы, сначала запросом выбирают её элементы (В ИЕРАРХИИ), затем в цикле у каждого меняют родителя:

Запрос = Новый Запрос;
Запрос.Текст =
    "ВЫБРАТЬ Ссылка ИЗ Справочник.Номенклатура
    |ГДЕ Ссылка В ИЕРАРХИИ(&Старая) И Ссылка <> &Старая";
Запрос.УстановитьПараметр("Старая", СтараяГруппа);
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
    Объект = Выборка.Ссылка.ПолучитьОбъект();
    Объект.Родитель = НоваяГруппа;
    Объект.Записать();
КонецЦикла;

Обойти всех потомков на любую глубину удобнее запросом с В ИЕРАРХИИ, а не рекурсией по Выбрать(Родитель) — запрос делает это одним обращением к базе и работает заметно быстрее рекурсивного обхода справочника.

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

Частые ошибки при работе с иерархией

🔸 Сравнивают с группой через = вместо В ИЕРАРХИИ. Отбор Номенклатура = &Папка вернёт пусто или только саму папку. Потомков даёт только В ИЕРАРХИИ.

🔸 Забывают про ЭтоГруппа в запросах и формах. Если нужны только конечные элементы (товары без папок), добавляйте условие ЭтоГруппа = ЛОЖЬ, иначе в список или подбор попадут и папки.

🔸 Пытаются сделать родителем элемент в иерархии групп и элементов. В этой схеме родитель — только группа. Если такое всё же нужно, вид иерархии изначально должен быть «иерархия элементов».

🔸 Делают слишком глубокое дерево. Пять-шесть уровней вложенности усложняют и ввод, и отчёты. Чаще удобнее два-три уровня плюс отбор по дополнительному реквизиту.

🔸 Включают иерархию «на будущее» на плоском справочнике. Лишний реквизит Родитель, дерево в формах и индекс ничего не дают, если вложенности нет, — только усложняют интерфейс.

🔸 Ищут элемент в дереве перебором вместо запроса. Чтобы найти позицию по коду или наименованию, используйте НайтиПоКоду / НайтиПоНаименованию или запрос, а не рекурсивный обход всех групп: платформа ищет по индексу, обход — вручную и медленно.

Частые вопросы

Можно ли сделать иерархическим документ, а не справочник?
Нет. Иерархия — свойство справочников, планов видов характеристик и некоторых других объектов, но не документов. Группировку документов по датам, организациям или контрагентам делают отборами и группировками в журналах и отчётах.
Чем группа отличается от обычного элемента?
Группа — это узел-контейнер в иерархии групп и элементов, у неё признак ЭтоГруппа = Истина. В неё вкладывают другие группы и элементы, но сама по себе она обычно не несёт «данных» позиции. Элемент — конечная запись, родителем других элементов быть не может.
Как перенести элемент в другую папку?
В режиме «1С:Предприятие» — перетащить мышью в дереве или командой перемещения в группу из командной панели списка. Программно — присвоить реквизиту Родитель ссылку на нужную группу и записать объект.
Почему отбор по группе не показывает вложенные позиции?
Скорее всего, в условии стоит = вместо оператора В ИЕРАРХИИ. Первый сравнивает с одним значением, второй разворачивает всю ветку с потомками.
Можно ли ограничить число уровней вложенности?
Да, свойством Количество уровней иерархии в конфигураторе. Ноль — без ограничений; любое положительное число запретит создавать группы глубже заданного уровня.
Как выдать сотруднику доступ только к своей ветке справочника?
Через RLS — ограничение доступа на уровне записей. В шаблоне ограничения условие строят оператором В ИЕРАРХИИ от разрешённой группы, тогда пользователю видна она и всё вложенное. На больших справочниках такое ограничение заметно нагружает базу — проверяйте скорость на реальных объёмах.