Запуск фонового задания с прогрессом во внешней обработке независимо от места вызова на Библиотеке стандартных подсистем

10.02.23

Разработка - БСП (Библиотека стандартных подсистем)

Открытый код. Реализован запуск как из справочника дополнительных обработок, так и с файла на диске без обязательного доступа с сервера. Используется актуальная процедура БСП ДлительныеОперации.ВыполнитьПроцедуру.

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

Наименование Файл Версия Размер
Запуск фонового задания с прогрессом во внешней обработке независимо от места вызова на Библиотеке стандартных подсистем:
.epf 9,17Kb
13
.epf 9,17Kb 13 Скачать

МЕТОДЫ

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

 

СРЕДА

Тестировалось на конфигурации Управление Торговлей 11.4.13.227, версия БСП 3.1.3.548, платформа 8.3.17.1549

 

ДЕМОНСТРАЦИЯ

Нажать на кнопку "Обзор"  и выбрать любой файл Excel с клиента, версия формата 2007.

 

КОД

Модуль объекта

Функция СведенияОВнешнейОбработке() Экспорт
	
	ИмяОбработки = Метаданные().Имя;
	Синоним = Метаданные().Синоним;
	Синоним = ?(ПустаяСтрока(Синоним), ИмяОбработки, Синоним);
	
	ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке();
	ПараметрыРегистрации.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиДополнительнаяОбработка();
	ПараметрыРегистрации.Наименование = Синоним;
	ПараметрыРегистрации.Версия = "1.0";
	ПараметрыРегистрации.Информация = Синоним;
	ПараметрыРегистрации.БезопасныйРежим = Ложь;
	
	ТаблицаКоманд = ПараметрыРегистрации.Команды;
		
	Команда = ТаблицаКоманд.Добавить();
	Команда.Идентификатор = "ОткрытьОбработку";
	Команда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыОткрытиеФормы();
	Команда.Представление = Синоним + " (открыть форму)";
	
	Возврат ПараметрыРегистрации;
	
КонецФункции

Процедура ЗагрузитьДанные(ПараметрыДлительнойОперации, АдресРезультата) Экспорт
	
	КоличествоСтрокВычисленияПрогресса = 1;
	ИмяВременногоФайла = ПолучитьИмяВременногоФайла("xlsx");
	
	ДлительныеОперации.СообщитьПрогресс(0, "Загрузка файла в систему...");
	
	ПараметрыДлительнойОперации.ДвоичныеДанные.Записать(ИмяВременногоФайла);
	ТабличныйДокумент.Прочитать(ИмяВременногоФайла, СпособЧтенияЗначенийТабличногоДокумента.Значение);
	ВысотаТаблицыБезЗаголовка = ТабличныйДокумент.ВысотаТаблицы - 1;
	
	ИсточникДанных = Новый ОписаниеИсточникаДанных(ТабличныйДокумент.Область(1, 1, ТабличныйДокумент.ВысотаТаблицы, ТабличныйДокумент.ШиринаТаблицы));
	ПостроительОтчетов = Новый ПостроительОтчета;
	ПостроительОтчетов.ИсточникДанных = ИсточникДанных;
	ПостроительОтчетов.Выполнить();
	
	ВыборкаДетальныеЗаписи = ПостроительОтчетов.Результат.Выбрать();
	ТекущаяСтрока = 0;
	СчетчикПрогресса = 0;
	
	Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
	
		КакаяТоПроцедураОбработкиСтроки(ВыборкаДетальныеЗаписи);
		ТекущаяСтрока = ТекущаяСтрока + 1;
		СчетчикПрогресса = СчетчикПрогресса + 1;
		
		Если СчетчикПрогресса = КоличествоСтрокВычисленияПрогресса Тогда
			
			Процент = Формат(ТекущаяСтрока / ВысотаТаблицыБезЗаголовка * 100, "ЧДЦ=2");
			ДлительныеОперации.СообщитьПрогресс(Процент, СтрШаблон("Обработка %1 строки из %2", ТекущаяСтрока, ВысотаТаблицыБезЗаголовка));
			СчетчикПрогресса = 0;
			
		КонецЕсли;
		
	КонецЦикла;
	
	ДанныеРезультата = Новый Структура("ВсегоСтрок", ТекущаяСтрока);
	ПоместитьВоВременноеХранилище(ДанныеРезультата, АдресРезультата);
	
