Универсальные сведения о внешней обработке

mikaelangelm 75 1 1 4

1 Универсальная функция для всех типов доп.обработок/отчетов Можно добавить в общий модуль и навсегда забыть об инициализации сведений вручную

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

//Пример использования в доп.отчете:
Функция СведенияОВнешнейОбработке() Экспорт
   СведенияОВнешнейОбработке(ВнешнийОтчетОбъект);
КонецФункции;
// см. ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке(СтандартныеПодсистемыСервер.ВерсияБиблиотеки()) 
//
// Параметры: 
// ОбработкаНаименование - ОбработкаОбъект.<ИмяОбработки>, Строка - Имя обработки, или Обработка.Метаданные().Синоним, если не определено  
// Команды 		- Неопределено, ТаблицаЗначений, Булево, Строка - 
//				  Если Неопределено, то команды не заполняются
//				  Если Истина, то создается ТЗ с 2 командами: 
//					1) Идентификатор="ВызовСерверногоМетода" и Использование="ВызовСерверногоМетода"
//					2) Идентификатор="ОткрытьОбработку"      и Использование="ОткрытиеФормы"   
//				  Если Строка, то создается единственная команда Использование="ВызовСерверногоМетода"  
// Вид 			- ПеречислениеСсылка.ВидыДополнительныхОтчетовИОбработок, Строка - Вид отчет/обработка
// Версия 		- Неопределено, Строка - 10 символов. Если неопределено, то берется текущая дата, в формате yyyy.MM.dd (напр. 2022.12.31)  
// Назначение	- Массив - Массив строк формата "<Тип>.<Вид>" (напр. "Справочник.Номенклатура" или "Документ.*" - для всех документов)
// Информация   - Строка - Обработка.Метаданные().Комментарий, если не определено 
// Разрешения 	- Булево, ОбъектXDTO, Массив - Если не булево, то устанавливает БезопасныйРежим=Истина и пытается добавить разрешения
//
// Возвращаемое значение:
//		ТаблицаЗначений
Функция СведенияОВнешнейОбработке(ОбработкаНаименование, Команды = Неопределено, Версия = Неопределено, Вид = "ДополнительнаяОбработка ", Назначение = Неопределено, Информация = Неопределено, Разрешения = Ложь) Экспорт        
	СведенияОВнешнейОбработке 	= ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке(СтандартныеПодсистемыСервер.ВерсияБиблиотеки());
	ПереданаОбработка 			= ТипЗнч(ОбработкаНаименование) <> Тип("Строка");
	ОбработкаМД					= ?(ПереданаОбработка, ОбработкаНаименование.Метаданные(), Неопределено); 
	Наименование				= ?(ПереданаОбработка, МетаданныеИмя(ОбработкаНаименование, "Синоним"), ОбработкаНаименование); 
	Имя							= ?(ПереданаОбработка, МетаданныеИмя(ОбработкаНаименование, "Имя"), 	ОбработкаНаименование);
	Если ТипЗнч(Вид) = Тип("Строка") Тогда
		Если ПереданаОбработка И СтрНачинаетсяС(Строка(ОбработкаНаименование.ЭтотОбъект), "ВнешнийОтчет") И Вид = "ДополнительнаяОбработка " Тогда
			Вид					= "ДополнительныйОтчет"; // Если передан Доп.отчет и не передан Вид
		КонецЕсли;
		Вид						= Метаданные.Перечисления.ВидыДополнительныхОтчетовИОбработок.ЗначенияПеречисления.Найти(СтрЗаменить(Вид, " ", ""));
		Если Вид = Неопределено Тогда
			ВызватьИсключение "СведенияОВнешнейОбработке: не удалось определить Вид обработки: "+Вид;
		Иначе
			Вид 				= Вид.Имя;  
		КонецЕсли;   
	ИначеЕсли ТипЗнч(Вид) 		= Тип("ПеречислениеСсылка.ВидыДополнительныхОтчетовИОбработок") Тогда 
		Вид = ДополнительныеОтчетыИОбработки.ВидВСтроку(Вид);
	ИначеЕсли ТипЗнч(Вид) 		= Тип("ОбъектМетаданных") Тогда
		Вид = Вид.Имя;
	КонецЕсли;	
	
	
	Если Версия = Неопределено Тогда 
		Версия = Формат(ТекущаяДата(), "ДФ=yyyy.MM.dd");
	КонецЕсли;
	// заполняет команду по умолчанию
	Если Команды = Истина Тогда // заполняются 2 команды (см. Описание этой ф-ии)
		ДобавитьКоманду(СведенияОВнешнейОбработке.Команды, "Вызов серверного метода", "ВызовСерверногоМетода", "ВызовСерверногоМетода"); 
	ИначеЕсли ТипЗнч(Команды) = Тип("Строка") Тогда Для Каждого Комадна Из СтрРазделить(Команды, ",", Ложь) Цикл // передан идентификатор единственной команды или команд через запятую с Использование="ВызовСерверногоМетода"
		ДобавитьКоманду(СведенияОВнешнейОбработке.Команды, "Команда " + СтрКэмелКейсВЗаголовок(СокрЛП(Комадна)), СокрЛП(Комадна), "ВызовСерверногоМетода"); // СтрКэмелКейсВЗаголовок(Комадна)
	КонецЦикла ИначеЕсли ТипЗнч(Команды) = Тип("ТаблицаЗначений") ИЛИ ТипЗнч(Команды) = Тип("Массив") Тогда Для Каждого СтрКоманда Из Команды Цикл	
		ДобавитьКоманду(СведенияОВнешнейОбработке.Команды, СтрКоманда);	
	КонецЦикла КонецЕсли;  
	// добавляет команду открытия основной формы, если не добавлена ранее, и форма задана
	Если ПереданаОбработка И Не ОбработкаМД.ОсновнаяФорма = Неопределено И СведенияОВнешнейОбработке.Команды.НайтиСтроки(Новый Структура("Использование,Идентификатор", "ОткрытиеФормы,ОткрытьОбработку")).Количество()=0 И СведенияОВнешнейОбработке.Команды.Найти(Перечисления.СпособыВызоваДополнительныхОбработок.ОткрытиеФормы, "Использование") = Неопределено Тогда
		ДобавитьКоманду(СведенияОВнешнейОбработке.Команды, ОбработкаМД.ОсновнаяФорма.Синоним, ОбработкаМД.ОсновнаяФорма.Имя, "ОткрытиеФормы"); СкрытьОткрытиеФормы = ОбработкаМД.ОсновнаяФорма.Имя;
	КонецЕсли;      
	// обрабатывает Вид доп.обработки/отчета
	Если нрег(вид) = нрег("ПечатнаяФорма") ИЛИ нрег(вид) = нрег("ЗаполнениеОбъекта") Тогда 
		Если Назначение = Неопределено Тогда
			Назначение = Новый Массив;
			Назначение.Добавить("Документ.*");
			Назначение.Добавить("Справочник.*");
		ИначеЕсли ТипЗнч(Назначение) = Тип("Строка") Тогда
			Назначение = СтрРазделить(Назначение, ",", Ложь);
		КонецЕсли;
		Если нрег(вид) = нрег("ПечатнаяФорма") Тогда Для Каждого СтрКоманда Из СведенияОВнешнейОбработке.Команды.НайтиСтроки(Новый Структура("Использование,Модификатор", "ВызовСерверногоМетода", "")) Цикл
			СтрКоманда.Модификатор 		= "ПечатьMXL";                                         
			СтрКоманда.ПоказыватьОповещение = Истина;
			СтрКоманда.Представление    = СтрЗаменить(СтрКоманда.Представление, "Команда ", "");
		КонецЦикла ИначеЕсли ВРЕГ(вид)=ВРЕГ("ЗаполнениеОбъекта") И СкрытьОткрытиеФормы<>Неопределено И Команды<>Неопределено Тогда 
			СведенияОВнешнейОбработке.Команды.Найти(СкрытьОткрытиеФормы, "Идентификатор").Скрыть = Истина; // скроем команду открытия формы, т.к. она лишняя (Команды уже переданы)
		КонецЕсли;        
		// если нет ф-ии модуля объекта ВыполнитьКоманду(), но команд(ы) передан(ы), значит Использование = "ВызовКлиентскогоМетода"
		Если ВРЕГ(вид)=ВРЕГ("ЗаполнениеОбъекта") И ТипЗнч(ОбработкаНаименование)<>Тип("Строка") И СведенияОВнешнейОбработке.Команды.Найти("ВызовСерверногоМетода", "Использование")<>Неопределено Тогда
			Попытка
				ОбработкаНаименование.ВыполнитьКоманду(Новый УникальныйИдентификатор); // ничего страшного случиться не должно, т.к. заполнение объекта подразумевает объект, а он не передан, т.е. нечего заполнять
			Исключение Для Каждого СтрКоманда ИЗ СведенияОВнешнейОбработке.Команды.НайтиСтроки(Новый Структура("Использование", "ВызовСерверногоМетода")) Цикл
				СтрКоманда.Использование = "ВызовКлиентскогоМетода";
			КонецЦикла КонецПопытки;
		КонецЕсли;
	ИначеЕсли нрег(вид) = нрег("ДополнительныйОтчет") Тогда
		Если СведенияОВнешнейОбработке.Команды.Найти("ОткрытиеФормы", "Использование") = Неопределено Тогда
			ДобавитьКоманду(СведенияОВнешнейОбработке.Команды, Наименование, Имя, "ОткрытиеФормы");
		КонецЕсли;
	КонецЕсли;
	Если Информация = Неопределено И ПереданаОбработка Тогда
		Информация = ОбработкаМД.Комментарий;
	КонецЕсли;
	
	СведенияОВнешнейОбработке.Наименование 	= Наименование;
	СведенияОВнешнейОбработке.Вид			= Вид;
	СведенияОВнешнейОбработке.Версия		= Версия;
	//Если Не Команды = Неопределено Тогда Для Каждого СтрТЗ Из Команды Цикл
	//	ЗаполнитьЗначенияСвойств(СведенияОВнешнейОбработке.Команды.Добавить(), СтрТЗ)
	//КонецЦикла КонецЕсли; 
	СведенияОВнешнейОбработке.Назначение	= Назначение;
	СведенияОВнешнейОбработке.Информация	= Информация;   
	БезопасныйРежим 						= ?(ТипЗнч(Разрешения) = Тип("Булево"), Разрешения, Истина);
	СведенияОВнешнейОбработке.БезопасныйРежим = БезопасныйРежим; 
	Если ТипЗнч(Разрешения) = Тип("Строка") Тогда
		РазрешенияМассив = СтрРазделить(Разрешения, Символы.ПС, Ложь);
	ИначеЕсли Не ТипЗнч(Разрешения) = Тип("Массив") Тогда
		РазрешенияМассив = Новый Массив;
		РазрешенияМассив.Добавить(Разрешения);
	Иначе
		РазрешенияМассив = Разрешения;
	КонецЕсли;
	Для Каждого Разрешение Из РазрешенияМассив Цикл //https://sstud.ru/выполнение-обработок-1с-в-безопасном-р/
		Если Не БезопасныйРежим Тогда
			Прервать;
		Иначе
			_Разрешения = СведенияОВнешнейОбработке.Разрешения;
		КонецЕсли;
		ТипЗнчРазрешения = ТипЗнч(Разрешение);
		Если ТипЗнчРазрешения = Тип("Булево") Тогда
			Прервать; 
		ИначеЕсли ТипЗнчРазрешения = Тип("ОбъектXDTO") Тогда  
			_Разрешения.Добавить(Разрешение);	
		ИначеЕсли ТипЗнчРазрешения = Тип("Строка") Тогда  
			Если СтрНайти(ВРЕГ(Разрешение), "HTTP") Тогда 
				СтрКомментарийС = СтрНайти(Разрешение, " ");
				Если СтрКомментарийС Тогда
					Комментарий = Прав(Разрешение, СтрДлина(Разрешение) - СтрКомментарийС);
					Разрешение = Лев(Разрешение, СтрКомментарийС - 1);  
				Иначе Комментарий = "" КонецЕсли; // не может быть Неопределено
				СтруктураURI = ОбщегоНазначенияКлиентСервер.СтруктураURI(Разрешение);
				_Разрешения.Добавить(РаботаВБезопасномРежиме.РазрешениеНаИспользованиеИнтернетРесурса(СтруктураURI.Схема, СтруктураURI.Хост, СтруктураURI.Порт, Комментарий));
			ИначеЕсли СтрНайти(ВРЕГ(Разрешение), "КАТАЛОГВРЕМЕННЫХФАЙЛОВ") Тогда
				_Разрешения.Добавить(РаботаВБезопасномРежиме.РазрешениеНаИспользованиеКаталогаВременныхФайлов(СтрНайти(ВРЕГ(Разрешение), "ЧТЕНИЕ") ИЛИ Не СтрНайти(ВРЕГ(Разрешение), "ЗАПИСЬ"), СтрНайти(ВРЕГ(Разрешение), "ЗАПИСЬ"), Разрешение));
			ИначеЕсли СтрНайти(Разрешение, ":/") ИЛИ СтрНайти(Разрешение, "\\") Тогда
				_Разрешение = ?(СтрЗаканчиваетсяНа(ВРЕГ(Разрешение), "ЧТЕНИЕ") ИЛИ СтрЗаканчиваетсяНа(ВРЕГ(Разрешение), "ЗАПИСЬ"), СокрЛП(Лев(Разрешение, СтрДлина(Разрешение)-6)), Разрешение); 
				_Разрешения.Добавить(РаботаВБезопасномРежиме.РазрешениеНаИспользованиеКаталогаФайловойСистемы(_Разрешение, СтрНайти(ВРЕГ(Разрешение), "ЧТЕНИЕ") ИЛИ Не СтрНайти(ВРЕГ(Разрешение), "ЗАПИСЬ"), СтрНайти(ВРЕГ(Разрешение), "ЗАПИСЬ"), Разрешение)); 
			ИначеЕсли СтрНачинаетсяС(ВРЕГ(Разрешение), "COM ") ИЛИ СтрНайти(Разрешение, "COM") Тогда // Учитывается только ProgID
				Разрешение = ?(Не СтрНачинаетсяС(ВРЕГ(Разрешение), "COM "), Разрешение, Сред(Разрешение, 5, СтрДлина(Разрешение)));
				_Разрешения.Добавить(РаботаВБезопасномРежиме.РазрешениеНаСозданиеCOMКласса(СтрРазделить(Разрешение, " ",Ложь)[0], , , ?(СтрРазделить(Разрешение, " ",Ложь).Количество()>1, СтрРазделить(Разрешение, " ",Ложь)[1], "")));
			ИначеЕсли СтрРазделить(Разрешение, ".").Количество() > 1 Тогда 
				РазрешенияМассив = СтрРазделить(Разрешение, "."); 
				Если СтроковыеФункцииКлиентСервер.ТолькоЛатиницаВСтроке(РазрешенияМассив[0]+РазрешенияМассив[1]) И РазрешенияМассив.Количество()>2 Тогда   
					_Разрешения.Добавить(РаботаВБезопасномРежиме.РазрешениеНаСозданиеCOMКласса(РазрешенияМассив[0]+"."+РазрешенияМассив[1], РазрешенияМассив[2]));
				Иначе
					_Разрешения.Добавить(РаботаВБезопасномРежиме.РазрешениеНаИспользованиеВнешнейКомпоненты(РазрешенияМассив[0]+"."+РазрешенияМассив[1], ?(РазрешенияМассив.Количество()>2, РазрешенияМассив[2], "")));
				КонецЕсли; 
			Иначе
				_Разрешения.Добавить(РаботаВБезопасномРежиме.РазрешениеНаИспользованиеПривилегированногоРежима(Разрешение));
			КонецЕсли;                                 
		КонецЕсли;
	КонецЦикла;
	
	Возврат СведенияОВнешнейОбработке
КонецФункции  	
0

См. также

Сведения О Внешней Обработке

Универсальные функции для регистрации внешних обработок. Для внешней обработки (*.epf)

Сведения о внешней обработке - Отчет

Сведения о внешней обработке - Печать

СведенияОВнешнейОбработке (БСП)

Универсальные функции для регистрации внешних отчетов. Для внешнего отчета (*.erf)

Регистрация сведений о внешнем отчете

Отладить внешнюю обработку

Шаблон модуля внешней обработки

Модератору