Как заполнить шаблон word из 1с. Работа с ActiveDocument в клиент-серверном варианте. Создание внешней печатной формы "Договор"

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

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

Создадим шаблон на основе документа Word для 1С. Сначала необходимо включить показ закладок для более удобной работы с документом:


Далее необходимо в файл шаблона для 1С, добавить текст и пару закладок. Закладка добавляется через меню «Вставка» — «Закладка». Нужно выделить текст закладки, скопировать его, открыть меню «Вставка — Закладка», вставить скопированный текст закладки и нажать «Добавить»:


Когда файл шаблона Word готов, создаем новую внешнею обработку в 1С, добавляем форму и в модуле формы вставляем следующий код: &НаКлиенте Процедура ПриОткрытии(Отказ) ЗаполнитьШаблонВорд(); КонецПроцедуры &НаКлиенте Функция ЗаполнитьШаблонВорд() //Попытка создать COM объект Попытка ОбъектВорд = Новый COMОбъект("Word.Application"); Исключение Сообщить("Ошибка при запуске Microsoft Word: " + ОписаниеОшибки(), СтатусСообщения.Внимание); Возврат Неопределено; КонецПопытки; //Путь к шаблону ОбъектВорд.Documents.Add("C:\Users\Константин\Desktop\Шаблон.docx"); ШаблонВорд = ОбъектВорд.ActiveDocument; //Получаем все закладки из шаблона Для каждого ЗакладкаВорд Из ШаблонВорд.Bookmarks Цикл Сообщить(ЗакладкаВорд.Name); КонецЦикла; //Заменяем закладку1 на текст ШаблонВорд.Bookmarks("Закладка1").Select(); ШаблонВорд.Application.Selection.TypeText("Текст для закладки №1."); //Заменяем закладку2 на текст ШаблонВорд.Bookmarks("Закладка2").Select(); ШаблонВорд.Application.Selection.TypeText("Текст для закладки №2."); //Заменяем закладку3 на текущую дату ШаблонВорд.Bookmarks("Закладка3").Select(); ШаблонВорд.Application.Selection.TypeText(ТекущаяДата()); ОбъектВорд.Application.Visible = Истина; ОбъектВорд.Activate(); //Закрытие документа //ОбъектВорд.Application.Quit(); КонецФункции

В результат запуска внешней обработки 1С по формированию печатной формы на основе шаблона в виде файла Word, мы получим следующий результат:

Информацию по методам COM объекта Word, а так же дополнительные данные можно узнать из MSDN .

Дополнение к заметке Использование шаблонов Word в 1С

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

1. А как поменять размер шрифта во вставляемом тексте?
Достаточно изменить размер шрифта закладки, в шаблоне. А вот, если необходимо динамически менять размерность, тогда:

//Заменяем закладку3 на текущую дату ШаблонВорд.Bookmarks("Закладка3").Select(); ШаблонВорд.Application.Selection.Font.Bold = 1; ШаблонВорд.Application.Selection.Font.Size = 20; ШаблонВорд.Application.Selection.TypeText(ТекущаяДата());

2. Картинки есть возможность выгружать в шаблон?
Да, конечно. Примеры для C# и VB описаны по ссылке: https://msdn.microsoft.com/ru-ru/library/ms178792.aspx , а для 1С код будет следующий:

// Вставка изображения ШаблонВорд.Bookmarks("Закладка3").Select(); ШаблонВорд.Application.Selection.InlineShapes.AddPicture("C:\Users\Константин\Desktop\logo_1c.png");

3. При выполнении кода: ОбъектВорд.Documents.Add(«C:/Шаблон.docx») (туда я поместил Ваш документ) получаю ошибку: «Ошибка при вызове метода контекста (Add)» в чем может быть причина?
Может попробовать изменить путь на: «C:\Шаблон.docx».

4. Подскажите пожалуйста еще почему при сохранении макета типа active document в файл word кодом:

ОбработкаОбъект = РеквизитФормыВЗначение("Объект"); Макет = ОбработкаОбъект.ПолучитьМакет("ШаблонПисьмаПросрочка"); ИмяФайла = КаталогВременныхФайлов() + "\"файл.doc"; Макет.Записать(ИмяФайла);

