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

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← К списку

Давайте вместе проанализируем одну из классических задач в разработке на 1С. Представим ситуацию: один менеджер вносит изменения в карточку номенклатуры, например, меняет ее наименование. В это же время другой менеджер работает с документом, где эта номенклатура уже выбрана. Проблема в том, что в форме у второго менеджера продолжает отображаться старое наименование, пока он не откроет форму заново. Это происходит из-за кэширования данных формой. Выясним, как решить эту проблему и обеспечить мгновенное обновление данных между разными сеансами.

Решение 1: Принудительное обновление данных на клиенте

Это самый простой и надежный, хотя и не полностью автоматический подход. Он заключается в том, чтобы дать пользователю возможность самому инициировать обновление данных в "проблемных" местах. Рассмотрим несколько вариантов реализации.

  1. Добавление кнопки "Обновить"

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

  2. Обновление данных при открытии формы

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

  3. Использование обработчика ожидания

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

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

Идея заключается в использовании метода ОповеститьОбИзменении(). Этот метод, в отличие от Оповестить(), работает не в рамках одного сеанса, а уведомляет все сеансы об изменении данных определенного типа. В результате динамические списки и другие элементы, связанные с этим типом данных, получат сигнал о необходимости обновиться.


&НаКлиенте
Процедура ПриОткрытии(Отказ)
	// При открытии формы сразу очищаем кэш и обновляем отображение
	ОчиститьКешНоменклатурыИОбновитьОтображение();
КонецПроцедуры

&НаКлиенте
Процедура Обновить(Команда)
	// То же самое делаем по нажатию специальной кнопки "Обновить"
	ОчиститьКешНоменклатурыИОбновитьОтображение();
КонецПроцедуры

&НаКлиенте
Процедура ОчиститьКешНоменклатурыИОбновитьОтображение()
	// 1. Уведомляем систему, что данные по справочнику "Номенклатура" могли измениться.
	// Это заставит платформу очистить внутренний кэш для этого типа данных.
	ОповеститьОбИзменении(Тип("СправочникСсылка.Номенклатура"));
	
	// 2. Принудительно обновляем визуальное представление нашей табличной части "Товары".
	Элементы.Товары.Обновить();	
КонецПроцедуры

Этот подход хорошо работает, когда нужно обновить данные по инициативе самого пользователя.

Решение 2: Использование серверных уведомлений (платформа 8.3.26 и выше)

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

Механизм основан на объекте УведомленияКлиента.

  1. Подписка на уведомления на клиенте.

    В форме, которая должна получать обновления, мы подписываемся на получение сообщений с определенным, уникальным именем (ключом). Для этого используем метод УведомленияКлиента.ПодключитьОбработчик().

  2. Отправка уведомления с сервера.

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

  3. Обработка уведомления на клиенте.

    Как только клиентское приложение получает уведомление с сервера, оно автоматически вызывает процедуру-обработчик, которую мы указали на первом шаге. В этой процедуре мы и выполняем все необходимые действия по обновлению интерфейса.

Рассмотрим подробнее преимущества этого подхода:

Этот метод является наиболее современным и предпочтительным для решения нашей задачи в актуальных версиях платформы 1С.

Важное замечание о кэшировании на сервере

Иногда в обсуждениях можно встретить упоминание серверной процедуры ОбновитьПовторноИспользуемыеЗначения(). Важно понимать, для чего она предназначена. Эта процедура очищает кэш результатов выполнения функций из общих модулей, которые были вызваны с опцией "Повторное использование возвращаемых значений".

Ключевой момент: этот кэш является локальным для одного сеанса. Это значит, что вызов ОбновитьПовторноИспользуемыеЗначения() в сеансе одного пользователя никак не повлияет на данные и их отображение в сеансах других пользователей. Поэтому для решения задачи межсеансового обновления этот метод не подходит.

← К списку