gifts2017

Функция заполнения документа word по шаблону. Аналог функции CRM_ЗаменитьШаблонВВордеНаТекст

Опубликовал Андрей Карпов (karpik666) в раздел Программирование - Универсальные функции

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

Основным функционалом, которым мы пользовались являлась печать договоров и коммерческих предложений из 1С в Word.

В crm это было реализована таким образом: создавался макет договора в формате doc – docx, и сохранялся на диске. Затем в коде получали этот договор, сохраняли на диске под другим именем и уже в этой копии заменялся текст на необходимый. Например, чтобы вставить в макет номер договора у нас нужно было вставить в этот макет текст вида {Номер}.  Обязанности по замене в crm выполняла функция CRM_ЗаменитьШаблонВВордеНаТекст, в которую передавался объект Word. Код этой функции зашит в ключ защиты, что и вызывало такие проблемы.

 

Предлагаю аналог функции «CRM_ЗаменитьШаблонВВордеНаТекст», выполняемый без ключа защиты

////////////////////////////////////////////////////////////////////////////////
//
// Функция ЗаменитьШаблонВВордеНаТекст
// 
// Описание:
//  Ищет, заданный текст в Word Документе. Если текст найден возвращает Истина. 
// 	Также, если передавать Параметр везде, то и выполняет замену найденного текста
// Параметры (название, тип, дифференцированное значение)
// 	Ворд - comobject Word, 
//  ТекстНайти - тип Строка, текст для поиска в документе
//  ТекстЗаменить - тип Строка, текст, на который будет заменятся ТекстНайти, 
// 	Везде - тип Булево (Если не передается, принимает значение Неопределено),
//  указывает где следует производить замену
// ОСНОВНЫЕ ПАРАМЕТРЫ ПЕРЕДАВАЕМЫЕ В ОБЪЕКТ FIND
//  УчитыватьРегистр - Тип Булево.
//  ИскатьЦелоеСлово - Тип Булево.
// 	ИспользоватьДопЗнаки - Тип Булево.
//  ИскатьКакЗвучит - Тип Булево.
// Возвращаемое значение: Истина ИЛИ Ложь	 	
Функция ЗаменитьШаблонВВордеНаТекст(Ворд, Знач ТекстНайти, ОбластьПоиска = Неопределено, Знач ТекстЗаменить = "", Везде = Неопределено, 
	УчитыватьРегистр = Ложь, ИскатьЦелоеСлово = Истина, ИспользоватьДопЗнаки = Ложь, ИскатьКакЗвучит = Ложь)
	
	//Колво раз, сколько нужно заменять текст в документе	
	Если Везде = Неопределено Тогда
		Колво = 0; //ни разу		
	ИначеЕсли Везде Тогда 
		Колво = 2;//Все 
	Иначе 
		Колво = 1;//1 раз
	КонецЕсли; 
	Если ОбластьПоиска = Неопределено Тогда
		ОбластьПоиска = Ворд.ActiveDocument.Content;		
	КонецЕсли; 
	//Если Текст больше 255 знаков, 
	//то вводим его методом печати, а не вставкой
	Если СтрДлина(ТекстЗаменить) > 255 И Колво > 0 Тогда
		ОбластьПоиска.Select();
		ОбластьПоиска	= Ворд.Selection;
		Find			= ОбластьПоиска.Find;
		Найден			= Ложь;
		Попытка
			Пока Find.Execute(ТекстНайти, УчитыватьРегистр, ИскатьЦелоеСлово, ИспользоватьДопЗнаки, ИскатьКакЗвучит) Цикл
				//Печатаем текст замены, если найден
				Ворд.Selection.TypeText(ТекстЗаменить);
				Найден = Истина;
				Если Колво = 1 Тогда
					Прервать 	
				КонецЕсли; 			
			КонецЦикла;
			Возврат Найден;
		Исключение
			Возврат Ложь;	
		КонецПопытки;
	Иначе
		Если Колво = 1 Тогда
			ОбластьПоиска.Select();
			ОбластьПоиска = Ворд.Selection;
		КонецЕсли; 
		
		Find = ОбластьПоиска.Find;
		//Убираем форматирование, чтобы оно не влияло на поиск
		Find.ClearFormatting();
		
		//Параметры объекта Find
		//1 - ТекстПоиска, тип Строка - по умолчанию "", можно использовать для поиска специальные символы:
		// "^p" - для поиска параграфов, "^t" - сиволы табуляции
		//2- УчитыватьРегистр, тип Булево - по умолчанию Ложь
		//3 - ИскатьЦелоеСлово, тип Булево - по умолчанию Истина
		//4 - ИспользоватьДопЗнаки - использует подстановочные знаки - по умолчанию Ложь
		//5 - ИскатьКакЗвучит - Ищет слова похожие по звучанию - по умолчанию Ложь
		//6 - НаправлениеВперед - Указывет направаление поиска вперед - по умолчанию Ложь
		//9 - ИскатьФорматирование - Указывает необходимо ли искать по форматированию - по умолчанию Ложь
		//10 - ТекстЗаменить - Текст для замены
		//11 - Колво - указыавет, сколько раз произоводить замену: 2 - во всем документе, 1 - только первый найденный, 0 - нигде
		Попытка
			Возврат Find.Execute(ТекстНайти,УчитыватьРегистр,ИскатьЦелоеСлово,ИспользоватьДопЗнаки, ИскатьКакЗвучит,,,,,ТекстЗаменить,Колво)
		Исключение
			Возврат Ложь;
		КонецПопытки;
	КонецЕсли;
