При разработке в среде 1С:Предприятие 7.7 часто возникает задача работы со связанными справочниками. Если движение «вниз» по структуре подчинения является типовой операцией (с использованием метода ИспользоватьВладельца()), то получение данных «вверх» от подчиненного элемента к вышестоящим владельцам нередко вызывает вопросы у начинающих специалистов или тех, кто давно не работал с платформой 7.7. Разберем по шагам, как правильно и безопасно перемещаться вверх по цепочке подчиненности объектов данных и метаданных.
Рассмотрим структуру подчинения, состоящую из трех уровней: справочник А3 подчинен справочнику А2, а справочник А2 подчинен справочнику А1. Имея ссылку на элемент самого нижнего уровня (А3), мы можем напрямую получить доступ к реквизитам вышестоящих справочников через системный реквизит Владелец.
Посмотрим на пример прямого обращения через точку:
// Получаем владельца первого уровня (А2)
ВладелецА2 = СпрА3.Владелец;
// Получаем владельца второго уровня (А1)
ВладелецА1 = СпрА3.Владелец.Владелец;
// Читаем конкретный реквизит корневого владельца
НаименованиеКорня = СпрА3.Владелец.Владелец.Наименование;
Проанализируем ситуацию, когда промежуточный владелец не заполнен или был удален. Прямое обращение через цепочку точек (Спр.Владелец.Владелец) в таком случае приведет к ошибке времени выполнения «Поле агрегатного объекта не обнаружено» или попытке обращения к пустому значению. Для предотвращения сбоев необходимо выполнять проверку валидности каждого промежуточного элемента.
Разберем алгоритм безопасного подъема вверх по иерархии с помощью метода Выбран():
ТекущийЭлемент = ВыбранныйЭлементА3;
Пока ПустоеЗначение(ТекущийЭлемент) = 0 Цикл
Если ТекущийЭлемент.Выбран() = 0 Тогда
Прервать;
КонецЕсли;
Сообщить("Уровень: " + ТекущийЭлемент.Вид() + " -> " + ТекущийЭлемент.Наименование);
// Переходим к следующему владельцу вверх по цепочке
ТекущийЭлемент = ТекущийЭлемент.Владелец;
КонецЦикла;
В приведенном цикле мы последовательно поднимаемся от подчиненного справочника к его родителю до тех пор, пока ТекущийЭлемент.Владелец не вернет пустое значение (что означает достижение вершины иерархии — неподчиненного справочника).
Если требуется заранее выяснить структуру подчинения справочников в конфигурации (например, узнать глубину вложенности или типы родительских справочников без привязки к конкретному элементу базы данных), следует использовать объект Метаданные.
Рассмотрим подробнее работу со свойствами метаданных:
Метаданные.Справочник(ИмяСправочника).Владелец.Метаданные.Справочник(ИмяСправочника).Владелец.Выбран() возвращает значение 0.Посмотрим на пример рекурсивного или циклического анализа метаданных:
ИмяСпр = "ПодчиненныйСправочник3";
СпрМД = Метаданные.Справочник(ИмяСпр);
Пока СпрМД.Владелец.Выбран() = 1 Цикл
Сообщить("Справочник " + СпрМД.Идентификатор + " подчинен справочнику " + СпрМД.Владелец.Идентификатор);
СпрМД = СпрМД.Владелец;
КонецЦикла;
При проектировании и программной обработке структур подчинения в 1С 7.7 важно учитывать ряд платформенных правил:
ИспользоватьВладельца(СсылкаНаВладельца), так и прямой установкой системного реквизита Спр.Владелец = СсылкаНаВладельца перед вызовом Записать().