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