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

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

ОписаниеОповещения в 1С: как работает механизм оповещений

Как работает ОписаниеОповещения в 1С: создание, передача в методы, обработчики, дополнительные параметры, типичные ошибки и примеры кода на встроенном языке.

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

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

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

Что такое ОписаниеОповещения и зачем оно нужно

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

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

Как создать объект: конструктор и его параметры

Объект создаётся конструктором Новый ОписаниеОповещения(...). У конструктора три основных параметра и один необязательный для служебных целей:

  • ИмяПроцедуры — строка с именем экспортной процедуры, которая будет вызвана. Процедура обязательно должна быть с ключевым словом Экспорт и находиться в указанном модуле.
  • Модуль — объект модуля, где лежит процедура. В форме это обычно ЭтотОбъект (или ЭтаФорма в устаревших версиях), в общем модуле — имя модуля.
  • ДополнительныеПараметры — произвольное значение (часто структура), которое будет передано в обработчик без изменений.
  • ИмяПроцедурыОбработкиОшибки — необязательный параметр: процедура, которая будет вызвана, если при выполнении основного обработчика возникнет исключение.
bsl
ДопПараметры = Новый Структура("Контрагент", Контрагент);
Оповещение = Новый ОписаниеОповещения("ПослеВопросаОПроведении", ЭтотОбъект, ДопПараметры);
ПоказатьВопрос(Оповещение, "Провести документ?", РежимДиалогаВопрос.ДаНет);

Важно: процедура-обработчик должна иметь строго определённую сигнатуру — первым параметром она принимает результат операции (его тип зависит от вызвавшего метода), вторым — дополнительные параметры, которые вы указали при создании оповещения.

bsl
&НаКлиенте
Процедура ПослеВопросаОПроведении(Результат, ДополнительныеПараметры) Экспорт
	Если Результат = КодВозвратаДиалога.Да Тогда
		ЗаписатьДокумент(ДополнительныеПараметры.Контрагент);
	КонецЕсли;
КонецПроцедуры

Как платформа вызывает обработчик

Когда вы передаёте оповещение в метод (ПоказатьВопрос, ПоказатьВводЗначения, ОткрытьФорму, НачатьПомещениеФайла и т.п.), платформа запоминает его внутри себя и связывает с конкретной операцией. Ваш код после вызова продолжает выполняться — именно поэтому нельзя писать логику «после вопроса» просто следующей строкой.

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

Если пользователь просто закрыл диалог крестиком или нажал Escape, обработчик всё равно вызывается — но результат будет Неопределено (для вопросов — соответствующий код возврата диалога). Обработчик обязан корректно обрабатывать и этот случай, иначе логика «повиснет» в неопределённом состоянии.

Работа с дополнительными параметрами

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

Типичный приём — цепочки оповещений: в обработчике первого диалога создаётся новое оповещение для второго, а дополнительные параметры копируются и дополняются. Так строятся многошаговые сценарии: «ввести количество → спросить подтверждение → выполнить запись». Чтобы цепочка не превратилась в лапшу из десятка процедур, осмысленно называйте обработчики по шагу сценария: ПослеВводаКоличества, ПослеПодтвержденияЗаписи.

Порядок действий при создании оповещения
  1. 1
    Определите, какие данные понадобятся обработчику, и соберите их в структуру
  2. 2
    Создайте объект: Новый ОписаниеОповещения(ИмяПроцедуры, ЭтотОбъект, Структура)
  3. 3
    Передайте оповещение в асинхронный метод (ПоказатьВопрос, ОткрытьФорму и т.п.)
  4. 4
    Напишите экспортную процедуру-обработчик с параметрами (Результат, ДополнительныеПараметры)
  5. 5
    Обработайте случай отказа пользователя (Результат = Неопределено)
  6. 6
    Проверьте сценарий в тонком и веб-клиенте, включая закрытие диалога крестиком

Оповещения при открытии и закрытии форм

Отдельный частый сценарий — получить результат из открываемой формы. При вызове ОткрытьФорму третьим параметром передаётся описание оповещения, которое сработает при закрытии формы. В открываемой форме результат возвращается через метод Закрыть(Результат) — переданное значение и попадёт в обработчик.

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

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

ОписаниеОповещения при ОткрытьФорму

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

Оповестить + ОбработкаОповещения

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

Закрыть(Результат)

Способ вернуть значение из модальной или обычной формы в оповещение о закрытии. Работает только в паре с переданным описанием оповещения.

Обработка ошибок и особенности контекста

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

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

Типичные ошибки
01
Процедура-обработчик без Экспорт — платформа не найдёт её и выдаст ошибку вызова
02
Неверная сигнатура обработчика: пропущен параметр ДополнительныеПараметры — получите ошибку о несоответствии числа параметров
03
Логика написана строкой после ПоказатьВопрос — она выполнится до ответа пользователя
04
Не обработан результат Неопределено при закрытии диалога крестиком — сценарий зависает или падает
05
Обработчик размещён в модуле формы, которая закрывается до срабатывания — ошибка вызова
06
Модальные методы Вопрос()/ВвестиЗначение() вместо оповещений — код не работает в веб-клиенте

Где применяется механизм и как проверить результат

ОписаниеОповещения используется практически во всех клиентских асинхронных API платформы: диалоги (ПоказатьВопрос, ПоказатьВводЗначения, ПоказатьПредупреждение), открытие форм, файловые операции (НачатьПомещениеФайла, НачатьПолучениеФайлов), работа с расширениями для работы с файлами и криптографией. Во всех этих местах единый принцип: создать оповещение, передать, получить результат в обработчике.

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

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

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

Обработчик вызывается
Норма

Процедура срабатывает при любом ответе и при закрытии крестиком

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

При отмене диалога обработчик не вызывается или падает с ошибкой

Дополнительные параметры
Норма

В обработчике доступны все переданные данные структуры

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

Параметры равны Неопределено — значит, не переданы при создании

Работа в веб-клиенте
Норма

Сценарий проходит без ошибок модальности

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

Сообщения о запрете модальных вызовов — остались старые методы

Итог

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

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

Часто задаваемые вопросы

Чем ОписаниеОповещения отличается от метода Оповестить()?

ОписаниеОповещения — это разовый обратный вызов конкретной процедуры после завершения конкретной операции. Оповестить() рассылает событие всем открытым формам, которые перехватывают его в ОбработкаОповещения. Первый механизм адресный и одноразовый, второй — широковещательный и многоразовый.

Почему платформа выдаёт ошибку «Процедура не обнаружена» при срабатывании оповещения?

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

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

Да, через параметр ДополнительныеПараметры. Обычно в него упаковывают структуру с произвольным числом ключей. Ограничений по составу нет, но передавать следует только сериализуемые в данном контексте данные.

Что получит обработчик, если пользователь закрыл диалог крестиком?

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

Можно ли использовать ОписаниеОповещения на сервере?

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

Как организовать цепочку из нескольких диалогов подряд?

В обработчике первого диалога создайте новое ОписаниеОповещения для второго шага, перенеся нужные данные в дополнительные параметры. Каждый шаг — отдельная экспортная процедура с осмысленным именем, иначе цепочку будет трудно сопровождать.