При разработке печатных форм в формате Microsoft Word, особенно для коммерческих предложений или официальных бланков, часто возникает задача добавить декоративную рамку по периметру всей страницы. Если вы используете типовые механизмы 1С, такие как Библиотека стандартных подсистем (БСП), вы можете столкнуться с тем, что рамки, настроенные в макете вручную, исчезают при формировании документа. Это происходит из-за того, что БСП копирует области макета в новый (пустой) документ, при этом параметры разделов и настройки страниц часто игнорируются.
В этой статье мы подробно разберем, как программно управлять границами страниц, используя объектную модель Word через COM-соединение, и рассмотрим нюансы работы в разных версиях Microsoft Office.
Прежде чем перейти к коду, выясним причину проблемы. Большинство механизмов печати в 1С (особенно в конфигурациях вроде УТ 11, ERP или БП 3.0) работают по принципу сборки документа из "кирпичиков" — областей макета. Программа создает новый пустой документ ActiveDocument и последовательно копирует в него содержимое из шаблона. Настройки границ страницы (Page Borders) хранятся в свойствах конкретного раздела Section. При копировании текста через буфер обмена или метод InsertXML эти настройки разделов зачастую не переносятся в целевой документ. Следовательно, рамку необходимо накладывать программно уже после того, как весь документ сформирован.
Для того чтобы обвести страницу рамкой, нам нужно обратиться к коллекции Borders первого раздела документа. Рассмотрим базовый алгоритм действий. Нам необходимо перебрать все стороны страницы (верхнюю, нижнюю, левую и правую) и назначить им стиль линии.
Проанализируем пример кода, который можно внедрить в процедуру печати:
// Получаем доступ к COM-объекту Word
oWord = ПечатнаяФорма.COMСоединение;
oDoc = oWord.Documents(1); // Обращаемся к активному документу
// Перебираем коллекции границ раздела
// Индексы границ: 1 - Верх, 2 - Лево, 3 - Низ, 4 - Право
Для НомерГраницы = 1 По 4 Цикл
Граница = oDoc.Sections(1).Borders.Item(НомерГраницы);
Граница.LineStyle = 1; // wdLineStyleSingle (сплошная линия)
Граница.LineWidth = 12; // Толщина линии (значение в пунктах * 4, например 12 = 3 пт)
Граница.Color = 0; // Черный цвет (wdColorBlack)
КонецЦикла;
В этом коде мы используем объект Sections(1), предполагая, что документ состоит из одного раздела. Если ваш документ сложный и содержит разрывы разделов, цикл необходимо будет применить ко всем элементам коллекции Sections.
При программном создании границ важно правильно указать параметры, иначе рамка может либо не отобразиться, либо выглядеть некорректно. Рассмотрим основные свойства объекта Border:
1 — это обычная сплошная линия (wdLineStyleSingle), а значение 19 — двойная тонкая линия (wdLineStyleDouble). Если вы используете Word 2013 или выше, рекомендуется начинать тестирование со значения 1, так как сложные стили могут зависеть от установленных компонентов рендеринга.4 соответствует 0.5 пт, 8 — 1 пт, 24 — 3 пт.0 (wdBorderDistanceFromPageEdge) — от края страницы.1 (wdBorderDistanceFromText) — от текста.Как показывает практика, код, успешно работающий в Word 2010, может давать сбои в более новых версиях. В Word 2013 изменился движок макетирования. Рассмотрим ситуацию, когда рамка применяется не к странице, а к каждому абзацу. Это происходит, если обращаться к коллекции Borders объекта Paragraph вместо Section.
Если рамка не появляется, попробуйте явно вызвать метод применения границ ко всем разделам или переключить режим просмотра документа, чтобы заставить Word перерисовать содержимое:
// Принудительное применение границ ко всем разделам
oDoc.Sections(1).Borders.ApplyPageBordersToAllSections();
// Обновление режима просмотра для корректного отображения
oWord.ActiveWindow.View.Type = 3; // wdPrintView (Режим разметки)
Если манипуляции с Borders не приносят желаемого результата (например, из-за специфических настроек полей в шаблоне БСП), можно воспользоваться более надежным, "дизайнерским" подходом. Мы можем программно нарисовать прямоугольник поверх всей страницы.
Разберем этот метод по шагам:
Shape (прямоугольник) с размерами листа.Пример реализации на языке 1С:
// Определяем параметры страницы (обычно это А4: 595x842 пункта)
ШиринаЛиста = oDoc.PageSetup.PageWidth;
ВысотаЛиста = oDoc.PageSetup.PageHeight;
// Добавляем прямоугольник
Рамка = oDoc.Shapes.AddShape(1, 0, 0, ШиринаЛиста, ВысотаЛиста); // 1 = msoShapeRectangle
Рамка.Fill.Visible = 0; // Прозрачный фон
Рамка.Line.Weight = 2; // Толщина линии контура
Рамка.Line.DashStyle = 1; // Сплошная линия
Рамка.ZOrder(5); // Переместить за текст (msoSendBehindText)
Этот метод гарантирует, что рамка останется на месте независимо от того, как БСП копирует текст, так как графический объект привязывается к координатам страницы.
Выясним, где именно в 1С лучше всего размещать этот код. В типовых решениях (УТ 11, ERP) за печать Word-документов отвечает модуль УправлениеПечатьюКлиент или специализированные менеджеры печати.
Проанализируем алгоритм вставки:
СформироватьПечатнуюФорму.COMСоединение.ПоказатьДокумент.Посмотрим на финальный вид интеграции:
// ... код формирования документа БСП ...
ДанныеПечати = УправлениеПечатью.СформироватьПечатнуюФорму(СсылкаНаМакет, ОбъектыПечати, Параметры);
ПечатнаяФорма = ДанныеПечати.Результат[0];
// Наш блок кастомизации
oWord = ПечатнаяФорма.COMСоединение;
Если oWord <> Неопределено Тогда
Попытка
Документ = oWord.Documents(1);
// Устанавливаем рамку через Borders
Для i = 1 По 4 Цикл
Документ.Sections(1).Borders.Item(i).LineStyle = 1;
Документ.Sections(1).Borders.Item(i).LineWidth = 8;
КонецЦикла;
Исключение
ЗаписьЖурналаРегистрации("Печать.Ошибка", УровеньЖурналаРегистрации.Ошибка, , , ПодробноеОписаниеОшибки());
КонецПопытки;
КонецЕсли;
УправлениеПечатьюКлиент.ПоказатьДокумент(ПечатнаяФорма);
Важный совет: Всегда используйте блоки Попытка...Исключение при работе с COM-объектами. Версии Word у пользователей могут отличаться, и некоторые свойства могут вести себя непредсказуемо. Это предотвратит аварийное завершение работы всей программы 1С при ошибке визуализации рамки.
Подводя итог, можно сказать, что работа с рамками в Word через 1С требует понимания структуры разделов документа. Если стандартная коллекция Borders не срабатывает из-за особенностей механизмов БСП, использование объекта Shape станет отличным альтернативным решением для создания качественных печатных форм.