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