КонецФункции

P.S. Пишите свои замечания по улучшению кода


Мои работы:

Общее

Перенос данных XML с Анализом и выборочной загрузкой.

Универсальный редактор таблиц и движения документа (LITE) (Обычная Форма)

Универсальный редактор таблиц и движения документа (PRO) (Обычная Форма)

Универсальный редактор Таблиц и Движений документов (Управляемая форма)

Запуск 1С под другим пользователем без пароля.

 

Управление торговлей 11

Установка цен в УТ11. Произвольный запрос к данным ИБ

 

ЗУП 2.5

Скрываем неиспользуемые виды расчета

Резервы отпусков в Документе "Отражение Зарплаты в Регламентированном Учете" (Оценочные Обязательства)

 

Комплексная И УПП

Форма работы с сотрудниками, как из зуп 2.5

 

См. также

Подписаться Добавить вознаграждение

Комментарии

1. script Мальчинко (script) 05.06.15 01:03
Функция CRM_ЗаменитьШаблонВВордеНаТекст(глКомпонента, Ворд, Знач ШаблонВВорде, Знач ТекстЗамены, Везде = Истина) Экспорт
Попытка
	Если Везде Тогда
		Везде = 1;
	КонецЕсли;

            НетОшибок = Истина;
            
            Selection = Ворд.ActiveDocument.Content;
            //Selection.Find.ClearFormatting();
            //Selection.Find.Replacement.ClearFormatting();
            //
            //Selection.Find.Forward = True;
            //Selection.Find.Wrap = wdFindContinue;
            //
            //Selection.Find.Format = False;
            //Selection.Find.MatchCase = False;
            //Selection.Find.MatchWholeWord = False;
            //Selection.Find.MatchWildcards = False;
            //Selection.Find.MatchSoundsLike = False;
            //Selection.Find.MatchAllWordForms = False;
            //
            //Selection.Find.Text = "";
            //Selection.Find.Replacement.Text = "";
            
            wdReplaceNone = 00000000; // не заменять
            wdReplaceOne  = 00000001; // заменять одно вхождение/по порядку
            wdReplaceAll  = 00000002; // заменить все вхождения
            
            // Начало табличной части
            Если (ШаблонВВорде = "{НачалоТаблицыОбязательныйПрефикс}") Тогда
                
                ПоискИЗамена = Selection.Find;
                ПоискИЗамена.Forward = -1;
                ПоискИЗамена.Text = ШаблонВВорде;
                ПоискИЗамена.Replacement.Text = "";
                ПоискИЗамена.Execute(, , , , , , , , , ,wdReplaceOne);
                
                Если ПоискИЗамена.Found Тогда
                    
                    Таблица = ПоискИЗамена.Parent;
                    Таблица.Select();
                    
                Иначе
                    
                    НетОшибок = Ложь;
                    
                    Если Константы.script_ВключитьРежимОтладки.Получить() Тогда
                        Сообщить(ОписаниеОшибки());
                    КонецЕсли;
                    
                КонецЕсли;
                
            Иначе
                
                Если Везде = 1 Тогда
                    
                    ПоискИЗамена = Selection.Find;
                    ПоискИЗамена.Forward = Истина;
                    ПоискИЗамена.ClearFormatting();
                    ПоискИЗамена.Replacement.ClearFormatting();	
                    
                    ПоискИЗамена.Text             = ШаблонВВорде;
                    ПоискИЗамена.Replacement.Text = ТекстЗамены;
                    ПоискИЗамена.Execute(, , , , , , , , , ,wdReplaceAll);
                    
                Иначе
                    
                    ПоискИЗамена                  = Selection.Find;
                    ПоискИЗамена.ClearFormatting();
                    ПоискИЗамена.Forward          = -1;
                    ПоискИЗамена.Wrap             = 1;
                    ПоискИЗамена.Text             = ШаблонВВорде;
                    ПоискИЗамена.Replacement.Text = ТекстЗамены;
                    ПоискИЗамена.Execute(, , , , , ,1 ,1 , , ,wdReplaceOne);
                    Если ПоискИЗамена.Found Тогда
                        
                        Таблица = ПоискИЗамена.Parent;
                        Таблица.Select();
                        
                    Иначе	
                        
                        НетОшибок = Ложь;
                        
                        Если Константы.script_ВключитьРежимОтладки.Получить() Тогда
                            Сообщить(ОписаниеОшибки());
                        КонецЕсли;
                        
                    КонецЕсли;
                КонецЕсли;
            КонецЕсли;
            
        КонецЕсли;
        // - {SCRIPT} 
		
    Исключение КонецПопытки;
	