Я получаю вместо нормального документа вот такой http://prntscr.com/eshgjk
Предполагаю, что метод Записать(,) по умолчанию, записывает файл в формате MXL. Попробуйте вторым параметром установить значение: ТипФайлаТабличногоДокумента.DOCX, более подробно описано в «Синтакс-помощнике».

5. У меня в документе есть ссылки на файлы которые расположены на сетевом диске. Как в шаблоне сделать гиперссылку на эти файлы?
Интересный вопрос, если попробовать сделать запись макроса и посмотреть результат, то в Visual Basic добавление гиперссылки будет выглядеть следующим образом:

Sub Макрос1() " " Макрос1 Макрос " " Selection.MoveLeft Unit:=wdCharacter, Count:=15, Extend:=wdExtend ActiveDocument.Hyperlinks.Add Anchor:=Selection.Range, Address:= _ "C:\Users\Константин\Desktop\Тест.txt", SubAddress:="", ScreenTip:="", _ TextToDisplay:="ТестоваяСсылка" End Sub

Описание метода добавления в MSDN: https://msdn.microsoft.com/en-us/vba/word-vba/articles/hyperlinks-add-method-word

Соответственно код для 1С следующий:

Функция ЗаполнитьШаблонВорд() //Попытка создать COM объект Попытка ОбъектВорд = Новый COMОбъект("Word.Application"); Исключение Сообщить("Ошибка при запуске Microsoft Word: " + ОписаниеОшибки(), СтатусСообщения.Внимание); Возврат Неопределено; КонецПопытки; //Путь к шаблону ОбъектВорд.Documents.Add("C:\Users\k.blagin\Desktop\Шаблон.docx"); ШаблонВорд = ОбъектВорд.ActiveDocument; //Получаем все ссылки из шаблона Для каждого ЗакладкаВорд Из ШаблонВорд.Hyperlinks Цикл Сообщить(ЗакладкаВорд.Name); КонецЦикла; //Меняем адрес уже существующей ссылки ШаблонВорд.Hyperlinks("Logs.zip").Address = "C:\Users\k.blagin\Desktop\Memory.zip"; //Заменяем закладку на ссылку ОбъектЗакладка = ШаблонВорд.Bookmarks("Закладка3"); ШаблонВорд.Hyperlinks.Add(ОбъектЗакладка.Range, "C:\Users\k.blagin\Desktop\Шаблон.docx", "", "Шаблон.docx", "C:\Users\k.blagin\Desktop\Шаблон.docx"); ОбъектВорд.Application.Visible = Истина; ОбъектВорд.Activate(); //Закрытие документа //ОбъектВорд.Application.Quit(); КонецФункции

ВНИМАНИЕ! При использовании кодов описанных ниже, уберите символ _
Давайте рассмотрим на примерах как это делается! =) Мне известно 2 способа:
1. Путем замены шаблонного текста в макете Wordа.
2. Путем вставки текста с помощью закладок в Wordе,

В первом случае сразу скажу, что длина строки передаваемая в функцию замены, довольно небольшая 255 символов, да и расстановка шаблонных выражений в макете Word занимает довольно много времени. Через процедуру Content.Find.Execute.

Во втором случае длина, насколько мне известно неограниченна, также воськаться с закладками намного быстрее и удобнее, чем расставлять шаблонный текст. Используя Bookmarks().S_elect(). Поэтому давайте на коде рассмотрим второй пример.

И так, для начала необходимо добавить Word макет к документу. Добавляем макет с помощью конструктора макетов указав Active document и выбрав соответствующий макет.

Называем его Акт. Открываем макет в 1Ске, ставим курсор в нужном месте, переходим в меню Вставка закладка нажимаем добавить закладку к примеру у меня это НарушенияТекст

