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

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

Как оповестить открытую форму в 1С

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

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

Механизм работает внутри одного сеанса клиентского приложения: оповещение получают только формы, открытые в данный момент у текущего пользователя. Это не способ передать данные другому пользователю или между сеансами — для таких задач существуют другие инструменты. Понимание границ механизма избавляет от типичных ошибок проектирования.

Ниже разобраны оба метода, настройка обработчика на принимающей стороне, передача параметров, типовые сценарии и ошибки, которые приводят к тому, что оповещение «не срабатывает».

Как устроен механизм оповещений в 1С

Оповещение — это сообщение с именем события, которое рассылается всем открытым формам сеанса. Каждая форма сама решает, реагировать на него или нет: в модуле формы должен быть объявлен обработчик ОбработкаОповещения(ИмяСобытия, Параметр, Источник). Если обработчика нет, форма молча игнорирует событие.

Важные свойства механизма, которые нужно учитывать при проектировании:

  • оповещение доставляется всем открытым формам, а не конкретной — адресат выбирается через уникальное имя события или проверку источника;
  • доставка выполняется синхронно в рамках клиентского сеанса;
  • закрытые формы оповещение не получают — оно не накапливается и не «дожидается» открытия;
  • между разными пользователями и сеансами оповещения не передаются.

Метод Оповестить: отправка произвольного события

Метод Оповестить — универсальный способ. Он вызывается на клиенте в модуле формы-источника и принимает три параметра: имя события (строка), произвольный параметр и источник. Все параметры, кроме имени, необязательны.

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

&НаКлиенте

Процедура СписокВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)

СтандартнаяОбработка = Ложь;

ДанныеСтроки = Элементы.Список.ДанныеСтроки(ВыбраннаяСтрока);

ПараметрыВыбора = Новый Структура;

ПараметрыВыбора.Вставить("Номенклатура", ДанныеСтроки.Ссылка);

ПараметрыВыбора.Вставить("Цена", ДанныеСтроки.Цена);

Оповестить("ПодборНоменклатуры", ПараметрыВыбора, ЭтотОбъект);

КонецПроцедуры

На форме-приёмнике (например, форме документа) событие перехватывается так:

&НаКлиенте

Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)

Если ИмяСобытия = "ПодборНоменклатуры" Тогда

НоваяСтрока = Объект.Товары.Добавить();

НоваяСтрока.Номенклатура = Параметр.Номенклатура;

НоваяСтрока.Цена = Параметр.Цена;

КонецЕсли;

КонецПроцедуры

Метод ОповеститьОбИзменении: стандартное обновление списков

Метод ОповеститьОбИзменении предназначен для одного конкретного сценария: сообщить открытым формам, что объект изменился. В качестве параметра передаётся ссылка на объект, тип или описание изменения. Динамические списки, у которых в настройках установлено автоматическое обновление при изменении данных, реагируют на такое оповещение без единой строки кода.

&НаКлиенте

Процедура ПослеЗаписи(ПараметрыЗаписи)

ОповеститьОбИзменении(Объект.Ссылка);

КонецПроцедуры

После такого вызова открытая форма списка этого объекта обновит строку автоматически. Формы, где обработано стандартное событие ОбработкаОповещения, получат его с именем события, которое платформа формирует для изменения объекта, — обычно вручную его обрабатывать не требуется.

Ограничение метода: он не передаёт произвольные данные. Если нужно передать, например, признак режима записи или дополнительные параметры, используйте обычный Оповестить или передавайте параметры записи через ПараметрыЗаписи.

Сравнение вариантов

Оповестить

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

ОповеститьОбИзменении

Стандартное уведомление об изменении объекта. Динамические списки обновляются автоматически. Не передаёт произвольные данные.

ОповеститьОЗаписиНового

Уведомление о создании нового объекта; списки реагируют добавлением строки. Применяется при программном создании объектов вне стандартной записи.

Настройка формы-приёмника: обработчик ОбработкаОповещения

Чтобы форма реагировала на событие, в её модуле должен быть обработчик с точной сигнатурой: ОбработкаОповещения(ИмяСобытия, Параметр, Источник) с директивой &НаКлиенте. Ошибка в имени процедуры или пропущенный параметр — и форма не получит событие, при этом платформа не выдаст никакого сообщения об ошибке.

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

&НаКлиенте

Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)

Если ИмяСобытия = "ПодборНоменклатуры"

И Источник = ОжидаемаяФормаПодбора Тогда

// обработка

КонецЕсли;

КонецПроцедуры

Если форма-источник открывается из формы-приёмника, надёжнее передать уникальный идентификатор приёмника в параметры открываемой формы и указывать его в оповещении. Тогда приёмник сравнивает переданный идентификатор со своим УникальныйИдентификатор и гарантированно реагирует только на «своё» событие, даже если открыто несколько одинаковых документов.

