К статье
Практический материал

Разработка и Конфигурация · 9 мин

Как получить родителя элемента в 1С

Как получить родителя элемента справочника в 1С: свойство Родитель, запросы с ИЕРАРХИЯ, обход групп, проверка принадлежности и типичные ошибки разработчиков.

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

В зависимости от контекста задача решается по-разному: через свойство Родитель у ссылки, через запрос с конструкцией В ИЕРАРХИИ, через выборку с обходом ПоГруппировкам или через функции общего назначения. Ниже разобраны все основные способы с примерами кода, ограничениями и типичными ошибками.

Что такое родитель в иерархическом справочнике

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

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

Получение родителя через свойство ссылки

Самый простой способ — обратиться к свойству Родитель напрямую от ссылки. При этом платформа выполняет неявное обращение к базе данных и возвращает ссылку на родительский объект:

РодительГруппа = НоменклатураСсылка.Родитель;

Если НЕ ЗначениеЗаполнено(РодительГруппа) Тогда

// Элемент находится в корне справочника

КонецЕсли;

Чтобы получить наименование или код родителя, можно продолжить цепочку: НоменклатураСсылка.Родитель.Наименование. Однако каждое такое разыменование — отдельное обращение к базе. Если родителей нужно получить для сотен элементов в цикле, такой подход заметно замедлит выполнение, и правильнее использовать запрос.

Получение родителя запросом

Запросом родителя получают, когда нужно обработать много элементов сразу или вывести родителя в отчёт. Поле Родитель доступно в тексте запроса как обычный реквизит:

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| Номенклатура.Ссылка КАК Элемент,

| Номенклатура.Родитель КАК Группа,

| Номенклатура.Родитель.Наименование КАК ГруппаНаименование

|ИЗ

| Справочник.Номенклатура КАК Номенклатура

|ГДЕ

| НЕ Номенклатура.ПометкаУдаления";

Запрос также позволяет получить родителя «второго уровня» — родителя родителя: Номенклатура.Родитель.Родитель. Глубина разыменования ограничена, и при необходимости подняться на произвольное число уровней запрос не подходит — используйте рекурсивный обход.

Проверка принадлежности к группе через В ИЕРАРХИИ

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

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| Номенклатура.Ссылка

|ИЗ

| Справочник.Номенклатура КАК Номенклатура

|ГДЕ

| Номенклатура.Ссылка В ИЕРАРХИИ(&Группа)";

Запрос.УстановитьПараметр("Группа", ГруппаОтбора);

Оператор учитывает всю вложенность: если элемент лежит в подгруппе третьего уровня внутри указанной группы, он тоже попадёт в выборку. Условие Родитель = &Группа дало бы только прямых «потомков», что является частой ошибкой при построении отборов.

Сравнение вариантов

Ссылка.Родитель

Подходит для одиночного элемента; простой код, но обращение к базе на каждый вызов.

Запрос с полем Родитель

Оптимален для пакетной обработки и отчётов; ограниченная глубина разыменования.

В ИЕРАРХИИ

Проверка вхождения в группу любой глубины; не возвращает самого родителя.

Выборка с обходом ПоГруппировкам

Построение полного дерева; требует рекурсии для обработки.

Обход дерева и поиск родителя верхнего уровня

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

Функция КорневойРодитель(Ссылка)

Текущий = Ссылка.Родитель;

Пока ЗначениеЗаполнено(Текущий.Родитель) Цикл

Текущий = Текущий.Родитель;

КонецЦикла;

Возврат Текущий;

КонецФункции

Альтернатива — выборка с обходом по группировкам, которая возвращает всё дерево целиком:

Запрос.Текст =

"ВЫБРАТЬ

| Номенклатура.Ссылка

|ИЗ

| Справочник.Номенклатура КАК Номенклатура

|ИТОГИ ПО

| Номенклатура.Ссылка ТОЛЬКО ИЕРАРХИЯ";

Выборка = Запрос.Выполнить().Выбрать(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией);

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

Порядок действий
  1. 1
    Определите, нужен ближайший родитель, корневая группа или проверка вхождения в группу
  2. 2
    Для одиночного элемента используйте Ссылка.Родитель
  3. 3
    Для массовой обработки напишите запрос с полем Родитель
  4. 4
    Для проверки вхождения на любой глубине примените В ИЕРАРХИИ
  5. 5
    Проверьте результат на элементе из корня справочника — родитель должен быть пустым

Особенности для разных объектов конфигурации

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

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

Проверка результата и типичные ошибки

После получения родителя всегда проверяйте результат на заполненность и на соответствие ожидаемому типу. В справочниках с иерархией групп и элементов родитель — это группа, и попытка записать элементу родителя-элемент (не группу) приведёт к ошибке при записи.

Типичные ошибки
01
Сравнение пустого родителя с Неопределено вместо проверки ЗначениеЗаполнено — условие никогда не сработает
02
Использование Родитель = &Группа вместо В ИЕРАРХИИ — из отбора выпадают элементы вложенных подгрупп
03
Разыменование Ссылка.Родитель в цикле по тысячам элементов — резкое падение производительности
04
Запись в Родитель ссылки на элемент, а не на группу в справочнике с иерархией групп и элементов — ошибка при записи
05
Попытка получить Родитель у неиерархического объекта — ошибка обращения к свойству
Контрольные точки

Как проверить результат

Родитель элемента из корня
Норма

Пустая ссылка, ЗначениеЗаполнено() возвращает Ложь

Тревожный признак

Неопределено или ошибка обращения

Отбор В ИЕРАРХИИ
Норма

В выборку входят элементы всех вложенных подгрупп

Тревожный признак

Видны только элементы первого уровня

Тип родителя
Норма

Для иерархии групп — объект с ЭтоГруппа = Истина

Тревожный признак

Родитель имеет тот же тип, что и элемент

Часто задаваемые вопросы

Как получить родителя, если у меня только наименование элемента?

Сначала найдите ссылку методом Справочники.Номенклатура.НайтиПоНаименованию(Наименование, Истина), затем обратитесь к свойству Родитель найденной ссылки. Если элементов с таким наименованием несколько, метод вернёт первый найденный — надёжнее искать по коду или уникальному идентификатору.

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

Используйте цикл с подъёмом по уровням: на каждой итерации берите Текущий.Родитель и добавляйте в массив, пока родитель не станет пустым. Для пакетной обработки многих элементов такой подход медленный — рассмотрите выборку с обходом ПоГруппировкамСИерархией.

Можно ли изменить родителя программно?

Да: получите объект методом Ссылка.ПолучитьОбъект(), присвойте свойству Родитель новую группу и вызовите Записать(). Убедитесь, что новый родитель — группа (для справочников с иерархией групп и элементов), иначе запись завершится ошибкой.

Почему В ИЕРАРХИИ не находит элементы, хотя группа указана верно?

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

Как получить родителя в СКД или динамическом списке?

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

Итог

Что важно запомнить

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