Оповещения форм 1С: Оповестить и ОбработкаОповещения

Дата: 06.10.2026 16:54:16
Управляемые формы
Клиент-сервер
Динамический список
Расширения
Программирование 1С
Комментарий:
0
Платформа:
8.3
Конфигурация:
Любая
Формы:
Управляемые

Оповещения форм 1С — механизм, которым одна открытая форма сообщает остальным, что данные изменились: записан документ, пересчитана сводка, клиент передан другому менеджеру. Отправляет оповещение метод Оповестить(ИмяСобытия, Параметр, Источник), принимает — событие формы ОбработкаОповещения с теми же тремя параметрами. Рядом живёт ОповеститьОбИзменении: он не передаёт формам данных, а обновляет динамические списки и сбрасывает кэши клиента. Ниже — как это устроено в 1С 8.3, код отправителя и получателя с фильтрами, перечитывание открытой карточки и рассылка в другие сеансы. Имена типовых объектов и событий сверены по выгрузке УТ 11.4.

Где встречается задача

  • Пользователь провёл оплату в соседней вкладке, и открытый заказ должен её увидеть. В УТ 11.4 форма заказа клиента так и делает: ловит Запись_ПриходныйКассовыйОрдер, Запись_ПоступлениеБезналичныхДенежныхСредств и другие события документов оплаты.
  • Обработка изменила данные на сервере, а открытые списки и карточки об этом не знают.
  • Своё рабочее место собирает сводку запросом и должно обновляться, когда документы записывают в других окнах.
  • Сканер штрихкода: в типовых формах УТ данные со сканера приходят оповещением ScanData с источником-строкой "ПодключаемоеОборудование".

Как устроены оповещения форм 1С

В 1С 8.3 оповещение отправляет Оповестить — метод глобального контекста, который есть только на клиенте: тонком, веб, мобильном и толстом. По синтаксис-помощнику метод посылает оповещение всем созданным формам и процедурам, подключённым через ПодключитьОбработчикОповещения. В каждой форме, где назначен обработчик ОбработкаОповещения, он вызывается с параметрами отправителя:

ПараметрТипЧто передают
ИмяСобытияСтрокаключ, по которому получатель понимает, что случилось
ПараметрПроизвольныйданные: ссылку, массив ссылок, структуру, параметры записи
ИсточникПроизвольныйотправителя: форму, ссылку на записанный объект или строку-метку

Что важно знать до написания кода:

  • Оповещение живёт только в текущем сеансе. Формы других пользователей и других сеансов того же пользователя его не получат.
  • Получают все созданные формы, в том числе сама форма-отправитель, если у неё есть обработчик.
  • Процедура с именем ОбработкаОповещения сама не вызывается. В конфигураторе выделите корень формы, в палитре свойств найдите раздел «События» → «ОбработкаОповещения» и нажмите кнопку с лупой: появится заготовка с директивой &НаКлиенте.
  • Платформа не рассылает события Запись_... сама. Это соглашение типовых конфигураций: вызов Оповестить написан в ПослеЗаписи форм объектов, и формат у форм разный.
  • Порядок, в котором формы получают оповещение, в документации не описан — логику на нём не стройте.
  • Кроме форм, оповещение получают экспортные процедуры модуля приложения или глобального общего модуля, подключённые ПодключитьОбработчикОповещения. Так событие ловят, даже когда нужная форма закрыта.

Как шлют оповещения типовые формы УТ 11.4 — от этого зависит, где получатель ищет ссылку:

СобытиеПараметрИсточник
Запись_ЗаказКлиентаПараметрыЗаписи с добавленной СделкойОбъект.Ссылка
Запись_РеализацияТоваровУслугПараметрыЗаписиОбъект.Ссылка
Запись_ПартнерыОбъект.Ссылкане передаётся
ScanDataданные со сканера"ПодключаемоеОборудование"

Отправителя любого события найдёт глобальный поиск конфигуратора (Ctrl+Shift+F) по имени события в кавычках.

Отправка: Оповестить после изменения данных

Пример — своя обработка «Передача клиентов менеджеру». Пользователь отмечает партнёров и выбирает нового основного менеджера; реквизит ОсновнойМенеджер у справочника Партнеры в УТ 11.4 есть. Сервер переписывает карточки, клиент сообщает об этом двумя способами: динамическим спискам — через ОповеститьОбИзменении, открытым формам — своим событием. Отправлять оповещения программно можно из любой клиентской процедуры: команды, обработчика события, обработчика ожидания.