КонецПроцедуры

Процедура КакаяТоПроцедураОбработкиСтроки(ВыборкаДетальныеЗаписи)
	
	Ждать(1);
	
КонецПроцедуры

Процедура Ждать(КоличествоСекунд)
	
	Попытка
		
		Соединение = Новый HTTPСоединение("127.0.0.0",,,,,КоличествоСекунд);
		Соединение.Получить(Новый HTTPЗапрос());
		
	Исключение
	Конецпопытки;
	
КонецПроцедуры

 

Обратите внимание на переменную КоличествоСтрокВычисленияПрогресса, которая определяет интервал между вычислением и отправкой прогресса на клиент. Здесь намеренно значение равно 1 в целях демонстрации.

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

Используется чтение табличным документом из файла, т.к. на данный момент Excel читается только так. Если же вы работаете с форматами MXL, ODS, то используйте чтение из потока в целях оптимизации. В процедуре КакаяТоПроцедураОбработкиСтроки в целях демонстрации выполняется ожидание длиной в 1 секунду.

 

 

Модуль формы

#Область ОбработчикиСобытийФормы

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

&НаКлиенте
Процедура ПриОткрытии(Отказ)
	
	Если ЗначениеЗаполнено(ПутьКВнешнейОбработке) Тогда
		
		АдресВнешнейОбработки = ПоместитьВоВременноеХранилище(Новый ДвоичныеДанные(ПутьКВнешнейОбработке), УникальныйИдентификатор);
		ЗаписатьКопиюОбработки(АдресВнешнейОбработки, ПутьКопииОбработки);
		
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ПриЗакрытии(ЗавершениеРаботы)
	УдалитьКопиюОбработкиНаСервере(ПутьКопииОбработки);
КонецПроцедуры

#КонецОбласти

#Область ОбработчикиКомандФормы

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

#КонецОбласти

#Область СлужебныеПроцедурыИФункции

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

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

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

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

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

&НаСервереБезКонтекста
Процедура ЗаписатьКопиюОбработки(АдресВнешнейОбработки, ПутьКопииОбработки)
	
	ДвоичныеДанныеОбработки = ПолучитьИзВременногоХранилища(АдресВнешнейОбработки);
	ПутьКопииОбработки = ПолучитьИмяВременногоФайла("epf");
	ДвоичныеДанныеОбработки.Записать(ПутьКопииОбработки);
	
КонецПроцедуры

&НаСервереБезКонтекста
Процедура УдалитьКопиюОбработкиНаСервере(ПутьКопииОбработки)

	Если Не ЗначениеЗаполнено(ПутьКопииОбработки) Тогда
		Возврат;
	КонецЕсли;
		
	ФайлОбработки = Новый Файл(ПутьКопииОбработки);
	
	Если ФайлОбработки.Существует() Тогда
		УдалитьФайлы(ПутьКопииОбработки);
	КонецЕсли;

КонецПроцедуры // УдалитьКопиюОбработкиНаСервере(ПутьКопииОбработки)()

#КонецОбласти

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

В функции ЗагрузитьСтатусыНаСервере структура ПараметрыДлительнойОперации определяет параметры для основной процедуры из модуля объекта, в примере в параметрах передается полученный с клиента файл Excel в виде двоичных данных. Ключ ДополнительныйРезультат вместо АдресРезультата используется из-за безусловного алгоритма разработчиков БСП в вызове ДлительныеОперации.ВыполнитьПроцедуру.

Реквизит Отладка необходим для запуска алгоритма не в фоне для быстрой отладки на клиент-серверных базах без необходимости добавлять параметр запуска РежимОтладки в конфигураторе. На рабочей задаче необходимо скрыть данный реквизит на форме.

Именно процедура ДлительныеОперации.ВыполнитьПроцедуруМодуляОбъектаОбработки позволяет запускать процедуры из модуля обработки. В зависимости от места запуска мы передаем либо ссылку, либо путь к временному файлу, куда скопирована обработка ранее. После завершения обработки в процедуре ОбзорПослеПомещенияФайлаЗавершение мы обращаемся именно к ключу АдресДополнительногоРезультата.

 

Форма и реквизиты

 

 

