Код 1C v 8.х Перем СсылкаНаДокумент;
Процедура СформироватбФайл_MS_Word_И_OpenOffice(Кнопка)
ДокументСсылка = СсылкаНаДокумент;
ИмяФайла = ПолучитьИмяВременногоФайла();
// Теперь формируем файл из MS Wordа
Попытка
MSWord = новый COMОбъект("Word.Application");
//Передаем текущие параметры форм в MSWord
MSWord.Documents.Open(ИмяФайла);
MSWordDoc = MSWord.ActiveDocument();
WordContent = MSWord.ActiveDocument().ActiveWindow .S_election;
//------------------------------------------------------------
// Перебираем таблицы в документе, и сопоставляем имена переменных
// с именами табличных частей.
Для ТекущаяТаблица = 1 ПО MSWordDoc.Tables.Count Цикл
мТабличнаяЧасть = Неопределено;
Для ТекущаяСтрока = 1 ПО MSWordDoc.Tables(ТекущаяТаблица).Rows.Count Цикл
Для ТекущаяКолонка = 1 ПО MSWordDoc.Tables(ТекущаяТаблица).Columns.Count Цикл
мТабличнаяЧасть = ИмяТабличнойЧастиВСтроке(
ПолучитьСтартПеременной( MSWordDoc.Tables(ТекущаяТаблица).Cell(ТекущаяСтрока,ТекущаяКолонка).Range.Text )
,ДокументСсылка);
Если мТабличнаяЧасть <> Неопределено Тогда
Прервать;;
КонецЕсли;
КонецЦикла;
Если мТабличнаяЧасть <> Неопределено Тогда
Прервать;;
КонецЕсли;
КонецЦикла;
//Итак мы имеем номер текущей таблицы и имя табличной части
Если мТабличнаяЧасть <> Неопределено Тогда
//Производим редактирование нашей таблицы в соответствии с количеством строк
ВсегоСтрокТЧ = 0;
Для Каждого строкаТЧ Из ДокументСсылка[мТабличнаяЧасть.Имя] Цикл
ВсегоСтрокТЧ = ВсегоСтрокТЧ+1;
КонецЦикла;
//ВсегоСтрокТЧ = ДокументСсылка[мТабличнаяЧасть.Имя].Количество;
// Добавляем строки
Для ТекущаяСтрокаТЧ = 1 По ВсегоСтрокТЧ Цикл
Если ТекущаяСтрокаТЧ <> ВсегоСтрокТЧ Тогда
MSWordDoc.Tables(ТекущаяТаблица).Rows.Add(MSWordDoc.Tables(ТекущаяТаблица).Rows(ТекущаяСтрока+ТекущаяСтрокаТЧ-1));
КонецЕсли;
//MSWordDoc.Tables(ТекущаяТаблица).Cell(ТекущаяСтрока+ТекущаяСтрокаТЧ-1,2).Range.Text = Строка(ТекущаяСтрокаТЧ);
Для ТекКол = 1 ПО MSWordDoc.Tables(ТекущаяТаблица).Columns.Count Цикл
Если ТекущаяСтрокаТЧ <> ВсегоСтрокТЧ Тогда
ТекстПеременной = ПолучитьПеременнуюИзСтроки(СокрЛП(MSWordDoc.Tables(ТекущаяТаблица).Cell(ТекущаяСтрока+ТекущаяСтрокаТЧ,ТекКол).Range.Text));
ТекстПеременной = ?(ПустаяСтрока(ТекстПеременной),"", "["+"_"+Строка(ТекущаяСтрокаТЧ)+"_"+ТекстПеременной+"]");
MSWordDoc.Tables(ТекущаяТаблица).Cell(ТекущаяСтрока+ТекущаяСтрокаТЧ-1,ТекКол).Range.Text = ТекстПеременной;
Иначе
ТекстПеременной = ПолучитьПеременнуюИзСтроки(СокрЛП(MSWordDoc.Tables(ТекущаяТаблица).Cell(ТекущаяСтрока+ТекущаяСтрокаТЧ-1,ТекКол).Range.Text));
ТекстПеременной = ?(ПустаяСтрока(ТекстПеременной),"", "["+"_"+Строка(ТекущаяСтрокаТЧ)+"_"+ТекстПеременной+"]");
MSWordDoc.Tables(ТекущаяТаблица).Cell(ТекущаяСтрока+ТекущаяСтрокаТЧ-1,ТекКол).Range.Text = ТекстПеременной;
КонецЕсли;
КонецЦикла;
КонецЦикла;
//MSWordDoc.Tables(ТекущаяТаблица).Rows.Delete();
//MSWordDoc.Tables(ТекущаяТаблица).Rows(3).Delete();
КонецЕсли;
КонецЦикла;
//------------------------------------------------------------
// Вытаскивам из шаблона текст
ТекстДокумента = MSWordDoc.Range(0, MSWordDoc.Characters.Count).Text;
// Из текста вытаскиваем Имена переменных залюченных а скобки []
Список = ПолучитьСписокПеременных(ТекстДокумента);
//Список.ВыбратьЭлемент();
// Заполняем в структуру ревизитовперечень переменных
СтруктураРеквизитов=СтруктураРеквизитовДокумента(ДокументСсылка);
ЗначениеРеквизита="";
Для Каждого ЭлементСписка Из Список Цикл
// Если находится соответствие переменной из документа и шаблона то производим замену
Если СтруктураРеквизитов.Свойство(ЭлементСписка.Значение, ЗначениеРеквизита ) Тогда
//Сообщить("["+ЭлементСписка.Значение+"]"+" : "+ЗначениеРеквизита);
WordContent.Find.Execute("["+ЭлементСписка.Значение+"]",0,0,0,0,0,-1,,,Строка(ЗначениеРеквизита),2);
Иначе
Сообщить("-> " + ЭлементСписка.Значение+" - Не найден в структуре документа");
// Заменим переменную на пустую строку
WordContent.Find.Execute("["+ЭлементСписка.Значение+"]",0,0,0,0,0,-1,,," ",2);
КонецЕсли;
КонецЦикла;
//автоматически обновляем поля документа
MSWord.S_election.WholeStory();
MSWord.S_election.Fields.Update();
MSWord.S_election.HomeKey();
//MSWordDoc.SaveAs(ИмяФайла);
//отображаем MSWord
MSWord.Visible=1;
MSWord.Activate();
Исключение
Предупреждение(ОписаниеОшибки());
MSWord.Quit();
КонецПопытки;
// Теперь формируем файл из OpenOffice
Попытка
ServiceManager = Новый COMОбъект("com.sun.star.ServiceManager");
Reflection = ServiceManager.createInstance("com.sun.star.reflection.CoreReflection");
Desktop = ServiceManager.createInstance("com.sun.star.frame.Desktop");
Args = Новый COMSafeArray("VT_DISPATCH", 1);
OOДокумент = Desktop.loadComponentFromURL(ПреобразоватьВURL(ИмяФайла), "_blank", 0, Args);
//------------------------------------------------------------
// Перебираем таблицы в документе, и сопоставляем имена переменных
// с именами табличных частей.
Для ТекущаяТаблица = 0 ПО OOДокумент.getTextTables().Count-1 Цикл
мТабличнаяЧасть = Неопределено;
Для ТекущаяСтрока = 0 ПО OOДокумент.getTextTables().getByIndex(ТекущаяТаблица).Rows.Count-1 Цикл
Для ТекущаяКолонка = 0 ПО OOДокумент.getTextTables().getByIndex(ТекущаяТаблица).Columns.Count-1 Цикл
мТабличнаяЧасть = ИмяТабличнойЧастиВСтроке(
ПолучитьСтартПеременной( OOДокумент.getTextTables().getByIndex(ТекущаяТаблица).getCellByPosition(ТекущаяКолонка, ТекущаяСтрока).string )
,ДокументСсылка);
Если мТабличнаяЧасть <> Неопределено Тогда
Прервать;;
КонецЕсли;
КонецЦикла;
Если мТабличнаяЧасть <> Неопределено Тогда
Прервать;;
КонецЕсли;
КонецЦикла;
//Итак мы имеем номер текущей таблицы и имя табличной части
Если мТабличнаяЧасть <> Неопределено Тогда
//Производим редактирование нашей таблицы в соответствии с количеством строк
ВсегоСтрокТЧ = 0;
Для Каждого строкаТЧ Из ДокументСсылка[мТабличнаяЧасть.Имя] Цикл
ВсегоСтрокТЧ = ВсегоСтрокТЧ+1;
КонецЦикла;
//ВсегоСтрокТЧ = ДокументСсылка[мТабличнаяЧасть.Имя].Количество;
// Добавляем строки
Для ТекущаяСтрокаТЧ = 1 По ВсегоСтрокТЧ Цикл
Если ТекущаяСтрокаТЧ <> ВсегоСтрокТЧ Тогда
// Добавляем строку перед нашей
OOДокумент.getTextTables().getByIndex(ТекущаяТаблица).Rows.I_nsertByIndex(ТекущаяСтрока+ТекущаяСтрокаТЧ-1, 1);
КонецЕсли;
Для ТекКол = 0 ПО OOДокумент.getTextTables().getByIndex(ТекущаяТаблица).Columns.Count-1 Цикл
Если ТекущаяСтрокаТЧ <> ВсегоСтрокТЧ Тогда
ТекстПеременной = ПолучитьПеременнуюИзСтроки(СокрЛП(OOДокумент.getTextTables().getByIndex(ТекущаяТаблица).getCellByPosition(ТекКол, ТекущаяСтрока+ТекущаяСтрокаТЧ).string));
ТекстПеременной = ?(ПустаяСтрока(ТекстПеременной),"", "["+"_"+Строка(ТекущаяСтрокаТЧ)+"_"+ТекстПеременной+"]");
OOДокумент.getTextTables().getByIndex(ТекущаяТаблица).getCellByPosition(ТекКол, ТекущаяСтрока+ТекущаяСтрокаТЧ-1).string = ТекстПеременной;
Иначе
ТекстПеременной = ПолучитьПеременнуюИзСтроки(СокрЛП(OOДокумент.getTextTables().getByIndex(ТекущаяТаблица).getCellByPosition(ТекКол, ТекущаяСтрока+ТекущаяСтрокаТЧ-1).string));
ТекстПеременной = ?(ПустаяСтрока(ТекстПеременной),"", "["+"_"+Строка(ТекущаяСтрокаТЧ)+"_"+ТекстПеременной+"]");
OOДокумент.getTextTables().getByIndex(ТекущаяТаблица).getCellByPosition(ТекКол, ТекущаяСтрока+ТекущаяСтрокаТЧ-1).string = ТекстПеременной;
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецЕсли;
КонецЦикла;
//------------------------------------------------------------
// Вытаскивам из шаблона текст
//ТекстДокумента = MSWordDoc.Range(0, MSWordDoc.Characters.Count).Text;
ТекстДокумента = ООПолучитьТекст(OOДокумент);
// Из текста вытаскиваем Имена переменных залюченных а скобки []
Список = ПолучитьСписокПеременных(ТекстДокумента);
//Список.ВыбратьЭлемент();
// Заполняем в структуру ревизитовперечень переменных
СтруктураРеквизитов=СтруктураРеквизитовДокумента(ДокументСсылка);
ЗначениеРеквизита="";
OOЗамена = OOДокумент.CreateReplaceDescriptor();
Для Каждого ЭлементСписка Из Список Цикл
// Если находится соответствие переменной из документа и шаблона то производим замену
Если СтруктураРеквизитов.Свойство(ЭлементСписка.Значение, ЗначениеРеквизита ) Тогда
OOЗамена.SearchString = "["+ЭлементСписка.Значение+"]";
OOЗамена.ReplaceString = Строка(ЗначениеРеквизита);
OOДокумент.ReplaceAll(OOЗамена);
Иначе
Сообщить("-> " + ЭлементСписка.Значение+" - Не найден в структуре документа");
// Заменим переменную на пустую строку
OOЗамена.SearchString = "["+ЭлементСписка.Значение+"]";
OOЗамена.ReplaceString = " ";
OOДокумент.ReplaceAll(OOЗамена);
КонецЕсли;
КонецЦикла;
OOДокумент.getCurrentController().getFrame().getContainerWindow().setFocus();
Исключение
Предупреждение(ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Код 1C v 8.х
Процедура ДобавитьФорматы(ПереченьРеквизитов,Значение,пПредставлениеРеквизита, ДокументСсылка = Неопределено)
Если ТипЗнч( Значение) = Тип( "Дата" ) Тогда
ПереченьРеквизитов. Вставить( пПредставлениеРеквизита+ "_" + "ДФddMMyyyy" , Формат( Значение, "ДФ=dd.MM.yyyy" ) ) ;
ПереченьРеквизитов. Вставить( пПредставлениеРеквизита+ "_" + "ДЛФDD" , Формат( Значение, "ДЛФ=DD" ) ) ;
ИначеЕсли ТипЗнч( Значение) = Тип( "Число" ) Тогда
ПереченьРеквизитов. Вставить( пПредставлениеРеквизита+ "_" + "ЧДЦ2ЧГ0" , Формат( Значение, "ЧДЦ=2; ЧГ=0" ) ) ;
ПереченьРеквизитов. Вставить( пПредставлениеРеквизита+ "_" + "ЧДЦ2" , Формат( Значение, "ЧДЦ=2" ) ) ;
ПереченьРеквизитов. Вставить( пПредставлениеРеквизита+ "_" + "ЧПропись" , Значение) ;
ИначеЕсли ( ТипЗнч( Значение) = Тип( "СправочникСсылка.КонтактныеЛица" ) ) или ( ТипЗнч( Значение) = Тип( "СправочникСсылка.ФизическиеЛица" ) ) Тогда
ПереченьРеквизитов. Вставить( пПредставлениеРеквизита+ "_" + "ФИО" , Строка( Значение) ) ;
КонецЕсли
КонецПроцедуры
Процедура ЗаполнитьРеквизиты(мГлубинаРекурсии,ПереченьРеквизитов,РеквизитСсылка,Реквизит,пПредставлениеРеквизита)
мГлубинаРекурсии = мГлубинаРекурсии+ 1 ;
ПереченьРеквизитов. Вставить( пПредставлениеРеквизита+ "_" + "Код" , РеквизитСсылка["Код" ]) ;
ПереченьРеквизитов. Вставить( пПредставлениеРеквизита+ "_" + "Наименование" , РеквизитСсылка["Наименование" ]) ;
Для Каждого ЭлементРеквизита Из Реквизит. Реквизиты Цикл
ПереченьРеквизитов. Вставить( пПредставлениеРеквизита+ "_" + ЭлементРеквизита. Имя, РеквизитСсылка[ЭлементРеквизита. Имя]) ;
Если ( Найти( ЭлементРеквизита. Тип, "Справочник ссылка" ) > 0 ) И ( мГлубинаРекурсии < = 3 ) И ( Найти( ЭлементРеквизита. Тип, "," ) = 0 ) Тогда
ЗаполнитьРеквизиты( мГлубинаРекурсии, ПереченьРеквизитов, РеквизитСсылка[ЭлементРеквизита. Имя], РеквизитСсылка[ЭлементРеквизита. Имя]. Метаданные( ) , пПредставлениеРеквизита+ "_" + ЭлементРеквизита. Имя) ;
Иначе
ДобавитьФорматы( ПереченьРеквизитов, РеквизитСсылка[ЭлементРеквизита. Имя], пПредставлениеРеквизита+ "_" + ЭлементРеквизита. Имя) ;
КонецЕсли
КонецЦикла ;
КонецПроцедуры
Функция ПолучитьСписокПеременных(ТекстШаблона)
СписокПеременных = Новый СписокЗначений( ) ;
ЕщеЕсть = Истина ;
Пока ЕщеЕсть Цикл
ПервыйСимвол = Найти( ТекстШаблона, "[" ) ;
Если ПервыйСимвол > 0 Тогда
ВторойСимвол = Найти( ТекстШаблона, "]" ) ;
Если ( ВторойСимвол > 0 И ВторойСимвол > ПервыйСимвол) Тогда
СписокПеременных. Добавить( Сред( ТекстШаблона, ПервыйСимвол + 1 , ВторойСимвол - ПервыйСимвол - 1 ) ) ;
ТекстШаблона = Сред( ТекстШаблона, ВторойСимвол + 1 ) ;
Иначе
ЕщеЕсть = Ложь ;
КонецЕсли ;
Иначе
ЕщеЕсть = Ложь ;
КонецЕсли ;
КонецЦикла ;
Возврат СписокПеременных;
КонецФункции
Функция СтруктураРеквизитовДокумента(ДокументСсылка) Экспорт
ПереченьРеквизитов = Новый Структура;
ПереченьРеквизитов. Вставить( "Дата" , ДокументСсылка["Дата" ]) ;
ДобавитьФорматы( ПереченьРеквизитов, ДокументСсылка["Дата" ], "Дата" ) ;
ПереченьРеквизитов. Вставить( "Номер" , ДокументСсылка["Номер" ]) ;
Реквизиты = ДокументСсылка. Метаданные( ) . Реквизиты;
Для Каждого Реквизит Из Реквизиты Цикл
мГлубинаРекурсии = 1 ;
ПереченьРеквизитов. Вставить( Реквизит. Имя, ДокументСсылка[Реквизит. Имя]) ;
ДобавитьФорматы( ПереченьРеквизитов, ДокументСсылка[Реквизит. Имя], Реквизит. Имя, ДокументСсылка) ;
Если Найти( Реквизит. Тип, "Справочник ссылка" ) > 0 Тогда
ЗаполнитьРеквизиты( мГлубинаРекурсии, ПереченьРеквизитов, ДокументСсылка[Реквизит. Имя], ДокументСсылка[Реквизит. Имя]. Метаданные( ) , Реквизит. Имя) ;
Иначе
КонецЕсли ;
КонецЦикла ;
ТабличныеЧасти = ДокументСсылка. Метаданные( ) . ТабличныеЧасти;
Для Каждого ТабличнаяЧасть Из ТабличныеЧасти Цикл
Если ТабличнаяЧасть. Имя = "Характеристики" Тогда
Для Каждого СтрокаТабличнойЧасти Из ДокументСсылка[ТабличнаяЧасть. Имя] Цикл
мПредставлениеРеквизита = "Характеристика" + "_" + СтрЗаменить( СтрокаТабличнойЧасти["ВидХарактеристики" ], " " , "_" ) ;
мЗначение = СтрокаТабличнойЧасти["ЗначениеХарактеристики" ];
ПереченьРеквизитов. Вставить( мПредставлениеРеквизита, мЗначение) ;
ДобавитьФорматы( ПереченьРеквизитов, мЗначение, мПредставлениеРеквизита, ДокументСсылка) ;
Если Найти( ТипЗнч( мЗначение) , "Справочник ссылка" ) > 0 Тогда
ЗаполнитьРеквизиты( мГлубинаРекурсии, ПереченьРеквизитов, мЗначение, мЗначение. Метаданные( ) , мПредставлениеРеквизита) ;
КонецЕсли ;
КонецЦикла ;
КонецЕсли ;
Реквизиты = ТабличнаяЧасть. Реквизиты;
Для Каждого Реквизит Из Реквизиты Цикл
Для Каждого СтрокаТабличнойЧасти Из ДокументСсылка[ТабличнаяЧасть. Имя] Цикл
мГлубинаРекурсии = 1 ;
мПредставлениеРеквизита = "_" + СтрокаТабличнойЧасти. НомерСтроки+ "_" + ТабличнаяЧасть. Имя+ "_НомерСтроки" ;
ПереченьРеквизитов. Вставить( мПредставлениеРеквизита, Строка( СтрокаТабличнойЧасти. НомерСтроки) ) ;
мПредставлениеРеквизита = "_" + СтрокаТабличнойЧасти. НомерСтроки+ "_" + ТабличнаяЧасть. Имя+ "_" + Реквизит. Имя;
мЗначение = СтрокаТабличнойЧасти[Реквизит. Имя];
ПереченьРеквизитов. Вставить( мПредставлениеРеквизита, мЗначение) ;
ДобавитьФорматы( ПереченьРеквизитов, мЗначение, мПредставлениеРеквизита, ДокументСсылка) ;
Если Найти( ТипЗнч( мЗначение) , "Справочник ссылка" ) > 0 Тогда
ЗаполнитьРеквизиты( мГлубинаРекурсии, ПереченьРеквизитов, мЗначение, мЗначение. Метаданные( ) , мПредставлениеРеквизита) ;
Иначе
КонецЕсли ;
КонецЦикла ;
Если Реквизит. Тип. СодержитТип( Тип( "Число" ) ) Тогда
мЗначение = ДокументСсылка[ТабличнаяЧасть. Имя]. Итог( Реквизит. Имя) ;
мПредставлениеРеквизита = "Итог" + "_" + ТабличнаяЧасть. Имя+ "_" + Реквизит. Имя;
ПереченьРеквизитов. Вставить( мПредставлениеРеквизита, мЗначение) ;
ДобавитьФорматы( ПереченьРеквизитов, мЗначение, мПредставлениеРеквизита, ДокументСсылка) ;
КонецЕсли ;
КонецЦикла ;
КонецЦикла ;
Возврат ПереченьРеквизитов;
КонецФункции
Функция ИмяТабличнойЧастиВСтроке(Строка,ДокументСсылка)
ТабличнаяЧасть= Неопределено ;
Если НЕ ПустаяСтрока( Строка) Тогда
ТабличнаяЧасть = ДокументСсылка. Метаданные( ) . ТабличныеЧасти. Найти( Строка)
КонецЕсли ;
Возврат ТабличнаяЧасть;
КонецФункции
Функция ПолучитьСтартПеременной(ПереданнаяСтрока) Экспорт
СтартПеременной = "" ;
ПервыйСимвол = Найти( ПереданнаяСтрока, "[" ) ;
Если ПервыйСимвол > 0 Тогда
ВторойСимвол = Найти( ПереданнаяСтрока, "]" ) ;
Если ( ВторойСимвол > 0 ) И ( ВторойСимвол > ПервыйСимвол) Тогда
Переменная = ( Сред( ПереданнаяСтрока, ПервыйСимвол+ 1 , ВторойСимвол- ПервыйСимвол- 1 ) ) ;
ВторойСимвол = Найти( Переменная, "_" ) ;
Если ( ВторойСимвол > 0 ) И ( ВторойСимвол > 1 ) Тогда
СтартПеременной = Сред( Переменная, 1 , ВторойСимвол- 1 ) ;
КонецЕсли ;
КонецЕсли ;
КонецЕсли ;
Возврат СтартПеременной;
КонецФункции
Функция ПолучитьПеременнуюИзСтроки(ПереданнаяСтрока) Экспорт
Переменная = "" ;
ПервыйСимвол = Найти( ПереданнаяСтрока, "[" ) ;
Если ПервыйСимвол > 0 Тогда
ВторойСимвол = Найти( ПереданнаяСтрока, "]" ) ;
Если ( ВторойСимвол > 0 ) И ( ВторойСимвол > ПервыйСимвол) Тогда
Переменная = ( Сред( ПереданнаяСтрока, ПервыйСимвол+ 1 , ВторойСимвол- ПервыйСимвол- 1 ) ) ;
КонецЕсли ;
КонецЕсли ;
Возврат Переменная;
КонецФункции
Функция ПреобразоватьВURL(ИмяФайла)
Возврат "file:///" + СтрЗаменить( ИмяФайла, "\" , "/" ) ;
КонецФункции
Функция ООПолучитьТекст(OOДокумент)
Текст = "" ;
oParEnum = OOДокумент. getText( ) . createEnumeration( ) ;
Пока oParEnum. hasMoreElements( ) Цикл
oPar = oParEnum. nextElement( ) ;
Если oPar. supportsService( "com.sun.star.text.Paragraph" ) ТОгда
Текст = Текст + oPar. getString( ) ;
ИначеЕсли oPar. supportsService( "com.sun.star.text.TextTable" ) Then
КонецЕсли ;
КонецЦикла ;
Для ТекущаяТаблица = 0 ПО OOДокумент. getTextTables( ) . Count- 1 Цикл
Для ТекущаяСтрока = 0 ПО OOДокумент. getTextTables( ) . getByIndex( ТекущаяТаблица) . Rows. Count- 1 Цикл
Для ТекущаяКолонка = 0 ПО OOДокумент. getTextTables( ) . getByIndex( ТекущаяТаблица) . Columns. Count- 1 Цикл
Текст = Текст + OOДокумент. getTextTables( ) . getByIndex( ТекущаяТаблица) . getCellByPosition( ТекущаяКолонка, ТекущаяСтрока) . string;
КонецЦикла ;
КонецЦикла ;
КонецЦикла ;
Возврат Текст;
КонецФункции