// Обработка «Передача клиентов менеджеру», модуль формы.
// Реквизиты формы: Клиенты (ТаблицаЗначений: Пометка, Партнер),
// НовыйМенеджер (СправочникСсылка.Пользователи). Команда «Передать».

&НаКлиенте
Процедура Передать(Команда)

	Если Не ЗначениеЗаполнено(НовыйМенеджер) Тогда
		ПоказатьПредупреждение(, "Выберите менеджера, которому передаются клиенты.");
		Возврат;
	КонецЕсли;

	Изменены = ПередатьНаСервере();
	Если Изменены.Количество() = 0 Тогда
		Возврат;
	КонецЕсли;

	// 1. Динамические списки партнеров: по каждой ссылке или сразу по типу.
	//    Порог условный: для большой пачки хватит одного вызова на тип.
	Если Изменены.Количество() > 20 Тогда
		ОповеститьОбИзменении(Тип("СправочникСсылка.Партнеры"));
	Иначе
		Для Каждого Партнер Из Изменены Цикл
			ОповеститьОбИзменении(Партнер);
		КонецЦикла;
	КонецЕсли;

	// 2. Открытые формы сеанса: свое событие с данными для фильтра.
	ДанныеСобытия = Новый Структура("Партнеры, НовыйМенеджер", Изменены, НовыйМенеджер);
	Оповестить("ИзмененОсновнойМенеджер", ДанныеСобытия, ЭтотОбъект);

	ПоказатьОповещениеПользователя("Клиенты переданы", ,
		СтрШаблон("Изменено карточек: %1", Изменены.Количество()));

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

&НаСервере
Функция ПередатьНаСервере()

	Изменены = Новый Массив;

	Для Каждого СтрокаКлиента Из Клиенты Цикл

		Если Не СтрокаКлиента.Пометка Или Не ЗначениеЗаполнено(СтрокаКлиента.Партнер) Тогда
			Продолжить;
		КонецЕсли;

		ПартнерОбъект = СтрокаКлиента.Партнер.ПолучитьОбъект();
		Если ПартнерОбъект = Неопределено
			Или ПартнерОбъект.ОсновнойМенеджер = НовыйМенеджер Тогда
			Продолжить; // битая ссылка или менеджер уже назначен
		КонецЕсли;

		Попытка
			// Карточку редактируют в другом окне - блокировка не встанет, пропускаем
			ПартнерОбъект.Заблокировать();
			ПартнерОбъект.ОсновнойМенеджер = НовыйМенеджер;
			ПартнерОбъект.Записать();
			Изменены.Добавить(СтрокаКлиента.Партнер);
		Исключение
			Сообщение = Новый СообщениеПользователю;
			Сообщение.Текст = СтрШаблон("%1: %2", СтрокаКлиента.Партнер,
				КраткоеПредставлениеОшибки(ИнформацияОбОшибке()));
			Сообщение.Сообщить();
		КонецПопытки;

	КонецЦикла;

	Возврат Изменены;

КонецФункции

Приём: ОбработкаОповещения с фильтром по событию, параметру и источнику

Получатель — своя обработка «Клиенты менеджера»: партнёры с открытыми заказами и датой последнего заказа. Таблица собрана запросом с группировкой, это реквизит типа ТаблицаЗначений, а не динамический список, поэтому ОповеститьОбИзменении её не обновит. Обработка оповещения здесь — цепочка фильтров: имя события, тип и содержимое параметра, источник. Запрос удобно проверить в консоли запросов.

// Обработка «Клиенты менеджера», модуль формы.
// Реквизиты формы: Менеджер (СправочникСсылка.Пользователи),
// Клиенты (ТаблицаЗначений: Партнер, Заказов, ПоследнийЗаказ).
// ОбработкаОповещения и МенеджерПриИзменении назначены в палитре свойств.

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

	Если ИмяСобытия = "ИзмененОсновнойМенеджер" Тогда
		// Свое событие: структура с массивом партнеров и новым менеджером.
		// Обновляемся, если клиенты пришли к нам или ушли из нашей таблицы.
		Партнеры = Неопределено;
		НовыйМенеджер = Неопределено;
		Если ТипЗнч(Параметр) = Тип("Структура")
			И Параметр.Свойство("Партнеры", Партнеры)
			И Параметр.Свойство("НовыйМенеджер", НовыйМенеджер)
			И (НовыйМенеджер = Менеджер Или ЕстьВТаблице(Партнеры)) Тогда

			ЗапланироватьОбновление();
			// Источник-строка: изменение пришло из другого сеанса (раздел ниже)
			Если Источник = "УведомленияКлиента" Тогда
				ПоказатьОповещениеПользователя("Список клиентов изменился", ,
					"Основного менеджера сменили в другом сеансе");
			КонецЕсли;

		КонецЕсли;

	ИначеЕсли ИмяСобытия = "Запись_ЗаказКлиента" Тогда
		// Типовая форма заказа: параметры записи в Параметре, ссылка в Источнике.
		// Чей это клиент, без сервера не узнать - обновляемся всегда.
		ЗапланироватьОбновление();

	ИначеЕсли ИмяСобытия = "Запись_Партнеры" Тогда
		// Типовая форма партнера: ссылка в Параметре, Источник не передается.
		// Менеджера могли сменить в самой карточке, фильтр по таблице не годится.
		ЗапланироватьОбновление();

	КонецЕсли;

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

