Наверх

1С Длительная операция БСП 3.0

Задайте вопрос эксперту

Подберем решение под ваши задачи

В интернете очень много информации о таком коде, но вряд ли вы найдете ту, которая действительно бы работала как вам нужно. В БСП есть механизм использования длительной операции, но он работает для обработок, которые подключены к справочнику «ДополнительныеОтчетыИОбработки», при обращении к ним создается временный файл на сервере и уже в дальнейшем сервер работает именно с этим файлом, обращаясь к его модулю объекта.
Мы сделаем почти так же: Развернем копию обработки при открытии на сервере и будем обращаться к процедурам модуля этой копии.

  1. Для начала создадим новую внешнюю обработку и дадим ей название, например, «НашаДлительнаяОперация»
    ДлОп 1.png - ITsale
  2. Создадим и назначим форму нашей обработке
    ДлОп 2.png - ITsale
  3. Сразу до начала написания кода распределим некоторые области для простоты работы и общей читаемости.
     Модуль формы обработки: #Область ВЫПОЛЕННИЕ_БЕЗ_ДЛИТЕЛЬНОЙ_ОПЕРАЦИИ #КонецОбласти #Область ПОМЕЩЕНИЕ_ОБРАБОТКИ_НА_СЕРВЕР #КонецОбласти #Область ВЫПОЛНЕНИЕ_С_ДЛИТЕЛЬНОЙ_ОПЕРАЦИИ #КонецОбласти #Область ПРОЦЕДУРЫ_И_ФУНКЦИИ #КонецОбласти 
    ДлОп 3.png - ITsale
     Модуль объекта обработки: #Область ДЛИТЕЛЬНАЯ_ОПЕРАЦИЯ #КонецОбласти #Область ОБЩИЕ_ПРОЦЕДУРЫ_И_ФУНКЦИИ_МОДУЛЯ #КонецОбласти 
    ДлОп 4.png - ITsale
  4. Создадим две команды на форме «ВыполнениеБезДлительнойОперации» и «ВыполнениеСДлительнойОперации»
    после4.jpg - ITsale
  5. Разметим форму группами управления - это улучшит юзабилити для пользователя
    ДлОп 5.png - ITsale

  6. Приступим к реквизитам формы и обработки (Они зависят от вашей задачи и прочих факторов которые вам придется самостоятельно определить, в нашем примере мы рассматриваем тестовый вариант выполнения)
    Это будут параметры для выполнения нашей длительной операции, которые мы будем передавать в процедуру модуля обработки
    ДлОп 6.png - ITsale

    ДлОп 6_1.png - ITsale
    ДлОп 6_2.png - ITsale
    ДлОп 6_3.png - ITsale

  7. Разместим основные элементы управления на форме
    ДлОп 7.png - ITsale
     Должно получиться вот так, но это все формальности, вы можете настроить элементы управления как угодно вам
    ДлОп 8.png - ITsale

  8. Добавим реквизиты для отображения прогресса выполнения, некоторые реквизиты для хранения переменных длительной операции, а также команду отмены выполнения длительной операции
    ДлОп 9.png - ITsale

    ДлОп 10.png - ITsale

    ДлОп 11.png - ITsale

Общий вид обработки стал выглядеть так:

ДлОп 12.png - ITsale
 

Первым делом определим процедуру «ПриСозданииНаСервере» если таковая нужна, мы же используем ее для примера в ознакомительных целях, она будет находится вне размеченных областей.

 &НаСервере Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка) //* Действия При создании на сервере. ОбщегоНазначенияКлиентСервер.СообщитьПользователю("Запуск обработки."); КонецПроцедуры 

Далее поработаем с областью «ВЫПОЛЕННИЕ_БЕЗ_ДЛИТЕЛЬНОЙ_ОПЕРАЦИИ», для этого зайдем на форму и назначим действие для команды «ВыполнениеБезДлительнойОперации»

ДлОп 13.png - ITsale
 

Реализовывать их мы не будем, но здесь можно выполнять тот код, который захотим: например, в котором нам не нужно использовать механизмы длительной операции.

ДлОп 14.png - ITsale
 