Теперь кидаем на форму документа кнопку Сформировать и по нажатию на нее пишем код который открывает наш макет Word ищем закладку по имени и вставляет туда текст:
Код 1C v 8.х //инициализация часть 1
СсылкаМакет = ПолучитьМакет(Акт);
MSWord = СсылкаМакет.Получить();
Попытка
СсылкаМакет = MSWord.Application.Documents(1);
СсылкаМакет.Activate();
//выгружаем табличную часть с нарушениями в строку часть 2
str = Новый COMОбъект(ADODB.Stream);
str.Open();
СтрочкаТаблицы = ЭлементыФормы.Нарушения.ТекущиеДанные;
Для Каждого СтрочкаТаблицы Из Нарушения Цикл
str.WriteText(+ СтрочкаТаблицы.Описание + Нарушены требования СНИПФЗГОСТ: + СтрочкаТаблицы.СНИПФЗГОСТ + Статья: + СтрочкаТаблицы.ЧастьСтатья + Символ(13),0);
КонецЦикла;
str.Position = 0;
НарушенияТекст = str.readText();

//вставляем в закладку текст с нарушениями часть 3
MSWord.Bookmarks(НарушенияТекст).S_elect();
MSWord.Application.S_election.TypeText(НарушенияТекст);

СсылкаМакет.Activate();
Исключение
//если ошибка
Сообщить(ОписаниеОшибки());
MSWord.Application.Quit();
КонецПопытки;
Это пример вывода множества строчек из табличной части одной строкой, если нужно просто выгрузить какой-то реквизит то можно пропустить часть 2 и перейти к части 3.

Для выгрузки табличной части в форме таблицы можно использовать функцию автоформата, примеру код выгрузки табличной части документа Предписание:
Код 1C v 8.х Word = MSWord.Application;
Документ = Word.ActiveDocument();
//Переместиться вниз на 22 строк
Word.S_election.MoveDown(,22);
Документ.Paragraphs.Add();
//подготовка таблицы:
Rng = Word.S_election.Range;
//Формируем заголовок:
Rng.I_nsertAfter(№ п/п*Установленные нарушения и меры по их устранению*Основания);
Rng.I_nsertParagraphAfter();
//сама таблица
СтрочкаТаблицы = ЭлементыФормы.НарушенияПредписание.ТекущиеДанные;
Для Каждого СтрочкаТаблицы из НарушенияПредписание Цикл
Rng.I_nsertAfter(Строка(СтрочкаТаблицы.НомерСтроки)+*+СтрочкаТаблицы.Описание + ; + СтрочкаТаблицы.Предписание +* + СтрочкаТаблицы.СНИПФЗГОСТ + + СтрочкаТаблицы.ЧастьСтатья);
Rng.I_nsertParagraphAfter();
КонецЦикла;
Rng.ConvertToTable(*);
Документ.Tables(1).AutoFormat(17); //номер таблицы в шаблоне
Word.Visible = Истина;
Ну вот и все =)

Еще способ Active document
В Конфигураторе Макеты - правый клик - Добавить
Тип макета: Active document
Создать новый - Документ Microsoft Word

Меню Вставка - Поле - Автоматизация - DocVariable
Написать имя поля в графе "Новое имя:" ДатаПриказа

В модуле формы документа создаем кнопку, и в ее обработчике пишем:



КомОбъект.Variables.Item("ДатаПриказа").Value="24.01.2007";
КомОбъект.Fields.UpDate();

КомОбъект.PrintOut(); //распечатать документ

//Ожидание окончания отправки на печать...
Пока objWord.Application.BackgroundPrintingStatus<>0 Цикл
Предупреждение("Ожидание",1);
КонецЦикла;

КомОбъект.Application.Quit(); //закрыть Word
КомОбъект = 0;
КонецПроцедуры

2) добавляем не поле, а Закладку
Меню Вставка - Закладка и далее указываем ее имя ("ИмяЗакл")
Код 1C v 8.х Процедура ОсновныеДействияФормыWord(Кнопка)
АктивныйДокумент = ПолучитьМакет("Макет");
КомОбъект = АктивныйДокумент.Получить();
КомОбъект.Application.Visible=1;
КомОбъект.Bookmarks(СокрЛП("ИмяЗакл")).S_elect();
КомОбъект.Application.S_election.TypeText(СокрЛП("тест проверка"));
КонецПроцедуры

Код 1C v 8.2 УП // Параметры договора обозначены в тексте переменными вида "[%НомерДоговора%]"
Функция ПечатьДокумента() Экспорт

