Как использовать аннотации &Перед и &После одновременно для одной процедуры в расширении 1С?

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

Часто при разработке расширений конфигурации возникает задача: необходимо добавить несколько строк собственного кода до выполнения типовой процедуры и еще пару строк — сразу после нее. При этом переносить сотни строк типового кода в расширение с помощью аннотации &Вместо категорически не хочется. Если попытаться "в лоб" написать две процедуры с аннотациями &Перед и &После, платформа 1С начнет ругаться на дублирование имени процедуры в расширении. Давайте разберем по шагам, как грамотно обойти это ограничение и какие еще существуют способы решения этой архитектурной задачи.

Штатное решение: уникальные имена процедур в расширении

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

Посмотрим на пример правильного оформления кода. Мы можем создать две процедуры с разными именами в расширении, но привязать их к одной и той же типовой процедуре:


&Перед("ТвояПроцедура")
Процедура Расш1_ТвояПроцедура(Параметр)
    // Ваш код, который должен выполниться ДО типового метода
КонецПроцедуры

&После("ТвояПроцедура")
Процедура Расш1_ТвояПроцедура_После(Параметр)
    // Ваш код, который должен выполниться ПОСЛЕ типового метода
КонецПроцедуры

Такой подход читается лучше всего, так как аннотации четко сигнализируют программисту о дополнении логики до и после типового кода.

Альтернативный вариант: использование &Вместо и ПродолжитьВызов()

Рассмотрим подробнее еще одну хорошую идею. Мы можем использовать аннотацию &Вместо совместно с методом ПродолжитьВызов(). Это позволяет перехватить управление, выполнить свои действия, затем запустить исходный типовой код и после него продолжить работу расширения.


&Вместо("Процедура")
Процедура Расш_Процедура(Параметр)
    // Ваш код до вызова типового метода
    ПродолжитьВызов(Параметр);
    // Ваш код после вызова типового метода
КонецПроцедуры

Главное и неочевидное преимущество этого способа — единый контекст.

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

Однако стоит учитывать и недостаток: архитектурно &Вместо говорит программисту о "перекрытии" алгоритма, что может усложнить чтение и понимание кода другими разработчиками.

Точечное изменение кода: аннотация &ИзменениеИКонтроль

Разберем еще один мощный инструмент, появившийся в платформе 1С начиная с версии 8.3.15 — аннотацию &ИзменениеИКонтроль. Данный механизм позволяет не просто написать код до и после, а точечно изменить середину типовой процедуры, используя инструкции препроцессора #Вставка, #КонецВставки, #Удаление и #КонецУдаления.

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

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

Порядок выполнения при наличии нескольких расширений

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

  1. Аннотации &Перед выполняются в обратном порядке подключения расширений — от самого нового (последнего зарегистрированного) к самому старому.
  2. Аннотации &После выполняются в прямом порядке — от первого зарегистрированного расширения к последнему.

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

Ограничения расширений и работа в привилегированном режиме

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

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

← На главную