В модуле сформируется код, перенесем его в область «ВЫПОЛЕННИЕ_БЕЗ_ДЛИТЕЛЬНОЙ_ОПЕРАЦИИ»

ДлОп 15.png - ITsale
 
ДлОп 15_1.png - ITsale
 

Далее перейдем к области «ПОМЕЩЕНИЕ_ОБРАБОТКИ_НА_СЕРВЕР». Определим процедуру «ПриОткрытии» с директивой &НаКлиенте
В ней мы начнем помещать наш файл обработки на сервер во временное хранилище. Далее обработаем результат помещения и запишем адрес хранения в реквизит формы.

ДлОп 16.png - ITsale
 #Область ПОМЕЩЕНИЕ_ОБРАБОТКИ_НА_СЕРВЕР &НаКлиенте Процедура ПриОткрытии(Отказ) //Создаем описание файла для начала помещения. ОписаниеПередаваемогоФайла = Новый ОписаниеПередаваемогоФайла(ИспользуемоеИмяФайлаОбработки()); //Определяем массив для передачи описаний файлов. МассивФайлов = Новый Массив; МассивФайлов.Добавить(ОписаниеПередаваемогоФайла); //Проверяем внешняя ли это обработка или нет. Если ЭтоВнешняяОбработка() Тогда ОписаниеОповещения = Новый ОписаниеОповещения("ОбработатьПомещенияФайлаОбработкиВоВременноеХранилище", ЭтотОбъект); НачатьПомещениеФайлов(ОписаниеОповещения, МассивФайлов,, Ложь, УникальныйИдентификатор); КонецЕсли; КонецПроцедуры &НаКлиенте Процедура ОбработатьПомещенияФайлаОбработкиВоВременноеХранилище(МассивФайлов, ОбработчикЗавершения) Экспорт //Записываем копию текущией обработки во временном хранилище. Если МассивФайлов <> Неопределено Тогда ХранениеФайлаОбработки = ВрменныйФайлОбработкиНаСервере(МассивФайлов[0].Хранение); КонецЕсли; КонецПроцедуры &НаСервере Функция ВрменныйФайлОбработкиНаСервере(Хранение) Результат = ПолучитьИмяВременногоФайла(); ДвоичныеДанные = ПолучитьИзВременногоХранилища(Хранение); ДвоичныеДанные.Записать(Результат); Возврат Результат; КонецФункции &НаСервере Функция ИспользуемоеИмяФайлаОбработки() Возврат РеквизитФормыВЗначение("Объект").ИспользуемоеИмяФайла; КонецФункции &НаСервере Функция ЭтоВнешняяОбработка() НаборИменОбработки = СтрРазделить(РеквизитФормыВЗначение("Объект").Метаданные().ПолноеИмя(),"."); Возврат (ВРег(НаборИменОбработки[0]) = "ВНЕШНЯЯОБРАБОТКА") КонецФункции #КонецОбласти 

Теперь заполним область «ВЫПОЛНЕНИЕ_С_ДЛИТЕЛЬНОЙ_ОПЕРАЦИИ» и для начала определим события для команды «ВыполнениеСДлительнойОперацией»

ДлОп 17.png - ITsale
 
ДлОп 17-1.png - ITsale
 

И помещаем полученный код в нашу область

ДлОп 17-2.png - ITsale
 

