При автоматизации документооборота часто возникает задача объединения нескольких независимых файлов в один общий документ. Одной из главных трудностей здесь становится нумерация: по умолчанию Microsoft Word применяет сквозную нумерацию ко всему файлу, тогда как для сложных отчетов или комплектов документов требуется, чтобы каждый блок начинался с первой страницы. В этой статье мы разберем, как с помощью средств 1С:Предприятие и COM-технологий управлять разделами Word и настраивать независимую нумерацию для каждого вставляемого фрагмента.
Прежде чем переходить к написанию кода, проанализируем, как Word обрабатывает страницы. Если мы просто добавляем текст или вставляем файлы друг за другом, программа считает их частью одного раздела. Чтобы «сбросить» номер страницы, нам необходимо принудительно создать новый раздел. В объектной модели Word за это отвечает метод InsertBreak. Рассмотрим подробнее типы разрывов. Для нашей задачи критически важно использовать именно разрыв раздела с новой страницы (в VBA это константа wdSectionBreakNextPage).
Для реализации корректной нумерации мы должны придерживаться следующего плана действий при сборке документа:
COMОбъект("Word.Application").Разберем конкретный пример кода. При работе с COM-объектами Word в 1С мы не можем напрямую использовать именованные константы (такие как wdSectionBreakNextPage), поэтому будем заменять их числовыми эквивалентами.
Сначала инициализируем приложение и подготовим базу для вставки:
// Инициализация Word
WordApp = Новый COMОбъект("Word.Application");
WordApp.Visible = Ложь; // Скрываем работу приложения для ускорения
НовыйДок = WordApp.Documents.Add();
Selection = WordApp.Selection;
// Допустим, мы в цикле обходим массив путей к файлам, которые нужно объединить
Для Каждого ПутьКФайлу Из МассивФайлов Цикл
// Если это не первый файл, вставляем разрыв раздела
Если МассивФайлов.Найти(ПутьКФайлу) > 0 Тогда
// 2 — это значение константы wdSectionBreakNextPage
Selection.InsertBreak(2);
КонецЕсли;
// Получаем текущий раздел, с которым будем работать
ТекущийРаздел = Selection.Sections.Item(1);
// Настраиваем нумерацию в этом разделе
Попытка
// Устанавливаем свойство перезапуска нумерации
ТекущийРаздел.PageSetup.RestartPageNumbering = Истина;
// Указываем, с какого числа начинать
ТекущийРаздел.PageSetup.StartingNumber = 1;
// Отключаем связь колонтитулов с предыдущим разделом
// 1 — это wdHeaderFooterPrimary (основной нижний колонтитул)
ТекущийРаздел.Footers.Item(1).LinkToPrevious = Ложь;
Исключение
Сообщить("Ошибка настройки колонтитулов: " + ОписаниеОшибки());
КонецПопытки;
// Вставляем содержимое файла
Selection.InsertFile(ПутьКФайлу);
КонецЦикла;
WordApp.Visible = Истина;
Выясним причину, по которой иногда нумерация все равно «сбивается». Это часто связано со свойством LinkToPrevious. По умолчанию каждый новый раздел в Word «связан» с предыдущим. Это означает, что если вы измените формат номера страницы или текст в нижнем колонтитуле второго раздела, он автоматически изменится и в первом. Для того чтобы добиться полной независимости, мы принудительно устанавливаем LinkToPrevious = Ложь. Это разрывает логическую цепочку между блоками документа.
Рассмотрим ситуацию, когда в документе еще нет полей нумерации. Если вы программно создаете документ «с нуля», разрыва раздела недостаточно — нужно еще и вставить само поле номера страницы в колонтитул. Проанализируем, как это сделать:
// Переходим к работе с нижним колонтитулом
Колонтитул = ТекущийРаздел.Footers.Item(1);
// Добавляем поле номера страницы
// 33 — это wdFieldPage
Колонтитул.Range.Fields.Add(Колонтитул.Range, 33);
Как было справедливо отмечено в обсуждении на форуме, при работе с COM-объектами MS Office лучшим помощником программиста 1С является редактор макросов в самом Word. Если вы не знаете, какое свойство отвечает за то или иное действие, выполните следующие шаги:
Для удобства разработки приведем список числовых значений, которые заменяют стандартные константы Word в коде 1С:
wdSectionBreakNextPage = 2 — разрыв раздела с новой страницы.wdHeaderFooterPrimary = 1 — основной колонтитул (в отличие от колонтитулов первой страницы или четных/нечетных).wdFieldPage = 33 — динамическое поле текущего номера страницы.wdFieldNumPages = 26 — динамическое поле общего количества страниц в документе.Используя эти методы, мы можем собирать сколь угодно сложные документы, сохраняя строгую структуру нумерации. Помните, что после завершения работы с COM-объектом крайне желательно корректно закрывать приложение и очищать переменные в 1С, чтобы избежать «зависания» процессов WINWORD.EXE в памяти сервера или клиентского компьютера.
// Корректное завершение
WordApp.Quit();
WordApp = Неопределено;
Таким образом, мы проанализировали основные приемы управления страницами и разделами. Сочетание программной вставки файлов и тонкой настройки объекта PageSetup позволяет решать задачи генерации отчетности любой сложности.