&НаКлиенте
Функция ЕстьВТаблице(Партнеры)

	Если ТипЗнч(Партнеры) <> Тип("Массив") Тогда
		Возврат Ложь;
	КонецЕсли;

	// НайтиСтроки на клиенте обращается к серверу, поэтому перебираем строки сами
	Для Каждого СтрокаКлиента Из Клиенты Цикл
		Если Партнеры.Найти(СтрокаКлиента.Партнер) <> Неопределено Тогда
			Возврат Истина;
		КонецЕсли;
	КонецЦикла;

	Возврат Ложь;

КонецФункции

&НаКлиенте
Процедура ЗапланироватьОбновление()

	// Пачка оповещений подряд даст одно обращение к серверу, а не десять
	ОтключитьОбработчикОжидания("ОбновитьКлиентов");
	ПодключитьОбработчикОжидания("ОбновитьКлиентов", 0.3, Истина);

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

&НаКлиенте
Процедура ОбновитьКлиентов()

	ОбновитьКлиентовНаСервере();

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

&НаКлиенте
Процедура МенеджерПриИзменении(Элемент)

	ОбновитьКлиентовНаСервере();

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

&НаСервере
Процедура ОбновитьКлиентовНаСервере()

	Если Не ЗначениеЗаполнено(Менеджер) Тогда
		Клиенты.Очистить();
		Возврат;
	КонецЕсли;

	Запрос = Новый Запрос;
	Запрос.Текст =
	"ВЫБРАТЬ
	|	ЗаказКлиента.Партнер КАК Партнер,
	|	КОЛИЧЕСТВО(ЗаказКлиента.Ссылка) КАК Заказов,
	|	МАКСИМУМ(ЗаказКлиента.Дата) КАК ПоследнийЗаказ
	|ИЗ
	|	Документ.ЗаказКлиента КАК ЗаказКлиента
	|ГДЕ
	|	ЗаказКлиента.Проведен
	|	И ЗаказКлиента.Статус <> ЗНАЧЕНИЕ(Перечисление.СтатусыЗаказовКлиентов.Закрыт)
	|	И ЗаказКлиента.Партнер.ОсновнойМенеджер = &Менеджер
	|
	|СГРУППИРОВАТЬ ПО
	|	ЗаказКлиента.Партнер
	|
	|УПОРЯДОЧИТЬ ПО
	|	ПоследнийЗаказ УБЫВ";
	Запрос.УстановитьПараметр("Менеджер", Менеджер);

	ЗначениеВРеквизитФормы(Запрос.Выполнить().Выгрузить(), "Клиенты");

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

Перечитать открытую карточку по оповещению

Открытая форма объекта хранит данные у себя, и ни один из двух вызовов её не обновит. Пользователь увидит старого менеджера, а записать карточку платформа не даст: версия в базе уже новее. В ресурсах платформы 8.3.27 для этого есть сообщение «Данные были изменены или удалены другим пользователем». Пусть карточка перечитывается сама — но только без несохранённых правок. В типовой УТ это делают расширением: заимствуйте форму элемента партнёра и в палитре свойств назначьте событию ОбработкаОповещения обработчик с типом вызова «После».

// Расширение (префикс Расш1_), заимствованная форма Справочник.Партнеры.ФормаЭлемента.
// В палитре свойств формы событию ОбработкаОповещения назначен обработчик
// с типом вызова «После»: он выполнится после типового.

