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