Как программно заполнить таблицу в Microsoft Word данными из 1С?

Программист 1С v7.7
← На главную

Часто перед разработчиком встает задача формирования печатных форм в формате Microsoft Word. Если заполнение простых параметров (шапки документа) через закладки обычно не вызывает затруднений, то работа с табличными частями требует более детального подхода. Разберем вместе, как организовать перенос данных из 1С в таблицу Word, рассмотрим классические методы и современные способы оптимизации этого процесса.

Метод 1: Прямое управление таблицей через COM-объект

Проанализируем классический подход, который основан на использовании механизма COM-соединения. В этом случае 1С управляет приложением Word.Application как внешним объектом. Рассмотрим пример кода, который позволяет перебрать строки табличной части документа и последовательно заполнить ячейки в Word.

Предположим, у нас уже открыт объект вордовского документа мОбъект. Основная логика заключается в обращении к коллекции Tables. Посмотрим на реализацию:


// Выбираем строки табличной части документа 1С
КоммерческоеПредложение.ВыбратьСтроки();

// Перебираем строки ТЧ в цикле
Для СчетчикЦикла = 1 По КоммерческоеПредложение.КоличествоСтрок() Цикл
    
    // Если это не последняя итерация, добавляем новую строку в таблицу Word
    // мОбъект.Tables(2) указывает на вторую таблицу в документе
    Если (СчетчикЦикла <> КоммерческоеПредложение.КоличествоСтрок()) Тогда
        мОбъект.Tables(2).Rows.Add(мОбъект.Tables(2).Rows(СчетчикЦикла));
    КонецЕсли;
    
    // Получаем текущую строку данных
    КоммерческоеПредложение.ПолучитьСтрокуПоНомеру(СчетчикЦикла);
    
    // Заполняем ячейки (Cell) по номеру колонки
    мОбъект.Tables(2).Cell(СчетчикЦикла, 1).Range.Text = КоммерческоеПредложение.НомерСтроки;
    мОбъект.Tables(2).Cell(СчетчикЦикла, 2).Range.Text = СокрЛП(КоммерческоеПредложение.Номенклатура.ПолнНаименование);
    мОбъект.Tables(2).Cell(СчетчикЦикла, 3).Range.Text = СокрЛП(Формат(КоммерческоеПредложение.Количество, "Ч010.2"));
    мОбъект.Tables(2).Cell(СчетчикЦикла, 4).Range.Text = Строка(КоммерческоеПредложение.Единица);
    мОбъект.Tables(2).Cell(СчетчикЦикла, 5).Range.Text = глФрм(КоммерческоеПредложение.Цена);
    мОбъект.Tables(2).Cell(СчетчикЦикла, 6).Range.Text = глФрм(КоммерческоеПредложение.СуммаНДС);
    мОбъект.Tables(2).Cell(СчетчикЦикла, 7).Range.Text = глФрм(КоммерческоеПредложение.Сумма);
КонецЦикла;

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

Метод 2: Использование шаблонов БСП (для 1С 8.3)

Если вы работаете на современной платформе 1С:Предприятие 8.3, использование прямого COM-управления считается устаревшим. В составе Библиотеки стандартных подсистем (БСП) есть мощный механизм печати по шаблонам .docx. Выясним, как это работает на практике.

Вместо программного перебора ячеек, мы создаем в шаблоне Word специальную Область. Это делается с помощью тегов:

  1. В начале строки таблицы пишем {v8 Область.СтрокаТаблицы}.
  2. В конце строки (в последней ячейке) пишем {/v8 Область.СтрокаТаблицы}.
  3. Внутри ячеек расставляем параметры, например: [Номенклатура], [Количество].

При выполнении кода 1С сама найдет эту область, размножит ее по количеству строк в вашей ТабличнойЧасти и подставит значения. Это избавляет от необходимости следить за индексами ячеек Cell(i, j).

Метод 3: Оптимизация скорости через ConvertToTable

Рассмотрим ситуацию, когда в документе сотни строк. Построчное заполнение через Cell().Range.Text будет работать очень медленно, так как каждое обращение к ячейке — это дорогостоящий вызов через интерфейс COM. Проанализируем способ ускорения процесса в десятки раз.

Суть метода заключается в подготовке всего текста таблицы в виде одной большой строки. Мы разделяем данные колонок символом табуляции Символ(9), а строки — символом перевода строки. После этого вставляем этот текст в Word и вызываем метод ConvertToTable().


// Формируем текстовый блок
ТекстТаблицы = "";
Для Каждого СтрокаТЧ Из Ссылка.Товары Цикл
    ТекстТаблицы = ТекстТаблицы + СтрокаТЧ.Номенклатура + Символ(9) + СтрокаТЧ.Количество + Символ(13);
КонецЦикла;

// Вставляем текст в нужную позицию и конвертируем
Selection = WordApp.Selection;
Selection.TypeText(ТекстТаблицы);
НоваяТаблица = Selection.ConvertToTable(Символ(9));

Этот метод позволяет мгновенно создавать таблицы любого размера, минимизируя количество обращений к объекту Word.

Важные рекомендации при работе на сервере

Выясним причины, по которым код может "зависать" при выполнении на сервере (например, в регламентном задании). При работе с COM-объектами Microsoft Office важно соблюдать следующие правила:

  1. Отключение видимости: Всегда устанавливайте Application.Visible = False. Если Word попытается показать диалоговое окно или ошибку на сервере, процесс заблокируется навсегда, так как нажать кнопку "ОК" некому.
  2. Подавление алертов: Используйте Application.DisplayAlerts = False, чтобы игнорировать предупреждения о совместимости или сохранении.
  3. Обязательное завершение: После формирования документа обязательно вызывайте метод Quit(). В противном случае в диспетчере задач сервера будут скапливаться процессы WINWORD.EXE, которые со временем "съедят" всю оперативную память.
  4. Обработка исключений: Оборачивайте работу с Word в конструкцию Попытка ... Исключение, чтобы в случае ошибки гарантированно закрыть приложение и освободить ресурсы.

Подводя итог, выбор метода зависит от ваших задач. Для простых форм в старых системах подойдет прямое заполнение ячеек. Для современных конфигураций идеальным выбором станет БСП. А если требуется высокая производительность при больших объемах данных — используйте метод ConvertToTable или прямое манипулирование XML-структурой файла (OpenXML).

← На главную