Известные проблемы

В процессе разработки можно получить следующую ошибку:


 

Она появляется из-за запуска платформой внешней обработки не из файла на диске, а из кеша дополнительных обработок. Кейс ошибки: обновляется справочник дополнительных обработок из файла на диске, запускается форма из формы справочника, а затем в этом же сеансе открывается обработка из файла на диске напрямую. Подобная ситуация работает и в обратном случае.

Если же не запускать из обоих мест в одном сеансе, то ошибки не будет.

См. также

Настройка истории изменений. Подключение новых объектов (которых нет в списке) к системе версионирования (БСП) без изменения конфигурации

БСП (Библиотека стандартных подсистем) Платформа 1С v8.3 Бесплатно (free)

Много материалов и видео в сети о том, как подключить объект, которого нет в списке настроек, к системе версионирования БСП. Суть сводится к изменению определяемого типа, на который все завязано. Но это предполагает изменение конфигурации. Недавно встала задача подключить объект, которого нет в определяемом типе без снятия замков. Пришлось изучить вопрос глубже. Здесь пояснения и краткая инструкция с картинками. Как подключиться, используя только расширение.

20.11.2023    652    user1374747    0    

22

Как включить привилегированный режим для дополнительных отчетов и обработок

БСП (Библиотека стандартных подсистем) Конфигурации 1cv8 Бесплатно (free)

Как отключить безопасный режим для дополнительных отчетов и обработок РазрешениеНаИспользованиеПривилегированногоРежима

14.10.2023    2143    SpecRam    15    

31

Справочник по методам БСП

Инструментарий разработчика БСП (Библиотека стандартных подсистем) Платформа 1С v8.3 Абонемент ($m)

Данная конфигурация представляет собой инструмент для изучения документации и набора методов для стандартных подсистем БСП (Библиотека стандартных подсистем) в среде 1С:Предприятие. Может помочь разработчикам для быстрого поиска кода и переноса его в другие конфигурации, а также изучения БСП. Это конфигурация не в является заменой сервиса ИТС , а только помогает разработчикам в изучении БСП.

2 стартмани

11.10.2023    4666    104    plm    13    

51

Ограничение видимости дополнительных отчетов по пользователям для БСП

Роли и права БСП (Библиотека стандартных подсистем) Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Розница 3.0 Абонемент ($m)

Часто нужно ограничить дополнительные отчеты по видимости для разных пользователей. В "варианте отчета" для дополнительного отчета (БСП) можно указать конкретных пользователей, которым доступен данный вариант. Но данная настройка не срабатывает, т.к. варианты дополнительных отчетов считаются "предопределенными".

1 стартмани

14.09.2023    704    3    itmind    1    

15
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. sandr13 29 09.09.23 14:19 Сейчас в теме
При испытании вылезает ошибка:
Ошибка при вызове метода контекста (Создать)
{ОбщийМодуль.ДлительныеОперации.Модуль(903)}:Обработка = ВнешниеОбработки.Создать(Параметры.ИмяОбработки, БезопасныйРежим);
{(1)}:ДлительныеОперации.ВыполнитьПроцедуруМодуляОбъектаОбработки(Параметры[0],Параметры[1])
{ОбщийМодуль.ОбщегоНазначения.Модуль(5113)}:Выполнить ИмяМетода + "(" + ПараметрыСтрока + ")";
{ОбщийМодуль.ДлительныеОперации.Модуль(1041)}:ОбщегоНазначения.ВыполнитьМетодКонфигурации(ИмяПроцедуры, ПараметрыВызова);
{ОбщийМодуль.ДлительныеОперации.Модуль(1031)}:ВызватьПроцедуру(ВсеПараметры.ИмяПроцедуры, ВсеПараметры.ПараметрыПроцедуры);

по причине:
Ошибка подключения внешних метаданных
по причине:
Каталог не обнаружен ''
при запуске указал очистку кэша не помогло. Версия УТ Управление торговлей, редакция 11 (11.4.13.275). Не думаю, что так сильно изменилась версия. В отладке при попытке выполнить строку ВнешниеОбработки.Создать(Параметры.ИмяОбработки, БезопасныйРежим), где Параметры.ИмяОбработки="", похоже что туда надо что-то вставить...
Оставьте свое сообщение