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

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

Как вызвать событие элемента формы в 1С

Как программно вызвать событие элемента формы в 1С: обработчики ПриИзменении, НачалоВыбора, Нажатие. Примеры кода, типичные ошибки и ограничения.

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

Ключевой принцип: обработчик события — это обычная процедура модуля формы. Её можно вызвать напрямую, передав те же параметры, что передаёт платформа: ссылку на элемент и, для некоторых событий, дополнительные параметры вроде «СтандартнаяОбработка» или «ВыбранноеЗначение». Главная сложность — получить корректную ссылку на элемент формы и не нарушить контекст выполнения (клиент/сервер).

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

Почему событие нельзя «нажать» напрямую

В платформе 1С нет метода вида Элементы.Поле1.ВызватьСобытие("ПриИзменении"). Элемент формы — это объект описания, а не активный компонент с очередью сообщений, как в некоторых других средах разработки. Событие генерирует сама платформа в ответ на действие пользователя или системное изменение данных.

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

Способ 1. Прямой вызов обработчика события

Самый простой приём — вызвать процедуру обработчика как обычную процедуру модуля формы. Для этого нужно передать ей параметры, которые платформа передавала бы автоматически. Минимальный набор для большинства событий — ссылка на элемент формы через коллекцию Элементы.

&НаКлиенте

Процедура ЗагрузитьДанныеПослеОткрытия()

// Программно меняем значение реквизита

Объект.СтавкаНДС = ПредопределенноеЗначение(

"Перечисление.СтавкиНДС.НДС20");

// Вручную вызываем обработчик события элемента

СтавкаНДСПриИзменении(Элементы.СтавкаНДС);

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

&НаКлиенте

Процедура СтавкаНДСПриИзменении(Элемент)

ПересчитатьСуммыДокумента();

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

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

bsl
// Вызов обработчика нажатия кнопки из другого места формы
КнопкаЗаполнитьНажатие(Элементы.Заполнить);

Способ 2. Вынос логики в отдельную процедуру

Прямой вызов обработчика хрупок: при изменении сигнатуры события или переименовании элемента код сломается. Более устойчивая практика — вынести всю полезную работу в отдельную процедуру, а обработчик события сделать тонкой обёрткой. Тогда программный вызов идёт к этой процедуре напрямую, без имитации параметров события.

&НаКлиенте

Процедура СтавкаНДСПриИзменении(Элемент)

ПересчитатьСуммыДокумента();

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

&НаКлиенте

Процедура ПересчитатьСуммыДокумента()

Для Каждого Строка Из Объект.Товары Цикл

Строка.СуммаНДС = Строка.Сумма * 20 / 120;

КонецЦикла;

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

&НаКлиенте

Процедура ПриОткрытии(Отказ)

// Тот же пересчёт без эмуляции события

ПересчитатьСуммыДокумента();

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

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

Способ 3. Команды формы и подключаемые обработчики

Для кнопок вместо события «Нажатие» часто используют команды формы. Команду можно выполнить программно — но не напрямую, а через вызов её обработчика. В типовых конфигурациях на БСП применяется механизм подключаемых команд: обработчик имеет вид Подключаемый_ВыполнитьКоманду, и программный вызов делается через тот же механизм.

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

&НаКлиенте

Процедура ПриОткрытии(Отказ)

ПодключитьОбработчикОжидания("ОбновитьСписокОтложенно", 0.1, Истина);

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

Сравнение подходов

Прямой вызов обработчика

Быстро реализовать, но нужно вручную формировать параметры события; ломается при смене сигнатуры

Отдельная процедура с логикой

Устойчиво к изменениям, работает в любом контексте; требует рефакторинга обработчиков

Обработчик ожидания

Подходит для отложенного запуска после открытия формы; не заменяет реальное событие элемента

Контекст выполнения: клиент и сервер

Частая причина неудачного вызова — неверная директива компиляции. Обработчики событий элементов формы компилируются с &НаКлиенте, и вызывать их можно только из клиентского кода той же формы. Из серверной процедуры или из другой формы напрямую обратиться к обработчику нельзя.

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

// В форме-источнике

