Добрый день, коллеги.
Основная идея обработки взята из публикации //infostart.ru/1c/articles/1112877/, т. е. чтобы запустить в фоновом задании процедуру модуля внешней обработки, надо создать копию этой обработки на сервере и уже запустить её методом "ДлительныеОперации.ВыполнитьПроцедуруМодуляОбъектаОбработки" через функцию БСП ДлительныеОперации.ВыполнитьВФоне. Впрочем БСП делает практически тоже самое для обработок подключенных к подсистеме "ДополнительныеОтчетыИОбработки".
Обработка писалась для себя как шаблон, что бы не вспоминать что и где надо исправить, ну и те примеры, которые уже есть на эту тему не очень удовлетворяли меня.
Собственно код:
Модуль обработки
#Область ПрограммныйИнтерфейс
Функция СведенияОВнешнейОбработке() Экспорт
	
	ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке(СтандартныеПодсистемыСервер.ВерсияБиблиотеки());
	ПараметрыРегистрации.Наименование = НСтр("ru = 'ШаблонОбработкиДлительнойОперацииСПрогрессом'");
	ПараметрыРегистрации.Информация = НСтр("ru = 'Шаблон обработки с длительной операцией и выводом прогресса '");
	ПараметрыРегистрации.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиДополнительнаяОбработка();
	ПараметрыРегистрации.Версия = "1.1.1";
	ПараметрыРегистрации.БезопасныйРежим = Ложь;
	
	Команда = ПараметрыРегистрации.Команды.Добавить();
	Команда.Представление = НСтр("ru = 'Открытие формы обработки...'");
	
	//Для совместимости Идентификатор называем также как и процедуру модуля
	Команда.Идентификатор = "ВыполнитьДлительнуюОперацию";
	Команда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыОткрытиеФормы();
	Команда.ПоказыватьОповещение = Ложь;
	Возврат ПараметрыРегистрации;
	
КонецФункции
//Имитация длительной операции
Процедура ВыполнитьДлительнуюОперацию(ПараметрыОбработки, АдресРезультата) Экспорт
	СчетчикШага = 0;
	Шаг = ПараметрыОбработки.КоличествоИтераций / 100;
	
	Для Счетчик = 1 По ПараметрыОбработки.КоличествоИтераций Цикл
		ДатаЗавершенияВМиллисекундах = ТекущаяУниверсальнаяДатаВМиллисекундах() + 1000;
		Пока ТекущаяУниверсальнаяДатаВМиллисекундах() < ДатаЗавершенияВМиллисекундах Цикл
		КонецЦикла;
		
		//БСП рекомендует вызывать ДлительныеОперации.СообщитьПрогресс не более 100 раз
		
		Если (Счетчик - СчетчикШага) >= Шаг Тогда
			СчетчикШага = Счетчик;
			ПроцентВыполнения = Цел(Счетчик * 100 / ПараметрыОбработки.КоличествоИтераций);
			ТестСообщения = СтрШаблон("Выполнено %1 из %2", Счетчик, ПараметрыОбработки.КоличествоИтераций);
			ДлительныеОперации.СообщитьПрогресс(ПроцентВыполнения, ТестСообщения);
		КонецЕсли;
	КонецЦикла;
	
КонецПроцедуры	
#КонецОбласти
В форме созданы следующие реквизиты:
- ИдентификаторДлительнойОперации - ТИП "УникальныйИдентификатор" используется для поиска и управления фоновым заданием
- ИдентификаторКомандыОбработки - ТИП "Строка"
- ИмяФайлаОбработки - ТИП "Строка" эти два реквизита для универсальности использования обработки как с подключением к БСП "ДополнительныеОтчетыИОбработки" и так и без нее
- ДлительнаяОперацияПроцент - Тип "Число" для вывода прогресса выполнения
- ДлительнаяОперацияТекст - Тип "Строка" для вывода текста прогресса выполнения, если использовать стандартный вывод БСП, то эти реквизиты не нужны.
Код модуля формы
#Область СобытияФормы
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	
	Если ЗначениеЗаполнено(Параметры.ДополнительнаяОбработкаСсылка) Тогда
		ИмяФайлаОбработки = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Параметры.ДополнительнаяОбработкаСсылка, "ИмяФайла");
		ИдентификаторКомандыОбработки = Параметры.ИдентификаторКоманды;
	Иначе
		ИмяФайлаОбработки = "";
		ИдентификаторКомандыОбработки = "ВыполнитьДлительнуюОперацию";
	КонецЕсли;
	
