При выгрузке конфигурации в файлы или рефакторинге проекта часто возникает необходимость получить полный список объектов метаданных и отфильтровать только те из них, которые не входят ни в одну из подсистем. Корневое свойство Метаданные представляет собой объект типа ОбъектМетаданныхКонфигурация, который не является единой коллекцией, поэтому его нельзя напрямую обойти простым циклом Для каждого.
Рассмотрим по шагам, как правильно организовать обход коллекций метаданных и определить состав объектов, оставшихся вне подсистем.
Для того чтобы собрать полный перечень объектов конфигурации, необходимо поочередно перебрать все подчиненные коллекции глобального объекта Метаданные. Для упрощения кода список имен коллекций (менеджеров) можно сформировать в виде строки с разделителями и разбить её функцией СтрРазделить.
Проанализируем пример кода для получения списка объектов всех основных типов:
КоллекцииСтр = "Справочники,Документы,ПланыВидовХарактеристик,ПланыСчетов,ПланыВидовРасчета,ПланыОбмена,БизнесПроцессы,Задачи,Константы,РегистрыСведений,РегистрыНакопления,РегистрыБухгалтерии,РегистрыРасчета,Отчеты,Обработки,Перечисления";
МассивКоллекций = СтрРазделить(КоллекцииСтр, ",");
ВсеОбъектыМетаданных = Новый Соответствие;
Для Каждого ИмяКоллекции Из МассивКоллекций Цикл
Для Каждого ОбъектМетаданных Из Метаданные[ИмяКоллекции] Цикл
ПолноеИмя = ИмяКоллекции + "." + ОбъектМетаданных.Имя;
ВсеОбъектыМетаданных.Вставить(ПолноеИмя, ОбъектМетаданных);
КонецЦикла;
КонецЦикла;
Выясним, какие объекты входят в состав подсистем. Поскольку подсистемы в 1С могут иметь древовидную структуру (вложенные подсистемы), обойти только верхний уровень Метаданные.Подсистемы недостаточно — требуется рекурсивный обход всей иерархии.
Разберем алгоритм поиска объектов, не включенных ни в одну подсистему:
Состав.Посмотрим на пример реализации данного алгоритма:
Процедура ЗаполнитьСоставПодсистемы(Подсистема, ОбъектыВПодсистемах)
Для Каждого ЭлементСостава Из Подсистема.Состав Цикл
ОбъектыВПодсистемах.Вставить(ЭлементСостава, Истина);
КонецЦикла;
Для Каждого ПодчиненнаяПодсистема Из Подсистема.Подсистемы Цикл
ЗаполнитьСоставПодсистемы(ПодчиненнаяПодсистема, ОбъектыВПодсистемах);
КонецЦикла;
КонецПроцедуры
// Использование алгоритма:
ОбъектыВПодсистемах = Новый Соответствие;
Для Каждого ТекПодсистема Из Метаданные.Подсистемы Цикл
ЗаполнитьСоставПодсистемы(ТекПодсистема, ОбъектыВПодсистемах);
КонецЦикла;
// Исключаем из полного списка объекты, входящие в подсистемы:
ОбъектыВнеПодсистем = Новый Массив;
Для Каждого КлючИЗначение Из ВсеОбъектыМетаданных Цикл
ОбъектМетаданных = КлючИЗначение.Значение;
Если ОбъектыВПодсистемах[ОбъектМетаданных] = Неопределено Тогда
ОбъектыВнеПодсистем.Добавить(ОбъектМетаданных);
КонецЕсли;
КонецЦикла;
Проанализируем технические особенности, которые необходимо учитывать при решении задачи:
ПолучитьСтруктуруХраненияБазыДанных() возвращает только объекты, физически создающие таблицы в СУБД (справочники, документы, регистры и т. д.). Обработки, отчеты и прикладные объекты без физических таблиц в данную структуру не попадают. Поэтому этот метод не подходит для получения полного перечня объектов метаданных.ИдентификаторыОбъектовМетаданных, однако при работе в режиме разработки его данные могут быть неактуальны до выполнения специальной процедуры обновления служебных данных.