Как автоматически обновить динамический список на форме при изменении данных на сервере

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

При разработке прикладных решений на платформе 1С:Предприятие 8.3 часто возникает задача: пользователь открыл форму обработки или журнала с динамическим списком, а в это время на сервере (в подписке на событие, фоновом задании или при работе другого сеанса) происходит запись регистров или справочников. Рассмотрим, как организовать автоматическое обновление данных в динамическом списке и какие ограничения платформы необходимо учитывать.

Ограничения серверного контекста

Проанализируем ключевое архитектурное ограничение платформы: стандартные методы клиентского оповещения Оповестить и ОповеститьОбИзменении доступны исключительно в контексте тонкого, толстого и веб-клиента. Вызвать их напрямую из серверных процедур (в модулях объектов, общих модулях с признаком «Сервер» или в обработчиках подписок на события) невозможно.

Разберем основные варианты решения этой задачи в зависимости от сценария работы и версии платформы.

Способ 1. Использование встроенного механизма автообновления динамического списка

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

Для настройки выполним следующие шаги:

  1. Откроем свойства динамического списка в редакторе формы.
  2. Установим флаг Автообновление в значение Истина.
  3. Зададим параметр ПериодАвтообновления (указывается в секундах).

Также эти параметры можно задать программно при создании формы на сервере или при открытии:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    Список.Автообновление = Истина;
    Список.ПериодАвтообновления = 10; // интервал обновления в секундах
КонецПроцедуры

Важно: частый опрос базы данных тяжелыми запросами динамического списка может создавать существенную нагрузку на СУБД. Рекомендуется использовать данный механизм с разумным интервалом или при небольшом количестве одновременно работающих пользователей.

Способ 2. Обновление в рамках текущего клиентского сеанса

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

Разберем пример клиентского кода:


&НаКлиенте
Процедура ВыполнитьОбработкуИОбновить(Команда)
    // Вызов серверной процедуры, где срабатывает подписка на событие
    ВыполнитьЗаписьДанныхНаСервере();
    
    // Вариант 1: Оповещение об изменении конкретной ссылки или ключа записи
    ОповеститьОбИзменении(Тип("СправочникСсылка.Номенклатура"));
    
    // Вариант 2: Прямое принудительное обновление динамического списка
    Элементы.Список.Обновить();
КонецПроцедуры

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

Способ 3. Опрос через легкий обработчик ожидания

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

Рассмотрим по шагам реализацию этого механизма:

  1. В подписке на событие при записи данных фиксируем факт изменения — например, инкрементируем счетчик версий или записываем текущую дату в константу или легкий регистр сведений.
  2. В форме подключаем клиентский обработчик ожидания через метод ПодключитьОбработчикОжидания.
  3. В обработчике ожидания выполняем быстрый серверный вызов, считывающий только значение флага/версии.
  4. Если версия изменилась, вызываем метод Элементы.Список.Обновить() и запоминаем новую версию.

Посмотрим на пример реализации в форме:


&НаКлиенте
Процедура ПриОткрытии(Отказ)
    ТекущаяВерсияДанных = 0;
    ПодключитьОбработчикОжидания("ПроверитьОбновлениеДанных", 5);
КонецПроцедуры

&НаКлиенте
Процедура ПроверитьОбновлениеДанных()
    АктуальнаяВерсия = ПолучитьАктуальнуюВерсиюНаСервере();
    
    Если АктуальнаяВерсия <> ТекущаяВерсияДанных Тогда
        ТекущаяВерсияДанных = АктуальнаяВерсия;
        Элементы.Список.Обновить();
    КонецЕсли;
КонецПроцедуры

&НаСервереБезКонтекста
Функция ПолучитьАктуальнуюВерсиюНаСервере()
    // Получение значения легкой константы или записи регистра
    Возврат Константы.ВерсияИзмененияДанных.Получить();
КонецФункции

Способ 4. Механизм передачи сообщений с сервера (начиная с 8.3.10)

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

← На главную