КонецПроцедуры
&НаКлиенте
Процедура ПередЗакрытием(Отказ, ЗавершениеРаботы, ТекстПредупреждения, СтандартнаяОбработка)
	Если ЗначениеЗаполнено(ИдентификаторДлительнойОперации) Тогда
		ПроверитьИОтменитьЕслиВыполняется(ИдентификаторДлительнойОперации);
	КонецЕсли;
КонецПроцедуры
#КонецОбласти
#Область ОбработчикиКомандФормы
&НаКлиенте
Процедура ВыполнитьОбработку(Команда)
	
	Если НЕ ЗначениеЗаполнено(ИмяФайлаОбработки) И Не СоздатьКопиюНаСервере() Тогда
			ПоказатьПредупреждение(,"Не удалось создать временный файл на сервере",, "Ошибка!!!");
			Возврат;
	КонецЕсли;	
	
	ПараметрыОжидания = ДлительныеОперацииКлиент.ПараметрыОжидания(ЭтотОбъект);
	
	//Если требуется стандарный вывод БСП тогда снять комментарий у следующих 2 строк
	//ПараметрыОжидания.ВыводитьОкноОжидания = ИСТИНА
	//ПараметрыОжидания.ВыводитьПрогрессВыполнения = Истина;
	//и закомментировать следующие 2 строки
	ПараметрыОжидания.ВыводитьОкноОжидания = Ложь;
	ПараметрыОжидания.ОповещениеОПрогрессеВыполнения = Новый ОписаниеОповещения("ПрогрессВыполнения", ЭтотОбъект);
	ПараметрыОжидания.ОповещениеПользователя.Показать = Истина;
	ПараметрыОжидания.ОповещениеПользователя.Текст = НСтр("ru = 'Успешное завершение'");
	ПараметрыОжидания.Интервал  = 1;
	ОповещениеПослеВыполнения = Новый ОписаниеОповещения("ПослеЗавершенияДлительнойОперации", ЭтотОбъект); 
	СтруктураДлительнойОперации = НачатьВыполнениеДлительнойОперации();
	ДлительныеОперацииКлиент.ОжидатьЗавершение(СтруктураДлительнойОперации, ОповещениеПослеВыполнения, ПараметрыОжидания);
	Если СтруктураДлительнойОперации.Статус = "Выполняется" Тогда
		ИдентификаторДлительнойОперации = СтруктураДлительнойОперации.ИдентификаторЗадания;
		//Если требуется стандарный вывод БСП тогда закомментировать следующие 4 строки
		Элементы.Страницы.ТекущаяСтраница = Элементы.ДлительныеОперации;
		Элементы.ГруппаКнопки.Видимость = Ложь;
		ДлительнаяОперацияПроцент = 0;
		ДлительнаяОперацияТекст = НСтр("ru = 'Пожалуйста подождите...'");
	КонецЕсли;
	
КонецПроцедуры
#КонецОбласти
#Область СлужебныеПроцедурыИФункции
&НаСервере
Функция СоздатьКопиюНаСервере()
	
	Попытка
		ИмяФайлаОбработки = ПолучитьИмяВременногоФайла("epf");
		//Если у пользователя ИБ установлен режим "Защита от опасных действий"
		//следующие 2 строчки вызывют ошибку поскольку в этом режиме они блокируются
		//Решение: подключать обработку к подсистеме "ДополнительныеОтчетыИОбрабоки"
		ДвоичныеДанные = Новый ДвоичныеДанные(РеквизитФормыВЗначение("Объект").ИспользуемоеИмяФайла);
		ДвоичныеДанные.Записать(ИмяФайлаОбработки);
		Результат = Истина;
	Исключение
		ИмяФайлаОбработки = "";
		Результат = Ложь;
	КонецПопытки;
	Возврат Результат;
	
