Давайте вместе проанализируем одну из классических задач в разработке на 1С. Представим ситуацию: один менеджер вносит изменения в карточку номенклатуры, например, меняет ее наименование. В это же время другой менеджер работает с документом, где эта номенклатура уже выбрана. Проблема в том, что в форме у второго менеджера продолжает отображаться старое наименование, пока он не откроет форму заново. Это происходит из-за кэширования данных формой. Выясним, как решить эту проблему и обеспечить мгновенное обновление данных между разными сеансами.
Это самый простой и надежный, хотя и не полностью автоматический подход. Он заключается в том, чтобы дать пользователю возможность самому инициировать обновление данных в "проблемных" местах. Рассмотрим несколько вариантов реализации.
Добавление кнопки "Обновить"
Самое очевидное решение — разместить на форме кнопку, по нажатию на которую будет происходить обновление данных. Это дает пользователю полный контроль над ситуацией. Хотя это и не автоматическое обновление, во многих случаях этого вполне достаточно и не перегружает систему.
Обновление данных при открытии формы
Можно обновлять данные в момент открытия формы. Это гарантирует, что пользователь всегда начнет работу с актуальной информацией. Однако, если данные изменятся во время работы с формой, они снова устареют.
Использование обработчика ожидания
Более продвинутый вариант — подключить обработчик ожидания с помощью метода ПодключитьОбработчикОжидания(). Он будет с определенным интервалом (например, раз в 30 секунд) вызывать серверную процедуру для проверки изменений и обновлять интерфейс. Этот метод обеспечивает автоматизацию, но создает постоянную небольшую нагрузку на систему из-за регулярных опросов сервера.
Посмотрим на пример кода, который объединяет обновление при открытии и по кнопке, используя специальный механизм оповещения платформы. Этот код не перечитывает всю форму, а обновляет только конкретную табличную часть, что более эффективно.
Идея заключается в использовании метода ОповеститьОбИзменении(). Этот метод, в отличие от Оповестить(), работает не в рамках одного сеанса, а уведомляет все сеансы об изменении данных определенного типа. В результате динамические списки и другие элементы, связанные с этим типом данных, получат сигнал о необходимости обновиться.
&НаКлиенте
Процедура ПриОткрытии(Отказ)
// При открытии формы сразу очищаем кэш и обновляем отображение
ОчиститьКешНоменклатурыИОбновитьОтображение();
КонецПроцедуры
&НаКлиенте
Процедура Обновить(Команда)
// То же самое делаем по нажатию специальной кнопки "Обновить"
ОчиститьКешНоменклатурыИОбновитьОтображение();
КонецПроцедуры
&НаКлиенте
Процедура ОчиститьКешНоменклатурыИОбновитьОтображение()
// 1. Уведомляем систему, что данные по справочнику "Номенклатура" могли измениться.
// Это заставит платформу очистить внутренний кэш для этого типа данных.
ОповеститьОбИзменении(Тип("СправочникСсылка.Номенклатура"));
// 2. Принудительно обновляем визуальное представление нашей табличной части "Товары".
Элементы.Товары.Обновить();
КонецПроцедуры
Этот подход хорошо работает, когда нужно обновить данные по инициативе самого пользователя.
Начиная с версии платформы 8.3.26, появился мощный и технологичный механизм, который позволяет отправлять уведомления напрямую с сервера в нужные клиентские сеансы. Это решает проблему кардинально: обновление происходит мгновенно и только тогда, когда это действительно нужно, без лишних опросов. Давайте разберем по шагам, как это работает.
Механизм основан на объекте УведомленияКлиента.
Подписка на уведомления на клиенте.
В форме, которая должна получать обновления, мы подписываемся на получение сообщений с определенным, уникальным именем (ключом). Для этого используем метод УведомленияКлиента.ПодключитьОбработчик().
Отправка уведомления с сервера.
В том месте, где происходят изменения данных (например, в модуле объекта справочника "Номенклатура" в процедуре ПослеЗаписи), мы вызываем серверный метод УведомленияКлиента.ОтправитьУведомление(). В него мы передаем то же самое имя (ключ), на которое подписались клиенты, и, при необходимости, какие-то данные.
Обработка уведомления на клиенте.
Как только клиентское приложение получает уведомление с сервера, оно автоматически вызывает процедуру-обработчик, которую мы указали на первом шаге. В этой процедуре мы и выполняем все необходимые действия по обновлению интерфейса.
Рассмотрим подробнее преимущества этого подхода:
Этот метод является наиболее современным и предпочтительным для решения нашей задачи в актуальных версиях платформы 1С.
Иногда в обсуждениях можно встретить упоминание серверной процедуры ОбновитьПовторноИспользуемыеЗначения(). Важно понимать, для чего она предназначена. Эта процедура очищает кэш результатов выполнения функций из общих модулей, которые были вызваны с опцией "Повторное использование возвращаемых значений".
Ключевой момент: этот кэш является локальным для одного сеанса. Это значит, что вызов ОбновитьПовторноИспользуемыеЗначения() в сеансе одного пользователя никак не повлияет на данные и их отображение в сеансах других пользователей. Поэтому для решения задачи межсеансового обновления этот метод не подходит.