Договор = ПолучитьМакет("ActiveDocument_ДоговорПоставки"); // получим макет-ActiveDocument
MSWord = Договор.Получить();
Попытка
Doc = MSWord.Application.Documents(1);
Doc.Activate();
Replace = Doc.Content.Find;

FindText = "{НомерДоговора}"; // что искать - имя_шаблона
MatchCase = Ложь; // использовать регулярные выражения
MatchWholeWord = Истина; // искать слово целиком
MatchWildcards = Ложь; // испоьзовать регулярные выражения
MatchSoundsLike = Неопределено; // искать созвучные
MatchAllWordForms = Неопределено; // искать все формы слова
Forward = Истина; // искать вперед
Wrap = Неопределено; // что должен вернуть Find-объект
Format_ = Ложь; // использовать форматирование
ReplaceWith = "N777"; // текст, на который надо заменить имя_шаблона

// кратко:
//Replace.Execute(FindText,Ложь,Истина,Ложь,Истина,Ложь,НомерДоговора);

Replace.Execute(
FindText,
MatchCase,
MatchWholeWord,
MatchWildcards,
MatchSoundsLike,
MatchAllWordForms,
Forward,
Wrap,
Format_,
НомерДоговора);

MSWord.Application.Visible = Истина;
MSWord.Activate();
Исключение
Сообщить(ОписаниеОшибки());
MSWord.Application.Quit();
КонецПопытки;

Возврат 0;

Итак, в чем суть моей статьи?

1. Есть сервер (x64), с установленным Office 2016 (x64), есть 1С 8.3.8 также x64 (имеется в виду сервер 1С). Пользователи подключаются как через тонкого клиента, так и через веб клиент.

2. Есть куча типовых договоров и накладных счет-фактур, оформленных (подготовленных) отделом продаж. Там шрифт, абзац и т.д., естественно, все оформлено в Word,Excel 2016 (x64), естественно, нет желания все это рисовать в 1С, а есть желание засунуть в макеты формата ActiveDocument

Решение банальное, вроде бы :) , не буду описывать весь механизм, как это делается, как заполняются данные из 1С в макет ActiveDocument - думаю, вы это знаете прекрасно и без меня. Но в ходе работы выяснилось, что не все так гладко в царстве COM объектов, а именно:

2. Какой вариант лучше выбрать: ActiveDocument или ДвоичныеДанные? Хотя для меня это звучит примерно как, что выбрать Водку С Пивом или Пиво С Водкой :) . Один фиг, надо забить документы данными из 1С и передать их Клиенту.

Ну да ладно пропустим лирику, я выбираю ActiveDocument, не буду описывать весь алгоритм, просто перечислю "подводные" камни и их решение. Все нижеизложенное это мои личные измышления и в никакой мере не претендуют на истину в последней инстанции. Возможно, вы решили эти проблемы или решите по другому.

1. Камень "первый ". Не работает метод SaveAs (как для MSWord, так и для MSExcel). При попытке записать ДвоичныеДанные 1С просто вылетает. Смотрим фрагмент листинга:

MSWord = Макет.Получить(); Попытка Документ = MSWord.Application.Documents(1); Документ.Activate(); //Далее каким-либо образом получаем данные и заполняем Word-овский документ //Получим путь во временной директории для сохранения туда файла ИмяВрем = ПолучитьИмяВременногоФайла(".docx"); Документ.SaveAs(ИмяВрем); //здесь начинается камень МойДокументВДвоичныхДанных = Новый ДвоичныеДанные(ИмяВрем); //ну а здесь этот камень нафиг выбивает 1С:) MSWord.Application.Quit();

Спасибо огромное.

Создание папок
C:\Windows\SysWOW64\config\systemprofile\Desktop
C:\Windows\System32\config\systemprofile\Desktop
проблему решило. Тема закрыта.

В чем причина? Причина в том, что код

MSWord = Макет.Получить();

Всегда вызывает экземпляр объекта COM (x32) независимо от того какой разрядности Office установлен. Вы никогда не задумывались, почему в макет ActoveDocument нельзя вставить файлы с расширением docx,xlsx

