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