В этой статье мы разберем, как обрабатывать длительные операции в 1С асинхронно, то есть таким образом, чтобы дать пользователю возможность продолжить работу, не дожидаясь завершения операции. А также перенести всю нагрузку по выполнению таких операций на сервер.
Для таких операций разработчики систем 1С рекомендуют использовать Фоновые задания. В последних версиях типовых конфигураций они оформляются окошком с котом.
Мы рассмотрим вариант, в котором дополнительно выводится прогресс выполнения операций в процентах.
В нашем примере длительная операция запускается нажатием кнопки на форме, поэтому на форме были созданы:
- сама кнопка,
- команда, привязанная к этой кнопке,
- клиентская процедура, запускаемая командой.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
&НаКлиенте Процедура ПолучитьПлатежныеОперации(Команда) //Запуск фонового задания на сервере. ДлительнаяОперация = ПолучитьПлатежныеОперацииНаСервере(); //Подключение обработчика завершения фонового задания. ПараметрыОжидания = ДлительныеОперацииКлиент.ПараметрыОжидания(ЭтотОбъект); ПараметрыОжидания.ВыводитьОкноОжидания = Истина; ПараметрыОжидания.ВыводитьПрогрессВыполнения = Истина; ПараметрыОжидания.ТекстСообщения = "Получение платежных операций..."; ОповещениеОЗавершении = Новый ОписаниеОповещения("ПолучитьПлатежныеОперацииЗавершение", ЭтотОбъект); ДлительныеОперацииКлиент.ОжидатьЗавершение(ДлительнаяОперация, ОповещениеОЗавершении, ПараметрыОжидания); КонецПроцедуры |
Клиентская процедура запускает фоновое задание на сервере и подключает обработчик ожидания завершения этого задания. Содержимое серверной функции, запускающей фоновое задание, приведем далее. При подключении обработчика ожидания устанавливаются несколько параметров:
- ВыводитьОкноОжидания — определяет, нужно ли показывать пользователю окно с котом.
- ВыводитьПрогрессВыполнения — говорит, надо ли в окне с котом показывать проценты выполнения задания.
- ТекстСообщения — надпись в окне с котом, отражающая содержание выполняемой операции
- ОповещениеОЗавершении — переменная с типом ОписаниеОповещения, которое определяет процедуру, выполняемую при завершении длительной операции.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
&НаСервере Функция ПолучитьПлатежныеОперацииНаСервере() НаименованиеЗадания = НСтр("ru = 'Получение платежных операций'"); ВыполняемыйМетод = "Обработки.аш_ФормированиеБухгалтерскихДокументов.ПолучитьПлатежныеОперации"; ПараметрыПроцедуры = Новый Структура; ПараметрыПроцедуры.Вставить("_Объект", новый Структура("Период, ОтборПравил, СформированныеДокументы, ИдентификаторФормы", Объект.Период, Объект.ОтборПравил.Выгрузить(), Объект.СформированныеДокументы.Выгрузить(), УникальныйИдентификатор)); ПараметрыВыполнения = ДлительныеОперации.ПараметрыВыполненияВФоне(УникальныйИдентификатор); ПараметрыВыполнения.НаименованиеФоновогоЗадания = НаименованиеЗадания; ПараметрыВыполнения.ЗапуститьВФоне = Истина; ПараметрыВыполнения.Вставить("ИдентификаторФормы", УникальныйИдентификатор); Возврат ДлительныеОперации.ВыполнитьФункцию(УникальныйИдентификатор, ВыполняемыйМетод, ПараметрыПроцедуры); КонецФункции |
Данная серверная функция запускает выполнение фонового задания. В этой функции нужно определить:
- НаименованиеЗадания — текстовое описание выполняемой операции.
- ВыполняемыйМетод — строка, определяющая функцию, которая будет выполняться в фоновом режиме. В данном случае эта функция находится в модуле менеджера обработки.
- ПарметрыПроцедуры — переменная с типом Структура, в которую можно записать любые параметры, необходимые для выполнения функции из переменной ВыполняемыйМетод.
После этого необходимо создать экспортную функцию, которая будет выполняться в фоновом режиме. Эта функция описана в переменной ВыполняемыйМетод и в нашем случае расположена в модуле менеджера обработки. Функция содержит один обязательный параметр. В нашем случае он называется Параметры, и в него передается структура из переменной ПараметрыПроцедуры.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
Функция ПолучитьПлатежныеОперации(Параметры) Экспорт //Здесь должен находиться код, определяющий выполнение длительной процедуры //Пример передачи прогресса выполнения фонового задания Процент = Окр(Выполнено/Всего*100,0); Если НЕ (Выполнено) % 10 Тогда ДлительныеОперации.СообщитьПрогресс(Окр(Процент,0)); КонецЕсли; Возврат Результат; КонецФункции |
Если мы хотим отразить в окне длительной операции прогресс выполнения, то периодически (например, при каждой итерации некоего цикла) нужно рассчитывать процент выполнения и передавать его в клиентское окно с помощью процедуры ДлительныеОперации.СообщитьПрогресс(Процент).
Функция возвращает некий результат, который будет помещен во временное хранилище. Оттуда мы его получим и обработаем в процедуре, вызываемой при завершении фонового задания. Эта процедура клиентская, экспортная, создается на форме, с которой запускалась длительная операция.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
&НаКлиенте Процедура ПолучитьПлатежныеОперацииЗавершение(Результат, ДополнительныеПараметры) Экспорт Если Результат = Неопределено Тогда Возврат; КонецЕсли; Если Результат.Статус = "Ошибка" Тогда ПоказатьПредупреждение(,Результат.КраткоеПредставлениеОшибки); Иначе ДлительныеОперацииЗавершениеНаСервере(Результат.АдресРезультата); Сообщить("Получение платежных операций завершено"); КонецЕсли; КонецПроцедуры |
Эта процедура имеет два обязательных параметра: Результат и ДополнительныеПараметры. В переменной Результат содержится статус выполнения задания и адрес временного хранилища с самим результатом, возвращенным в нашем случае функцией ПолучитьПлатежныеОперации() из модуля менеджера обработки.
В данной процедуре мы прежде всего проверяем, не равна ли переменная Результат значению Неопределено (это значение возвращается, если пользователь отменил длительную операцию). Если нет, то проверяем, не было ли ошибок при выполнении фонового задания. Если ошибок не было, то запускаем процедуру, в которую передаем адрес временного хранилища с результатом длительной операции.
1 2 3 4 5 6 7 8 |
&НаСервере Процедура ДлительныеОперацииЗавершениеНаСервере(АдресХранилища) Результат = ПолучитьИзВременногоХранилища(АдресХранилища); //Здесь должен быть код обработки полученного результата КонецПроцедуры |
Это последняя процедура, в которой мы получаем результат длительной операции из временного хранилища и обрабатываем его.