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