Разработка и Конфигурация · 12 мин
Как инициировать событие в 1С
Как инициировать событие в 1С: метод Оповестить, обработчики ожидания, события формы и подписки на события. Примеры кода, типичные ошибки и FAQ.
В 1С:Предприятии «инициировать событие» означает вызвать программный механизм, который запустит обработчик в другой части конфигурации: открытой форме, модуле объекта или общем модуле. В зависимости от задачи используются разные инструменты: метод Оповестить(), подключение обработчика ожидания, события формы, подписки на события в конфигураторе и регламентные задания. Выбор зависит от того, кто должен получить событие и в каком контексте — клиентском или серверном.
Чаще всего разработчику нужно передать сигнал из одной формы в другую: например, после записи документа обновить список в открытом окне журнала. Для этого достаточно вызвать Оповестить("ЗаписанДокумент", Параметры, КлючУникальности), а в форме-приёмнике реализовать процедуру ОбработкаОповещения(ИмяСобытия, Параметр, Источник). Это простейший и самый распространённый сценарий инициирования события.
Перед написанием кода важно понять границы механизмов: оповещения работают только между открытыми формами в рамках одного сеанса, подписки на события срабатывают при изменении данных, а обработчики ожидания выполняются по таймеру на клиенте. Ниже разобраны все основные способы с примерами кода и критериями выбора.
Способы инициирования событий: какой механизм выбрать
В платформе 1С нет единственного «события» — есть семейство механизмов, каждый из которых решает свою задачу. Неправильный выбор приводит к тому, что событие либо не доходит до получателя, либо срабатывает слишком часто и замедляет работу пользователей.
Основные варианты: метод Оповестить() для связи между формами, ОповеститьОбИзменении() для уведомления об изменении конкретного объекта, подписки на события для серверной логики при записи данных, обработчики ожидания для периодических проверок на клиенте, регламентные задания для фонового выполнения на сервере.
Сравнение вариантов
Связь между открытыми формами в одном сеансе. Не работает между разными сеансами и пользователями.
Реакция на запись или проведение объектов на сервере. Срабатывает для всех пользователей, но не передаёт данные в открытые формы.
Периодические действия на клиенте по таймеру. Не подходит для точного реагирования на изменения данных.
Фоновое выполнение на сервере по расписанию. Не взаимодействует с интерфейсом пользователя напрямую.
Инициирование события через Оповестить
Метод Оповестить() — основной способ передать событие между открытыми формами. Синтаксис: Оповестить(ИмяСобытия, Параметр, Источник). Имя события — произвольная строка, по которой приёмник отличит ваше сообщение от других. Параметр — любое значение, чаще всего структура с данными. Источник обычно передают как ЭтаФорма или уникальный идентификатор формы, чтобы приёмник мог проверить отправителя.
Пример: в форме документа после записи нужно обновить список заказов. В модуле формы документа пишем:
&НаКлиенте
Процедура ПослеЗаписи(ПараметрыЗаписи)
ПараметрыОповещения = Новый Структура("Ссылка", Объект.Ссылка);
Оповестить("ЗаписанЗаказПокупателя", ПараметрыОповещения, ЭтаФорма);
КонецПроцедуры
В форме списка, которая должна отреагировать, добавляем обработчик:
&НаКлиенте
Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)
Если ИмяСобытия = "ЗаписанЗаказПокупателя" Тогда
Элементы.Список.Обновить();
КонецЕсли;
КонецПроцедуры
Обратите внимание: обработчик сработает во всех открытых формах, где объявлена процедура ОбработкаОповещения. Поэтому всегда проверяйте ИмяСобытия и, при необходимости, Источник, иначе форма будет реагировать на чужие сообщения.
- 1Определите, какая форма должна получить событие, и убедитесь, что она открыта в момент вызова
- 2В форме-источнике вызовите Оповестить() с уникальным именем события и структурой параметров
- 3В форме-приёмнике создайте процедуру ОбработкаОповещения с проверкой ИмяСобытия
- 4Протестируйте: откройте обе формы, выполните действие-источник и убедитесь, что приёмник среагировал
- 5Проверьте, что при закрытой форме-приёмнике система работает без ошибок — оповещение просто никому не доставляется
ОповеститьОбИзменении и события динамических списков
Для стандартного сценария «объект изменился — обновите списки» платформа предлагает специализированный метод ОповеститьОбИзменении(Ссылка). Он автоматически инициирует обновление всех динамических списков, в которых отображается этот объект, без необходимости писать обработчик вручную.
Этот метод удобно вызывать после программной записи объекта, когда стандартная команда «Записать» не использовалась и интерфейс не обновился сам. Например, после массовой обработки документов из формы обработки:
&НаКлиенте
Процедура ОбработатьДокументы(Команда)
ОбработатьДокументыНаСервере();
Для Каждого Ссылка Из СписокОбработанных Цикл
ОповеститьОбИзменении(Ссылка);
КонецЦикла;
КонецПроцедуры
Ограничение: метод сообщает только факт изменения конкретной ссылки и не передаёт произвольные параметры. Если приёмнику нужны дополнительные данные (например, какое именно поле изменилось), используйте обычный Оповестить() со структурой параметров.
Подписки на события: инициирование на сервере
Подписка на событие — механизм конфигуратора, который автоматически вызывает обработчик при наступлении системного события: записи, проведения, удаления объекта. Здесь событие инициирует сама платформа, а разработчик лишь подписывается на него. Настройка выполняется в конфигураторе: ветка «Общие» → «Подписки на события».
Для создания подписки укажите источник (например, ДокументОбъект.ЗаказКлиента), событие (ПриЗаписи, ОбработкаПроведения) и обработчик — экспортную процедуру общего модуля. Платформа будет вызывать её каждый раз при наступлении события, независимо от того, кто инициировал запись: пользователь, обмен данными или фоновое задание.
Процедура ПриЗаписиЗаказаОбновитьСтатус(Источник, Отказ) Экспорт
Если Источник.ОбменДанными.Загрузка Тогда
Возврат;
КонецЕсли;
// логика реакции на запись
КонецПроцедуры
Ключевой риск подписок — рекурсия и избыточные срабатывания. Проверяйте Источник.ОбменДанными.Загрузка, чтобы не выполнять логику при загрузке данных через обмены, и используйте ДополнительныеСвойства для передачи флагов между обработчиками и предотвращения повторных вызовов.
Обработчики ожидания: событие по таймеру
Если событие должно инициироваться не действием пользователя, а временем, применяется ПодключитьОбработчикОжидания(ИмяПроцедуры, Интервал, Однократно). Платформа будет вызывать указанную клиентскую процедуру с заданным интервалом в секундах.
&НаКлиенте
Процедура ПриОткрытии(Отказ)
ПодключитьОбработчикОжидания("ПроверитьНовыеСообщения", 60);
КонецПроцедуры
&НаКлиенте
Процедура ПроверитьНовыеСообщения()
// периодическая проверка
КонецПроцедуры
Обработчик ожидания работает только пока открыта форма, которая его подключила. При закрытии формы вызовы прекращаются автоматически, но хорошей практикой считается явный вызов ОтключитьОбработчикОжидания() при закрытии. Не ставьте слишком маленький интервал: частые обращения к серверу из обработчика ожидания заметно нагружают систему при большом числе пользователей.
Генерация событий формы и программный вызов обработчиков
Иногда требуется инициировать стандартное событие формы вручную — например, вызвать обработчик изменения поля после программного заполнения данных. Прямого метода «сгенерировать событие» нет, но обработчик можно вызвать как обычную процедуру, передав нужные параметры:
&НаКлиенте
Процедура ЗаполнитьПоУмолчанию()
Объект.Валюта = ПредопределенноеЗначение("Справочник.Валюты.Рубль");
ВалютаПриИзменении(Элементы.Валюта); // программный вызов обработчика
КонецПроцедуры
Такой приём корректен, если обработчик не зависит от интерактивного контекста. Для оповещений с гарантированной доставкой результата используйте ОписаниеОповещения — механизм обратного вызова, который инициирует выполнение процедуры после закрытия формы или завершения асинхронной операции через ВыполнитьОбработкуОповещения().
Проверка результата и отладка событий
Отладка событийных механизмов отличается тем, что точку останова нужно ставить не в месте инициирования, а в обработчике. Для оповещений установите точку в ОбработкаОповещения формы-приёмника и убедитесь, что она открыта в отлаживаемом сеансе. Для подписок на события включите отладку серверных вызовов и поставьте точку в общем модуле обработчика.
Если событие не срабатывает, проверьте типичные причины: форма-приёмник закрыта, имя события написано с опечаткой (строки сравниваются без учёта регистра, но лишние пробелы ломают сравнение), подписка на событие не включена в конфигурации или её обработчик находится в модуле без флага «Сервер». Для диагностики полезно временно добавить Сообщить(ИмяСобытия) в начало обработчика.
Как проверить результат
Процедура ОбработкаОповещения в приёмнике вызывается с правильным ИмяСобытия
Обработчик молчит — форма закрыта или имя события не совпадает
Обработчик общего модуля вызывается при каждой записи объекта
Не вызывается — проверьте источник подписки и флаги компиляции модуля
Процедура вызывается с заданным интервалом, пока форма открыта
Вызовов нет — процедура не экспортная или имя указано с ошибкой
FAQ
Можно ли передать событие другому пользователю через Оповестить?
Нет, метод Оповестить работает только между формами внутри одного сеанса. Для передачи сигналов между пользователями применяют регистрацию изменений в планах обмена, систему взаимодействия или периодический опрос данных через регламентные задания и обработчики ожидания.
Чем отличается Оповестить от ОповеститьОбИзменении?
Оповестить передаёт произвольное имя события и параметры, а получатель обязан иметь обработчик ОбработкаОповещения. ОповеститьОбИзменении принимает только ссылку и автоматически обновляет динамические списки и открытые формы этого объекта без написания обработчика.
Почему обработчик ожидания перестал работать?
Обработчик ожидания привязан к форме: после её закрытия вызовы прекращаются. Также проверьте, что процедура объявлена с директивой &НаКлиенте, её имя в ПодключитьОбработчикОжидания указано строкой без ошибок, а форма не была переоткрыта с потерей подключения.
Как избежать зацикливания в подписке на событие записи?
Перед повторной записью объекта установите признак в Источник.ДополнительныеСвойства, например ДополнительныеСвойства.Вставить("ОбработкаВыполнена", Истина), а в начале обработчика проверяйте этот флаг и выходите. Дополнительно пропускайте выполнение при Источник.ОбменДанными.Загрузка = Истина.
Можно ли инициировать событие из внешней обработки?
Да, внешние обработки используют те же механизмы: Оповестить из формы обработки дойдёт до всех открытых форм сеанса, а ПодключитьОбработчикОжидания будет работать, пока открыта форма обработки. Ограничение — внешняя обработка не может иметь собственных подписок на события, они создаются только в конфигурации или расширении.
Что выбрать для периодической серверной задачи без участия пользователя?
Регламентное задание. Оно выполняется на сервере по расписанию независимо от открытых сеансов, поддерживает журнал ошибок и повторные запуски. Обработчик ожидания для этой цели не подходит, так как требует открытой формы и работающего клиента.
Что важно запомнить
Для связи между открытыми формами используйте Оповестить с проверкой ИмяСобытия в приёмнике, для реакции на запись данных — подписки на события с защитой от рекурсии, для периодических действий — обработчики ожидания на клиенте и регламентные задания на сервере. Оповещения не пересекают границу сеанса: для связи между пользователями нужны другие механизмы.