В теле процедуры «ВыполнениеСДлительнойОперацией» напишем такой код:

 ОчиститьСообщения(); ВремяНачалаДлительнойОперации = ТекущаяДата(); Элементы.ГруппаПрогрессДлительнойОперации.Видимость = Истина; СопровождающийТекст = НСтр("ru = 'Наша длительная операция'"); ОбработчикЗавершения = Новый ОписаниеОповещения("ПослеЗавершенияДлительнойОперации", ЭтотОбъект, СопровождающийТекст); ОповещениеОПрогрессеВыполнения = Новый ОписаниеОповещения("ВыполнитьДействиеПрогрессВыполнения", ЭтотОбъект, СопровождающийТекст); НастройкиОжидания = ДлительныеОперацииКлиент.ПараметрыОжидания(ЭтаФорма); НастройкиОжидания.ВыводитьПрогрессВыполнения = Истина; НастройкиОжидания.ВыводитьОкноОжидания = Ложь; НастройкиОжидания.ВыводитьСообщения = Истина; НастройкиОжидания.ТекстСообщения = НСтр("ru = 'Выполнение длительно операции...'"); НастройкиОжидания.ОповещениеОПрогрессеВыполнения = ОповещениеОПрогрессеВыполнения; // Выполняемая команда общего модуля обработки // см. ОбщийМодуль.ОбработкаДанныхВФоне ВыполняемаяКоманда = Новый Структура("Идентификатор", "ОбработкаДанныхВФоне" ); ДлительнаяОперация = ВыполнениеСДлительнойОперациейНаСервере (ВыполняемаяКоманда, УникальныйИдентификатор); ИдентификаторФоновогоЗадания = ДлительнаяОперация.ИдентификаторЗадания; ДлительныеОперацииКлиент.ОжидатьЗавершение(ДлительнаяОперация, ОбработчикЗавершения, НастройкиОжидания); 

Далее в теле процедуры «ЗаполнитьВФонеНаСервере», переобозначим ее как функцию и определим 2 параметра для нее: ВыполняемаяКоманда, УникальныйИдентификатор

 &НаСервере Функция ВыполнениеСДлительнойОперациейНаСервере(ВыполняемаяКоманда, УникальныйИдентификатор) // Структура для передачи параметров, в процедуру, выполняемую в модуле объкта // длительной операцией. ПараметрыВыполненияОбработки = Новый Структура(); ПараметрыВыполненияОбработки.Вставить("Параметр1", Объект.Параметр1); ПараметрыВыполненияОбработки.Вставить("Параметр2", Объект.Параметр2); ПараметрыВыполненияОбработки.Вставить("Параметр3", Объект.Параметр3); ВыполняемыйМетод = "ДлительныеОперации.ВыполнитьПроцедуруМодуляОбъектаОбработки"; ЭтоВнешняяОбработка = ЭтоВнешняяОбработка(); ИмяОбработки = ?(ЭтоВнешняяОбработка, ХранениеФайлаОбработки, РеквизитФормыВЗначение("Объект").Метаданные().ПолноеИмя()); ПараметрыЗадания = Новый Структура; ПараметрыЗадания.Вставить("БезопасныйРежим", Ложь); ПараметрыЗадания.Вставить("ИмяОбработки", ИмяОбработки); ПараметрыЗадания.Вставить("ИмяМетода", ВыполняемаяКоманда.Идентификатор); ПараметрыЗадания.Вставить("ПараметрыВыполнения", ПараметрыВыполненияОбработки); ПараметрыЗадания.Вставить("ЭтоВнешняяОбработка", ЭтоВнешняяОбработка); ПараметрыЗадания.Вставить("ДополнительнаяОбработкаСсылка", Справочники.ДополнительныеОтчетыИОбработки.ПустаяСсылка()); ПараметрыВыполнения = ДлительныеОперации.ПараметрыВыполненияВФоне(УникальныйИдентификатор); ПараметрыВыполнения.НаименованиеФоновогоЗадания = НСтр("ru = 'Имя фонового задания'"); ПараметрыВыполнения.ЗапуститьВФоне = Истина; ПараметрыВыполнения.Вставить("ИдентификаторФормы", УникальныйИдентификатор); ПараметрыВыполнения = ДлительныеОперации.ПараметрыВыполненияВФоне(УникальныйИдентификатор); Возврат ДлительныеОперации.ВыполнитьВФоне(ВыполняемыйМетод, ПараметрыЗадания, ПараметрыВыполнения); КонецФункции 

Так же определим обработчики оповещений, процедуры обработчиков обязательно должны быть экспортными

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

