При переходе с платформы 1С 7.7 на 8.3 многие разработчики сталкиваются с тем, что привычные механизмы прямого управления объектами Microsoft Word через COMСоединение «прячутся» за программными интерфейсами Библиотеки стандартных подсистем (БСП). Одной из частых задач является динамическое изменение оформления текста: например, когда в зависимости от условий определенный пункт договора должен стать жирным или подчеркнутым. В этой статье мы подробно разберем, как реализовать такое поведение, сохранив преимущества использования БСП.
Стандартный механизм заполнения макетов в БСП основан на передаче структуры параметров. Мы подготавливаем ДанныеПечати, и система сама подставляет их в теги вида {v8 ИмяПараметра}. Однако БСП по умолчанию не поддерживает передачу форматирования. Если мы попытаемся передать в параметр объект ФорматированнаяСтрока, система просто преобразует его в обычный текст, и все оформление будет потеряно. Поэтому нам необходимо вмешаться в процесс формирования документа либо на этапе подготовки данных, либо на этапе постобработки готового макета.
Самый гибкий способ — это использование методов VBA Word через COM-соединение, которое предоставляет БСП. При использовании подсистемы УправлениеПечатью, после инициализации печати, мы получаем доступ к объекту приложения Word. Рассмотрим, как это работает программно.
Проанализируем алгоритм: мы находим нужный фрагмент текста в уже заполненном документе и применяем к нему свойства Font.Bold (жирный) и Font.Underline (подчеркивание). Разберем пример функции, которая выполняет поиск и замену с форматированием:
Функция ВыполнитьЗаменуСФорматированием(Знач WordDocument, Параметр, Значение, СделатьЖирным = Ложь)
СтрокаПоиска = "{" + Параметр + "}"; // Или другой маркер, используемый в макете
СтрокаЗамены = Строка(Значение);
// Получаем объект выделения из документа
Selection = WordDocument.Application.Selection;
FindObject = Selection.Find;
// Сбрасываем предыдущие настройки поиска
FindObject.ClearFormatting();
FindObject.Replacement.ClearFormatting();
// Настраиваем параметры поиска
FindObject.Text = СтрокаПоиска;
FindObject.Forward = Истина;
FindObject.Wrap = 1; // wdFindContinue
Пока FindObject.Execute() Цикл
// После успешного выполнения Execute, найденный текст становится выделенным (Selection)
Selection.TypeText(СтрокаЗамены);
// Теперь применяем форматирование к вставленному тексту
// Нужно учитывать, что TypeText заменяет выделение, поэтому для форматирования
// лучше использовать объект Range перед вставкой
Если СделатьЖирным Тогда
Selection.MoveLeft(1, СтрДлина(СтрокаЗамены), 1); // Выделяем вставленный текст обратно
Selection.Font.Bold = -1; // -1 соответствует Истина в COM для Word
Selection.Collapse(0); // wdCollapseEnd - снимаем выделение в конец текста
КонецЕсли;
КонецЦикла;
КонецФункции
Рассмотрим более продвинутый подход. Чтобы не искать каждый параметр по отдельности, мы можем окружить в коде 1С нужные данные специальными символами-маркерами, например, #Текст#. После того как БСП заполнит макет, мы вызываем один универсальный метод поиска по шаблону.
Выясним преимущества этого метода: он позволяет выделять жирным не всю строку, а только конкретную часть данных внутри предложения. Для реализации используем поиск Wildcards (подстановочные знаки):
ДанныеПечати.Вставить("Основание", "#" + ТекстОснования + "#");ЗаполнитьПараметры, вызываем обработчик:
// Пример использования Wildcards через COM
WordApp = ПечатнаяФорма.Handler.COMСоединение.Application;
FindObject = WordApp.Selection.Find;
FindObject.ClearFormatting();
FindObject.Replacement.ClearFormatting();
FindObject.Replacement.Font.Bold = Истина; // Устанавливаем жирный для замены
FindObject.Replacement.Font.Underline = 1; // wdUnderlineSingle
// Маска поиска: ищем текст между знаками #
FindObject.Text = "\#(*)\#";
FindObject.Replacement.Text = "\1"; // Оставляем только текст внутри скобок (первая группа)
FindObject.MatchWildcards = Истина;
FindObject.Execute(,,,,,,,,,, 2); // 2 = wdReplaceAll
Если вариантов оформления немного (например, только два состояния: "Срочный договор" и "Бессрочный"), проанализируем ситуацию с точки зрения архитектуры макета. Иногда проще завести в Word-файле две разные области (строки таблицы или абзацы), одна из которых уже отформатирована как жирная, а вторая — как обычная.
В этом случае мы используем возможности БСП по выводу областей:
ОбластьЖирная и ОбластьОбычная.Этот способ считается наиболее «чистым» с точки зрения БСП, так как он не требует прямого манипулирования COM-объектами, что критично для стабильности работы сервера приложений (особенно в среде Linux, где COM недоступен).
При работе с Word из 1С важно правильно передавать значения свойств. Посмотрим на основные константы, которые могут понадобиться:
-1 для включения и 0 для выключения. Значение 9999998 (wdToggle), часто встречающееся в старых примерах, просто переключает текущее состояние, что может привести к непредсказуемому результату.1 для обычного подчеркивания (wdUnderlineSingle).Selection.Range.HighlightColorIndex = 7 (желтый).Разберем ситуацию, когда печать происходит на сервере без установленного Microsoft Office (используя механизмы OpenXML, доступные в новых версиях БСП). В этом случае методы Selection и Find работать не будут. Если ваша конфигурация работает в облаке или на Linux-сервере, единственным надежным способом форматирования остается использование **нескольких предопределенных областей в макете** с разным оформлением, так как БСП при копировании области сохраняет её стили оформления из файла-шаблона.
Таким образом, выбор метода зависит от ваших технических условий: если гарантирован запуск на Windows-клиенте с установленным Word — используйте COM-поиск; если важна кроссплатформенность — используйте управление областями макета.