Типовые сценарии использования

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

Форма подбора открывается поверх документа и остаётся открытой. Каждый выбор строки отправляет оповещение, документ добавляет позицию. Источник не закрывается — поэтому обработчик закрытия не подходит, и Оповестить здесь правильный инструмент.

Обновление списка после записи элемента

Элемент справочника записан из отдельной формы, а открытая форма списка должна показать изменения. Достаточно ОповеститьОбИзменении(Ссылка) в обработчике ПослеЗаписи — при включённом автообновлении динамического списка дополнительный код не нужен.

Уведомление родительской формы из дочерней

Если дочерняя форма открыта с указанием владельца (ОткрытьФорму с параметром Владелец), оповещение можно адресовать через владельца, а на родительской форме проверять источник. Это защищает от ситуации, когда открыто несколько документов и все реагируют на одно событие.

Оповещение из общего кода

Метод Оповестить доступен не только в модулях форм, но и в клиентских общих модулях. Это удобно для централизованных событий: например, после завершения обмена данными общий модуль рассылает событие «ОбменЗавершен», а все заинтересованные формы обновляют свои показатели.

Типичные ошибки
01
Опечатка или разный регистр в имени события на источнике и приёмнике — событие молча теряется
02
Отсутствует директива &НаКлиенте у ОбработкаОповещения — обработчик не вызывается
03
Оповещение вызывается на сервере — метод недоступен в серверном контексте, возникает ошибка
04
Нет проверки источника — несколько открытых одинаковых форм реагируют на чужое событие
05
Ожидание, что закрытая форма получит оповещение — доставка работает только для открытых форм текущего сеанса
06
Попытка оповестить форму другого пользователя — механизм не работает между сеансами

Проверка результата и диагностика

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

Если точка в обработчике не срабатывает вообще — проблема в сигнатуре процедуры или в том, что форма-приёмник закрыта. Если обработчик вызывается, но условие не выполняется — сравните посимвольно имена событий. Полезно временно добавить в начало обработчика вывод имени события через Сообщить, чтобы увидеть, какие события вообще приходят форме.

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

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

Вызов Оповестить
Норма

Точка останова на строке Оповестить срабатывает, параметры заполнены

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

Код не выполняется или стоит в серверной процедуре

Доставка в приёмник
Норма

ОбработкаОповещения вызывается, ИмяСобытия совпадает с отправленным

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

Обработчик не вызывается — проверьте сигнатуру и директиву &НаКлиенте

Реакция формы
Норма

Данные приёмника обновляются, изменения видны пользователю

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

Событие приходит, но условие по Источнику отсекает обработку

Несколько копий формы
Норма

Реагирует только та форма, для которой предназначено событие

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

Обновляются все открытые копии — добавьте проверку владельца

Ограничения и альтернативы

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

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

Частые вопросы

Можно ли оповестить конкретную форму, а не все открытые?

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

Почему ОбработкаОповещения не вызывается, хотя Оповестить выполняется?

Проверьте три вещи: обработчик объявлен с директивой &НаКлиенте; имя процедуры и число параметров в точности соответствуют сигнатуре ОбработкаОповещения(ИмяСобытия, Параметр, Источник); форма-приёмник действительно открыта в момент отправки. Чаще всего причина в одном из этих пунктов.

Чем ОповеститьОбИзменении отличается от Оповестить?

ОповеститьОбИзменении — специализированный метод для уведомления об изменении объекта; на него автоматически реагируют динамические списки с включённым автообновлением. Оповестить — универсальный метод с произвольным именем события и параметрами, требующий собственного обработчика на приёмной стороне.

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

Нет, метод доступен только в клиентском контексте, поскольку адресаты — открытые формы клиентского приложения. Если событие возникает в серверной логике, верните признак на клиент и вызовите Оповестить уже там, например после завершения серверного вызова.

Получит ли оповещение форма, открытая у другого пользователя?

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

Что выбрать: Оповестить или обработку закрытия формы?

Если вспомогательная форма открывается для однократного выбора и закрывается — используйте ОткрытьФорму с ОписаниеОповещенияОЗакрытии и обрабатывайте результат в обработчике закрытия. Оповестить оправдан, когда форма-источник остаётся открытой и событий несколько, либо когда событие должны получить сразу несколько форм.

Итог

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

Оповещение открытой формы делается методом Оповестить с именем события на источнике и обработчиком ОбработкаОповещения на приёмнике; для обновления списков после записи достаточно ОповеститьОбИзменении. Механизм работает только между открытыми формами текущего сеанса, поэтому имя события должно быть уникальным, а источник — проверяться, чтобы исключить ложные срабатывания.