Как сделать прогресс-бар и отображать ход выполнения операции в управляемых формах 1С?

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

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

Разберем по шагам основные архитектурные подходы и практические методы создания шкалы прогресса в управляемых формах 1С:Предприятие.

Способ 1. Использование подсистемы «Длительные операции» (Библиотека стандартных подсистем)

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

Рассмотрим порядок реализации длительного алгоритма с помощью БСП:

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

Посмотрим на пример серверной процедуры длительного расчета:


Процедура ВыполнитьОбработкуНаСервере(ПараметрыВыполнения, АдресРезультата) Экспорт
    
    МассивДанных = ПараметрыВыполнения.ДанныеДляОбработки;
    ВсегоЭлементов = МассивДанных.Количество();
    
    Для Индекс = 0 По ВсегоЭлементов - 1 Цикл
        
        // Выполняем полезное действие над элементом
        ОбработатьЭлемент(МассивДанных[Индекс]);
        
        // Вычисляем процент выполнения
        Процент = Окр(((Индекс + 1) / ВсегоЭлементов) * 100);
        
        // Передаем статус в механизм БСП
        ТекстСообщения = СтрШаблон("Обработано %1 из %2 строк", Индекс + 1, ВсегоЭлементов);
        ДлительныеОперации.СообщитьПрогресс(Процент, ТекстСообщения);
        
    КонецЦикла;
    
КонецПроцедуры

Способ 2. Фоновое задание и обработчик ожидания (без БСП)

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

Проанализируем алгоритм взаимодействия клиента и сервера:

  1. Запуск фонового задания: при нажатии кнопки на форме вызывается серверный метод, который стартует фоновое задание с помощью ФоновыеЗадания.Выполнить().
  2. Передача прогресса: внутри фонового потока состояние можно передавать через глобальное временное хранилище по уникальному идентификатору формы или формировать объекты СообщениеПользователю со специальной структурой данных.
  3. Снятие показаний: на клиенте запускается обработчик ожидания через ПодключитьОбработчикОжидания(), который с интервалом в 1–2 секунды запрашивает статус фонового задания и значение прогресса, обновляя элемент формы.
  4. Завершение: при получении признака окончания фонового процесса обработчик ожидания отключается с помощью ОтключитьОбработчикОжидания().

Посмотрим на пример реализации клиентского опроса состояния:


&НаКлиенте
Процедура ЗапуститьПроцесс(Команда)
    
    ИдентификаторЗадания = ЗапуститьЗаданиеНаСервере();
    ПодключитьОбработчикОжидания("ПроверитьСтатусЗадания", 1);
    
КонецПроцедуры

&НаКлиенте
Процедура ПроверитьСтатусЗадания()
    
    РезультатПроверки = ПроверитьПрогрессНаСервере(ИдентификаторЗадания);
    
    // Обновляем реквизит формы, связанный с Полем индикатора
    ПрогрессВыполнения = РезультатПроверки.Процент;
    
    Если РезультатПроверки.Завершено Тогда
        ОтключитьОбработчикОжидания("ПроверитьСтатусЗадания");
        ПоказатьОповещениеПользователя("Успех", , "Обработка успешно завершена!");
    КонецЕсли;
    
КонецПроцедуры

Способ 3. Порционная обработка с периодическим возвратом на клиента

Когда операция не требует выполнения в отдельном потоке фонового задания, можно использовать порционный подход. Задача разбивается на пачки элементов (например, по 100–500 записей).

Рассмотрим схему работы:

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

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

Способ 4. Метод «Состояние» при длительных клиентских операциях

Если длительный процесс происходит непосредственно на клиенте (например, разбор локального файла Microsoft Excel или выгрузка данных через COM-соединение), доступен стандартный метод платформы Состояние().

Разберем пример его применения в цикле:


&НаКлиенте
Процедура ПрочитатьФайлНаКлиенте()
    
    ВсегоСтрок = ТаблицаФайла.Количество();
    
    Для НомерСтроки = 1 По ВсегоСтрок Цикл
        
        // Обработка строки файла
        ОбработатьСтрокуКлиент(НомерСтроки);
        
        Процент = Окр((НомерСтроки / ВсегоСтрок) * 100);
        Состояние("Обработка файла данных...", Процент, "Прервать работу: Ctrl + Break");
        
    КонецЦикла;
    
КонецПроцедуры

Визуализация прогресса на форме

Для наглядного отображения прогресса в управляемой форме применяются следующие элементы:

  1. Поле индикатора: стандартный элемент интерфейса. Добавьте реквизит формы числового типа (например, ПрогрессВыполнения), перетащите его в элементы формы и выберите вид Поле индикатора. Настройте свойства МинимальноеЗначение = 0, МаксимальноеЗначение = 100 и включите флаг ОтображатьЗначение.
  2. Поле HTML-документа: если требуется нестандартная или брендированная анимация, в форму добавляется элемент с видом Поле HTML-документа, куда передается динамически сформированная HTML/CSS-разметка с прогресс-баром.

Важные рекомендации и ограничения

  1. Оптимизация частоты обновления: не следует отправлять данные о прогрессе на каждой итерации при миллионах записей. Частые вызовы создают избыточную нагрузку на сеть и сервер. Оптимально фиксировать прогресс не чаще одного раза в 1–2 секунды или с шагом в 1–5%.
  2. Транзакции: избегайте передачи состояния выполнения через запись в таблицы базы данных (например, в регистр сведений) внутри одной неделимой транзакции. До момента фиксации транзакции данные не будут видны клиентскому сеансу.
← На главную