Как программно узнать список всех справочников, подчиненных текущему в 1С 7.7?

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

В процессе разработки универсальных обработок в 1С:Предприятии 7.7 часто возникает задача программного анализа структуры метаданных. Одной из типичных проблем является необходимость удаления элемента справочника вместе со всеми его данными в подчиненных справочниках. Поскольку состав конфигурации может меняться, жесткое прописывание имен справочников в коде — плохая практика. Разберем, как сделать это гибко и универсально.

Принцип организации связей в метаданных 1С 7.7

В отличие от более современных версий платформы, где связь может быть сложной, в версии 7.7 каждый справочник может иметь только одного владельца. Информация об этой связи хранится непосредственно в свойствах самого подчиненного справочника. Если мы хотим узнать, кто подчинен справочнику Контрагенты, нам нужно просмотреть все справочники в конфигурации и проверить, не указан ли справочник Контрагенты в качестве их владельца.

Для решения этой задачи мы будем использовать объект Метаданные, который предоставляет доступ к описанию структуры всей конфигурации в режиме исполнения (Runtime).

Реализация функции поиска подчиненных справочников

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


Функция сзПодчиненныеСправочники(ИмяВидаВладельца) Экспорт
    Перем сзПодчиненные;
    Перем нПодч, МетаСпр;
    
    сзПодчиненные = СоздатьОбъект("СписокЗначений");
    
    // Перебираем все справочники конфигурации по индексу
    Для нПодч = 1 По Метаданные.Справочник() Цикл
        МетаСпр = Метаданные.Справочник(нПодч);
        
        // Проверяем, назначен ли вообще владелец для текущего справочника
        Если МетаСпр.Владелец.Выбран() = 1 Тогда
            
            // Сравниваем вид владельца с искомым видом
            Если МетаСпр.Владелец.Вид = ИмяВидаВладельца Тогда
                // Если совпало, добавляем вид подчиненного справочника в список
                сзПодчиненные.ДобавитьЗначение(МетаСпр.Вид);
            КонецЕсли;
            
        КонецЕсли;
    КонецЦикла;
    
    Возврат сзПодчиненные;
КонецФункции

Разбор ключевых методов и свойств

Давайте подробнее проанализируем инструменты, которые мы использовали в коде выше:

  1. Метаданные.Справочник(): Без параметров этот метод возвращает общее количество справочников в конфигурации. Это позволяет нам организовать цикл Для.
  2. Метаданные.Справочник(нПодч): При передаче числового индекса метод возвращает объект метаданных конкретного справочника.
  3. МетаСпр.Владелец: Это свойство также является объектом метаданных. Если у справочника нет владельца, этот объект будет "пустым".
  4. Выбран(): Метод, который позволяет проверить, определен ли объект метаданных (в данном контексте — назначен ли владелец). Если возвращает 0, значит справочник не является подчиненным.
  5. МетаСпр.Владелец.Вид: Строковое представление (идентификатор) справочника-владельца. Именно его мы сравниваем с нужным нам значением (например, "Контрагенты").

Обработка данных в найденных справочниках

После того как мы получили список видов подчиненных справочников, нам необходимо произвести действия с их элементами. Рассмотрим, как программно выбрать элементы, принадлежащие конкретному владельцу. Для этого используется метод ИспользоватьВладельца().

Представим, что у нас есть переменная ОбъектВладелец (ссылка на элемент справочника Контрагенты). Проанализируем пример удаления подчиненных записей:


Процедура УдалитьПодчиненныеЭлементы(ОбъектВладелец)
    Перем СпПодчиненных, ВидПодч, спрОбъект;
    
    // Получаем список видов справочников, которые нам нужно почистить
    СпПодчиненных = сзПодчиненныеСправочники(ОбъектВладелец.Вид());
    
    Для итератор = 1 По СпПодчиненных.РазмерСписка() Цикл
        ВидПодч = СпПодчиненных.ПолучитьЗначение(итератор);
        
        спрОбъект = СоздатьОбъект("Справочник." + ВидПодч);
        
        // Устанавливаем фильтр по владельцу
        спрОбъект.ИспользоватьВладельца(ОбъектВладелец);
        
        // Выбираем все элементы, принадлежащие данному владельцу
        спрОбъект.ВыбратьЭлементы();
        Пока спрОбъект.ПолучитьЭлемент() = 1 Цикл
            // Выполняем удаление или иную обработку
            спрОбъект.Удалить(0); // 0 - пометка на удаление, 1 - непосредственное удаление
        КонецЦикла;
    КонецЦикла;
КонецПроцедуры

Важные нюансы и рекомендации

При работе с программным поиском подчиненных объектов следует учитывать несколько критически важных моментов:

Рекурсивная подчиненность: В 1С 7.7 возможна многоуровневая подчиненность (например, Контрагенты -> ДенежныеСчета -> РеквизитыСчетов). Наш базовый алгоритм найдет только прямых "детей". Если ваша задача — полное очищение данных, функцию поиска нужно вызывать рекурсивно для каждого найденного подчиненного справочника, чтобы найти "внуков" и так далее по дереву метаданных.

Иерархия внутри справочника: Не путайте подчиненность (связь разных справочников) и иерархию (связь групп и элементов внутри одного справочника). Если справочник-владелец является иерархическим, подчиненные элементы могут быть привязаны как к элементам, так и к группам. Метод ИспользоватьВладельца() корректно отрабатывает в обоих случаях.

Контроль ссылочной целостности: Если вы планируете непосредственное удаление (Удалить(1)), обязательно используйте метод НайтиСсылки(). Подчиненный элемент может быть выбран в реквизитах документов или других справочников, не связанных отношениями владения. Прямое удаление без проверки может привести к появлению "битых" ссылок в базе данных (Объект не найден).

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

Таким образом, мы разобрали универсальный способ получения структуры подчиненности, который будет работать в любой конфигурации на платформе 1С:Предприятие 7.7 без внесения изменений в программный код при добавлении новых справочников.

← На главную