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