При формировании печатных форм договоров, коммерческих предложений или соглашений из 1С программисты часто сталкиваются с необходимостью выгрузки данных в формат Microsoft Word (MS Word). Использование COM-объекта позволяет создавать документы высокой сложности. Однако при динамическом создании таблиц часто возникает проблема: все созданные колонки по умолчанию имеют одинаковую ширину, либо текст внутри них отображается некорректно, сжимаясь или съезжая за пределы страницы.
В этой статье мы подробно разберем, как программно управлять размерами колонок таблиц Word из 1С, проанализируем основные ошибки, с которыми сталкиваются разработчики (такие как сбои при вызове метода SetWidth), и рассмотрим альтернативные, более надежные архитектурные подходы к решению этой задачи.
При работе с таблицами Word через COM-соединение стандартные подходы 1С к форматированию табличных документов не работают. Нам приходится напрямую общаться с объектной моделью Microsoft Office VBA. Здесь кроются две главные ловушки для разработчика:
AllowAutoFit.10 через код приводит к тому, что колонка сжимается до микроскопического размера в 3,5 мм, вызывая закономерную ошибку Word «Значение лежит вне допустимого диапазона».Разберем классический способ создания таблицы с нуля и последующего назначения размеров колонок. Чтобы не запутаться в пунктах, мы будем использовать встроенный метод приложения Word CentimetersToPoints, который переводит привычные сантиметры в понятные движку Word единицы измерения.
Рассмотрим пошаговый пример инициализации приложения, создания таблицы и настройки размеров каждой колонки отдельно:
// Инициализируем COM-соединение с Word
Попытка
MSWord = Новый COMОбъект("Word.Application");
Исключение
Предупреждение("Не удалось запустить Microsoft Word. Проверьте установку приложения!");
Возврат;
КонецПопытки;
// Открываем новый документ или макет
Документ = MSWord.Documents.Add();
MSWord.Visible = Истина; // Делаем процесс видимым для отладки
// Определяем позицию вставки таблицы (например, начало документа)
Position = Документ.Range(0, 0);
// Добавляем таблицу: 5 строк, 3 колонки
// Параметры метода Add: (Диапазон, КоличествоСтрок, КоличествоКолонок, ПоведениеАвтоподбора, ПоведениеВыравнивания)
Таблица = Документ.Tables.Add(Position, 5, 3, 1, 2);
// КРИТИЧЕСКИ ВАЖНО: Отключаем автоматический подбор ширины колонок!
Таблица.AllowAutoFit = Ложь;
// Задаем ширину для каждой колонки индивидуально в сантиметрах
// Для этого используем встроенный конвертер приложения CentimetersToPoints
Таблица.Columns(1).Width = MSWord.CentimetersToPoints(2.0); // Номер строки (2 см)
Таблица.Columns(2).Width = MSWord.CentimetersToPoints(4.5); // Артикул товара (4.5 см)
Таблица.Columns(3).Width = MSWord.CentimetersToPoints(10.0); // Наименование товара (10 см)
Обратите внимание на свойство AllowAutoFit. Если установить его в значение Ложь, Word зафиксирует указанные нами размеры колонок и не будет пытаться растягивать их при вставке длинных наименований номенклатуры. Текст просто перенесется на следующую строку внутри ячейки, сохранив общую структуру документа в порядке.
В некоторых версиях MS Office прямое изменение свойства Width для всей колонки может отрабатывать некорректно, если в таблице есть объединенные ячейки. В таких ситуациях более стабильные результаты показывает использование предпочтительной ширины (PreferredWidth). Посмотрим, как применить этот метод в 1С:
// Указываем тип предпочтительной ширины в пунктах (константа wdPreferredWidthPoints = 3)
Таблица.Columns.PreferredWidthType = 3;
// Задаем ширину конкретным колонкам
Таблица.Columns(1).PreferredWidth = MSWord.CentimetersToPoints(1.5);
Таблица.Columns(2).PreferredWidth = MSWord.CentimetersToPoints(3.5);
Многие разработчики пытаются использовать метод SetWidth, заимствуя примеры из VBA-макросов. Синтаксис метода выглядит следующим образом: SetWidth(ColumnWidth, RulerStyle). При его переносе в 1С часто возникает ошибка «Метод объекта не обнаружен» или «Исключительная ситуация: Значение лежит вне допустимого диапазона».
Выясним причину этой проблемы. Второй параметр метода — RulerStyle — определяет, как именно Word должен перестраивать соседние колонки при изменении текущей. Он принимает значения из перечисления WdRulerStyle:
0 (wdAdjustNone) — регулирует только выбранную колонку, не сдвигая остальные.1 (wdAdjustProportional) — пропорционально масштабирует все остальные колонки, сохраняя общую ширину таблицы.2 (wdAdjustFirstColumn) — изменяет только первую колонку справа от изменяемой.3 (wdAdjustSameWidth) — делает все последующие колонки одинаковой ширины.Если вы хотите использовать именно SetWidth, вызов из 1С должен выглядеть следующим образом:
// Изменяем ширину 2-й колонки на 5 см без изменения пропорций остальных
Таблица.Columns(2).SetWidth(MSWord.CentimetersToPoints(5.0), 0);
Важно помнить, что поведение метода SetWidth сильно зависит от общего выравнивания таблицы в документе (по левому краю, по центру или по правому краю). Если таблица выровнена по центру, применение этого метода может дать непредсказуемые результаты верстки. Именно поэтому прямое присвоение свойств Width или PreferredWidth является более предпочтительным и безопасным решением.
Программное создание таблиц с нуля с помощью 1С — это трудоемкий и хрупкий процесс. Вам приходится кодом описывать границы ячеек, настраивать шрифты шапки, указывать цвета заливки, отступы и размеры. Любое изменение в макете со стороны заказчика потребует от вас переписывания десятков строк кода 1С.
Гораздо эффективнее использовать подход, принятый в современных версиях Библиотеки Стандартных Подсистем (БСП):
.docx или .dotx.{Номенклатура}, {Количество}).Проанализируем пример кода, который реализует такой алгоритм работы с готовым макетом:
// Открываем существующий файл шаблона договора
ШаблонПуть = "C:\Templates\ДоговорПоставки.docx";
Документ = MSWord.Documents.Open(ШаблонПуть);
// Предположим, что наша таблица товаров — первая в документе
Таблица = Документ.Tables(1);
// Получаем строку-шаблон (вторая строка таблицы, первая — шапка)
СтрокаШаблон = Таблица.Rows(2);
// Выборка данных из табличной части документа 1С (например, Реализация товаров)
Для Каждого СтрокаТовара Из СсылкаНаДокумент.Товары Цикл
// Создаем новую строку в таблице Word путем копирования существующей
// Это позволяет полностью сохранить все шрифты, границы и ширину колонок!
НоваяСтрока = Таблица.Rows.Add(СтрокаШаблон);
// Заполняем ячейки данными
НоваяСтрока.Cells(1).Range.Text = СтрокаТовара.НомерСтроки;
НоваяСтрока.Cells(2).Range.Text = СтрокаТовара.Номенклатура.Артикул;
НоваяСтрока.Cells(3).Range.Text = СтрокаТовара.Номенклатура.Наименование;
НоваяСтрока.Cells(4).Range.Text = СтрокаТовара.Количество;
НоваяСтрока.Cells(5).Range.Text = СтрокаТовара.Цена;
НоваяСтрока.Cells(6).Range.Text = СтрокаТовара.Сумма;
КонецЦикла;
// Удаляем исходную пустую строку-шаблон, которая использовалась как образец
СтрокаШаблон.Delete();
Преимущества этого метода очевидны: вся визуальная часть настраивается пользователем или аналитиком непосредственно в Word. Программист в 1С отвечает исключительно за логику заполнения ячеек данными, при этом ширина колонок гарантированно останется именно такой, какой ее настроили в шаблоне.
При программном заполнении или создании таблиц часто требуется выровнять текст: например, номера строк и артикулы разместить по центру, наименования — по левому краю, а числовые показатели (цену, количество, сумму) — прижать к правому краю.
Рассмотрим, как управлять выравниванием текста внутри ячеек таблицы Word из 1С.
Горизонтальное выравнивание абзаца: за это отвечает свойство ParagraphFormat.Alignment. Мы можем применить его как к конкретной ячейке, так и ко всей строке или колонке сразу. В качестве значения передаются числовые константы:
0 — выравнивание по левому краю;1 — выравнивание по центру;2 — выравнивание по правому краю;3 — выравнивание по ширине ячейки.Применим эти знания на практике при заполнении строки таблицы:
// Выравниваем шапку таблицы (строка №1) по центру
ШапкаТаблицы = Таблица.Rows(1);
ШапкаТаблицы.Range.ParagraphFormat.Alignment = 1;
// Выравниваем данные в строках
НоваяСтрока.Cells(1).Range.ParagraphFormat.Alignment = 1; // Номер строки — по центру
НоваяСтрока.Cells(3).Range.ParagraphFormat.Alignment = 0; // Наименование — по левому краю
НоваяСтрока.Cells(5).Range.ParagraphFormat.Alignment = 2; // Цена — по правому краю
Вертикальное выравнивание внутри ячейки: чтобы текст красиво располагался ровно посередине ячейки по высоте (особенно при разной высоте строк), используется свойство VerticalAlignment у объекта ячейки:
0 — выравнивание по верхнему краю ячейки;1 — выравнивание строго по центру;3 — выравнивание по нижнему краю ячейки.Пример применения вертикального выравнивания для ячеек строки таблицы:
// Выравниваем текст ячейки по центру по вертикали
ЯчейкаНоменклатуры = НоваяСтрока.Cells(3);
ЯчейкаНоменклатуры.VerticalAlignment = 1;
Комбинируя рассмотренные методы управления шириной колонок, использование готовых шаблонов и настройки позиционирования текста, вы сможете создавать профессионально оформленные печатные формы документов в формате MS Word, которые будут стабильно формироваться из 1С независимо от объема выгружаемых данных.