Как реализовать выделение шрифта в макете Word через БСП в 1С 8.3

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

При переходе с платформы 1С 7.7 на 8.3 многие разработчики сталкиваются с тем, что привычные механизмы прямого управления объектами Microsoft Word через COMСоединение «прячутся» за программными интерфейсами Библиотеки стандартных подсистем (БСП). Одной из частых задач является динамическое изменение оформления текста: например, когда в зависимости от условий определенный пункт договора должен стать жирным или подчеркнутым. В этой статье мы подробно разберем, как реализовать такое поведение, сохранив преимущества использования БСП.

Проблема использования стандартных механизмов

Стандартный механизм заполнения макетов в БСП основан на передаче структуры параметров. Мы подготавливаем ДанныеПечати, и система сама подставляет их в теги вида {v8 ИмяПараметра}. Однако БСП по умолчанию не поддерживает передачу форматирования. Если мы попытаемся передать в параметр объект ФорматированнаяСтрока, система просто преобразует его в обычный текст, и все оформление будет потеряно. Поэтому нам необходимо вмешаться в процесс формирования документа либо на этапе подготовки данных, либо на этапе постобработки готового макета.

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

Самый гибкий способ — это использование методов 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 - снимаем выделение в конец текста
        КонецЕсли;
    КонецЦикла;
    
КонецФункции

Способ 2: Метод символьных маркеров (Wildcards)

Рассмотрим более продвинутый подход. Чтобы не искать каждый параметр по отдельности, мы можем окружить в коде 1С нужные данные специальными символами-маркерами, например, #Текст#. После того как БСП заполнит макет, мы вызываем один универсальный метод поиска по шаблону.

Выясним преимущества этого метода: он позволяет выделять жирным не всю строку, а только конкретную часть данных внутри предложения. Для реализации используем поиск Wildcards (подстановочные знаки):

  1. В коде формирования данных добавляем маркеры: ДанныеПечати.Вставить("Основание", "#" + ТекстОснования + "#");
  2. В процедуре печати, после выполнения метода ЗаполнитьПараметры, вызываем обработчик:

// Пример использования 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

Способ 3: Использование областей макета

Если вариантов оформления немного (например, только два состояния: "Срочный договор" и "Бессрочный"), проанализируем ситуацию с точки зрения архитектуры макета. Иногда проще завести в Word-файле две разные области (строки таблицы или абзацы), одна из которых уже отформатирована как жирная, а вторая — как обычная.

В этом случае мы используем возможности БСП по выводу областей:

Этот способ считается наиболее «чистым» с точки зрения БСП, так как он не требует прямого манипулирования COM-объектами, что критично для стабильности работы сервера приложений (особенно в среде Linux, где COM недоступен).

Важные замечания по константам COM

При работе с Word из 1С важно правильно передавать значения свойств. Посмотрим на основные константы, которые могут понадобиться:

Ограничения при работе на стороне сервера

Разберем ситуацию, когда печать происходит на сервере без установленного Microsoft Office (используя механизмы OpenXML, доступные в новых версиях БСП). В этом случае методы Selection и Find работать не будут. Если ваша конфигурация работает в облаке или на Linux-сервере, единственным надежным способом форматирования остается использование **нескольких предопределенных областей в макете** с разным оформлением, так как БСП при копировании области сохраняет её стили оформления из файла-шаблона.

Таким образом, выбор метода зависит от ваших технических условий: если гарантирован запуск на Windows-клиенте с установленным Word — используйте COM-поиск; если важна кроссплатформенность — используйте управление областями макета.

← На главную