Всех привет !!
В данной статье пойдет речь о индикации длительных операций во внешней обработке. Хотя таких статей уже много ,решил добавить еще одну так как описанный здесь метод мне еще не попадался (возможно где-то и есть), может кому-то пригодится. Необходима версия БСП 2.4 и выше.
С проблемой индикации длительной операции я столкнулся совсем недавно , когда необходимо было перевести обработку с 2.0 на 3.0, где использовалась индикация хода выполнения различных операций и процент выполнения изменялся в разных процедурах обработки . Поэтому пришлось вникать в этот механизм. Перечитав несколько статей на этом ресурсе, и не до конца разобравшись , решил посмотреть как реализован механизм индикации в типовой конфигурации (БП 3.0).
Сначала мое внимание привлек метод общего модуля ДлительныеОперации.СообщитьПрогресс, который служит для передачи информации о процессе выполнения (можно передать процент выполнения , сопроводительный текст и дополнительные параметры). Поэтому я стал смотреть где используется данный метод и как обрабатывается информация переданная с помощью данного метода. Оказалось все довольно просто.
Если внимательно посмотреть код запуска длительной операции для дополнительной обработки (Общий модуль ДополнительныйОтчетыИОбработкиКлиент.ВыполнитьКомандуВФоне) , то там можно увидеть следующее
Процедура ВыполнитьКомандуВФоне(Знач ИдентификаторКоманды, Знач ПараметрыКоманды, Знач Обработчик)
.....
.....
НастройкиОжидания = ДлительныеОперацииКлиент.ПараметрыОжидания(Форма);
НастройкиОжидания.ТекстСообщения = СопровождающийТекст;
НастройкиОжидания.ВыводитьОкноОжидания = Истина;
НастройкиОжидания.ПолучатьРезультат = ПолучатьРезультат; // для обратной совместимости
НастройкиОжидания.ВыводитьСообщения = Истина;
ДлительныеОперацииКлиент.ОжидатьЗавершение(Задание, Обработчик, НастройкиОжидания);
КонецПроцедуры
Тут нас интересует структура НастройкиОжидания. Она получается функцией из общего модуля ДлительныеОперацииКлиент.ПарметрыОжидания (). Вот ее код :
// Возвращает пустую структуру для параметра ПараметрыОжидания процедуры ДлительныеОперацииКлиент.ОжидатьЗавершение.
//
// Параметры:
// ФормаВладелец - УправляемаяФорма, Неопределено - форма, из которой вызывается длительная операция.
//
// Возвращаемое значение:
// Структура - параметры выполнения задания:
// * ФормаВладелец - УправляемаяФорма, Неопределено - форма, из которой вызывается длительная операция.
// * ТекстСообщения - Строка - текст сообщения, выводимый на форме ожидания.
// Если не задан, то выводится "Пожалуйста, подождите...".
// * ВыводитьОкноОжидания - Булево - если Истина, то открыть окно ожидания с визуальной индикацией длительной операции.
// Если используется собственный механизм индикации, то следует указать Ложь.
// * ВыводитьПрогрессВыполнения - Булево - выводить прогресс выполнения в процентах на форме ожидания.
// * ОповещениеОПрогрессеВыполнения - ОписаниеОповещения - оповещение, которое периодически вызывается при
// проверке готовности фонового задания. Параметры процедуры-обработчика оповещения:
// ** Прогресс - Структура, Неопределено - структура со свойствами или Неопределено, если задание было отменено. Свойства:
// *** Статус - Строка - "Выполняется", если задание еще не завершилось;
// "Выполнено", если задание было успешно выполнено;
// "Ошибка", если задание завершено с ошибкой;
// "Отменено", если задание отменено пользователем или администратором.
// *** ИдентификаторЗадания - УникальныйИдентификатор - идентификатор запущенного фонового задания.
// *** Прогресс - Структура, Неопределено - результат функции ДлительныеОперации.ПрочитатьПрогресс,
// если ВыводитьПрогрессВыполнения = Истина.
// *** Сообщения - ФиксированныйМассив, Неопределено - если ВыводитьСообщения = Истина, массив объектов СообщениеПользователю,
// очередная порция сообщений, сформированных в процедуре-обработчике длительной операции.
// ** ДополнительныеПараметры - Произвольный - произвольные данные, переданные в описании оповещения.
//
// * ВыводитьСообщения - Булево - выводить в оповещения о завершении и прогресс сообщения,
// сформированные в процедуре-обработчике длительной операции.
// * Интервал - Число - интервал в секундах между проверками готовности длительной операции.
// По умолчанию 0 - после каждой проверки интервал увеличивается с 1 до 15 секунд
// с коэффициентом 1.4.
// * ОповещениеПользователя - Структура - содержит свойства:
// ** Показать - Булево - если Истина, то по завершении длительной операции вывести оповещение пользователя.
// ** Текст - Строка - текст оповещения пользователя.
// ** НавигационнаяСсылка - Строка - навигационная ссылка оповещения пользователя.
// ** Пояснение - Строка - пояснение оповещения пользователя.
//
// * ПолучатьРезультат - Булево - Служебный параметр. Не предназначен для использования.
//
Функция ПараметрыОжидания(ФормаВладелец) Экспорт
Результат = Новый Структура;
Результат.Вставить("ФормаВладелец", ФормаВладелец);
Результат.Вставить("ТекстСообщения", "");
Результат.Вставить("ВыводитьОкноОжидания", Истина);
Результат.Вставить("ВыводитьПрогрессВыполнения", Ложь);
Результат.Вставить("ОповещениеОПрогрессеВыполнения", Неопределено);
Результат.Вставить("ВыводитьСообщения", Ложь);
Результат.Вставить("Интервал", 0);
Результат.Вставить("ПолучатьРезультат", Ложь);
ОповещениеПользователя = Новый Структура;
ОповещениеПользователя.Вставить("Показать", Ложь);
ОповещениеПользователя.Вставить("Текст", Неопределено);
ОповещениеПользователя.Вставить("НавигационнаяСсылка", Неопределено);
ОповещениеПользователя.Вставить("Пояснение", Неопределено);
Результат.Вставить("ОповещениеПользователя", ОповещениеПользователя);
Возврат Результат;
КонецФункции
Если взглянуть на описание к данной функции, то можно заметить что структура имеет поле ОповещениеОПрогрессеВыполнения , куда необходимо передать ОписаниеОповещения, с указании процедуры, которая будет периодически вызываться при проверки завершения длительной операции и обрабатывать сообщения преданные с помощью метода ДлительныеОперации.СообщитьПрогресс .
Так же необходимо установить в поле ВыводитьПрогрессВыполнеия значение Истина , без этого данный метод работать не будет.
К сожалению, по умолчанию, для дополнительных обработок предусмотрен только вывод окна с котиком (за это отвечает поле ВыводитьОкноОжидания структуры НастройкиОжидания ) , поэтому для изменения механизма оповещения необходимо скопировать метод общего модуля ДополнительныйОтчетыИОбработкиКлиент.ВыполнитьКомандуВФоне к себе в обработку в модуль формы и сделать нужные изменения
&НаКлиенте
Процедура ВыполнитьКомандуВФоне(Знач ИдентификаторКоманды, Знач ПараметрыКоманды, Знач Обработчик) Экспорт
ИмяПроцедуры = "ДополнительныеОтчетыИОбработкиКлиент.ВыполнитьКомандуВФоне";
ОбщегоНазначенияКлиентСервер.ПроверитьПараметр(
ИмяПроцедуры,
"ИдентификаторКоманды",
ИдентификаторКоманды,
Тип("Строка"));
ОбщегоНазначенияКлиентСервер.ПроверитьПараметр(
ИмяПроцедуры,
"ПараметрыКоманды",
ПараметрыКоманды,
Тип("Структура"));
ОбщегоНазначенияКлиентСервер.ПроверитьПараметр(
ИмяПроцедуры,
"ПараметрыКоманды.ДополнительнаяОбработкаСсылка",
ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(ПараметрыКоманды, "ДополнительнаяОбработкаСсылка"),
Тип("СправочникСсылка.ДополнительныеОтчетыИОбработки"));
ОбщегоНазначенияКлиентСервер.ПроверитьПараметр(
ИмяПроцедуры,
"Обработчик",
Обработчик,
Новый ОписаниеТипов("ОписаниеОповещения, УправляемаяФорма"));
ПараметрыКоманды.Вставить("ИдентификаторКоманды", ИдентификаторКоманды);
ПолучатьРезультат = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(ПараметрыКоманды, "ПолучатьРезультат", Ложь);
Форма = Неопределено;
Если ПараметрыКоманды.Свойство("ФормаВладелец", Форма) Тогда
ПараметрыКоманды.ФормаВладелец = Неопределено;
КонецЕсли;
Если ТипЗнч(Обработчик) = Тип("ОписаниеОповещения") Тогда
ОбщегоНазначенияКлиентСервер.ПроверитьПараметр(ИмяПроцедуры, "Обработчик.Модуль",
Обработчик.Модуль,
Тип("УправляемаяФорма"));
Форма = ?(Форма <> Неопределено, Форма, Обработчик.Модуль);
Иначе
Форма = Обработчик;
Обработчик = Неопределено;
ПолучатьРезультат = Истина; // для обратной совместимости
КонецЕсли;
Задание = ДополнительныеОтчетыИОбработкиВызовСервера.ЗапуститьДлительнуюОперацию(Форма.УникальныйИдентификатор, ПараметрыКоманды);
СопровождающийТекст = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(ПараметрыКоманды, "СопровождающийТекст", "");
Заголовок = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(ПараметрыКоманды, "Заголовок");
Если ЗначениеЗаполнено(Заголовок) Тогда
СопровождающийТекст = СокрЛП(Заголовок + Символы.ПС + СопровождающийТекст);
КонецЕсли;
Если Не ЗначениеЗаполнено(СопровождающийТекст) Тогда
СопровождающийТекст = НСтр("ru = 'Команда выполняется.'");
КонецЕсли;
НастройкиОжидания = ДлительныеОперацииКлиент.ПараметрыОжидания(ЭтаФорма);
НастройкиОжидания.ТекстСообщения = СопровождающийТекст;
НастройкиОжидания.ВыводитьОкноОжидания = Ложь; //Обязательно Ставим ложь что бы убрать котика иначе ошибка
НастройкиОжидания.ВыводитьПрогрессВыполнения = Истина; // необходимо для вывода информации о ходе выполнения
НастройкиОжидания.ПолучатьРезультат = ПолучатьРезультат; // для обратной совместимости
НастройкиОжидания.ВыводитьСообщения = Истина;
ОповещениеОПрогрессеВыполнения = Новый ОписаниеОповещения("ПрогрессВыполнения", ЭтотОбъект);
НастройкиОжидания.ОповещениеОПрогрессеВыполнения = ОповещениеОПрогрессеВыполнения; // задаем наше оповещение о прогрессе выполнения
ДлительныеОперацииКлиент.ОжидатьЗавершение(Задание, Обработчик, НастройкиОжидания);
КонецПроцедуры
Обратите внимание значение что для поля ВыводитьОкноОжидания структуры НастройкиОжидания необходимо установить значение в Ложь (т.е. формы с котиком выводиться не будет ) иначе получите ошибку (нельзя одновременно выводить окно ожидания и использовать свою индикацию прогресса)
Осталось только написать свою процедуру обработки процесса выполнения я например сделал так
&НаКлиенте
Процедура ПрогрессВыполнения(Результат, ДополнительныеПараметры) Экспорт
Если Результат.Статус = "Выполняется" или Результат.Статус = "Выполнено" Тогда
Прогресс = Результат.Прогресс;
Если Прогресс <> Неопределено Тогда
Индикатор = Прогресс.Процент; // Индикатор - полей Индикатор на форме
ТекстСопровождения = Прогресс.Текст; // поле надпись на форме
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Вот собственно и все .В файлах прикрепил шаблон внешней обработки, где выполнены все необходимые действия Вам остается только описать саму длительную операцию , обработку прогресса и обработку завершения длительной операции.