Для некоторых длительных операций нужно обработать результат уже у пользователя, поэтому мы можем получить его некоторыми процедурами, а опишем мы их в области «ПРОЦЕДУРЫ_И_ФУНКЦИИ_ДЛЯ_ФОНОВОГО_ЗАДАНИЯ»

 &НаСервере Процедура ОбработатьРезультатВыполнения(АдресРезультата) Результат = ПолучитьИзВременногоХранилища(АдресРезультата); ОбщегоНазначенияКлиентСервер.СообщитьПользователю(Результат.Сообщение); ВозвращаемыйРезультат = Результат.ВозвращаемыйРезультат; // Например: Загружаем данные полученной ТЗ, в ТЗ на форме обработки // ** Объект.ОбъектыИзменения.Очистить(); // ** Объект.ОбъектыИзменения.Загрузить(ВозвращаемыйРезультат); // Очищаем временное хранилище, для избежание его переполнения. УдалитьИзВременногоХранилища(АдресРезультата); КонецПроцедуры &НаКлиенте Процедура ОбработатьПоЗавершению() Элементы.ГруппаПрогрессЗадачи.Видимость = Ложь; Элементы.ТекстЗадания.Заголовок = ""; ПроцентВыполнения = 0; ОбщегоНазначенияКлиент.СообщитьПользователю("Обработка завершена. "); КонецПроцедуры 
ДлОп 18.png - ITsale

Вернемся к области «ВЫПОЛНЕНИЕ_С_ДЛИТЕЛЬНОЙ_ОПЕРАЦИИ» и допишем команды отмены задания, это делается очень легко, достаточно знать идентификатор фонового задания, который мы записали выше в коде запуска задания, он хранится в реквизите формы с одноименным наименованием ИдентификаторФоновогоЗадания
Определим события для команды «Отменить выполнение»

ДлОп 19.png - ITsale
 
ДлОп 19-1.png - ITsale
 

И в процедуре «ОтменитьВыполнениеДлительнойОперацииНаСервере» напишем одну строчку

ДлОп 20.png - ITsale
 &НаСервере Процедура ОтменитьВыполнениеДлительнойОперацииНаСервере() ДлительныеОперации.ОтменитьВыполнениеЗадания(ИдентификаторФоновогоЗадания); КонецПроцедуры 

Наконец, мы переходим к модулю объекта, тут все предельно просто - заполняем следующим кодом:

 // Отладка модуля обработки выполняется, // при параметрах запуска конфигурации: "/C РежимОтладки". // Для выполнения длительной операции требуется выключить данный параметр. #Область ДЛИТЕЛЬНАЯ_ОПЕРАЦИЯ Процедура ОбработкаДанныхВФоне(Параметры, АдресРезультата) Экспорт // Получаем результат обработки нашей процедурой и помещаем его в хранилище. Результат = ОбработкаДанныхДоговоров(Параметры, АдресРезультата); ПоместитьВоВременноеХранилище(Результат, АдресРезультата); КонецПроцедуры Функция ОбработкаДанныхДоговоров(Параметры, АдресРезультата) Параметр1 = Параметры.Параметр1; Параметр2 = Параметры.Параметр2; Параметр3 = Параметры.Параметр3; Результат = Новый Структура("Сообщение, ВозвращаемыйРезультат"); КоличествоОбработанных = Число(Параметр1); ВремяФиниша = ТекущаяДатаСеанса() + 100; Пока ТекущаяДатаСеанса()<ВремяФиниша Цикл Процент = 100 - (ВремяФиниша - ТекущаяДатаСеанса()); ТекстСобщения = СтрШаблон("Выполнено %1 процентов: Параметр1 - %2, Параметр2 - %3, Параметр3 - %4", Процент, Параметр1, Параметр2, Параметр3); Если НЕ (Процент % 10) Тогда ДлительныеОперации.СообщитьПрогресс(Процент, ТекстСобщения); КонецЕсли; КонецЦикла; Результат.Сообщение = "Сообщение для результата"; Результат.ВозвращаемыйРезультат = ВремяФиниша; Возврат Результат; КонецФункции #КонецОбласти #Область ОБЩИЕ_ПРОЦЕДУРЫ_И_ФУНКЦИИ_МОДУЛЯ // Здесь можно заполнить дополнительные процедуры/функции #КонецОбласти 

Отладка модуля обработки может выполняться при параметре отладки конфигуратора «/C РежимОтладки»

Наглядно:
Длительная операция 1с - ITsale

Скачать внешнюю обработку
Откройте новые возможности для вашего бизнеса с Тарифами 1С:ИТС!

Нет комментариев
Оставьте комментарий первым
Новый комментарий

Обратный звонок
Оцените сайт