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

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

При формировании печатных форм и отчетов во внешних файлах Microsoft Word нередко возникает задача динамического создания таблиц. Например, когда строки табличной части документа необходимо сгруппировать по датам или подразделениям, выводя для каждой группы отдельную таблицу с собственным заголовком и параметрами форматирования.

Разберем подробно, как реализовать такую логику через механизм COM-соединения, настроить параметры ширины колонок, выравнивание текста и избежать типичных ошибок при позиционировании элементов.

Подключение к Word и последовательное добавление текста и таблиц

Частая ошибка при работе с объектом Word.Application — активное использование объекта Selection. При вставке новых блоков курсор может смещаться в начало документа или приводить к непредвиденному наложению текста. Чтобы элементы выводились строго друг за другом, надежнее управлять диапазонами с помощью объекта Range.

Рассмотрим по шагам алгоритм последовательного добавления заголовка и таблицы в конец документа:

  1. Инициализируем COM-объект и открываем документ или создаем его на базе макета.
  2. Определяем позицию в конце содержимого через свойство Content.End.
  3. Вставляем текст заголовка с переводом строки.
  4. Создаем таблицу в новой конечной позиции и заполняем ячейки данными.

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


// Создание COM-объекта Word
Ворд = Новый COMОбъект("Word.Application");
Ворд.Visible = Ложь;

Документ = Ворд.Documents.Add();

// Добавление текстового заголовка в конец документа
ПозицияТекста = Документ.Range(Документ.Content.End - 1, Документ.Content.End - 1);
ПозицияТекста.InsertAfter("Дата дежурства: 15.10.2023 (с 09:00 до 18:00)" + Символы.ПС);

// Определение новой позиции вставки для таблицы
ПозицияТаблицы = Документ.Range(Документ.Content.End - 1, Документ.Content.End - 1);
ЧислоСтрок = 3;
ЧислоКолонок = 4;
Таблица = Документ.Tables.Add(ПозицияТаблицы, ЧислоСтрок, ЧислоКолонок);

Форматирование таблицы: ширина колонок и выравнивание

После добавления таблицы требуется задать читаемый вид: настроить ширину столбцов, а также горизонтальное и вертикальное выравнивание данных внутри ячеек.

Проанализируем основные свойства форматирования:

  1. Ширина колонок: управляется через свойство PreferredWidth для каждого столбца коллекции Columns.
  2. Горизонтальное выравнивание: задается через ParagraphFormat.Alignment. Значение 1 соответствует выравниванию по центру, 0 — по левому краю, 2 — по правому краю, 3 — по ширине.
  3. Вертикальное выравнивание в ячейках: настраивается через свойство VerticalAlignment конкретной ячейки Cell или всего диапазона Cells. Константы: 0 — по верхнему краю, 1 — по центру, 3 — по нижнему краю.

Посмотрим на пример настройки созданной таблицы:


// Горизонтальное выравнивание всего текста таблицы по центру
Таблица.Range.ParagraphFormat.Alignment = 1;

// Вертикальное выравнивание во всех ячейках по центру
Таблица.Range.Cells.VerticalAlignment = 1;

// Установка ширины конкретных колонок (в пунктах)
Таблица.Columns(1).PreferredWidth = 40;  // № п/п
Таблица.Columns(2).PreferredWidth = 180; // ФИО сотрудника
Таблица.Columns(3).PreferredWidth = 100; // Должность
Таблица.Columns(4).PreferredWidth = 80;  // Часы

// Заполнение ячейки шапки
Ячейка = Таблица.Cell(1, 1);
Ячейка.Range.Text = "№";
Ячейка.Range.Bold = Истина;

Группировка данных из запроса и вывод нескольких таблиц

Если требуется сформировать динамическое количество таблиц (например, отдельная таблица на каждую дату), данные из табличной части документа удобно предварительно сгруппировать запросом с помощью конструкции ИТОГИ ПО.

Разберем пример обхода группировок запроса:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	ТЧ.ДатаВыхода КАК ДатаВыхода,
    |	ТЧ.НомерСтроки КАК НомерСтроки,
    |	ТЧ.Сотрудник.Наименование КАК Сотрудник,
    |	ТЧ.ЧасыРаботы КАК ЧасыРаботы
    |ИЗ
    |	Документ.ГрафикДежурств.Состав КАК ТЧ
    |ГДЕ
    |	ТЧ.Ссылка = &Ссылка
    |ИТОГИ ПО
    |	ДатаВыхода";

Запрос.УстановитьПараметр("Ссылка", ДокументСсылка);
РезультатЗапроса = Запрос.Выполнить();

ВыборкаПоДатам = РезультатЗапроса.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);

Пока ВыборкаПоДатам.Следующий() Цикл
    
    // 1. Вставляем заголовок группы
    ПозицияЗаголовка = Документ.Range(Документ.Content.End - 1, Документ.Content.End - 1);
    ПозицияЗаголовка.InsertAfter("Дата: " + Формат(ВыборкаПоДатам.ДатаВыхода, "ДФ=dd.MM.yyyy") + Символы.ПС);
    
    // 2. Создаем таблицу для текущей даты
    ПозицияТаблицы = Документ.Range(Документ.Content.End - 1, Документ.Content.End - 1);
    КоличествоСтрок = ВыборкаПоДатам.Количество() + 1; // +1 для строки заголовков
    Таблица = Документ.Tables.Add(ПозицияТаблицы, КоличествоСтрок, 3);
    
    // Заполняем шапку
    Таблица.Cell(1, 1).Range.Text = "№";
    Таблица.Cell(1, 2).Range.Text = "Сотрудник";
    Таблица.Cell(1, 3).Range.Text = "Часы";
    
    // 3. Заполняем строки детальными записями
    ВыборкаДетали = ВыборкаПоДатам.Выбрать();
    ИндексСтроки = 2;
    
    Пока ВыборкаДетали.Следующий() Цикл
        Таблица.Cell(ИндексСтроки, 1).Range.Text = Строка(ВыборкаДетали.НомерСтроки);
        Таблица.Cell(ИндексСтроки, 2).Range.Text = Строка(ВыборкаДетали.Сотрудник);
        Таблица.Cell(ИндексСтроки, 3).Range.Text = Строка(ВыборкаДетали.ЧасыРаботы);
        ИндексСтроки = ИндексСтроки + 1;
    КонецЦикла;
    
    // Добавляем отступ после таблицы
    ПозицияОтступа = Документ.Range(Документ.Content.End - 1, Документ.Content.End - 1);
    ПозицияОтступа.InsertAfter(Символы.ПС);
    
КонецЦикла;

Важные особенности и альтернативные решения

При использовании COM-объекта Word.Application важно учитывать следующие технические ограничения:

  1. Зависимость от операционной системы: COM-вызовы работают только под управлением ОС Windows и требуют установленного пакета Microsoft Office.
  2. Очистка памяти: в конце работы с COM-объектом обязательно выполняйте сохранение/закрытие документа и вызов метода Ворд.Quit(), а также очистку переменных (Ворд = Неопределено;), чтобы исключить зависание фоновых процессов WINWORD.EXE.
  3. Производительность: заполнение больших таблиц через COM происходит медленно из-за межпроцессного взаимодействия. Если документ содержит сотни строк, целесообразно рассмотреть альтернативный вариант — формирование стандартного объекта ТабличныйДокумент в 1С с последующим сохранением в формате DOCX с помощью метода ТабличныйДокумент.Записать("файл.docx", ТипФайлаТабличногоДокумента.DOCX);, что работает на сервере быстрее и без установки MS Office.
← На главную