Фоновое задание в модуле внешней обработки
Почитал разные варианты решения с использованием фонового задания в модуле объекта внешней обработки. Максимально похожий на правду и , но мне не нравится реализация некоторых моментов.
1) Там используется просто сохранении копии обработки на сервере и помещении во временное хранилище.
2) И в функции ДлительныеОперации.ВыполнитьПроцедуру()/ВыполнитьВФоне() - указывают в качестве исполняемого метода - метод "ДлительныеОперации.ВыполнитьПроцедуруМодуляОбъектаОбработки".
Вот 2 пункта которые мне не нравятся. Поскольку как мне кажется я нашел более лаконичный прием, хоть и делает тоже самое, почти.
1) Сначала выполняю НачатьПомещениеФайлаНаСервер()
2) Подключаю внешнею обработку, по адресу в хранилище. ВнешнииОбработки.Подключить(Адрес)
На этих пунктах все ок. После выполнения п.2 возвращается имя подключенной обработки = имя файла без расширения.
Проблема начинается когда я пытаюсь выполнить Да, да именно так и должен собираться метод - слова "МодульОбъекта" обязательны.
Так вот, там по сути выполняется метод ВнешнииОбработки.Создать() - но на этом месте вылетает ошибка с тем, что якобы файл не обнаружен. Хотя я пробовал тоже самое выполнить в п.2 Сначала подключаю, потом создаю и тут это работает даже могу выполнить экспортную процедуру и модуля объекта и все ок. Эти шаги в синтаксис-помощнике описаны. Но в модуле ДлительныеОперациии не работает. Я проверял, что там в параметрах передается (все нормально). Просто как будто на этом этапе обработка уже не доступна или типа того. Неужели вот это все хрень и не нужно выполнять "ВнешнииОбработки.Подключенить(Адрес)", а достаточно просто записать копию на сервере?
1) Там используется просто сохранении копии обработки на сервере и помещении во временное хранилище.
2) И в функции ДлительныеОперации.ВыполнитьПроцедуру()/ВыполнитьВФоне() - указывают в качестве исполняемого метода - метод "ДлительныеОперации.ВыполнитьПроцедуруМодуляОбъектаОбработки".
Вот 2 пункта которые мне не нравятся. Поскольку как мне кажется я нашел более лаконичный прием, хоть и делает тоже самое, почти.
1) Сначала выполняю НачатьПомещениеФайлаНаСервер()
2) Подключаю внешнею обработку, по адресу в хранилище. ВнешнииОбработки.Подключить(Адрес)
На этих пунктах все ок. После выполнения п.2 возвращается имя подключенной обработки = имя файла без расширения.
Проблема начинается когда я пытаюсь выполнить
ДлительныеОперации.ВыполнитьПроцедуру(, "ВнешняяОбработка."+ИмяОбработки+".МодульОбъекта.МойМетод")
Так вот, там по сути выполняется метод ВнешнииОбработки.Создать() - но на этом месте вылетает ошибка с тем, что якобы файл не обнаружен. Хотя я пробовал тоже самое выполнить в п.2 Сначала подключаю, потом создаю и тут это работает даже могу выполнить экспортную процедуру и модуля объекта и все ок. Эти шаги в синтаксис-помощнике описаны. Но в модуле ДлительныеОперациии не работает. Я проверял, что там в параметрах передается (все нормально). Просто как будто на этом этапе обработка уже не доступна или типа того. Неужели вот это все хрень и не нужно выполнять "ВнешнииОбработки.Подключенить(Адрес)", а достаточно просто записать копию на сервере?
По теме из базы знаний
- Отслеживание выполнения фонового задания
- Запуск фонового задания во внешней обработке. Отключение предупреждений защиты от опасных действий в фоновом задании
- Индикация прогресса выполнения фонового задания на управляемой форме внешней обработки
- Запуск в фоне процедуры модуля внешней обработки на управляемых формах без БСП
- Шаблон внешней обработки на основе БСП с фоновым выполнением модуля обработки и выводом индикации фонового задания
Найденные решения
Остальные ответы
Подписаться на ответы
Инфостарт бот
Сортировка:
Древо развёрнутое
Свернуть все
(1) Если обработка подключена как внешняя, то в качестве параметров задания использую следующую структуру:
Ссылка на открываемую внешнюю обработку содержится в параметрах формы в свойстве "ДополнительнаяОбработкаСсылка"
Если обработка открывается через Файл-Открыть, то параметры задания передаю следующие
ПутьНаСервере - это полный путь к файлу обработки на сервере (сохраняю его предварительно во временные файлы, при закрытии формы удаляю)
В обоих случаях в качестве выполняемого метода использую "ДлительныеОперации.ВыполнитьПроцедуруМодуляОбъектаОбработки"
ИмяМетода в параметрах задания - это как раз экспортная процедура модуля обработки
Примерно все выглядит следующим образом
ВнешняяОбработка - реквизит формы с типом СправочникСсылка.ДополнительныеОтчетыИОбработки, инициализируется при создании формы
ПутьНаСервере - реквизит формы с типом Строка (хранит путь к обработке на сервере)
Прогресс "сообщаю" в экспортной процедуре:
ПараметрыЗадания = Новый Структура;
ПараметрыЗадания.Вставить("ИмяМетода", ИмяМетода);
ПараметрыЗадания.Вставить("ПараметрыВыполнения", ПараметрыОбработки);
ПараметрыЗадания.Вставить("ЭтоВнешняяОбработка", Истина);
ПараметрыЗадания.Вставить("ДополнительнаяОбработкаСсылка", ВнешняяОбработка);
Ссылка на открываемую внешнюю обработку содержится в параметрах формы в свойстве "ДополнительнаяОбработкаСсылка"
Если обработка открывается через Файл-Открыть, то параметры задания передаю следующие
ПараметрыЗадания = Новый Структура;
ПараметрыЗадания.Вставить("ИмяОбработки", ПутьНаСервере);
ПараметрыЗадания.Вставить("ИмяМетода", ИмяМетода);
ПараметрыЗадания.Вставить("ПараметрыВыполнения", ПараметрыОбработки);
ПараметрыЗадания.Вставить("ЭтоВнешняяОбработка", Истина);
ПутьНаСервере - это полный путь к файлу обработки на сервере (сохраняю его предварительно во временные файлы, при закрытии формы удаляю)
В обоих случаях в качестве выполняемого метода использую "ДлительныеОперации.ВыполнитьПроцедуруМодуляОбъектаОбработки"
ИмяМетода в параметрах задания - это как раз экспортная процедура модуля обработки
Примерно все выглядит следующим образом
ВнешняяОбработка - реквизит формы с типом СправочникСсылка.ДополнительныеОтчетыИОбработки, инициализируется при создании формы
ПутьНаСервере - реквизит формы с типом Строка (хранит путь к обработке на сервере)
&НаКлиенте
Процедура НачатьПодготовкуФайлаВФоне()
Состояние("Подготовка данных...");
Если Не ЗначениеЗаполнено(ВнешняяОбработка) И ПустаяСтрока(ПутьНаСервере) Тогда
ПутьНаСервере = ИспользуемоеИмяФайла();
ИначеЕсли Не ЗначениеЗаполнено(ВнешняяОбработка) И Не ПустаяСтрока(ПутьНаСервере) Тогда
Если Не ФайлСуществуетНаСервере(ПутьНаСервере) Тогда
ПутьНаСервере = ИспользуемоеИмяФайла();
КонецЕсли;
КонецЕсли;
ИмяЗадания = "Выгрузка данных в шаблон Excel";
ПараметрыЗапуска = ПодготовитьДанные(); // тут массив структур, передается в качестве параметра процедуры
ДлительнаяОперация = ЗапуститьДлительнуюОперацию("ПодготовитьДанныеПоТоварамНаСервере", ПараметрыЗапуска, ИмяЗадания);
ПараметрыОжидания = ДлительныеОперацииКлиент.ПараметрыОжидания(ЭтотОбъект);
ПараметрыОжидания.ВыводитьПрогрессВыполнения = Истина;
ПараметрыОжидания.ВыводитьОкноОжидания = Ложь;
ПараметрыОжидания.ОповещениеОПрогрессеВыполнения = Новый ОписаниеОповещения("ПрогрессВыполнения", ЭтотОбъект); // для отображения прогресса
ПараметрыОжидания.Интервал = 2;
Доступность = Ложь;
Состояние("Ожидайте завершения процесса подготовки файла Excel...");
ДлительныеОперацииКлиент.ОжидатьЗавершение(
ДлительнаяОперация,
Новый ОписаниеОповещения("ВыполнитьПроцедуруФоново_Выполнено", ЭтотОбъект),
ПараметрыОжидания);
КонецПроцедуры
&НаСервереБезКонтекста
Функция ФайлСуществуетНаСервере(ПутьНаСервере)
Файл = Новый Файл(ПутьНаСервере);
Возврат Файл.Существует();
КонецФункции
&НаСервере
Функция ЗапуститьДлительнуюОперацию(ИмяМетода, ПараметрыОбработки, ИмяЗадания)
ВыполняемыйМетод = "ДлительныеОперации.ВыполнитьПроцедуруМодуляОбъектаОбработки";
ПараметрыЗадания = Новый Структура;
Если Не ЗначениеЗаполнено(ВнешняяОбработка) Тогда
ПараметрыЗадания.Вставить("ИмяОбработки", ПутьНаСервере);
КонецЕсли;
ПараметрыЗадания.Вставить("ИмяМетода", ИмяМетода);
ПараметрыЗадания.Вставить("ПараметрыВыполнения", ПараметрыОбработки);
ПараметрыЗадания.Вставить("ЭтоВнешняяОбработка", Истина);
Если ЗначениеЗаполнено(ВнешняяОбработка) Тогда
ПараметрыЗадания.Вставить("ДополнительнаяОбработкаСсылка", ВнешняяОбработка);
КонецЕсли;
ПараметрыВыполнения = ДлительныеОперации.ПараметрыВыполненияВФоне(УникальныйИдентификатор);
ПараметрыВыполнения.НаименованиеФоновогоЗадания = ИмяЗадания;
РезультатФоновогоЗадания = ДлительныеОперации.ВыполнитьВФоне(ВыполняемыйМетод, ПараметрыЗадания, ПараметрыВыполнения);
Возврат РезультатФоновогоЗадания;
КонецФункции
&НаКлиенте
Функция ИспользуемоеИмяФайла()
ПутьНаКлиенте = ПолучитьИмяФайлаНаКлиенте();
ДвоичныеДанные = Новый ДвоичныеДанные(ПутьНаКлиенте);
Возврат СохранитьОбработкуНаСервере(ПоместитьВоВременноеХранилище(ДвоичныеДанные, УникальныйИдентификатор));
КонецФункции
&НаСервере
Функция ПолучитьИмяФайлаНаКлиенте()
ЭтотОб = РеквизитФормыВЗначение("Объект");
Возврат ЭтотОб.ИспользуемоеИмяФайла;
КонецФункции
&НаСервере
Функция СохранитьОбработкуНаСервере(АдресВХ)
ДвоичныеДанные = ПолучитьИзВременногоХранилища(АдресВХ);
ИмяВременногоФайла = ПолучитьИмяВременногоФайла("epf");
ДвоичныеДанные.Записать(ИмяВременногоФайла);
Возврат ИмяВременногоФайла;
КонецФункции
&НаКлиенте
Процедура ПрогрессВыполнения(Результат, Контекст) Экспорт
Если Результат.Статус = "Выполняется" или Результат.Статус = "Выполнено" Тогда
Прогресс = Результат.Прогресс;
Если Прогресс <> Неопределено Тогда
Индикатор = Прогресс.Процент; // Индикатор - полей Индикатор на форме
Элементы.ДекорацияПояснение.Заголовок = Прогресс.Текст; // поле надпись на форме
КонецЕсли;
КонецЕсли;
Если Результат.Статус = "Выполнено" Или Результат.Статус = "Отменено" Тогда
Элементы.ГруппаИндикация.Видимость = Ложь;
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ВыполнитьПроцедуруФоново_Выполнено(Результат, ДополнительныеПараметры) Экспорт
Если Результат = Неопределено Тогда
Возврат;
ИначеЕсли Результат.Статус = "Ошибка" Тогда
Доступность = Истина;
ОбщегоНазначенияКлиент.СообщитьПользователю(Результат.ПодробноеПредставлениеОшибки);
ИначеЕсли Результат.Статус = "Выполнено" Тогда
Доступность = Истина;
Данные = ПолучитьИзВременногоХранилища(Результат.АдресРезультата);
Если Данные = Неопределено Тогда
Возврат;
КонецЕсли;
РежимВыбора = РежимДиалогаВыбораФайла.Сохранение;
Диалог = Новый ДиалогВыбораФайла(РежимВыбора);
Оповещение = Новый ОписаниеОповещения("СохранениеФайлаТовары_Завершение", ЭтотОбъект, Данные);
Диалог.Фильтр = "Файл EXCEL|*.xlsx";
Диалог.Заголовок = "Выберите файл для сохранения данных";
Диалог.Показать(Оповещение);
КонецЕсли;
КонецПроцедуры
ПоказатьПрогресс "сообщаю" в экспортной процедуре:
ДлительныеОперации.СообщитьПрогресс(ПроцентВыполнения, "Выгружено строк: "+Строка(Итератор-2)+" из "+Строка(Всего));
(9) Вы сделали совсем иначе, нежели я описал) Если обработка загружена в справочник дополнительных обработок, не нужно отображать прогресс выполнения и не нужна обработка результата выполнения, то запуск в фоне будет следующим:
Собственно, здесь используется типовые механизмы БСП для параметризации фонового задания и, собственно,его запуска.
&НаКлиенте
Процедура НачатьПодготовкуФайлаВФоне()
ИмяЗадания = "Выгрузка данных в шаблон Excel"; // имя фонового задания
ПараметрыЗапуска = ПодготовитьДанные(); // сюда передаем параметры для процедуры, выполняемой в фоне
ИмяПроцедуры = "ПодготовитьДанныеПоТоварамНаСервере"; // имя экспортной процедуры модуля обработки
ДлительнаяОперация = ЗапуститьДлительнуюОперацию(ИмяПроцедуры , ПараметрыЗапуска, ИмяЗадания);
КонецПроцедуры
&НаСервере
Функция ЗапуститьДлительнуюОперацию(ИмяМетода, ПараметрыОбработки, ИмяЗадания)
ВыполняемыйМетод = "ДлительныеОперации.ВыполнитьПроцедуруМодуляОбъектаОбработки";
ПараметрыЗадания = Новый Структура;
ПараметрыЗадания.Вставить("ИмяМетода", ИмяМетода);
ПараметрыЗадания.Вставить("ПараметрыВыполнения", ПараметрыОбработки);
ПараметрыЗадания.Вставить("ЭтоВнешняяОбработка", Истина);
ПараметрыЗадания.Вставить("ДополнительнаяОбработкаСсылка", ВнешняяОбработка); // ВнешняяОбработка - ссылка на элемент справочника дополнительных обработок
ПараметрыВыполнения = ДлительныеОперации.ПараметрыВыполненияВФоне(УникальныйИдентификатор);
ПараметрыВыполнения.НаименованиеФоновогоЗадания = ИмяЗадания;
РезультатФоновогоЗадания = ДлительныеОперации.ВыполнитьВФоне(ВыполняемыйМетод, ПараметрыЗадания, ПараметрыВыполнения);
Возврат РезультатФоновогоЗадания;
КонецФункции ПоказатьСобственно, здесь используется типовые механизмы БСП для параметризации фонового задания и, собственно,его запуска.
(11) Во, сейчас ответ более осмысленный) В этом весь и прикол, я не хочу никуда эту обработку загружать, мне нужно открыл запустил 1 раз задание и все. Оно выполнилось. Конец. Эта обработка за раз кучу объектов читает, записывает. Поэтому надо ее в фоне. Врятли когда-либо она еще мне пригодится. Если бы, она была нужна, я бы вообще все в общем модуле через фоновое задание сделал и все. Может объяснишь тогда соль. При открытии обработки, у меня выполняется процедура и в обработке описания оповещения, мне возвращается некоторая информация по файлу и его адрес во временном хранилище, далее я передаю адрес для подключения этой внешней обработки по адресу , мне возвращается имя файла, все ок. а потом запускаю выполнение основной процедуры через длительные операции. Но тут случается прикол, если я передаю в качестве выполняемого метода, такой путь: "ВнешняяОбработка."+ИмяОбработки+".МодульОбъекта.МояПроцедура" то он начинает выполнять в основном потоке и это работает. А если если передаю "ДлительныеОперации.ВыполнитьПроцедуруМодуляОбъектаОбработки" то, начинает выполнять уже в фоне, и выдает ошибку на том что файл не найден.
НачатьПомещениеФайлаНаСерверВнешниеОбработки.Подключить(Адрес)
(12)
Так там уже процедура ждет полный путь к файлу на сервере, а не адрес во временном хранилище. поэтому и приходится его в temp сохранять, а потом удалять
А если если передаю "ДлительныеОперации.ВыполнитьПроцедуруМодуляОбъектаОбработки" то, начинает выполнять уже в фоне, и выдает ошибку на том что файл не найден.
Так там уже процедура ждет полный путь к файлу на сервере, а не адрес во временном хранилище. поэтому и приходится его в temp сохранять, а потом удалять
(15) Так я и не адрес во временном хранилище передаю. Адрес во временном хранилище используется только в контексте модуля формы и за его пределы не выходит. С помощью адреса во временном хранилище я использую объект "ВнешниеОбработки" и его метод "Подключить" в параметр передаю адрес временного хранилища, он же мне возвращает имя обработки. Во временном хранилище лежат двоичные данные обработки.
(11) В обоих случаях когда код выполняется в основном потоке и в фоне. Там выполняется:
Видимо он в основном потоке имеет доступ то ли к двоичным данным, то к файлу в целом.
Но в фоновом процессе он уже не может получить доступ, для него всего этого нет.
ВнешниеОбработки.Создать(ИмяФайла)Видимо он в основном потоке имеет доступ то ли к двоичным данным, то к файлу в целом.
Но в фоновом процессе он уже не может получить доступ, для него всего этого нет.
(6) Понятно, спасибо.
действительно, я тоже, где-то использовал подобную конструкцию
правда через попытку,
действительно, я тоже, где-то использовал подобную конструкцию
правда через попытку,
Выполнить("Задание = ДлительныеОперации.ЗапуститьВыполнениеВФоне(
|ЭтаФорма.УникальныйИдентификатор,
|""ДлительныеОперации.ВыполнитьПроцедуруМодуляОбъектаОбработки"",
|ПараметрыМетода,
|прДанные.ИмяМетода);");
Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот