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

Публикация № 1112877

Разработка - Практика программирования

68
Как запустить фоновое задание из модуля внешней обработки используя БСП. Как отключить безопасный режим и сообщения защиты от опасных действий независимо от профиля безопасности пользователя в фоновом задании во внешней обработке.

1. Как запустить фоновое задание из модуля внешней обработки используя БСП

 

После тщетных попыток запустить в фоне процедуру модуля объекта внешней обработки, я все-таки решил глубже копнуть все механизмы длительных операций БСП. Все процедуры выполнения кода в фоне из подсистемы "Длительные операции" работают на сервере. То есть все происходит так: берется внешняя обработка, хранящаяся в справочнике "ДополнительныеОтчетыИОбработки", разворачивается на сервере (вот тут ключевой момент) и из этого экземпляра обработки выполняются указанные процедуры / функции модуля объекта (см. процедуру "ЗапуститьФоновоеЗаданиеСКонтекстомКлиента" модуля "ДлительныеОперации" БСП 3.х). Если вы вызываете ту же самую обработку из "файл-открыть", то БСП тупо пытается запустить указанные методы из обработки на сервере, в то время как обработка находится на клиенте.

 

Выходом было создать копию внешней обработки на сервере и запустить процедуру ее (копии) модуля объекта в фоне. Для этого, при открытии формы я помещал обработку во временное хранилище и тут же создавал копию на сервере в временном файле. Имя файла на сервере хранил в реквизите формы.

&НаКлиенте
Процедура ПриОткрытии(Отказ)

    Если ЭтоВнешняяОбработка() Тогда
        ОписаниеОповещения = Новый ОписаниеОповещения("ОбработатьРезультатПомещенияФайлаОбработки", ЭтотОбъект);
        НачатьПомещениеФайлов(ОписаниеОповещения, ИмяФайлаОбработки(), Ложь, УникальныйИдентификатор);
    КонецЕсли;

КонецПроцедуры

&НаКлиенте
Процедура ОбработатьРезультатПомещенияФайлаОбработки(ПомещенныеФайлы, ОбработчикЗавершения) Экспорт

	Если ПомещенныеФайлы <> Неопределено Тогда
		// Создаем копию текущией обработки на сервере
		ХранениеФайлаОбработки = КопияОбработкиНаСервере(ПомещенныеФайлы[0].Хранение);
	КонецЕсли;

КонецПроцедуры

&НаСервере
Функция КопияОбработкиНаСервере(Хранение)

	Результат = ПолучитьИмяВременногоФайла();
	ДвоичныеДанные = ПолучитьИзВременногоХранилища(Хранение);
	ДвоичныеДанные.Записать(Результат);
	
	Возврат Результат;

КонецФункции
	
&НаСервере
Функция ИмяФайлаОбработки()

	Возврат РеквизитФормыВЗначение("Объект").ИспользуемоеИмяФайла;
	
КонецФункции

&НаСервере
Функция ЭтоВнешняяОбработка()
	
	ЧастиИмени = СтрРазделить(РеквизитФормыВЗначение("Объект").Метаданные().ПолноеИмя(), ".");
	Возврат (ВРег(ЧастиИмени[0]) = "ВНЕШНЯЯОБРАБОТКА")
	
КонецФункции

Ну вот, собственно и все. Осталось только правильно вызвать процедуру из модуля объекта копии обработки на сервере.

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


&НаСервере
Функция НачатьВыполнениеФоновогоЗаданияНаСервере()
	
	ПараметрыВыполненияОбработки = Новый Структура;
	// Здесь указываете параметры, передаваемые в процедуру, выполняемую в фоне
	// ....
	// ...

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

 

2. Как отключить безопасный режим и сообщения защиты от опасных действий независимо от профиля безопасности пользователя в фоновом задании во внешней обработке

 

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

Я думаю, что многим приходилось сталкиваться с тем, что на сервере надо было подтвердить разрешение на запуск com-соединения. И все выключали защиту от опасных действий в профиле пользователя, чего делать не рекомендуется. Я пошел другим путем. Создаю две экспортные процедуры в модуле объекта внешней обработки: одна - непосредственно функция, которая будет выполнять необходимые действия и другая, которая вызовет первую с отключенным контролем прав доступа профиля.

Выглядит это так:

Функция ОбработкаДанных(...) Экспорт

	...	

КонецФункции

