При формировании печатных форм договоров, коммерческих предложений и других документов часто используются макеты Microsoft Word. Однако разработчики нередко сталкиваются с ситуацией: в основном тексте документа переменные и параметры успешно заполняются, а в верхних и нижних колонтитулах поля остаются пустыми или не обновляются. Разберем по шагам, как устроен этот механизм, в каком формате сохранять файлы и как программно передавать данные в колонтитулы.
Для внесения изменений в существующий макет печатной формы выполним следующие действия:
docx или doc).{DOCVARIABLE ИмяПараметра \* MERGEFORMAT}. Чтобы переключаться между значениями полей и их кодовыми названиями, нажмем комбинацию клавиш Alt + F9.DocVariable), либо вручную через нажатие клавиш Ctrl + F9 с последующим вводом имени переменной.Выясним причину такого поведения. В объектной модели Microsoft Word колонтитулы, сноски и основной текст относятся к разным текстовым слоям (StoryRanges). Коллекция полей документа ActiveDocument.Fields обращается только к основному телу документа (wdMainTextStory).
Когда программный код 1С выполняет стандартное обновление через ActiveDocument.Fields.Update(), обновляется исключительно основной текст, а колонтитулы игнорируются. Чтобы параметры отобразились в колонтитулах, необходимо принудительно обновить поля во всех областях документа.
Рассмотрим универсальный способ обновления переменных документа. Переберем все текстовые диапазоны документа и связанные с ними области, вызвав для каждого метод обновления полей.
Посмотрим на пример реализации в 1С:
// Создаем COM-объект и открываем документ
Ворд = Новый COMОбъект("Word.Application");
Ворд.Visible = Ложь;
Документ = Ворд.Documents.Open(ПутьКФайлу);
// Устанавливаем значение переменной
Документ.Variables.Item("Организация").Value = "ООО ""Ромашка""";
// Обновляем поля во всех диапазонах документа, включая колонтитулы
Для Каждого ОбластьТекста Из Документ.StoryRanges Цикл
ОбластьТекста.Fields.Update();
// Проверяем наличие связанных областей (например, следующих колонтитулов)
Пока ОбластьТекста.NextStoryRange <> Неопределено Цикл
ОбластьТекста = ОбластьТекста.NextStoryRange;
ОбластьТекста.Fields.Update();
КонецЦикла;
КонецЦикла;
Документ.Save();
Ворд.Quit();
Если в макете вместо переменных DOCVARIABLE используются текстовые маркеры (например, [ПечНомерДоговора]), колонтитул обрабатывается как отдельный объект диапазона Range секции документа.
Проанализируем пример кода с явным обращением к верхнему колонтитулу:
// Получаем диапазон верхнего колонтитула первой секции
Колонтитул = Документ.Sections.Item(1).Headers.Item(1).Range;
// Выполняем автозамену текста в колонтитуле
Колонтитул.Find.Execute("[ПечНомерДоговора]", 0, 0, , , , , , , НомерДоговора, 2);
Колонтитул.Find.Execute("[ПечДатаДоговора]", 0, 0, , , , , , , Формат(ДатаДоговора, "ДФ=dd.MM.yyyy"), 2);
Параметр 2 в конце вызова метода Execute соответствует константе wdReplaceAll, что обеспечивает замену всех совпадений в пределах указанного колонтитула.
Рассмотрим еще один простой прием: вызов механизма предварительного просмотра печати заставляет Word автоматически рассчитать и обновить абсолютно все поля во всех секциях и колонтитулах без ручного цикла по коллекциям.
// Заполняем переменные
Документ.Variables.Item("Организация").Value = "ООО ""Ромашка""";
// Включаем и выключаем предпросмотр для сквозного обновления
Документ.PrintPreview();
Документ.ClosePrintPreview();
При автоматизации формирования документов на платформе 1С важно учитывать технические ограничения:
docx без COM-объекта Word. Параметры задаются в формате {v8 ИмяПараметра}, а замена выполняется на уровне XML-структуры архива (включая файлы header.xml и footer.xml). Это работает на сервере без необходимости установки MS Office.Документ.Bookmarks.Item("ИмяЗакладки").Range.Text = "Значение".Word.Application доступна только в операционных системах Windows. При выполнении кода в 64-разрядном кластере серверов 1С прямое управление через COM может потребовать дополнительной настройки DCOM, поэтому предпочтительно формировать документы на стороне тонкого клиента либо переходить на средства БСП.