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

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

Как вызвать процедуру из расширения в 1С

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

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

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

Как устроена видимость кода расширения

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

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

Перехват типовой процедуры через аннотации

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

Аннотации &Перед и &После

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

&После("ПриСозданииНаСервере")

Процедура Расш1_ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

// Код расширения выполнится после типового обработчика

Сообщить("Форма создана, расширение сработало");

КонецПроцедуры

Аннотация &Вместо

Аннотация &Вместо полностью подменяет типовую процедуру. Типовой код при этом не выполняется, если его не вызвать явно через ПродолжитьВызов(). Это рискованный вариант: при обновлении типовой конфигурации изменения в перекрытой процедуре не применятся, и логика может устареть.

&Вместо("РассчитатьСкидку")

Функция Расш1_РассчитатьСкидку(ПараметрыДокумента)

Если ПараметрыДокумента.ЕстьАкция Тогда

Возврат 10; // своя логика

КонецЕсли;

Возврат ПродолжитьВызов(ПараметрыДокумента); // типовая логика

КонецФункции

Аннотация &ИзменениеИКонтроль

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

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

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

Типичная архитектура выглядит так: перехваченная процедура содержит минимум кода и делегирует работу собственному общему модулю расширения. Это упрощает сопровождение: вся прикладная логика собрана в одном месте, а перехватчики остаются тонкими и легко переносятся при обновлении.

Порядок действий
  1. 1
    Добавьте в расширение собственный общий модуль, установите нужные флаги (Сервер, ВызовСервера, Клиент)
  2. 2
    Создайте в нём экспортную процедуру с ключевым словом Экспорт
  3. 3
    Заимствуйте в расширение модуль формы или объекта, откуда нужен вызов
  4. 4
    Добавьте перехватчик с аннотацией (&После, &Вместо или &ИзменениеИКонтроль)
  5. 5
    В теле перехватчика вызовите процедуру своего общего модуля
  6. 6
    Обновите конфигурацию базы данных и проверьте работу в режиме Предприятия

Вызов через подписки на события и переопределяемые модули

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

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

Сравнение способов вызова

&Перед / &После

Подходят для добавления логики без изменения типовой. Ограничение: нельзя изменить результат типовой функции напрямую.

&Вместо

Полная подмена логики. Риск: пропуск изменений типовой процедуры при обновлении конфигурации.

&ИзменениеИКонтроль

Точечное изменение с контролем при обновлении. Требует дисциплины при переносе правок.

Подписка на событие

Вызов по событию платформы без перехвата конкретной процедуры. Не подходит для обработчиков форм.

Ограничения и контекст вызова

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

Отдельный момент — фоновые задания. Процедуру общего модуля расширения можно запустить через ФоновыеЗадания.Выполнить("МойМодуль.МояПроцедура", Параметры), если расширение подключено в сеансе, где выполняется задание. Если расширение подключено только для конкретного пользователя, фоновое задание из сеанса другого пользователя процедуру не найдёт.

Проверка результата и типичные ошибки

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

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

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

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

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

Срабатывание перехвата
Норма

Точка останова в процедуре расширения активируется при выполнении операции

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

Отладчик не заходит в процедуру — проверьте аннотацию и сигнатуру

Применение расширения
Норма

В списке расширений статус без ошибок, база обновлена

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

Расширение отмечено как неприменённое или с предупреждением

Вызов общего модуля
Норма

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

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

Ошибка «Процедура или функция не обнаружена»

Итог

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

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

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

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

Нет, типовая конфигурация не видит объекты расширения. Обходные пути — перехват процедуры переопределяемого модуля, который типовой код вызывает сам, либо подписка на событие, обработчик которой находится в расширении.

Почему перехватчик с аннотацией &После не выполняется?

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

Чем &ИзменениеИКонтроль лучше &Вместо?

&ИзменениеИКонтроль сохраняет типовой текст процедуры внутри расширения и при обновлении конфигурации показывает расхождения, позволяя перенести правки контролируемо. &Вместо полностью подменяет процедуру, и изменения поставщика применяться не будут.

Можно ли вызвать процедуру расширения из фонового задания?

Да, через ФоновыеЗадания.Выполнить с указанием имени метода общего модуля расширения. Условие — расширение должно быть подключено в сеансе, где выполняется задание, иначе метод не будет найден.

Работает ли вызов процедур расширения в безопасном режиме?

Безопасный режим не запрещает сам вызов процедур, но ограничивает опасные операции: доступ к файловой системе, COM-объектам, внешним компонентам. Если процедура расширения использует такие операции, её нужно перепроектировать или отключить безопасный режим для данного расширения с пониманием рисков.