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