Оповестить("ИзмененаСтавкаНДС", Новый Структура("Ставка", Ставка), ЭтотОбъект);

// В форме-приёмнике

&НаКлиенте

Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)

Если ИмяСобытия = "ИзмененаСтавкаНДС" Тогда

ПересчитатьСуммыДокумента();

КонецЕсли;

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

Типичные ошибки при программном вызове событий

Первая ошибка — ожидание, что присвоение значения реквизиту в коде вызовет «ПриИзменении». Платформа генерирует это событие только при интерактивном редактировании. Программное изменение требует явного вызова обработчика или процедуры с логикой.

Вторая ошибка — передача в обработчик имени элемента строкой вместо самого элемента. Правильно: ПолеПриИзменении(Элементы.Контрагент), а не ПолеПриИзменении("Контрагент"). Внутри обработчика часто обращаются к свойствам элемента, и строка вызовет ошибку.

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

Типичные ошибки
01
Присвоение реквизиту в коде и ожидание срабатывания ПриИзменении — событие возникает только при интерактивном вводе
02
Передача строки с именем элемента вместо Элементы.ИмяЭлемента — обработчик падает при обращении к свойствам
03
Вызов клиентского обработчика из серверной процедуры — ошибка контекста компиляции
04
Несовпадение числа параметров с сигнатурой события — ошибка выполнения при вызове

Как проверить, что вызов отработал

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

Для отладки удобно поставить точку останова внутри обработчика и выполнить программный вызов: стек вызовов покажет, откуда пришло управление, а значения параметров — корректно ли сформирован элемент. Если обработчик использует «СтандартнаяОбработка» или другие выходные параметры, убедитесь, что при программном вызове их значения не влияют на логику непредвиденным образом.

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

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

Значения реквизитов после вызова
Норма

Данные пересчитаны так же, как при ручном вводе

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

Значения не изменились или посчитаны дважды

Состояние элементов формы
Норма

Видимость и доступность соответствуют данным

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

Кнопки и поля остались в старом состоянии

Повторный интерактивный ввод
Норма

Обработчик срабатывает один раз и корректно

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

Двойной пересчёт или ошибка при ручном изменении

Когда программный вызов события не нужен

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

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

Итог

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

Событие элемента формы в 1С вызывают программно, обращаясь к процедуре-обработчику напрямую с параметром Элементы.ИмяЭлемента, либо — надёжнее — вынося логику в отдельную процедуру. Программное изменение реквизита само по себе событие не вызывает, а клиентские обработчики недоступны из серверного контекста.

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

Вызывается ли «ПриИзменении», если изменить реквизит программно?

Нет. Событие «ПриИзменении» возникает только при интерактивном редактировании пользователем. После программного присвоения значения обработчик нужно вызвать явно или выполнить его логику через отдельную процедуру.

Как вызвать обработчик события из другой формы?

Напрямую — никак, модуль формы закрыт для внешних вызовов. Используйте механизм оповещений: в форме-источнике вызовите Оповестить с именем события и параметрами, а в форме-приёмнике обработайте его в процедуре ОбработкаОповещения.

Что передавать в параметр «Элемент» при ручном вызове?

Ссылку на элемент формы из коллекции Элементы, например Элементы.Контрагент. Если конкретный элемент не важен для логики, иногда передают Неопределено, но это безопасно только когда обработчик не обращается к свойствам параметра.

Можно ли вызвать клиентский обработчик с сервера?

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

Как программно «нажать» кнопку формы?

Специального метода нажатия нет. Вызовите процедуру-обработчик команды кнопки напрямую: ИмяОбработчика(Элементы.ИмяКнопки) для события «Нажатие» или ИмяОбработчикаКоманды(Команда) для команды формы. Оптимально — вынести действие кнопки в отдельную процедуру.

Почему после программного вызова логика срабатывает дважды?

Обычно потому, что обработчик вызван из кода, а затем пользователь изменил поле вручную, и событие сработало снова. Проверьте, не дублируете ли вы вызов: например, в «ПриОткрытии» и одновременно в обработчике ожидания. Оставьте одну точку входа.