Автоматизация формирования печатных форм в формате Microsoft Word — одна из самых востребованных задач в среде 1С 7.7. Это особенно актуально для сложных юридических договоров, спецификаций и писем, где требуется гибкое форматирование, которое трудно реализовать в обычном табличном документе 1С. В данной статье мы подробно проанализируем, как связать эти две системы, разберем типичные ошибки новичков и изучим продвинутые методы работы с текстом, таблицами и колонтитулами.
Представим ситуацию: у нас есть готовый шаблон договора в формате .doc или .dot, и нам необходимо подставить в него данные из информационной базы (ФИО контрагента, сумма, дата и т.д.). Для начала работы нам нужно создать COM-объект, который позволит управлять приложением Word.
Рассмотрим стандартный блок инициализации. Обратите внимание, что мы обязательно используем конструкцию Попытка ... Исключение, так как на компьютере пользователя Word может быть просто не установлен.
Попытка
WordApp = СоздатьОбъект("Word.Application");
// Делаем приложение невидимым на время заполнения для ускорения работы
WordApp.Visible = 0;
Исключение
Сообщить("Ошибка: Microsoft Word не найден на этом компьютере!");
Возврат;
КонецПопытки;
Как показывает практика и обсуждения на форумах, использование закладок (Bookmarks) часто вызывает трудности: они могут «схлопываться», удаляться пользователем или некорректно смещаться при вставке текста. Более надежным способом является использование специальных меток-заполнителей прямо в тексте документа, например [НомерДоговора] или %Дата%.
Разберем алгоритм реализации этого метода. Мы будем использовать объект Find, который доступен через ActiveDocument.Range().Find. Это позволяет выполнять замену во всем теле документа.
// Открываем шаблон документа
НовыйДок = WordApp.Documents.Add(ПутьКШаблону);
// Получаем объект для поиска
Fnd = WordApp.ActiveDocument.Range().Find;
Fnd.ClearFormatting(); // Очищаем форматирование поиска
// Список параметров для замены (можно использовать СписокЗначений)
Для Счетчик = 1 По СписокПараметров.РазмерСписка() Цикл
ЗначениеЗамены = СписокПараметров.ПолучитьЗначение(Счетчик, ИмяМетки);
// Выполняем замену. Параметр '2' в конце означает 'Replace All' (заменить все)
// Структура метода: Execute(FindText, MatchCase, MatchWholeWord, ..., ReplaceWith, Replace)
Fnd.Execute("[" + ИмяМетки + "]", , , , , , , , , ЗначениеЗамены, 2);
КонецЦикла;
Этот метод хорош тем, что структура документа остается целостной, а метки визуально понятны любому пользователю, редактирующему шаблон.
Если специфика вашей задачи требует использования именно встроенного механизма Word Bookmarks, важно правильно обращаться к диапазону (Range) закладки. Типичная ошибка — использование метода Select(), который перемещает курсор и может приводить к удалению самой закладки после вставки текста.
Проанализируем правильный подход, который сохраняет структуру документа:
// Обращаемся к закладке напрямую через Range
Попытка
ИмяЗакладки = "ДатаДоговора";
ТекстДляВставки = ТекущаяДата();
WordApp.ActiveDocument.Bookmarks(ИмяЗакладки).Range().Text = ТекстДляВставки;
Исключение
Сообщить("Закладка " + ИмяЗакладки + " не найдена в документе!");
КонецПопытки;
Выясним одну важную техническую особенность: метод Find.Execute в Word имеет встроенное ограничение — строка замены (ReplaceWith) не может превышать 255 символов. Если вы попытаетесь вставить длинный текст (например, преамбулу или реквизиты), 1С выдаст ошибку или текст будет обрезан.
Рассмотрим способы решения этой проблемы:
WordApp.Selection.Paste().Execute можно программно найти начало и конец метки в тексте и заменить свойство Text объекта Range, которое не имеет таких жестких ограничений.В реальных задачах, таких как спецификация к договору, количество строк в документе заранее неизвестно. Выясним, как программно расширять таблицы Word из 1С 7.7. Рассмотрим пример заполнения товарной части:
// Допустим, нам нужна первая таблица в документе
Таблица = WordApp.ActiveDocument.Tables(1);
ВыбратьСтроки();
Пока ПолучитьСтроку() = 1 Цикл
// Добавляем новую строку в конец таблицы
НоваяСтрока = Таблица.Rows.Add();
// Заполняем ячейки (Row, Column)
НоваяСтрока.Cells(1).Range.Text = Товар.Наименование;
НоваяСтрока.Cells(2).Range.Text = Количество;
НоваяСтрока.Cells(3).Range.Text = Формат(Цена, "Ч15.2");
КонецЦикла;
Важный момент: Обращение к ячейкам таблицы в Word начинается с 1, а не с 0. Также помните, что создание строк в Word — операция довольно медленная, поэтому для очень больших таблиц (сотни строк) лучше рассмотреть другие методы формирования (например, запись в HTML или XML).
Стандартный поиск через Range().Find часто игнорирует текст, находящийся в верхнем или нижнем колонтитуле (Header/Footer). Чтобы замена произошла везде, проанализируем ситуацию с перебором всех «историй» (StoryRanges) документа.
// Перебор всех частей документа для полной замены
Для НомерИстории = 1 По WordApp.ActiveDocument.StoryRanges.Count() Цикл
ТекущаяИстория = WordApp.ActiveDocument.StoryRanges.Item(НомерИстории);
Пока ТекущаяИстория <> 0 Цикл
ТекущаяИстория.Find.Execute("[Номер]", , , , , , , , , НомерДок, 2);
// Проверяем наличие связанных историй (например, колонтитулы следующей страницы)
ТекущаяИстория = ТекущаяИстория.NextStoryRange;
КонецЦикла;
КонецЦикла;
Чтобы процесс формирования документа выглядел профессионально и не мешал пользователю, стоит придерживаться следующих правил:
WordApp.ScreenUpdating = 0 в начале и 1 в конце. Это значительно ускорит процесс.Visible = 0), пока документ не будет полностью готов.WordApp = 0;. Если вы создавали временный файл, не забудьте вызвать WordApp.Quit(0);, чтобы процесс WINWORD.EXE не остался «висеть» в диспетчере задач.Рассмотрим финальный блок кода, который корректно завершает работу и показывает результат пользователю:
// Показываем результат пользователю
WordApp.Visible = 1;
WordApp.Activate();
// Сохраняем документ (необязательно)
// WordApp.ActiveDocument.SaveAs("C:\Docs\Contract_" + НомерДоговора + ".doc");
// Очищаем переменные 1С
Документ = 0;
WordApp = 0;
Следование этим рекомендациям позволит вам создать надежную и быструю систему формирования документов любой сложности, которая будет стабильно работать даже на старых версиях платформы 1С 7.7.