Длительная операция во внешней обработке

Печать (Ctrl+P)

Для выполнения длительных операций в версиях конфигурации на базе БСП 3.0/3.1 служит следующая функция в общем модуле ДлительныеОперации:

Функция ВыполнитьВФоне(Знач ИмяПроцедуры, Знач ПараметрыПроцедуры, Знач ПараметрыВыполнения) Экспорт

Описание этой функции в версии БСП 3.0 отличается от ее описания в версии БСП 3.1

Параметр ИмяПроцедуры – Это имя экспортной процедуры общего модуля, модуля менеджера объекта
или модуля обработки, которую необходимо выполнить в фоне., Например “МойОбщийМодуль.МояПроцедура”, “Отчеты.ЗагруженныеДанные.Сформировать”
или “Обработки.ЗагрузкаДанных.МодульОбъекта.Загрузить”.

Сложности возникают, когда обработка является внешне. В описании функции в версии БСП 3.0 написано так:

Запустить выполнение процедуры в фоновом задании, если это возможно.
При выполнении любого из следующих условий запуск выполняется не в фоне, а сразу в основном потоке:

  • если вызов выполняется в файловой базе во внешнем соединении (в этом режиме фоновые задания не поддерживаются);
  • если приложение запущено в режиме отладки (параметр /C РежимОтладки) – для упрощения отладки конфигурации;
  • если в файловой ИБ имеются активные фоновые задания – для снижения времени ожидания пользователя;
  • если выполняется процедура модуля внешней обработки или внешнего отчета.
  • Не следует использовать эту функцию, если необходимо безусловно запускать фоновое задание.
  • Может применяться совместно с функцией ДлительныеОперацииКлиент.ОжидатьЗавершение.

Согласно этому описанию, функция ВыполнитьВФоне в версии БСП 3.0 не выполняется в фоновом режиме если выполняется процедура модуля внешней обработки. Это не совсем так или я не совсем понял что, тут имеется ввиду. Тем не менее я решил показать простой пример выполнения длительной операции во внешней обработке для БСП 3.0/3.1.

Следует отметить, что в описании функции ВыполнитьВФоне в версии БСП 3.1 рекомендуется вместо этой функции использовать функции ВыполнитьФункцию и ВыполнитьПроцедуру.

Вызываемые функции могть быть с произвольным числом параметров, но не более 7. Значения передаваемых параметров функции, а также возвращаемое значение должны быть сериализуемыми.

Функция ВыполнитьФункцию(Знач ПараметрыВыполнения, ИмяФункции, Знач Параметр1 = Неопределено, Знач Параметр2 = Неопределено, Знач Параметр3 = Неопределено, Знач Параметр4 = Неопределено,Знач Параметр5 = Неопределено, Знач Параметр6 = Неопределено, Знач Параметр7 = Неопределено) Экспорт
ПараметрыВызова = СписокПараметров(Параметр1, Параметр2, Параметр3, Параметр4, Параметр5, Параметр6, Параметр7);
ПараметрыВыполнения = ПодготовитьПараметрыВыполнения(ПараметрыВыполнения, Истина);
Возврат ВыполнитьВФоне(ИмяФункции, ПараметрыВызова, ПараметрыВыполнения);
КонецФункции
Функция ВыполнитьПроцедуру(Знач ПараметрыВыполнения = Неопределено, ИмяПроцедуры, Знач Параметр1 = Неопределено,Знач Параметр2 = Неопределено, Знач Параметр3 = Неопределено, Знач Параметр4 = Неопределено,Знач Параметр5 = Неопределено, Знач Параметр6 = Неопределено, Знач Параметр7 = Неопределено) Экспорт
ПараметрыВызова = СписокПараметров(Параметр1, Параметр2, Параметр3, Параметр4,Параметр5,Параметр6, Параметр7);
ПараметрыВыполнения = ПодготовитьПараметрыВыполнения(ПараметрыВыполнения, Ложь);
Возврат ВыполнитьВФоне(ИмяПроцедуры, ПараметрыВызова, ПараметрыВыполнения);
КонецФункции


Особенность выполнения длительной операции во внешней обработке заключается в том, что она должна быть в списке справочника дополнительных внешних обработок. В общем виде процесс запуска и обработки результата длительной операции во внешней обработке выглядит следующим образом:

  1. Создать 2 реквизита в форме обработки как показано на рис. 1

2 При открытии обработки проверить открыто ли обработка из справочника внешних обработок и возможность запуска в фоне:

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

3) В модуле объекта внешней обработки я добавил процедуру расчета ВыполнитьРасчетВФоне , которая будет исполняться в фоне и функцию ВыполнитьРасчет. которая будет выполняться не фоне если не возможно выполнить расчет в фоне ( Следует отметить, что длительные процедуры должны располагаться только в менеджере объекта или в серверном общем модуле или в модуле внешней обработки):

Функция ВыполнитьРасчетНеВфоне(Параметры)Экспорт 
 Параметр1 = Параметры.Параметр1;
 Параметр2 = Параметры.Параметр2; 
 Результат = Параметр1+ Параметр2;
 Возврат Результат;
 КонецФункции

 Процедура ВыполнитьРасчетВФоне(Параметры, АдресРезультата) Экспорт 
 Результат = ВыполнитьРасчетНеВфоне(Параметры);    
 ПоместитьВоВременноеХранилище(Результат, АдресРезультата);
 КонецПроцедуры

