При разработке внешних печатных форм нередко возникает задача: в зависимости от данных документа (например, строк табличной части) сформировать единый файл MS Word, объединяющий страницы из разных макетов ActiveDocument. Разберем по шагам, какими способами можно программно скомпоновать несколько макетов в один результирующий документ, как управлять разрывами страниц и каких ошибок следует избегать при автоматизации Word через COM.
Наиболее универсальный подход для произвольного (N-ного) количества страниц и макетов заключается в последовательном копировании содержимого каждого макета в базовый документ. Для этого открываем основной документ, а затем в цикле получаем очередной макет, копируем его содержимое в буфер обмена и вставляем в конец основного документа через разрыв страницы.
Рассмотрим пример реализации на встроенном языке 1С:
// Создаем экземпляр MS Word через COM
WordApp = Новый COMОбъект("Word.Application");
WordApp.Visible = Ложь;
Попытка
// Создаем результирующий документ
ИтоговыйДокумент = WordApp.Documents.Add();
// Получаем массив нужных макетов в зависимости от условий
СписокМакетов = Новый Массив;
СписокМакетов.Добавить("Макет1");
Если ТребуетсяВтораяСтраница Тогда
СписокМакетов.Добавить("Макет2");
КонецЕсли;
wdCollapseEnd = 0;
wdPageBreak = 7;
wdDoNotSaveChanges = 0;
Для Индекс = 0 По СписокМакетов.Количество() - 1 Цикл
ИмяМакета = СписокМакетов[Индекс];
МакетОбъект = ПолучитьМакет(ИмяМакета);
// Получаем временный COM-документ из макета
ВременныйDoc = МакетОбъект.Получить();
// Сначала выполняем автозамену параметров в изолированном макете
Замена = ВременныйDoc.Content.Find;
Замена.Execute("<Контрагент>", Ложь, Истина, Ложь, , , Истина, , Ложь, СокрЛП(СсылкаНаОбъект.Контрагент.НаименованиеПолное));
Если Индекс > 0 Тогда
// Переходим в конец итогового документа и вставляем разрыв страницы
Диапазон = ИтоговыйДокумент.Content;
Диапазон.Collapse(wdCollapseEnd);
Диапазон.InsertBreak(wdPageBreak);
Диапазон.Collapse(wdCollapseEnd);
Иначе
Диапазон = ИтоговыйДокумент.Content;
КонецЕсли;
// Копируем содержимое заполненного макета и вставляем в итоговый
ВременныйDoc.Content.Copy();
Диапазон.Paste();
// Закрываем временный документ без сохранения
ВременныйDoc.Close(wdDoNotSaveChanges);
КонецЦикла;
// Показываем готовый сформированный документ пользователю
WordApp.Visible = Истина;
WordApp.Activate();
Исключение
WordApp.Quit(0);
WordApp = Неопределено;
ВызватьИсключение "Ошибка при формировании документа Word: " + ОписаниеОшибки();
КонецПопытки;
Второй вариант заключается в выгрузке каждого макета во временный файл на диск с последующей вставкой в результирующий документ через метод InsertFile объекта Range. Этот метод особенно удобен, когда макеты содержат сложные колонтитулы, таблицы или внедренную графику.
Разберем алгоритм по шагам:
ПолучитьИмяВременногоФайла("docx") и открываем его как базовый документ.Range.Collapse(0), добавляем разрыв страницы и вызываем Range.InsertFile(ИмяФайла).УдалитьФайлы().Если вариантов вывода немного (например, строго «Страница 1», «Страница 2» или «Страница 1 + Страница 2»), самым простым и производительным решением будет подготовка трех готовых макетов:
В коде достаточно определить условие и загрузить один нужный макет, не тратя время на манипуляции с буфером обмена и вставку файлов.
Проанализируем тонкости, которые необходимо учитывать при интеграции 1С и Microsoft Word:
ReplaceWith метода Execute ограничен длиной в 255 символов. Если реквизит (например, полный адрес или реквизиты договора) длиннее, возникнет ошибка COM-объекта. Для длинных строк безопаснее использовать закладки (Bookmarks) либо прямую замену текста найденного диапазона Range.Text.wdPageBreak (значение 7) применит параметры первого листа ко всему документу. В этом случае необходимо использовать разрыв раздела с новой страницы: wdSectionBreakNextPage (значение 2).Попытка ... Исключение, в блоке Исключение принудительно вызывайте WordApp.Quit(0) и очищайте переменную (WordApp = Неопределено).ActiveDocument и COM-соединение с Word работают исключительно на клиенте под управлением ОС Windows с установленным пакетом MS Office. На сервере 1С под управлением Linux данный механизм не поддерживается.Если печатную форму требуется формировать универсально (в веб-клиенте, на сервере или под Linux), рекомендуется перевести макет на стандартный ТабличныйДокумент 1С. В нем объединение листов выполняется штатным методом ТабличныйДокумент.ВывестиГоризонтальныйРазделительСтраниц(), а готовый результат можно сохранить в PDF или DOCX без использования внешних офисных приложений.