КонецФункции
&НаСервере
Функция НачатьВыполнениеДлительнойОперации()
	
	//Собственные параметры задания
	ПараметрыВыполненияОбработки = Новый Структура;
	ПараметрыВыполненияОбработки.Вставить("КоличествоИтераций", КоличествоИтераций);
		
	//Стандартные параметры задания
	ПараметрыЗадания = Новый Структура;
	ПараметрыЗадания.Вставить("ИмяОбработки", ИмяФайлаОбработки);
	ПараметрыЗадания.Вставить("ИмяМетода", ИдентификаторКомандыОбработки);	
	ПараметрыЗадания.Вставить("ПараметрыВыполнения", ПараметрыВыполненияОбработки);
	ПараметрыЗадания.Вставить("ДополнительнаяОбработкаСсылка", Параметры.ДополнительнаяОбработкаСсылка);
	ПараметрыЗадания.Вставить("ЭтоВнешняяОбработка", Истина);
	ВыполняемыйМетод = "ДлительныеОперации.ВыполнитьПроцедуруМодуляОбъектаОбработки";
	
	ПараметрыВыполнения = ДлительныеОперации.ПараметрыВыполненияВФоне(УникальныйИдентификатор);
	ПараметрыВыполнения.НаименованиеФоновогоЗадания = СтрШаблон("Фоновое выполнение обработки %1", ПараметрыЗадания.ИмяОбработки);
	Результат = ДлительныеОперации.ВыполнитьВФоне(ВыполняемыйМетод, ПараметрыЗадания, ПараметрыВыполнения);
	Возврат Результат;
	
КонецФункции
&НаКлиенте
// Если используется стандартный вывод БСП  в процедуре нет необходимости
Процедура ПрогрессВыполнения(Результат, ДополнительныеПараметры) Экспорт
	
	Если Результат.Статус = "Выполняется" Тогда
		Прогресс = ПрочитатьПрогресс(Результат.ИдентификаторЗадания);
		Если Прогресс <> Неопределено Тогда
			ДлительнаяОперацияПроцент = Прогресс.Процент;
			ДлительнаяОперацияТекст = Прогресс.Текст;
		КонецЕсли;
	КонецЕсли;
	
КонецПроцедуры
&НаСервереБезКонтекста
Функция ПрочитатьПрогресс(ИдентификаторЗадания)
	Возврат ДлительныеОперации.ПрочитатьПрогресс(ИдентификаторЗадания);
КонецФункции
&НаКлиенте
Процедура ПослеЗавершенияДлительнойОперации(Результат, ДополнительныеПараметры) Экспорт
	
	Если Результат = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	Если Результат.Статус = "Выполнено" Тогда
		// Если используется стандартный вывод БСП закомментировать следующие 3 строчки
		ДлительнаяОперацияПроцент = 100;
		Элементы.Страницы.ТекущаяСтраница = Элементы.НастройкиОбработки;
		Элементы.ГруппаКнопки.Видимость = Истина;
	Иначе
		ПоказатьПредупреждение(, Результат.КраткоеПредставлениеОшибки);
	КонецЕсли;
	
КонецПроцедуры
&НаСервереБезКонтекста
Процедура  ПроверитьИОтменитьЕслиВыполняется(ИдентификаторЗадания)
	
	ДлительнаяОперация = ДлительныеОперации.ОперацияВыполнена(ИдентификаторЗадания);
	Если ДлительнаяОперация.Статус = "Выполняется" Тогда
		ДлительныеОперации.ОтменитьВыполнениеЗадания(ИдентификаторЗадания);
	КонецЕсли;
КонецПроцедуры
#КонецОбласти
Обработка тестировалась на версиях БСП 3.1.5.385 и 3.1.7.37 платформа 1с версии 8.3.20.1710
Вступайте в нашу телеграмм-группу Инфостарт
 
                                    