3) Запуск операции на сервере и подключение обработчика ожидания если это возможно:

 &НаКлиенте
 Процедура ВыполнитьРасчет()
//создаем структуру параметров расчетов
ПараметрыРасчета = Новый Структура("Параметр1,Параметр2", 10, 20);
Если ДоступноВыполнениеВФоне Тогда
ДлительнаяОперация = НачатьВыполнениеВФонеНаСервере(ПараметрыРасчета);
 ОповещениеОЗавершении = Новый ОписаниеОповещения("ОбработатьРезультат", ЭтотОбъект);
 ПараметрыОжидания = ДлительныеОперацииКлиент.ПараметрыОжидания(ЭтотОбъект);
  ДлительныеОперацииКлиент.ОжидатьЗавершение(ДлительнаяОперация, ОповещениеОЗавершении, ПараметрыОжидания);
Иначе
НачатьВыполнитьРасчетНеВФоне(ПараметрыРасчета ); //Не возможно		
КонецЕсли;
КонецПроцедуры

4 )Начать расчет в фоне или не в фоне

//Это расчет в фоне
&НаСервере
Функция НачатьВыполнениеВФонеНаСервере(ПараметрыРасчета)
//ПараметрыВыполнения = ДлительныеОперации.ПараметрыВыполненияФункции(УникальныйИдентификатор); // БСП 3.1
ПараметрыВыполнения = ДлительныеОперации.ПараметрыВыполненияВФоне(УникальныйИдентификатор); // БСП 3.0
ВыполняемыйМетод = "ДлительныеОперации.ВыполнитьПроцедуруМодуляОбъектаОбработки";
ПараметрыЗадания = Новый Структура;
ПараметрыЗадания.Вставить("ДополнительнаяОбработкаСсылка",ДополнительнаяОбработкаСсылка);
ПараметрыЗадания.Вставить("ИмяМетода", "ВыполнитьРасчетВФоне");
ПараметрыЗадания.Вставить("ЭтоВнешняяОбработка", Истина);
ПараметрыЗадания.Вставить("ПараметрыВыполнения",ПараметрыРасчета);
РезультатВыполнения = ДлительныеОперации.ВыполнитьВФоне(ВыполняемыйМетод,ПараметрыЗадания, ПараметрыВыполнения);
Возврат РезультатВыполнения;
КонецФункции 
// Это результат расчета не в фоне
&НаСервере
Процедура НачатьВыполнитьРасчетНеВФоне(ПараметрыРасчета)
ВнешняяОбработка = РеквизитФормыВЗначение("Объект");
Резултьат = ВнешняяОбработка.ВыполнитьРасчетНеВфоне(ПараметрыРасчета);
КонецПроцедуры

Следует отметить, что функция ПараметрыВыполненияВФоне, которая возвращает структуру параметров выполнения отсутствует в БСП3.1.. Вместо этой функции используется ПараметрыВыполненияФункции и ПараметрыВыполненияПроцедуры

5) Обработка результата длительной операции:

 &НаКлиенте
  Процедура ОбработатьРезультат(Результат, ДополнительныеПараметры) Экспорт
 
Если Результат = Неопределено Тогда
     Возврат;
     КонецЕсли;
Если Результат.Статус = "Выполнено" Тогда
     ТекстСообщения = ПолучитьИзВременногоХранилища(Результат.АдресРезультата);
 ИначеЕсли Результат.Статус = "Ошибка" Тогда 
    ТекстСообщения = Результат.ПодробноеПредставлениеОшибки;
 КонецЕсли;
 Если Результат.Сообщения <> Неопределено Тогда 
    Для каждого СообщениеПользователю Из Результат.Сообщения Цикл
         СообщениеПользователю.Сообщить();
     КонецЦикла;
 КонецЕсли; 
 ОбщегоНазначенияКлиент.СообщитьПользователю("Результат: "+ ТекстСообщения);
 КонецПроцедуры

Следует отметить, что в качестве параметра нужно передать параметры, которые поддерживают серализацию, иначе длительная операция не выполняется и выдается сообщение -“Параметр фонового задания не поддерживает сериализацию” .

Например , если параметр ТаблицаДанных имеет тип ДанныеФормыЭлементКоллекции, то нужно преобразовать на тип ТаблицаЗначений с помощью метода выгрузить таким образом

Тз =ТаблицаДанных.Выгрузить();
ПараметрыВызова = Новый Структура(“Параметр1,Параметр2,Таблица”, 10, 20,Тз);

В описании механизма длительных операции написано, что все значения параметров фонового задания должны поддерживать сериализацию (речь идет о сериализации, а не о ХМL – сериализации). Сериализация — это преобразование объекта или дерева объектов в какой-либо формат с тем, чтобы потом эти объекты можно было восстановить из этого формата. А XML – сериализация – это процесс преобразования данных 1С:Предприятия 8 в последовательность данных формата XML и наоборот, прежде всего для обмена данными между различными информационными базами 1С:Предприятия.

Известно, сериализация данных применима для всех объектов 1С. Однако в документации по встроенному языку в описании объектов возможность сериализации указывается отметкой “Сериализуется“.
Например, в синтакс-помощнике объекта ТаблицаЗначений написано «Возможен обмен с сервером. Сериализуется. Данный объект может быть сериализован в/из XDTO. Тип XDTO, соответствующий данному объекту, определяется в пространстве имен {http://v8.1c.ru/8.1/data/core}. Имя типа XDTO: ValueTable»

Previous Article
Next Article

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.