Почему не работает аннотация &Вместо в модуле формы 1С и как перехватить обработчик динамического элемента

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

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

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

Причины, по которым &Вместо не срабатывает в модуле формы

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

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

Способ 1. Перехват процедуры программного создания элемента

Если элемент формы создается программно в коде типовой конфигурации, наиболее надежный способ переопределить его поведение — использовать аннотацию &Вместо для самой процедуры, в которой происходит создание элемента или вызов метода УстановитьДействие().

Рассмотрим пример. Допустим, в типовой конфигурации есть процедура, создающая реквизит и элемент формы:


&НаСервере
Процедура СоздатьДинамическийЭлемент()
    // Типовой код создания элемента
    НовыйЭлемент = Элементы.Добавить("ПолеВводаКода", Тип("ПолеФормы"), ЭтаФорма);
    НовыйЭлемент.Вид = ВидПоляФормы.ПолеВвода;
    НовыйЭлемент.УстановитьДействие("ПриИзменении", "ТиповаяПроцедура_ПриИзменении");
КонецПроцедуры

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


&НаСервере
&Вместо("СоздатьДинамическийЭлемент")
Процедура Расш_СоздатьДинамическийЭлемент()
    // Выполняем базовое создание элемента
    ПродолжитьВызов();
    
    // Переназначаем событие на нашу процедуру из расширения
    Элемент = Элементы.Найти("ПолеВводаКода");
    Если Элемент <> Неопределенность Тогда
        Элемент.УстановитьДействие("ПриИзменении", "Расш_ПриИзмененииСобственная");
    КонецЕсли;
КонецПроцедуры

Способ 2. Перехват целевой процедуры обработчика

Если вам не требуется менять алгоритм создания элемента, а нужно лишь скорректировать логику работы самого обработчика события (например, процедуры ТиповаяПроцедура_ПриИзменении), перехватывать нужно именно эту процедуру в модуле формы расширения.

Для корректной работы важно строго соблюдать следующие правила:

  1. Директивы компиляции: Директива (&НаКлиенте, &НаСервере или &НаСервереБезКонтекста) у перехватывающего метода в расширении должна полностью совпадать с оригинальной процедурой.
  2. Сигнатура метода: Количество и типы передаваемых параметров должны строго соответствовать исходной процедуре.

Посмотрим на пример перехвата клиентского обработчика события:


&НаКлиенте
&Вместо("ТиповаяПроцедура_ПриИзменении")
Процедура Расш_ТиповаяПроцедура_ПриИзменении(Элемент)
    // Дополнительный код до выполнения основной логики
    Сообщить("Сработало событие в расширении");
    
    // Вызов оригинального кода типовой конфигурации
    ПродолжитьВызов(Элемент);
    
    // Дополнительный код после выполнения основной логики
КонецПроцедуры

Способ 3. Переназначение действия через &После

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

Рассмотрим шаг за шагом, как перенаправить событие динамически созданного элемента:

  1. В модуле формы расширения создаем обработчик ПриСозданииНаСервере с аннотацией &После.
  2. Находим программно созданный элемент по его имени через коллекцию Элементы.
  3. Методом УстановитьДействие() назначаем новую процедуру-обработчик, объявленную в модуле формы расширения.

&НаСервере
&После("ПриСозданииНаСервере")
Процедура Расш_ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    ДинамическийЭлемент = Элементы.Найти("МоеДинамическоеПоле");
    Если ДинамическийЭлемент <> Неопределенность Тогда
        ДинамическийЭлемент.УстановитьДействие("ПриИзменении", "Расш_ОбработчикПриИзменении");
    КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура Расш_ОбработчикПриИзменении(Элемент)
    // Собственная логика обработки события элемента
КонецПроцедуры

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

← На главную