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