Введение
Привет всем! Продолжаем цикл статей по возможностям асинхронной работы платформы 1с в рамках конфигурации разработчика - Библиотеки стандартных подсистем (БСП).
В предыдущей статье мы рассмотрели базовый - рабочий процесс-функционал для запуска длительных операций, используя основную для этого функцию - ДлительныеОперации.ВыполнитьВФоне.
Согласно последним рекомендациям БСП (версия 3.1.3.303) предлагается использовать более современные функции для работы с длительными операциями - это ВыполнитьПроцедуру и ВыполнитьФункцию.
Но, а кто хочет научиться работать с функционалом длительных операций вообще в рамках БСП - прошу ознакомиться с первой частью моей статьи - Гарантированно рабочий пример использования длительных операций на БСП с отображением прогресса. [Часть 1].
Итак, перейдем к рассмотрению функции БСП ВыполнитьПроцедуру:
Рабочий пример функционала БСП "ВыполнитьПроцедуру"
В данном разделе я привожу рабочий код внешней обработки для запуска метода "Выполнить процедуру". Будем "отлавливать" статус методом формы "выполнить процедуру" (без излишеств).
В общем виде "на входе" данная функция выглядит вот так (до 7 параметров):
ВыполнитьПроцедуру(Знач ПараметрыВыполнения = Неопределено, ИмяПроцедуры, Знач Параметр1 = Неопределено,
Знач Параметр2 = Неопределено, Знач Параметр3 = Неопределено, Знач Параметр4 = Неопределено,
Знач Параметр5 = Неопределено, Знач Параметр6 = Неопределено, Знач Параметр7 = Неопределено) Экспорт
а вот и код обработки:
&НаКлиенте
Процедура ЗапуститьОперацию(Команда)
ПараметрыЗапуска = Новый Структура;
ПараметрыЗапуска.Вставить("ДатаНачала1", НачалоДня(ЭтаФорма.ДатаНачала));
ПараметрыЗапуска.Вставить("ДатаОкончания1",КонецДня(ЭтаФорма.ДатаОкончания));
ПараметрыЗапуска.Вставить("Организация1", ЭтаФорма.Организация);
СтруктураФоновогоЗадания = ВыполнитьФоновоеЗаданиеНаСервере(ПараметрыЗапуска, УникальныйИдентификатор);
ИДЗадания = СтруктураФоновогоЗадания.ИдентификаторЗадания;
ПараметрыОжидания = ДлительныеОперацииКлиент.ПараметрыОжидания(ЭтотОбъект);
//ПараметрыОжидания.ВыводитьОкноОжидания = Ложь;
ПараметрыОжидания.ВыводитьПрогрессВыполнения = Истина;
ПараметрыОжидания.Интервал = 2;
ДлительныеОперацииКлиент.ОжидатьЗавершение(СтруктураФоновогоЗадания, Новый ОписаниеОповещения("ОбработатьДанные", ЭтотОбъект), ПараметрыОжидания);
КонецПроцедуры
&НаКлиенте
Процедура ОбработатьДанные(Результат, ДополнительныеПараметры) Экспорт
КонецПроцедуры
&НаСервере
Функция ВыполнитьФоновоеЗаданиеНаСервере(ПараметрыЗапуска, УникальныйИдентификатор)
НаименованиеЗадания = "Запуск длительной операции";
ВыполняемыйМетод = "ДлительныйМодуль.ПроведемДокументыМетодомСуществующейПроцедуры";
ПараметрыВыполнения = ДлительныеОперации.ПараметрыВыполненияПроцедуры();
ПараметрыВыполнения.НаименованиеФоновогоЗадания = НаименованиеЗадания;
ПараметрыВыполнения.ЗапуститьВФоне = Истина;
СтруктураФоновогоЗадания = ДлительныеОперации.ВыполнитьПроцедуру(ПараметрыВыполнения, ВыполняемыйМетод, ПараметрыЗапуска.ДатаНачала1, ПараметрыЗапуска.ДатаОкончания1, ПараметрыЗапуска.Организация1);
Возврат СтруктураФоновогоЗадания;
КонецФункции
Вышенаписанного кода достаточно. Все будет работать.
Структура выполняемой процедуры для длительной операции "ВыполнитьПроцедуру"
В данном разделе, я привожу пример процедуры для общего серверного модуля, чтобы код из раздела выше - отработал. Это - самая обычная процедура - фактически - это любая процедура из конфигурации (расширения):
&НаСервере
Процедура ПроведемДокументыМетодомСуществующейПроцедуры(ДатаНачала, ДатаОкончания, Организация) Экспорт
МассивВозврат = Новый Массив;
ПоискДляПроведения = Новый Запрос("ВЫБРАТЬ
| РеализацияТоваровУслуг.Ссылка КАК Ссылка
|ИЗ
| Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг
|ГДЕ
| РеализацияТоваровУслуг.Дата МЕЖДУ &Дата1 И &Дата2
| И РеализацияТоваровУслуг.Организация = &Организация
|
|УПОРЯДОЧИТЬ ПО
| РеализацияТоваровУслуг.Дата");
ПоискДляПроведения.УстановитьПараметр("Дата1", ДатаНачала);
ПоискДляПроведения.УстановитьПараметр("Дата2", ДатаОкончания);
ПоискДляПроведения.УстановитьПараметр("Организация", Организация);
НашлиДокументы = ПоискДляПроведения.Выполнить().Выгрузить();
ВсегоДокументов = НашлиДокументы.Количество();
ТекДок = 1;
Для Каждого Стр11 ИЗ НашлиДокументы Цикл
Док = Стр11.Ссылка.ПолучитьОбъект();
Док.Проведен = Ложь;
Док.ПометкаУдаления = Ложь;
Попытка
Док.Записать(РежимЗаписиДокумента.Проведение, РежимПроведенияДокумента.Неоперативный);
Исключение
Док.Записать(РежимЗаписиДокумента.Запись);
КонецПопытки;
ПроцентВыполнения = (ТекДок/ВсегоДокументов)*100;
ПроцентВыполнения = Окр(ПроцентВыполнения,0);
МассивВозврат.Добавить(ПроцентВыполнения);
// сообщаем "процент" и "текст сообщения"
ДлительныеОперации.СообщитьПрогресс(ПроцентВыполнения,СокрЛП(Док.Ссылка));
ТекДок = ТекДок + 1;
КонецЦикла;
// ПоместитьВоВременноеХранилище(МассивВозврат, АдресРезультата);
КонецПроцедуры
Рабочий пример функционала БСП "ВыполнитьФункцию"
Теперь, рассмотрим еще одну функцию выполнения длительной операции "ВыполнитьФункцию". В общем виде она выглядит вот так - до 7-ми входящих параметров:
Функция ВыполнитьФункцию(Знач ПараметрыВыполнения, ИмяФункции, Знач Параметр1 = Неопределено,
Знач Параметр2 = Неопределено, Знач Параметр3 = Неопределено, Знач Параметр4 = Неопределено,
Знач Параметр5 = Неопределено, Знач Параметр6 = Неопределено, Знач Параметр7 = Неопределено) Экспорт
&НаКлиенте
Процедура ЗапуститьОперацию(Команда)
//ИДЗадания = "";
//Индикатор = 0;
//СтрокаСостояния = "";
ПараметрыЗапуска = Новый Структура;
ПараметрыЗапуска.Вставить("ДатаНачала1", НачалоДня(ЭтаФорма.ДатаНачала));
ПараметрыЗапуска.Вставить("ДатаОкончания1",КонецДня(ЭтаФорма.ДатаОкончания));
ПараметрыЗапуска.Вставить("Организация1", ЭтаФорма.Организация);
СтруктураФоновогоЗадания = ВыполнитьФоновоеЗаданиеНаСервере(ПараметрыЗапуска, УникальныйИдентификатор);
ИДЗадания = СтруктураФоновогоЗадания.ИдентификаторЗадания;
ПараметрыОжидания = ДлительныеОперацииКлиент.ПараметрыОжидания(ЭтотОбъект);
//ПараметрыОжидания.ВыводитьОкноОжидания = Ложь;
ПараметрыОжидания.ВыводитьПрогрессВыполнения = Истина;
ПараметрыОжидания.Интервал = 2;
ДлительныеОперацииКлиент.ОжидатьЗавершение(СтруктураФоновогоЗадания, Новый ОписаниеОповещения("ОбработатьДанные", ЭтотОбъект), ПараметрыОжидания);
КонецПроцедуры
&НаСервере
Функция ВыполнитьФоновоеЗаданиеНаСервере(ПараметрыЗапуска, УникальныйИдентификатор)
НаименованиеЗадания = "Запуск длительной операции";
ВыполняемыйМетод = "ДлительныйМодуль.ПроведемДокументыМетодомСуществФункцией";
ПараметрыВыполнения = ДлительныеОперации.ПараметрыВыполненияФункции(УникальныйИдентификатор);
ПараметрыВыполнения.НаименованиеФоновогоЗадания = НаименованиеЗадания;
ПараметрыВыполнения.ЗапуститьВФоне = Истина;
СтруктураФоновогоЗадания = ДлительныеОперации.ВыполнитьФункцию(ПараметрыВыполнения, ВыполняемыйМетод, ПараметрыЗапуска.ДатаНачала1, ПараметрыЗапуска.ДатаОкончания1, ПараметрыЗапуска.Организация1);
Возврат СтруктураФоновогоЗадания;
КонецФункции
&НаКлиенте
Процедура ОбработатьДанные(Результат, ДополнительныеПараметры) Экспорт
Если Результат = Неопределено Тогда
Возврат;
КонецЕсли;
Сообщить(ПолучитьИЗВременногоХранилища(Результат.АдресРезультата));
КонецПроцедуры
Структура выполняемой процедуры для длительной операции "ВыполнитьФункцию"
Функция в общем модуле будет выглядеть вот так (тоже "любая" функция из конфигурации или расширения):
&НаСервере
Функция ПроведемДокументыМетодомСуществФункцией(ДатаНачала, ДатаОкончания, Организация) Экспорт
МассивВозврат = Новый Массив;
ПоискДляПроведения = Новый Запрос("ВЫБРАТЬ
| РеализацияТоваровУслуг.Ссылка КАК Ссылка
|ИЗ
| Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг
|ГДЕ
| РеализацияТоваровУслуг.Дата МЕЖДУ &Дата1 И &Дата2
| И РеализацияТоваровУслуг.Организация = &Организация
|
|УПОРЯДОЧИТЬ ПО
| РеализацияТоваровУслуг.Дата");
ПоискДляПроведения.УстановитьПараметр("Дата1", ДатаНачала);
ПоискДляПроведения.УстановитьПараметр("Дата2", ДатаОкончания);
ПоискДляПроведения.УстановитьПараметр("Организация", Организация);
НашлиДокументы = ПоискДляПроведения.Выполнить().Выгрузить();
ВсегоДокументов = НашлиДокументы.Количество();
ТекДок = 1;
Для Каждого Стр11 ИЗ НашлиДокументы Цикл
Док = Стр11.Ссылка.ПолучитьОбъект();
Док.Проведен = Ложь;
Док.ПометкаУдаления = Ложь;
Попытка
Док.Записать(РежимЗаписиДокумента.Проведение, РежимПроведенияДокумента.Неоперативный);
Исключение
Док.Записать(РежимЗаписиДокумента.Запись);
КонецПопытки;
ПроцентВыполнения = (ТекДок/ВсегоДокументов)*100;
ПроцентВыполнения = Окр(ПроцентВыполнения,0);
МассивВозврат.Добавить(ПроцентВыполнения);
ДлительныеОперации.СообщитьПрогресс(ПроцентВыполнения,СокрЛП(Док.Ссылка));
ТекДок = ТекДок + 1;
КонецЦикла;
//Возвращаем количество элементов в массиве (просто для примера)
Возврат МассивВозврат.Количество();
КонецФункции
Для примера использования данной функции - я возвращаю в ней количество элементов в массиве.
Все, мы рассмотрели базовое применение двух относительно новых методов библиотеки стандартных подсистем ВыполнитьПроцедуру и ВыполнитьФункцию. Переходим к выводам и итогам.
Выводы и итоги
В данной части материала о длительных операциях - мы рассмотрели новые и рекомендуемые методы БСП - "ВыполнитьПроцедуру" и "ВыполнитьФункцию". Рассмотрели как их запускать, какие параметры передавать, как отслеживать и получать результат выполнения. Надеюсь, что данный материал будет вам максимально полезен - методики современные, сэкономят вам время. Я постарался описать их наиболее просто и без излишеств.
Основной и очень существенный плюс, на мой взгляд, использования этих методов - возможность уже брать готовые функции и процедуры конфигурации (расширения) и запускать их в асинхронном режиме. Что говорить - БСП существенно развивается.
Спасибо, что дочитали данную статью до конца. В своей статье я использовал БСП версии 3.1.3.303 и платформу 1с 8.3.17.1549.
Другие материалы
Если вам интересен мой практический подход и информация, которую вы сможете реально использовать, если у вас есть желание, чтобы данный комплекс статей наполнялся практическими материалы для программистов - я не откажусь от поддержки как данной статьи, так и всего комплекса статей в целом.
Так же прошу ознакомиться с другими моими статьями по БСП и типовым конфигурациям:
Честный знак - запрос содержания упаковки по ее коду [табачная продукция]
Работаем с контактной информацией в конфигурациях на БСП
Возможности работы со строками при помощи БСП, которые должен знать каждый программист