это можно проверить и через ДиспетчерЗадач, но факт есть факт - макет ActiveDocument вызывает неявно экземпляр COM (x32) и поэтому все дальнейшие манипуляции нужно делать учитывая это особенность.

1. Либо сервер и все ПО должно быть x32. Тогда ничего делать (в смысле переписывать код) не надо

2. Либо переписать код, таким образом

// получаем имя временного файла ВремФайл = ПолучитьИмяВременногоФайла("doc"); // этот код точно вызовет экземпляр COM нужной разрядности, в нашем случае x64 Word = Новый COMОбъект("Word.Application"); Word.Displayalerts = 0; ДокументН = Word.Application.Documents.Add(); ДокументН.SaveAs(ВремФайл,0); Word.Quit(); // далее все по старому Макет = УправлениеПечатью.МакетПечатнойФормы("Документ.АктПередачиОборудования."+НазваниеМакета); MSWord = Макет.Получить(); Попытка Документ = MSWord.Application.Documents(1); Документ.Activate(); // здесь что-то делаем, заполняем данные // здесь мы пересохраним наш файл из COM x62 в COM x64 MSWord.Application.Selection.WholeStory(); MSWord.Application.Selection.Copy(); ДокументН = MSWord.Application.Documents.Open(ВремФайл); ДокументН.Activate(); MSWord.Application.Selection.Paste(); ДокументН.SaveAs(ВремФайл,0); ДокументН.Close(); MSWord = Неопределено; Исключение // Если произойдет ошибка выводятся данные об ошибке и объект закрывается. Информация = ИнформацияОбОшибке(); ОбщегоНазначенияКлиентСервер.СообщитьПользователю("Ошибка - "+Информация.Описание+" код ошибки - "+СокрЛП(Информация.ИсходнаяСтрока)); MSWord.Application.Quit(); КонецПопытки;

Думаю, тут все понятно, сначала мы создали экземпляр COM нужной разрядности, создали пустой файл и сохранили во временную папку, далее работает с COM x32, заполняем данными и напоследок копируем содержимое всего документа и сохраняем в ранее подготовленный файл.

Все то же самое, но только для Excel

ВремФайл = ПолучитьИмяВременногоФайла("xls"); Excel = Новый COMОбъект("Excel.Application"); Excel.Displayalerts = 0; КнигаН = Excel.WorkBooks.Add(); ЛистН = КнигаН.WorkSheets(1); КнигаН.SaveAs(ВремФайл, -4143); Excel.Quit(); Макет = УправлениеПечатью.МакетПечатнойФормы("Документ.НакладнаяОборудования."+НазваниеМакета); MSExcel = Макет.Получить(); КнигаН = MSExcel.Application.Workbooks.Open(ВремФайл); ЛистН = КнигаН.WorkSheets(1); Попытка WBook = MSExcel.Application.Workbooks(1); Лист = WBook.WorkSheets(1); Лист.Activate(); // что-то делаем, заполняем данными из 1С MSExcel.Application.WorkBooks(1).WorkSheets(1).Cells.Copy(ЛистН.Cells); КнигаН.Save(); КнигаН.Close(); Исключение // Если произойдет ошибка выводятся данные об ошибке и объект закрывается. Информация = ИнформацияОбОшибке(); ОбщегоНазначенияКлиентСервер.СообщитьПользователю("Ошибка - "+Информация.Описание+" код ошибки - "+СокрЛП(Информация.ИсходнаяСтрока)); MSExcel.Application.Quit(); КонецПопытки;

ну вот "первый " камень я решил, на сервере x64 с Office x64, все работает точно как часы, без ошибок и не надо создавать никаких папок и все прочее.

Камень "второй ". фрагмент кода

ВремФайл = ПолучитьИмяВременногоФайла("xls");

есть не очень хорошо, потому как идет запись в папку: "c:\Users\ че там....", вообще эта папка всегда в черном списке всех фаерволов, антивирусов и прочее, прочее, хотя бы открыть центр управления безопасностью Word или Excel. Глянем и мы туда

придется возится с этим, иначе есть вероятность появления "странных" ошибок. Поэтому я предлагаю следующее:

1. Открываем Конфигуратор и добавляем новый РегистрСведений

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

