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

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

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

Причина появления «колёсика» при вызове сервера

Для начала разберем природу возникновения курсора ожидания. В платформе 1С любое обращение к серверу через директивы &НаСервере или &НаСервереБезКонтекста является блокирующей операцией для потока интерфейса. Как только управление передается на сервер, клиентское приложение «замирает» в ожидании ответа. Если время этого ожидания превышает определенный порог (обычно около 100–200 мс), операционная система или сама платформа меняет вид курсора, сигнализируя о занятости процесса.

Важно понимать, что использование &НаСервереБезКонтекста не избавляет от появления «колёсика». Хотя этот метод передает на сервер меньше данных (не передаются данные формы), сам факт сетевого вызова и ожидания ответа остается неизменным. Проанализируем ситуацию: даже пустая процедура может вызвать мерцание курсора, если сетевая задержка между клиентом и сервером ощутима.

Решение 1: Использование динамических списков вместо табличных частей

Если специфика задачи позволяет, самым эффективным способом избавиться от «колёсика» будет замена Табличной части (данных обработки) на Динамический список. Рассмотрим, почему это работает лучше:

  1. Механизм автообновления: У динамического списка есть свойство ПериодАвтообновления. В отличие от ручного обработчика ожидания, платформа выполняет опрос сервера для динамических списков более оптимизированно.
  2. Оповещение сервера: Начиная с современных версий платформы 8.3, для динамических списков доступно свойство ОбновлятьПриИзмененииДанныхСервера. В этом случае клиент не опрашивает сервер постоянно, а получает сигнал об изменении данных в базе. Это происходит в фоновом режиме и абсолютно незаметно для пользователя.

Для реализации этого подхода выполним следующие шаги:

  1. Добавим на форму реквизит типа ДинамическийСписок.
  2. В качестве основной таблицы укажем таблицу документов или соответствующий регистр сведений.
  3. Настроим произвольный запрос, чтобы данные соответствовали вашей логике.
  4. В свойствах списка установим флаг ОбновлятьПриИзмененииДанныхСервера.

Решение 2: Система взаимодействия (Collaboration System)

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

Разберем алгоритм реализации:

1. В модуле документа (который проводит второй сотрудник) в процедуре ПослеЗаписиНаСервере добавим код отправки сообщения:


// Отправка сообщения через систему взаимодействия
Инфо = СистемаВзаимодействия.СоздатьСообщение(НужноеОбсуждение);
Инфо.Текст = "СтатусИзменен";
Инфо.Записать();

2. На форме первого сотрудника (в модуле формы) опишем обработчик получения сообщения:


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

Этот метод работает асинхронно. Клиентское приложение не «висит» в ожидании, а просто реагирует на входящее событие. Курсор при этом остается неподвижным.

Решение 3: Оптимизация «легкого опроса» через фоновые задания

Если использование динамического списка невозможно, а Система взаимодействия не настроена, придется дорабатывать ПодключитьОбработчикОжидания. Чтобы минимизировать появление «колёсика», нужно сделать вызов сервера максимально коротким по времени.

Проанализируем стратегию «быстрой проверки»:

  1. Вместо того чтобы каждый раз полностью перечитывать табличную часть, создадим на сервере сверхбыструю функцию, которая проверяет только один флаг (например, версию данных или наличие изменений в небольшом регистре сведений).
  2. Используем &НаСервереБезКонтекста для этой проверки.
  3. Только если функция вернула Истина (данные изменились), выполняем полноценное обновление формы.

Пример кода для такой проверки:


&НаКлиенте
Процедура ОбработчикОжидания()
    // Быстрая проверка без передачи контекста формы
    Если ПроверитьНаличиеИзмененийНаСервере() Тогда
        // Только если изменения есть, вызываем тяжелое обновление
        ОбновитьТабличнуюЧасть();
    КонецЕсли;
КонецПроцедуры

&НаСервереБезКонтекста
Функция ПроверитьНаличиеИзмененийНаСервере()
    // Запрос к индексному регистру или легкая проверка версии
    Запрос = Новый Запрос("ВЫБРАТЬ ПЕРВЫЕ 1 Истина ИЗ РегистрСведений.ИзмененияСтатусов ГДЕ Просмотрено = ЛОЖЬ");
    Возврат НЕ Запрос.Выполнить().Пустой();
КонецФункции

Решение 4: Фоновые задания для длительных операций

Если проверка изменений сама по себе занимает длительное время, имеет смысл запустить Фоновое задание. Схема взаимодействия будет следующей:

  1. Обработчик ожидания запускает фоновое задание (это быстрый вызов, который не вызывает «колёсика»).
  2. Следующие итерации обработчика ожидания проверяют статус выполнения этого задания через ФоновыеЗадания.НайтиПоУникальномуИдентификатору.
  3. Когда задание завершено, клиент забирает результат и обновляет интерфейс.

Рассмотрим пример проверки статуса фонового задания:


&НаКлиенте
Процедура ПроверитьСтатусЗадания()
    Статус = ПолучитьСтатусЗадания(ИдентификаторЗадания);
    Если Статус = "Завершено" Тогда
        ПолучитьРезультатИОбновитьФорму();
    КонецЕсли;
КонецПроцедуры

Важное резюме: Чтобы пользователь не замечал процесса обновления, стремитесь к тому, чтобы любой вызов сервера укладывался в 50–100 миллисекунд. Если время отклика выше — используйте асинхронные механизмы (Систему взаимодействия) или встроенные возможности Динамических списков, которые работают на уровне ядра платформы более деликатно, чем пользовательский код.

← На главную