К статье
Практический материал

Разработка и Конфигурация · 12 мин

Как обратиться к объекту расширения в 1С

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

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

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

Ниже разобраны все три сценария с примерами кода, ограничениями и способами проверить результат до выкладки в продуктив.

Что такое объект расширения и как он виден платформе

Когда расширение подключено и активно, платформа объединяет его метаданные с основной конфигурацией. Добавленный расширением справочник «МаршрутыДоставки» после перезапуска сеанса доступен как Справочники.МаршрутыДоставки — точно так же, как штатный объект. Заимствованные объекты (изменённые формы, модули, роли) подменяют оригиналы прозрачно для вызывающего кода.

Ключевая особенность: если расширение отключено, удалено или не применено из-за несовместимости версии, его объекты исчезают из метаданных. Любое прямое обращение к ним из кода основной конфигурации приведёт к ошибке компиляции модуля или к исключению времени выполнения. Поэтому архитектурно правильно либо вызывать объекты расширения только из кода самого расширения, либо оборачивать обращения проверками.

Как получить само расширение через менеджер РасширенияКонфигурации

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

Отбор = Новый Структура("Имя", "МоеРасширение");

Найденные = РасширенияКонфигурации.Получить(Отбор);

Если Найденные.Количество() > 0 Тогда

Расширение = Найденные[0];

Сообщить("Версия: " + Расширение.Версия);

Сообщить("Активно: " + Расширение.Активно);

Сообщить("Безопасный режим: " + Расширение.БезопасныйРежим);

Иначе

Сообщить("Расширение не установлено");

КонецЕсли;

Объект РасширениеКонфигурации содержит свойства: Имя, Синоним, Версия, Активно, БезопасныйРежим, ЗащитаОтОпасныхДействий, ИспользоватьВОсновныхРолях, УникальныйИдентификатор. Метод ПолучитьДанные() возвращает двоичные данные расширения (файл .cfe), а УстановитьДанные() позволяет программно обновить расширение из файла.

Обратите внимание: методы записи и изменения расширений требуют права «Администрирование расширений конфигурации». В типовых ролях это право есть у администратора, но не у рядовых пользователей. Чтение списка расширений доступно шире, однако полагаться на это в коде под любым пользователем не стоит — проверяйте поведение под целевой ролью.

bsl
Отбор = Новый Структура("Имя", "МоеРасширение");
Массив = РасширенияКонфигурации.Получить(Отбор);
Если Массив.Количество() > 0 Тогда
    Возврат Массив[0].Активно;
КонецЕсли;

Как обратиться к объектам, добавленным расширением

Когда расширение активно, его объекты доступны через стандартные менеджеры: Справочники.ИмяОбъекта, Документы.ИмяОбъекта, РегистрыСведений.ИмяОбъекта и так далее. Внутри кода самого расширения это работает безусловно. Проблема возникает, когда к объекту расширения обращается код основной конфигурации или другого расширения.

Безопасный шаблон — проверка через метаданные перед обращением:

Если Метаданные.Справочники.Найти("МаршрутыДоставки") <> Неопределено Тогда

НовыйЭлемент = Справочники["МаршрутыДоставки"].СоздатьЭлемент();

НовыйЭлемент.Наименование = "Тестовый маршрут";

НовыйЭлемент.Записать();

Иначе

// Расширение не подключено — выполняем обходную логику

КонецЕсли;

Строковое обращение Справочники["МаршрутыДоставки"] вместо точечного Справочники.МаршрутыДоставки важно: оно не ломает компиляцию модуля, если объекта нет. Точечное обращение к несуществующему объекту вызывает ошибку ещё на этапе проверки модуля — и вся процедура станет недоступной.

Как вызвать процедуру из общего модуля расширения

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

Универсальный приём — вызов через ОбщегоНазначения.ОбщийМодуль() в БСП-подобных конфигурациях или через Вычислить()/Выполнить() с проверкой наличия модуля в метаданных:

Если Метаданные.ОбщиеМодули.Найти("МойМодульРасширения") <> Неопределено Тогда

Результат = Вычислить("МойМодульРасширения.ПолучитьНастройки()");

КонецЕсли;

Более надёжная архитектура — инверсия зависимости: расширение само регистрируется в механизме подписок на события или в переопределяемых модулях основной конфигурации. Тогда основная конфигурация вообще не знает о расширении, а расширение вызывается платформой через стандартные точки расширения (обработчики событий, аннотации &ИзменениеИКонтроль, &Вместо, &После, &Перед).

Как проверить подключение и применимость расширения перед обращением

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

