При правильной архитектуре основной код 1С выполняется на сервере. И, если операция достаточно долгая, то возникает потребность в прогресс баре.
Для реализации подобной задачи необходимо пустить выполнение основного кода в фоновое задание. И, систематически обращаясь к фоновому заданию, получать сообщения о прогрессе.
Имея 4 модуля ксПрогрессБар, ксПрогрессБарВызовСервера, ксПрогрессБарКлиент, ксПрогрессБарКлиентСервер (которые можно достать из cf файла) функционал прогресса будет выглядеть примерно так:
1. Код модуля клиента
Основная идея заключается в том, что серверный код мы выполняем фоновым заданием ВыполнениеВФоне.ТестПрогрессБара. И при этом, подключив обработчик ожидания СобратьИнформациюХодаВыполнения, начинаем сбор состояния, пока метод ксПрогрессБарКлиент.ПоказатьСостояние не вернёт флаг о завершении фонового задания.
&НаКлиенте
Процедура Тест(Команда)
ТестНаСервере();
Если ВыполнятьВФоне() Тогда
ПодключитьОбработчикОжидания("СобратьИнформациюХодаВыполнения", ВремяОткликаСбораИнфорамацииХодаВыполнения());
КонецЕсли;
КонецПроцедуры
Процедура ТестНаСервере()
Если ВыполнятьВФоне() Тогда
Доступность = Ложь;
ФоновыеЗадания.Выполнить("ВыполнениеВФоне.ТестПрогрессБара", , УникальныйИдентификатор, НСтр("ru = 'Тест прогресс бара'"));
Иначе
ВыполнениеВФоне.ТестПрогрессБара();
КонецЕсли;
КонецПроцедуры
&НаКлиентеНаСервереБезКонтекста
Функция ВыполнятьВФоне()
Возврат НЕ ксКэшНаСеанс.ИнформационнаяБазаФайловая();
КонецФункции
&НаКлиенте
Процедура СобратьИнформациюХодаВыполнения()
Если НЕ ксПрогрессБарКлиент.ПоказатьСостояние(УникальныйИдентификатор) Тогда
ОтключитьОбработчикОжидания("СобратьИнформациюХодаВыполнения");
Доступность = Истина;
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Функция ВремяОткликаСбораИнфорамацииХодаВыполнения()
Возврат 1;
КонецФункции
2. Код модуля сервера (основная часть вашего кода)
Для оповещения текущего состояния, необходимо воспользоваться методом ксПрогрессБар.УвеличитьСчетчикИУстановитьСостояние, который увеличит значение итератора на единицу, и, высчитав текущий прогресс относительно общего количества, сообщит пользователю текущее событие и текст пояснения.
Процедура ТестПрогрессБара() Экспорт
количествоИтераций = 2000000;
текстСообщения = НСтр("ru = 'Тест прогресс бара'");
пояснение = НСтр("ru = 'Пустой цикл для тестирования'");
общееКоличество = количествоИтераций;
ц = 0;
Для цИтератор = 1 По количествоИтераций Цикл
ксПрогрессБар.УвеличитьСчетчикИУстановитьСостояние(ц, общееКоличество, текстСообщения, пояснение);
// Основной код.
КонецЦикла;
КонецПроцедуры
3. Результат
Итогом будет вот такой прогресс бар:
4. Заключение
Минусы:
-данный функционал получилось реализовать только для тонкого клиента. Хотя в основном для отрисовки прогресса используется типовой метод "Состояние".
Замечания:
-отладку фонового задания можно включить так:
-или, решением такой проблемы, может быть разработка дополнительного режима отладки, после включения которого, код будет выполняться не в фоне. Как пример, можно модернизировать метод ВыполнятьВФоне:
&НаКлиентеНаСервереБезКонтекста
Функция ВыполнятьВФоне(пТестирование)
Возврат НЕ пТестирование
И НЕ ксКэшНаСеанс.ИнформационнаяБазаФайловая();
КонецФункции
Плюсы:
+пользователь не только видит прогресс, но и может свободно пользоваться базой.