&НаКлиенте
Процедура Расш1_ОбработкаОповещенияПосле(ИмяСобытия, Параметр, Источник)

	Партнеры = Неопределено;
	Если ИмяСобытия <> "ИзмененОсновнойМенеджер"
		Или ТипЗнч(Параметр) <> Тип("Структура")
		Или Не Параметр.Свойство("Партнеры", Партнеры)
		Или ТипЗнч(Партнеры) <> Тип("Массив") Тогда
		Возврат;
	КонецЕсли;

	// Наша ли это карточка? У нового, еще не записанного партнера ссылка пустая.
	Если Не ЗначениеЗаполнено(Объект.Ссылка) Или Партнеры.Найти(Объект.Ссылка) = Неопределено Тогда
		Возврат;
	КонецЕсли;

	Если Не Модифицированность Тогда
		ЭтотОбъект.Прочитать();
		ПоказатьОповещениеПользователя("Карточка перечитана", , "Основной менеджер изменен в другом окне");
		Возврат;
	КонецЕсли;

	// Есть несохраненные правки: молча перечитывать нельзя
	ПослеОтвета = Новый ОписаниеОповещения("Расш1_ПеречитатьЗавершение", ЭтотОбъект);
	ПоказатьВопрос(ПослеОтвета, "Основного менеджера этого партнера изменили в другом окне. "
		+ "Перечитать карточку? Несохраненные правки пропадут.", РежимДиалогаВопрос.ДаНет);

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

&НаКлиенте
Процедура Расш1_ПеречитатьЗавершение(Ответ, ДополнительныеПараметры) Экспорт

	Если Ответ = КодВозвратаДиалога.Да Тогда
		ЭтотОбъект.Прочитать();
	КонецЕсли;

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

Разбор ключевых строк

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

Оповестить и ОповеститьОбИзменении: в чём разница

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

В конфигурациях на БСП оба вызова собраны в ОбщегоНазначенияКлиент.ОповеститьОбИзмененииОбъекта и ОповеститьОбИзмененииОбъектов (есть в УТ 11.4 и КА 2.5). Они вызывают ОповеститьОбИзменении и Оповестить("Запись_" + имя объекта); для одной ссылки она уходит в источник, для массива из нескольких источник не передаётся.

Остальные «оповещения» 1С 8 — другие механизмы с похожими именами:

МетодКомуКак принять
Оповеститьвсе созданные формы сеансаОбработкаОповещения
ОповеститьОбИзменениидинамические списки и кэши клиентаобработчика нет, список перечитается сам
ОповеститьОВыборевладелец формы выбора или подбораОбработкаВыбора
ОповеститьОЗаписиНовоговладелец подчинённой формыОбработкаЗаписиНового
ОписаниеОповещенияодна процедура обратного вызоваэкспортная процедура из описания
ПоказатьОповещениеПользователяпользователь: всплывающее окно—

Вернуть результат из формы, которую открыли сами, проще через ОписаниеОповещения — примеры в статье как открыть форму программно. Широковещательное Оповестить нужно, когда отправитель не знает получателей.

Оповестить другие сеансы: УведомленияКлиента

С платформы 8.3.26 сервер может отправить уведомление клиентским сеансам: УведомленияКлиента.ОтправитьУведомление(Ключ, Данные, Адресаты). Без адресатов оно уходит всем сеансам, с массивом номеров сеансов — только им. На клиенте его принимают через УведомленияКлиента.ПодключитьОбработчик(Ключ, ОписаниеОповещения). Удобно сразу превратить уведомление в обычное Оповестить: формы-получатели менять не придётся.

// Обработка «Передача клиентов менеджеру»: вызов в конце ПередатьНаСервере(),
// когда массив Изменены не пустой. Нужна платформа 8.3.26 или новее.

&НаСервереБезКонтекста
Процедура УведомитьДругиеСеансы(Знач Партнеры, Знач НовыйМенеджер)

	Данные = Новый Структура;
	Данные.Вставить("Партнеры", Партнеры);
	Данные.Вставить("НовыйМенеджер", НовыйМенеджер);
	Данные.Вставить("Сеанс", НомерСеансаИнформационнойБазы());

	// Адресаты не указаны: уведомление получат все сеансы, включая текущий
	УведомленияКлиента.ОтправитьУведомление("ИзмененОсновнойМенеджер", Данные);

КонецПроцедуры
// Обработка «Клиенты менеджера», дополнение к модулю формы.
// Реквизит формы НомерСеанса (Число). ПриСозданииНаСервере, ПриОткрытии
// и ПриЗакрытии назначены в палитре свойств формы.

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

	// На тонком клиенте номер сеанса можно получить только через сервер
	НомерСеанса = НомерСеансаИнформационнойБазы();

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