Возврат Истина;
	
КонецФункции
...Показать Скрыть
2. script Мальчинко (script) 05.06.15 01:06
Функция CRM_ЗаменитьШаблонВOpenOfficeНаТекст(глКомпонента, Параметры, ТегиКолонок) Экспорт
		Попытка
			Если ТегиКолонок Тогда
				
				Для Каждого Тег Из Параметры.ТаблицаТегов Цикл //заполнение строк номенклатуры и итогов по разделам
					Результат = CRM_ПолучитьРезультатВыполненияДействия(Тег.Действие, Параметры.СтрокаМассива, Параметры.Параметры);
					
					СтруктураПараметров = Новый Структура;
					СтруктураПараметров.Вставить("ОбъектOpenOffice"	, Параметры.Параметры.ОбъектВорд);
					СтруктураПараметров.Вставить("СтрокаПоиска"		, Тег.Представление);
					СтруктураПараметров.Вставить("СтрокаЗамены"		, CRM_ОбработатьСтрокуЗамены(Результат));
					
					CRM_ЗаменитьШаблонВOpenOfficeНаТекст(глКомпонента, СтруктураПараметров, Ложь);
					
				КонецЦикла;	
				
			Иначе
				
				OpenOffice = Параметры.ОбъектOpenOffice;
				Replace               = OpenOffice.CreateReplaceDescriptor();
				Replace.SearchString  = Параметры.СтрокаПоиска;
				Replace.ReplaceString = CRM_ОбработатьСтрокуЗамены(Параметры.СтрокаЗамены);
				
				OpenOffice.ReplaceAll(Replace);
				
			КонецЕсли;
			
			Возврат Истина;
			
		Исключение
			
			Сообщить(ОписаниеОшибки());
			Возврат Ложь;
			
		КонецПопытки		
	
КонецФункции

...Показать Скрыть
3. Андрей (h00k) 05.06.15 03:41
(0) ОМГ, а остальные защищенные процедуры и функции не нужны?!
Всегда думал что в црм основные функции это работа с бизнес процессами и т.п., а оказывается вот оно как, замена шаблона в ворде важнее...

П.С.: Полное отключение защиты - 5 минут, производится изменением пары строк в конфигурации и его гораздо проще поддерживать чем "дописанные" процедуры. Но гораздо правильнее сначала научиться настраивать ключи защиты, так-как защита у рарус не самая "глючная" и если возникли такие сложности, то это говорит, скорее всего, о "кривой" настройке сервера...
4. Андрей Карпов (karpik666) 05.06.15 03:41
(1) script, это откуда такое счастье? Это ваш код или это закрытый модуль? :-)
5. Андрей Карпов (karpik666) 05.06.15 03:47
(3) h00k, конфигурации уже 8 лет, не обновлялась и столько же ключам, может действительно виноват сервак, но им занимался другой человек, еще был конфликт из за Ос, когда на сервер поставили Windows 2012. Про строчки знаю, которые нужно закомментировать, и бизнес процессы работают и без ключа, а вот доп функции нет, так как код зашит в ключ защиты :-(
6. Андрей Карпов (karpik666) 05.06.15 03:50
(3) h00k, большинство функций не нужны были, хотя нужно было еще штрихкод вставлять, но эту проблему решили наподобии этого кода.
7. Андрей Карпов (karpik666) 05.06.15 04:24
(3) h00k, поводом отказаться от защиты crm это еще то, что с ней конфигурация запускается капец как долго, пока пройдут все проверки=)
8. Андрей (h00k) 05.06.15 05:41
(5) karpik666,
Про строчки знаю, которые нужно закомментировать,

Просто закомментировать - это не решение, это потеря основного функционала.

поводом отказаться от защиты crm это еще то, что с ней конфигурация запускается капец как долго, пока пройдут все проверки=)

На правильно настроенной системе проверка файлов защиты в 1.4 занимает пару секунд, а в 2.0 и того быстрее.
А по поводу отключения защиты, я могу вспомнить лишь один случай, когда это имело смысл - необходимо было заставить црм 1.4 работать на линукс.
9. script Мальчинко (script) 05.06.15 09:25
Отключать защиту приходится при серьезной доработке црм.
Я собираюсь, начать публиковать цикл статей о том, чего так не хватает в црм 1.4, и как это реализовать. И в некоторых случаях, без обхода защищенных функций, просто не обойтись.
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа