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