Порядок проверки доступности объектов расширения
  1. 1
    Получите расширение через РасширенияКонфигурации.Получить() с отбором по имени
  2. 2
    Проверьте свойство Активно — неактивное расширение не применяется
  3. 3
    Убедитесь через Метаданные.Найти(), что нужный объект реально существует в текущем сеансе
  4. 4
    Обращайтесь к объекту строковым индексом менеджера, а не точечной нотацией
  5. 5
    Оберните вызов в Попытка/Исключение и зафиксируйте ошибку в журнале регистрации

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

Ограничения и типичные ошибки

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

В безопасном режиме (свойство БезопасныйРежим) код расширения не может обращаться к файловой системе, COM-объектам и внешним компонентам. Если расширение загружено из файла в базу с включённым профилем безопасности, вызовы НайтиФайлы() или работа с временными файлами завершатся исключением — это нужно учитывать при проектировании.

Типичные ошибки
01
Точечное обращение Справочники.ОбъектРасширения из основной конфигурации — при отключении расширения модуль перестаёт компилироваться и ломаются все процедуры модуля
02
Проверка только наличия расширения без проверки флага Активно — код падает, хотя расширение «установлено»
03
Использование &Вместо там, где достаточно &После — после обновления конфигурации теряются изменения типовой логики
04
Обращение к объекту расширения из другого расширения без проверки порядка применения — расширения применяются в неопределённом порядке, и зависимость может не сработать
05
Игнорирование безопасного режима — код, работающий в тестовой базе, падает в рабочей с профилем безопасности

Программная установка и обновление расширения

Если под «обращением к объекту расширения» понимается загрузка расширения из файла, используется связка ПолучитьДанные() и УстановитьДанные() или создание нового расширения через РасширенияКонфигурации.Создать():

ДанныеФайла = Новый ДвоичныеДанные("C:\Extensions\МоеРасширение.cfe");

Расширение = РасширенияКонфигурации.Создать();

Расширение.БезопасныйРежим = Ложь;

Расширение.УстановитьДанные(ДанныеФайла);

Расширение.Записать();

После записи расширение применяется не мгновенно: для подключения новых метаданных требуется перезапуск сеанса (в клиент-серверном режиме — переподключение сеансов, работающих с расширением). Проверка результата: открыть сеанс заново и убедиться, что Метаданные содержат добавленные объекты, а в журнале регистрации нет ошибок применения расширения.

Как проверить результат

Контрольные точки

Контрольные точки

Список расширений в конфигураторе или через РасширенияКонфигурации.Получить()
Норма

Расширение есть, Активно = Истина, версия соответствует ожидаемой

Тревожный признак

Расширения нет в списке или Активно = Ложь

Метаданные.Справочники.Найти("ИмяОбъектаРасширения")
Норма

Возвращает объект метаданных — можно обращаться из кода

Тревожный признак

Возвращает Неопределено — расширение не применено, обращаться нельзя

Журнал регистрации после перезапуска сеанса
Норма

Нет ошибок применения расширения

Тревожный признак

Ошибки совместимости версии конфигурации или прав доступа

Вызов объекта под целевой ролью пользователя
Норма

Код выполняется без исключений

Тревожный признак

Нарушение прав доступа или ошибка компиляции модуля

Частые вопросы

Можно ли из одного расширения обратиться к объекту другого расширения?

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

Почему объект расширения виден в конфигураторе, но недоступен в коде?

Чаще всего расширение не применено к текущему сеансу: оно подключено после старта сеанса, либо отключено, либо несовместимо с текущей версией конфигурации. Перезапустите сеанс и проверьте РасширенияКонфигурации.Получить() — свойство Активно и наличие объекта в Метаданные.

Как обратиться к реквизиту, добавленному расширением, в запросе?

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

Чем отличается Получить() с отбором от перебора всех расширений?

Отбор по имени работает быстрее и читаемее, но учитывайте, что имя расширения регистрозависимо в отборе не всегда и может отличаться от синонима, который видит пользователь в списке. Для надёжности сравнивайте имя через ВРег() при переборе, если точное написание неизвестно.

Можно ли вызвать экспортную процедуру модуля расширения из внешней обработки?

Да, если расширение активно: обращение идёт как к обычному общему модулю. Но внешняя обработка компилируется в контексте текущих метаданных, поэтому при отключённом расширении точечный вызов вызовет ошибку. Используйте Вычислить("ИмяМодуля.ИмяПроцедуры()") с предварительной проверкой наличия модуля.

Что происходит с данными при отключении расширения?

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

Итог

Что важно запомнить

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