При работе с расширениями в 1С:Предприятии 8.3 разработчики часто сталкиваются с ситуацией, когда стандартный обход коллекции Метаданные возвращает объекты всей объединенной конфигурации. Если ваша задача — программно определить, какие именно объекты (справочники, документы, реквизиты) были созданы или изменены именно в вашем расширении, стандартного цикла по Метаданные.Справочники будет недостаточно. Разберем подробно, как решить эту задачу, используя встроенные инструменты платформы и приемы прикладного программирования.
Рассмотрим основной способ идентификации принадлежности объекта. У каждого объекта метаданных (будь то справочник, документ или перечисление) существует метод РасширениеКонфигурации(). Проанализируем, как он работает:
Неопределено, это означает, что объект принадлежит основной конфигурации и никак не задействован в расширениях.РасширениеКонфигурации, значит, данный объект метаданных либо был полностью создан в расширении, либо заимствован в него из основной конфигурации для доработки.Посмотрим на пример кода, который позволяет найти все справочники, относящиеся к конкретному расширению:
Для Каждого Спр Из Метаданные.Справочники Цикл
ТекущееРасширение = Спр.РасширениеКонфигурации();
Если ТекущееРасширение <> Неопределено Тогда
Если ТекущееРасширение.Имя = "ИмяВашегоРасширения" Тогда
Сообщить("Справочник " + Спр.Имя + " принадлежит расширению " + ТекущееРасширение.Имя);
КонецЕсли;
КонецЕсли;
КонецЦикла;
Выясним важный нюанс: метод РасширениеКонфигурации() покажет объект даже в том случае, если он просто заимствован (например, чтобы добавить на форму кнопку). Если же вам нужно отфильтровать только те объекты, которые были **созданы** в расширении "с нуля", следует использовать свойство ПринадлежностьОбъекта. Рассмотрим возможные значения этого перечисления:
Проанализируем пример фильтрации только новых справочников расширения:
Для Каждого Спр Из Метаданные.Справочники Цикл
Если Спр.ПринадлежностьОбъекта = ПринадлежностьОбъекта.Расширение Тогда
Сообщить("Это новый справочник, созданный в расширении: " + Спр.Имя);
КонецЕсли;
КонецЦикла;
Часто возникает вопрос: как универсально определить расширение, в модуле которого выполняется код, не прописывая его имя строкой? Платформа не предоставляет прямой функции ЭтоРасширение(), но мы можем использовать метод «якорного объекта».
Разберем этот метод по шагам:
Посмотрим на практическую реализацию:
// Предположим, у нас есть константа "ТехническаяКонстантаДляОпределенияРасширения"
МоеРасширение = Метаданные.Константы.ТехническаяКонстантаДляОпределенияРасширения.РасширениеКонфигурации();
Для Каждого Документ Из Метаданные.Документы Цикл
Если Документ.РасширениеКонфигурации() = МоеРасширение Тогда
// Этот документ задействован в текущем расширении
КонецЕсли;
КонецЦикла;
Ситуация усложняется, когда нам нужно найти реквизиты, добавленные расширением в типовой справочник (например, в справочник Номенклатура). В этом случае проверка на уровне самого справочника ничего не даст, так как он принадлежит конфигурации. Нам нужно спуститься на уровень ниже. Рассмотрим, как это сделать:
СправочникМетаданные = Метаданные.Справочники.Номенклатура;
// Проверяем добавленные реквизиты
Для Каждого Реквизит Из СправочникМетаданные.Реквизиты Цикл
Если Реквизит.РасширениеКонфигурации() = МоеРасширение Тогда
Сообщить("В справочник 'Номенклатура' расширением добавлен реквизит: " + Реквизит.Имя);
КонецЕсли;
КонецЦикла;
// Аналогично для табличных частей
Для Каждого ТЧ Из СправочникМетаданные.ТабличныеЧасти Цикл
Если ТЧ.РасширениеКонфигурации() = МоеРасширение Тогда
Сообщить("Добавлена табличная часть: " + ТЧ.Имя);
КонецЕсли;
КонецЦикла;
Если ваша конфигурация построена на базе БСП (Библиотека Стандартных Подсистем), вы можете использовать справочник ИдентификаторыОбъектовРасширений. Это наиболее производительный способ в крупных системах. Вместо того чтобы перебирать все метаданные в памяти (что может быть медленно), вы можете выполнить запрос к этому справочнику.
Проанализируем преимущества этого подхода:
ИмяРасширения, что позволяет легко фильтровать объекты.Пример запроса для получения имен всех справочников расширения через БСП:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Идентификаторы.Имя КАК ИмяОбъекта
|ИЗ
| Справочник.ИдентификаторыОбъектовРасширений КАК Идентификаторы
|ГДЕ
| Идентификаторы.ИмяРасширения = &ИмяРасширения
| И Идентификаторы.ТипИнформационнойСсылки = ЗНАЧЕНИЕ(Перечисление.ТипыИнформационныхСсылок.Справочник)";
Запрос.УстановитьПараметр("ИмяРасширения", "МоеРасширение");
Результат = Запрос.Выполнить().Выгрузить();
Наконец, стоит упомянуть объект РасширенияКонфигурации (менеджер), который позволяет получить информацию о самих установленных в системе расширениях. С его помощью мы можем узнать состояние расширения, его версию и имя.
Рассмотрим, как получить список всех активных расширений в системе:
МассивРасширений = РасширенияКонфигурации.Получить();
Для Каждого ТекущееРасширение Из МассивРасширений Цикл
Если ТекущееРасширение.Активно Тогда
Сообщить("Установлено активное расширение: " + ТекущееРасширение.Имя + " версия: " + ТекущееРасширение.Версия);
КонецЕсли;
КонецЦикла;
Таким образом, комбинируя методы РасширениеКонфигурации(), свойство ПринадлежностьОбъекта и, при наличии, механизмы БСП, мы можем гибко и эффективно управлять метаданными в рамках модулей расширений. Для готового анализа изменений и затронутых объектов можно использовать инструмент для анализа доработок в расширениях 1С.