Как динамически заполнять таблицы в шаблонах Word (DOCX) из 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

В практике разработчика 1С часто возникает задача формирования печатных форм в формате MS Word. Обычно это связано с тем, что заказчик или контролирующие органы принимают отчеты строго по определенному вордовскому шаблону, в котором должно сохраняться сложное форматирование текста (выделение отдельных слов жирным шрифтом внутри одной ячейки, подчеркивание, индивидуальные стили границ). Если шапка и подвал документа статичны, то табличная часть отчета почти всегда динамическая: в одном месяце может быть 5 строк с услугами, а в другом — 50.

В этой статье мы подробно рассмотрим, как решить задачу формирования динамических таблиц в документах Word. Мы разберем классические методы работы через COM-соединение (ActiveDocument), а также современные, более стабильные и кроссплатформенные альтернативы, такие как шаблоны БСП, HTML-макеты и прямая модификация XML-структуры файла.

---

Решение 1: Шаблоны БСП (Библиотека стандартных подсистем) — современный стандарт без COM

Если ваша конфигурация построена на базе БСП (версии 3.0 и выше), у вас уже есть готовый мощный инструмент для работы с офисными документами. Этот метод полностью заменяет устаревший и нестабильный ActiveDocument и решает главную проблему COM-технологий — зависимость от операционной системы Windows и обязательной установки MS Office на сервере (что особенно критично для серверов 1С на операционной системе Linux). Для быстрого старта можно использовать готовый шаблон внешней печатной формы для БСП 3.1, который позволяет выводить данные без COM-соединения.

Как это работает по шагам:

  1. Создайте макет в формате .docx.
  2. Для вывода динамических таблиц в самом шаблоне разметка областей делается с помощью специального синтаксиса в квадратных скобках. Например, строка таблицы, которую нужно размножить, помечается как [ИмяОбласти.ИмяПараметра].
  3. В коде 1С мы инициализируем макет через функции общего модуля БСП и в цикле выводим строки, передавая структуру данных. Платформа сама клонирует строки таблицы внутри файла и заменяет параметры.

Рассмотрим пример программной реализации вывода таблицы услуг с помощью БСП:


// Получаем макет из общих макетов или макетов объекта
МакетОфисногоДокумента = УправлениеПечатью.ИнициализироватьМакетОфисногоДокумента(ПолучитьМакет("МойШаблонDocx"), "DOCX");

ДанныеДокумента = Новый Структура;
ДанныеДокумента.Вставить("НомерДоговора", "123-Ф");
ДанныеДокумента.Вставить("ДатаДоговора", Формат(ТекущаяДата(), "ДЛФ=DD"));

// Создаем массив структур для табличной части
ТаблицаУслуг = Новый Массив;

Для Каждого СтрокаВыборки Из РезультатЗапроса Цикл
    СтрокаТаблицы = Новый Структура;
    СтрокаТаблицы.Вставить("НомерСтроки", СтрокаВыборки.НомерСтроки);
    СтрокаТаблицы.Вставить("Наименование", СтрокаВыборки.Услуга);
    СтрокаТаблицы.Вставить("Сумма", СтрокаВыборки.Сумма);
    ТаблицаУслуг.Добавить(СтрокаТаблицы);
КонецЦикла;

// Связываем массив строк с областью таблицы в шаблоне
ДанныеДокумента.Вставить("СтрокаТаблицыУслуг", ТаблицаУслуг);

// Формируем печатную форму
ПечатныйДокумент = УправлениеПечатью.СформироватьДокумент(МакетОфисногоДокумента, ДанныеДокумента);
УправлениеПечатью.ОчиститьВременныеФайлы(МакетОфисногоДокумента);

Преимущества метода: Полная кроссплатформенность, высокая скорость генерации, стабильная работа на сервере под управлением Linux, отсутствие зависших процессов winword.exe в диспетчере задач. Если вам необходимо реализовать аналогичный механизм на более старых версиях систем, подойдёт шаблон внешней печатной формы для печати в Word под БСП 2.2.

---

Решение 2: Использование COM-объекта (ActiveDocument)

Если вам необходимо работать напрямую через MS Word на Windows-клиенте, мы можем использовать COM-соединение. При работе с таблицами через COM-объект разработчики обычно используют два основных подхода.

Вариант А: Прямая вставка строк через объектную модель Tables

Мы открываем документ, находим нужную таблицу по ее индексу и программно добавляем строки методом Add(), после чего заполняем ячейки по индексам строк и колонок.

Проанализируем пример кода:


Попытка
    WordApp = Новый COMОбъект("Word.Application");
Исключение
    Сообщить("Не удалось запустить MS Word. Проверьте установку приложения.");
    Возврат;
КонецПопытки;

WordApp.Visible = Ложь; // Скрываем окно программы от пользователя
ПутьКШаблону = "C:\Templates\ReportTemplate.docx";
Документ = WordApp.Documents.Open(ПутьКШаблону);

// Предположим, что таблица для заполнения — первая в документе
Таблица = Документ.Tables(1);

НомерСтрокиВорда = 2; // Предположим, что первая строка — это шапка таблицы
Для Каждого СтрокаДанных Из ТЗ_Данные Цикл
    // Добавляем новую строку в таблицу Word
    НоваяСтрока = Таблица.Rows.Add();
    
    // Заполняем ячейки данными
    НоваяСтрока.Cells(1).Range.Text = СтрокаДанных.НомерСтроки;
    НоваяСтрока.Cells(2).Range.Text = СтрокаДанных.НаименованиеУслуги;
    НоваяСтрока.Cells(3).Range.Text = СтрокаДанных.Сумма;
    
    НомерСтрокиВорда = НомерСтрокиВорда + 1;