&НаКлиенте
Процедура ПриОткрытии(Отказ)

	УведомленияКлиента.ПодключитьОбработчик("ИзмененОсновнойМенеджер",
		Новый ОписаниеОповещения("ПриПолученииУведомления", ЭтотОбъект));

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

&НаКлиенте
Процедура ПриЗакрытии(ЗавершениеРаботы)

	УведомленияКлиента.ОтключитьОбработчик("ИзмененОсновнойМенеджер");

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

&НаКлиенте
Процедура ПриПолученииУведомления(Данные, ДополнительныеПараметры) Экспорт

	// Свой сеанс формы уже оповестил обычным Оповестить
	Сеанс = Неопределено;
	Если ТипЗнч(Данные) <> Тип("Структура")
		Или Не Данные.Свойство("Сеанс", Сеанс)
		Или Сеанс = НомерСеанса Тогда
		Возврат;
	КонецЕсли;

	// Дальше - обычное оповещение своего сеанса: обработчики форм не меняются
	Оповестить("ИзмененОсновнойМенеджер", Данные, "УведомленияКлиента");

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

ОтключитьОбработчик по справке работает по ключу. Если форм-подписчиков в сеансе может быть несколько, держите одну подписку на сеанс.

Типичные ошибки

  • Обработчик молчит. Процедура ОбработкаОповещения написана, но не назначена событию в палитре свойств; в расширении у заимствованной формы не назначен обработчик с типом вызова. Ошибки при этом нет.
  • «Процедура или функция с указанным именем не определена (Оповестить)». Вызов в процедуре &НаСервере: метод только клиентский. Верните данные с сервера и оповестите на клиенте.
  • «Поле объекта не обнаружено (Партнеры)» и «Значение не является значением объектного типа (Партнеры)». Первое — в структуре нет такого ключа, второе — Параметр равен Неопределено: Оповестить вызвали без параметра. Проверяйте ТипЗнч и Свойство.
  • Ссылку ищут не там. Запись_ЗаказКлиента несёт ссылку в источнике, Запись_Партнеры — в параметре. Условие Параметр = Объект.Ссылка для заказа молча не выполнится.
  • Опечатка или другой регистр в имени события. Строки через «=» сравниваются с учётом регистра, ошибки не будет. Имена своих событий держите в одном месте, например в функциях общего модуля.
  • Список не обновился после ОповеститьОбИзменении. У динамического списка нет основной таблицы, а такие списки уведомление не трогает. Обновите его в ОбработкаОповещения через Элементы.Список.Обновить() — подробнее в статье про динамический список.
  • Зацикливание. Форма в ответ на событие шлёт его же, и обработчики вызывают друг друга без конца. Отвечайте другим именем события или проверяйте источник.

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

Получает ли форма собственное оповещение?

Да: оповещение уходит всем созданным формам, а отправитель — одна из них. Если форма и шлёт, и слушает одно событие, первой строкой обработчика отсеките своё: Если Источник = ЭтотОбъект Тогда Возврат; КонецЕсли;. Это работает, если в источник передаётся форма.

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

Нет, метод есть только на клиенте. Серверная процедура возвращает ссылки или флаг, а клиентская часть вызывает Оповестить. Для фонового задания то же делают в клиентском обработчике его завершения. Другим сеансам на 8.3.26+ сообщают через УведомленияКлиента, а в документации БСП 3.2.1 описан метод ОтправитьСерверноеОповещение.

Нужно ли вызывать ОповеститьОбИзменении после записи в форме?

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

Работают ли оповещения в обычных формах?

Да, механизм старше управляемых форм: по справке Оповестить доступен с версии 8.0, а у обычной формы в толстом клиенте есть событие ОбработкаОповещения с теми же параметрами. Для этой пары оповещения в управляемых формах 1С 8.3 отличаются директивой: там обработчик помечен &НаКлиенте, в обычной форме директиву не пишут. Назначают обработчик так же, в свойствах формы.

Когда проще заказать

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

По теме

Не хотите разбираться сами?

Адаптируем это решение под вашу базу. Оценка бесплатно.

Оставить задачу

Станьте частью сообщества!
Войдите или зарегистрируйтесь, и вы сможете участвовать в обсуждениях.


1С, 1С:Предприятие — товарные знаки ООО «1С». Сайт не является официальным представительством фирмы «1С» и не аффилирован с ней.