НазваниеМакета - Идентификатор макета

ДокументOffice - ХранилищеЗначений, здесь мы и держим наш готовый файл

2. Дописываем выше написанный код следующим образом:

МЗ = РегистрыСведений.ВременноеХранилищеOffice.СоздатьМенеджерЗаписи(); МЗ.Объект = Выборка.Ссылка; МЗ.НазваниеМакета = НазваниеМакета; МЗ.Прочитать(); МЗ.Объект = Выборка.Ссылка; МЗ.НазваниеМакета = НазваниеМакета; МЗ.ДокументOffice = Новый ХранилищеЗначения(Новый ДвоичныеДанные(ВремФайл)); МЗ.Записать(); УдалитьФайлы(ВремФайл);

Что мы делаем, мы записываем готовый файл в регистр сведений и затем удаляем сам временный файл, решаем проблему "Центра безопасности Word,Excel". Осталось только одно показать этот готовый файл Клиенту (клиент тонкий и веб)

3. Камень "третий " - передача файла клиенту, тут просто выложу весь код, что-то взял из БСП, что-то из Демонстрационная конфигурация "Управляемое приложение", что-то из Инета, но в общем вот код (целиком)

//////////////////////////////////////////////////////////////////////////////// // СЛУЖЕБНЫЕ ПРОЦЕДУРЫ И ФУНКЦИИ БСП &НаСервере Функция ПолучитьМакет() ОбъектСсылка = СтруктураДанных.Объект; НазваниеМакета = СтруктураДанных.НазваниеМакета; КлючЗаписи = РегистрыСведений.ВременноеХранилищеOffice.СоздатьКлючЗаписи(Новый Структура("Объект,НазваниеМакета",ОбъектСсылка,НазваниеМакета)); // Адрес = ПолучитьНавигационнуюСсылку(КлючЗаписи,"ДокументOffice"); Возврат Адрес; КонецФункции // &НаКлиенте Процедура ПослеЗапускаПриложения(КодВозврата, ИмяПриложения) Экспорт; // КонецПроцедуры &НаКлиенте Процедура ПослеПолученияФайлов(ПереданныеФайлы, ДополнительныеПараметры) Экспорт Если НЕ ПереданныеФайлы=Неопределено Тогда Для каждого Описание Из ПереданныеФайлы Цикл ОпПослеЗапускаПриложения = Новый ОписаниеОповещения("ПослеЗапускаПриложения", ЭтотОбъект, Описание.Имя); НачатьЗапускПриложения(ОпПослеЗапускаПриложения, Описание.Имя); КонецЦикла; КонецЕсли; КонецПроцедуры &НаКлиенте Процедура ПослеВыбораКаталога(ВыбранныеФайлы, ИмяКоманды) Экспорт Если ВыбранныеФайлы = Неопределено Тогда Возврат; КонецЕсли; Каталог = ВыбранныеФайлы; ОбщегоНазначенияВызовСервера.СохранитьРабочийКаталог(Каталог); Если ИмяКоманды = "Накладная" Тогда НазваниеМакета = "Накладная" КонецЕсли; СтруктураДанных.Вставить("Каталог", Каталог); ПодключитьОбработчикОжидания("Подключаемый_ПередатьФайлКлиенту",5,Истина); КонецПроцедуры &НаКлиенте Процедура ОткрытьФайлыЧерезРасширение(ИмяКоманды) ОпПослеВыбораКаталога = Новый ОписаниеОповещения("ПослеВыбораКаталога", ЭтотОбъект, ИмяКоманды); Каталог = ОбщегоНазначенияВызовСервера.ПолучитьРабочийКаталог(); Если Каталог = Неопределено ИЛИ Каталог = "" Тогда Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.ВыборКаталога); Диалог.Заголовок = НСтр("ru = "Выбор каталога временного хранения файлов"", "ru"); Диалог.Показать(ОпПослеВыбораКаталога); Иначе ВыбранныеФайлы = Новый Массив; ВыбранныеФайлы.Добавить(Каталог); ВыполнитьОбработкуОповещения(ОпПослеВыбораКаталога, ВыбранныеФайлы); КонецЕсли; КонецПроцедуры &НаКлиенте Процедура ОбработатьПодключениеРасширенияРаботыСФайлами(РасширениеПодключено,ДополнительныеПараметры) Экспорт Если РасширениеПодключено Тогда ОткрытьФайлыЧерезРасширение(ДополнительныеПараметры.ИмяКоманды); КонецЕсли; КонецПроцедуры &НаКлиенте Процедура Подключаемый_ПередатьФайлКлиенту() Адрес = ПолучитьМакет(); Если Адрес<>Неопределено Тогда ОтключитьОбработчикОжидания("Подключаемый_ПередатьФайлКлиенту"); НомерДокумента = СтруктураДанных.НомерДокумента; Каталог = СтруктураДанных.Каталог; НазваниеМакета = СтруктураДанных.НазваниеМакета; ПутьКфайлу = Каталог+"\"+НазваниеМакета+"_№"+НомерДокумента+".xls"; Описание = Новый ОписаниеПередаваемогоФайла(ПутьКфайлу, Адрес); ПередаваемыеФайлы = Новый Массив; ПередаваемыеФайлы.Добавить(Описание); НачатьПолучениеФайлов(Новый ОписаниеОповещения("ПослеПолученияФайлов", ЭтотОбъект), ПередаваемыеФайлы, "", Ложь); КонецЕсли; КонецПроцедуры &НаСервере Процедура ВыполнитьПечатьСервер() ОбъектСсылка = СтруктураДанных.Объект; НазваниеМакета = СтруктураДанных.НазваниеМакета; СтруктураДанных.Вставить("НомерДокумента", ОбъектСсылка.Номер); МассивОбъектов = Новый Массив; МассивОбъектов.Добавить(ОбъектСсылка); Документы.НакладнаяОборудования.ПечатьНакладная(МассивОбъектов,НазваниеМакета,Истина); КонецПроцедуры &НаКлиенте Процедура Подключаемый_ВыполнитьПечать() ВыполнитьПечатьСервер(); КонецПроцедуры // СтандартныеПодсистемы.Печать &НаКлиенте Процедура Подключаемый_ВыполнитьКомандуПечати(Команда) Ссылка = Элементы.Список.ТекущиеДанные.Ссылка; СтруктураДанных = Новый Структура; СтруктураДанных.Вставить("Объект", Ссылка); СтруктураДанных.Вставить("НазваниеМакета", "Накладная"); ПодключитьОбработчикОжидания("Подключаемый_ВыполнитьПечать", 1, Истина); ОписаниеКоманды = УправлениеПечатьюКлиент.ОписаниеКомандыПечати(Команда.Имя,ИмяФормы); НачатьУстановкуРасширенияРаботыСФайлами(); НачатьПодключениеРасширенияРаботыСФайлами(Новый ОписаниеОповещения("ОбработатьПодключениеРасширенияРаботыСФайлами",ЭтотОбъект,Новый Структура("ИмяКоманды",ОписаниеКоманды.Идентификатор))); КонецПроцедуры // Конец СтандартныеПодсистемы.Печать

Немного пояснений:

1. Во-первых, клиент у нас работает как через Тонкий, так и через Веб режимы, поэтому заранее в свойствах Конфигуратор ставим следующие значения:

Чтобы не было проблем при работе с браузером

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

3. И последнее, подключаем Расширение для работы с Файлами (помним что в режиме Тонкий клиент, это расширение включено всегда). И через код:

передаем файл Клиенту используя механизм НавигационнаяСсылка, получаем следующие сообщения в браузере (Тонкий само собой работает):

ну вот, кажется, все. Надеюсь, это поможет кому-нибудь...

По поводу Word, Excel файлы вставлять в виде ДвоичныхДанные? проблема-то в чем?

1. Мы либо должны вытащить из макета эти ДвоичныеДанные и заполнить данными из 1С и ВНИМАНИЕ снова записать в виде ДвоичныхДанных (Водка С Пивом или Пиво С Водкой)

2. Либо мы должно получить макет ДвоичныеДанные на стороне Клиента и там заполнить его, НО COM объект поддерживается только браузером IE и то с танцами с настройками ActiveX, другие браузеры давно отказались от использования ActiveX



Просмотров