КонецЦикла;

// Сохраняем результат и закрываем Word
Документ.SaveAs("C:\Reports\ReadyReport.docx");
Документ.Close();
WordApp.Quit();

Важная деталь: При добавлении строк через Rows.Add() Word автоматически копирует форматирование предыдущей строки, но сложные стили (например, чередующаяся заливка строк разным цветом) могут отображаться некорректно.

Вариант Б: Метод копирования шаблонной строки (через буфер обмена)

Чтобы гарантированно сохранить сложное форматирование и структуру ячеек таблицы, мы можем оставить в шаблоне ровно одну строку с параметрами-маркерами (например, [Услуга], [Цена]). В коде 1С мы программно выделяем эту строку, копируем ее в буфер обмена, а затем в цикле вставляем нужное количество раз. После вставки мы выполняем автозамену параметров на реальные значения в каждой вставленной строке.

Разберем этот алгоритм концептуально:

  1. Найти в документе строку-шаблон с ключевыми словами.
  2. Выделить строку средствами VBA: Selection.SelectRow().
  3. Скопировать в буфер обмена: Selection.Copy().
  4. В цикле выполнять вставку строки: Selection.Paste().
  5. Вызывать метод автозамены текста Find.Execute() в рамках текущей выделенной строки для заполнения параметров.

---

Решение 3: Верстка шаблона в HTML — альтернатива без COM

Интересной альтернативой, предложенной участниками форума, является использование HTML-шаблонов. Текстовый процессор Word отлично открывает HTML-файлы, сохраняя стили CSS и разметку таблиц.

Как реализовать этот подход:

  1. Создайте нужный документ в MS Word, добавьте таблицу, настройте рамки и шрифты.
  2. Сохраните документ из Word в формате "Веб-страница (html)".
  3. Загрузите полученный HTML-код в макет 1С с типом "Текстовый документ". Несмотря на то, что Word генерирует избыточный HTML-код, оптимизировать его вручную не обязательно — мы можем использовать его "как есть".
  4. Найдите в коде тег строки таблицы <tr>, которая выступает шаблоном. Замените ее содержимое на маркеры автозамены.
  5. В коде 1С мы просто считываем HTML-шаблон, в цикле дублируем строку таблицы, подставляя наши данные, и сохраняем файл с расширением .doc или .html.

Посмотрим на пример заполнения HTML-шаблона:


ТекстШаблона = ПолучитьМакет("НашHTMLШаблон").ПолучитьТекст();

// Выделяем шаблон строки таблицы
ШаблонСтроки = "<tr><td>[Номер]</td><td>[Услуга]</td><td>[Сумма]</td></tr>";
СтрокиТаблицыHTML = "";

НомерСтр = 1;
Для Каждого Строка Из ТаблицаУслуг Цикл
    ТекущаяСтрока = СтрЗаменить(ШаблонСтроки, "[Номер]", Строка(НомерСтр));
    ТекущаяСтрока = СтрЗаменить(ТекущаяСтрока, "[Услуга]", Строка.Наименование);
    ТекущаяСтрока = СтрЗаменить(ТекущаяСтрока, "[Сумма]", Строка.Сумма);
    
    СтрокиТаблицыHTML = СтрокиТаблицыHTML + ТекущаяСтрока;
    НомерСтр = НомерСтр + 1;
КонецЦикла;

// Вставляем сгенерированные строки в общую структуру HTML-документа
ИтоговыйHTML = СтрЗаменить(ТекстШаблона, "[ТабличнаяЧасть]", СтрокиТаблицыHTML);

// Записываем файл на диск
ТекстовыйФайл = Новый ТекстовыйДокумент;
ТекстовыйФайл.УстановитьТекст(ИтоговыйHTML);
ТекстовыйФайл.Записать("C:\Reports\Report.doc", КодировкаТекста.UTF8);

Преимущества метода: Метод работает невероятно быстро, не требует установленного MS Office на компьютере и стабильно функционирует в веб-клиенте и на серверах Linux. При открытии файла .doc, созданного таким образом, Word автоматически отобразит его в привычном для пользователя виде.

---

Решение 4: Экспорт из Табличного документа 1С (MXL) в формат DOCX

Если требования к оформлению документа жесткие, но вам не хочется тратить время на программирование COM-объектов Word или разборку тегов HTML, существует самый простой и надежный обходной путь:

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

Посмотрим на пример кода сохранения:


ТабДок = Новый ТабличныйДокумент;
// ... Код стандартного заполнения ТабДока данными из макета MXL ...

// Сохраняем готовый результат напрямую в формат Word (.docx)
ТабДок.Записать("C:\Reports\ReadyReport.docx", ТипФайлаТабличногоДокумента.Docx);

Преимущества метода: Разработка макета занимает минимум времени, отладка печатной формы происходит стандартно и привычно для любого программиста 1С, гарантирована 100% стабильность работы серверного кода без зависаний стороннего ПО.

---

Резюме и рекомендации

Выбор оптимального метода зависит от архитектуры вашей информационной системы:

← На главную