При разработке интерактивных интерфейсов в 1С часто возникает задача автоматического обновления данных. Типичный сценарий: один пользователь ждет изменения статуса документа, который редактирует другой сотрудник. Однако стандартное решение через ПодключитьОбработчикОжидания часто сопровождается неприятным визуальным эффектом — курсор мыши на мгновение превращается в «колёсико» ожидания (песочные часы), что мешает комфортной работе. Рассмотрим подробнее, почему это происходит и как реализовать обновление незаметно для пользователя.
Для начала разберем природу возникновения курсора ожидания. В платформе 1С любое обращение к серверу через директивы &НаСервере или &НаСервереБезКонтекста является блокирующей операцией для потока интерфейса. Как только управление передается на сервер, клиентское приложение «замирает» в ожидании ответа. Если время этого ожидания превышает определенный порог (обычно около 100–200 мс), операционная система или сама платформа меняет вид курсора, сигнализируя о занятости процесса.
Важно понимать, что использование &НаСервереБезКонтекста не избавляет от появления «колёсика». Хотя этот метод передает на сервер меньше данных (не передаются данные формы), сам факт сетевого вызова и ожидания ответа остается неизменным. Проанализируем ситуацию: даже пустая процедура может вызвать мерцание курсора, если сетевая задержка между клиентом и сервером ощутима.
Если специфика задачи позволяет, самым эффективным способом избавиться от «колёсика» будет замена Табличной части (данных обработки) на Динамический список. Рассмотрим, почему это работает лучше:
ПериодАвтообновления. В отличие от ручного обработчика ожидания, платформа выполняет опрос сервера для динамических списков более оптимизированно.ОбновлятьПриИзмененииДанныхСервера. В этом случае клиент не опрашивает сервер постоянно, а получает сигнал об изменении данных в базе. Это происходит в фоновом режиме и абсолютно незаметно для пользователя.Для реализации этого подхода выполним следующие шаги:
ДинамическийСписок.ОбновлятьПриИзмененииДанныхСервера.Это наиболее современный и технологичный метод. Если ваша информационная база подключена к Системе взаимодействия, вы можете использовать механизм «сообщений» для передачи сигнала об обновлении между разными клиентскими сеансами. Это полностью исключает необходимость периодических опросов сервера.
Разберем алгоритм реализации:
1. В модуле документа (который проводит второй сотрудник) в процедуре ПослеЗаписиНаСервере добавим код отправки сообщения:
// Отправка сообщения через систему взаимодействия
Инфо = СистемаВзаимодействия.СоздатьСообщение(НужноеОбсуждение);
Инфо.Текст = "СтатусИзменен";
Инфо.Записать();
2. На форме первого сотрудника (в модуле формы) опишем обработчик получения сообщения:
&НаКлиенте
Процедура ПриПолученииСообщения(Сообщение, ДополнительныеПараметры)
Если Сообщение.Текст = "СтатусИзменен" Тогда
// Здесь вызываем процедуру обновления данных
ОбновитьДанныеНаФорме();
КонецЕсли;
КонецПроцедуры
Этот метод работает асинхронно. Клиентское приложение не «висит» в ожидании, а просто реагирует на входящее событие. Курсор при этом остается неподвижным.
Если использование динамического списка невозможно, а Система взаимодействия не настроена, придется дорабатывать ПодключитьОбработчикОжидания. Чтобы минимизировать появление «колёсика», нужно сделать вызов сервера максимально коротким по времени.
Проанализируем стратегию «быстрой проверки»:
&НаСервереБезКонтекста для этой проверки.Истина (данные изменились), выполняем полноценное обновление формы.Пример кода для такой проверки:
&НаКлиенте
Процедура ОбработчикОжидания()
// Быстрая проверка без передачи контекста формы
Если ПроверитьНаличиеИзмененийНаСервере() Тогда
// Только если изменения есть, вызываем тяжелое обновление
ОбновитьТабличнуюЧасть();
КонецЕсли;
КонецПроцедуры
&НаСервереБезКонтекста
Функция ПроверитьНаличиеИзмененийНаСервере()
// Запрос к индексному регистру или легкая проверка версии
Запрос = Новый Запрос("ВЫБРАТЬ ПЕРВЫЕ 1 Истина ИЗ РегистрСведений.ИзмененияСтатусов ГДЕ Просмотрено = ЛОЖЬ");
Возврат НЕ Запрос.Выполнить().Пустой();
КонецФункции
Если проверка изменений сама по себе занимает длительное время, имеет смысл запустить Фоновое задание. Схема взаимодействия будет следующей:
ФоновыеЗадания.НайтиПоУникальномуИдентификатору.Рассмотрим пример проверки статуса фонового задания:
&НаКлиенте
Процедура ПроверитьСтатусЗадания()
Статус = ПолучитьСтатусЗадания(ИдентификаторЗадания);
Если Статус = "Завершено" Тогда
ПолучитьРезультатИОбновитьФорму();
КонецЕсли;
КонецПроцедуры
Важное резюме: Чтобы пользователь не замечал процесса обновления, стремитесь к тому, чтобы любой вызов сервера укладывался в 50–100 миллисекунд. Если время отклика выше — используйте асинхронные механизмы (Систему взаимодействия) или встроенные возможности Динамических списков, которые работают на уровне ядра платформы более деликатно, чем пользовательский код.