Входят ли добавленные объекты расширений в глобальную коллекцию Метаданные

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

Поведение глобального объекта Метаданные

Проанализируем базовый принцип работы платформы. Глобальное свойство Метаданные всегда жестко связано только с основной конфигурацией. Это означает, что если мы добавили новый справочник или документ непосредственно в расширение (а не заимствовали его), он не будет отображаться в итераторах типа Для Каждого Объект Из Метаданные.Справочники Цикл. Платформа изолирует дерево объектов основной конфигурации от деревьев объектов каждого конкретного расширения.

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

Поиск объектов через НайтиПоПолномуИмени и НайтиПоТипу

Выясним, как платформа объединяет пространства имен в режиме «Предприятие». Несмотря на то что в коллекции Метаданные.Документы объектов расширения нет, специальные методы поиска работают иначе. Методы Метаданные.НайтиПоПолномуИмени() и Метаданные.НайтиПоТипу() анализируют все пространство имен текущего сеанса.

Рассмотрим пример: если в расширении создан справочник ДопСправочник, то следующий код вернет объект метаданных, несмотря на его отсутствие в общем дереве:


ОбъектМетаданных = Метаданные.НайтиПоПолномуИмени("Справочник.ДопСправочник");
Если ОбъектМетаданных <> Неопределено Тогда
    Сообщить("Объект найден, его имя: " + ОбъектМетаданных.Имя);
КонецЕсли;

Это происходит потому, что данные методы обращаются к динамически сформированной модели данных сеанса, в которой расширения уже «приклеены» к основной конфигурации. Это ключевое различие, которое нужно учитывать при разработке.

Программный анализ конкретного расширения

Иногда требуется проанализировать структуру конкретного расширения, чтобы понять, какие именно объекты оно привнесло в систему. Для этого мы не можем использовать глобальный контекст напрямую. Нам понадобится менеджер расширений. Разберем по шагам, как получить доступ к метаданным расширения программно:

  1. Получаем массив всех расширений через РасширенияКонфигурации.Получить().
  2. Извлекаем двоичные данные конкретного расширения методом ПолучитьДанные() (для внешней работы с ними пригодится распаковщик конфигураций).
  3. Создаем специальный объект ОбъектМетаданныхКонфигурация, передавая в него эти данные.

Рассмотрим пример кода, реализующий этот алгоритм:


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

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

Различия между заимствованными и собственными объектами

Проанализируем ситуацию, когда объект уже существует в основной конфигурации, но мы «заимствовали» его в расширение. Здесь поведение платформы разделяется:

Работа с менеджерами и конструктором запросов

Посмотрим, как расширения влияют на другие инструменты разработчика. В программном коде обращение к менеджерам объектов из расширений происходит прозрачно. Если расширение подключено, конструкция Справочники.ДопСправочник.НайтиПоНаименованию(...) будет работать корректно, так как коллекция Справочники в рантайме объединяет менеджеры из всех источников.

Однако стоит обратить внимание на поведение Конструктора запросов:

Использование типов данных для обхода ограничений

Если вам необходимо проверить, относится ли объект к расширению, или работать с типами, которые могут появиться только после подключения расширения, используйте функцию Тип(). Платформа динамически расширяет пространство типов при загрузке сеанса. Например, Тип("СправочникСсылка.МойОбъектИзРасширения") вернет валидный тип, который можно использовать для сравнения в универсальных алгоритмах обработки данных. Это наиболее надежный способ интеграции расширений в общие механизмы системы без прямого обращения к дереву метаданных.

← На главную