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