Процедура ОбработкаДанныхВФоне(Параметры, АдресРезультата) Экспорт

	ЧастиИмени = СтрРазделить(ЭтотОбъект.Метаданные().ПолноеИмя(), ".");
	ЭтоВнешняяОбработка = (ВРег(ЧастиИмени[0]) = "ВНЕШНЯЯОБРАБОТКА");
	Если ЭтоВнешняяОбработка Тогда 
		ОбработкаОбъект = ВнешниеОбработки.Создать(ЭтотОбъект.ИспользуемоеИмяФайла, Ложь, ОбщегоНазначения.ОписаниеЗащитыБезПредупреждений());
		Результат = ОбработкаОбъект.ОбработкаДанных(...);
	Иначе
		Результат = ОбработкаДанных(...);
	КонецЕсли;

	ПоместитьВоВременноеХранилище(Результат, АдресРезультата);
	
КонецПроцедуры

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

Пример использования, созданный из обработки демонстрационной конфигурации БСП прилагается (создавалась на платформе 8.3.13.1513, совместима с любой платформой 8.3, которая поддерживает БСП 3.0 и старше)

 

Предупреждение. Нельзя использовать реквизиты и табличные части внешней обработке в процедурах/функциях, выполняемых в фоне. Данные реквизиты должны быть переданы непосредственно в вызываемую процедуру/функцию из модуля формы.

 

68

Скачать файлы

Наименование Файл Версия Размер
ДемоДлительнаяОперация
.epf 10,96Kb
23.08.19
4
.epf 10,96Kb 4 Скачать

См. также

Специальные предложения

Комментарии
Избранное Подписка Сортировка: Древо
1. jONES1979 26.08.19 09:17 Сейчас в теме
2. BenGunn 169 26.08.19 11:53 Сейчас в теме
(1) Это так важно? Ну не грамотный!
jONES1979; +1 2 Ответить
3. jONES1979 26.08.19 15:21 Сейчас в теме
(2) "не грамотный" -> "неграмотный"
Но теперь-то грамотный! А грамотность - это первое впечатление! И отсутствие подсознательного раздражения от читаемого текста.
...
Я забыл что оказывается здесь нельзя почистить комменты. Ну тогда сорри, в другой раз в личку напишу)
HEKPOH; kuzyara; +2 Ответить
4. BenGunn 169 26.08.19 16:04 Сейчас в теме
(3) Мне гораздо больше нравится мысль, что подобное еще никто не делал (если даже и сделал, то не говорит об этом).
jONES1979; +1 Ответить
5. BenGunn 169 26.08.19 16:10 Сейчас в теме
(3)
«Неграмотный» или «не грамотный»: слитно или раздельно?
Если коротко, то пишется слитно, когда утверждается безграмотность, и пишется раздельно, когда отрицается грамотность.

Он неграмотный. (Утверждается безграмотность).

Он не грамотный. (Отрицается грамотность).

(Этот принцип действует и для наречия «неграмотно»).
7. BenGunn 169 27.08.19 00:39 Сейчас в теме
(3) Да ну, нафиг! Посмотрел твой профиль... Да ты, оказывается, флудер! Сказать только ради того, чтобы сказать?! Отличная позиция! А не хочешь сделать что-нибудь полезное? Ну, кроме того, что раздувать щеки с умным видом?!
Summer_13; mai_k; jONES1979; +3 Ответить
9. jONES1979 27.08.19 06:23 Сейчас в теме
(7) Зачем переходить на личности, вам скучно? За полезное на работе деньги платят, а не звёздочки в интернете. Форум - это по определению место для общения, что позволяет отвлечься. Кого первого-то на флудеразм пробило? Поправили бы свою опечатку и копали дальше,.. а не капали.

За статью спасибо, кстати. С моей помощью теперь она чуть ли не идеальна))
10. BenGunn 169 27.08.19 08:25 Сейчас в теме
(9)

Ну я говорю, флудер!

Кстати, где ты здесь видишь форум? Здесь специалисты делятся знаниями, а не ищут орфографические ошибки. Теми самыми знаниями, кстати, которые кто-нибудь использует в той самой работе, за которую деньги платят. А судя по тому, что пишешь в коментах, тебе еще очень далеко до такого уровня... Поищи развлекуху где-нибудь на Фейсбуке, там таких как ты любят
jONES1979; +1 Ответить
11. jONES1979 27.08.19 08:55 Сейчас в теме
(10)
- К чему эти ярлыки? Не опускайтесь до моего уровня!
- Форум написано вверху.
- Я не искал ошибок, они сами бросаются в глаза и сбивают восприятие.
- За знания я никогда не устану говорить спасибо! Спасибо!
Прикрепленные файлы:
6. PerlAmutor 45 26.08.19 21:23 Сейчас в теме
Спасибо. Довольно интересные трюки.
8. BenGunn 169 27.08.19 00:49 Сейчас в теме
12. Oldsad 27.08.19 10:41 Сейчас в теме
Оставьте свое сообщение