Как заменить текст в ФорматированнойСтроке, сохранив оформление?

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

При разработке интерфейсов на управляемых формах 1С:Предприятие часто возникает задача вывода динамического текста с разным оформлением (цветами, шрифтами или гиперссылками). Для этих целей используется объект ФорматированнаяСтрока. Однако многие разработчики сталкиваются с неприятной особенностью: при попытке использовать стандартную функцию СтрЗаменить() для подстановки параметров (например, имени клиента) всё визуальное оформление исчезает, и строка превращается в обычный текст.

В этой статье мы подробно разберем, почему так происходит, и изучим несколько способов, позволяющих выполнить замену текста с сохранением всех стилей оформления.

Почему СтрЗаменить() «ломает» форматирование?

Выясним причину такого поведения платформы. Объект ФорматированнаяСтрока — это не просто массив символов, а сложный объект, содержащий коллекцию элементов, каждый из которых обладает своими свойствами: шрифт, цвет текста, цвет фона и наличие гиперссылки. Когда мы передаем этот объект в функцию СтрЗаменить(), платформа выполняет неявное преобразование типа. Функция ожидает на вход значение типа Строка, поэтому она извлекает из сложного объекта только его текстовое содержимое, отбрасывая все метаданные о стилях. Результатом работы функции всегда является обычная Строка.

Проанализируем ситуацию: поскольку объект ФорматированнаяСтрока является неизменяемым (read-only), мы не можем просто «зайти» внутрь и поменять часть текста. Нам необходимо создать новый объект ФорматированнаяСтрока, собрав его из нужных фрагментов.

Способ №1: Программная сборка из частей (Конструктор)

Рассмотрим самый надежный и производительный метод. Если шаблон текста заранее известен, мы можем не использовать поиск и замену, а собрать итоговую строку из массива элементов. Конструктор объекта ФорматированнаяСтрока позволяет передавать в него массив, состоящий из обычных строк и других объектов ФорматированнаяСтрока.

Разберем по шагам, как это реализовать в коде:


// Предположим, нам нужно вывести: "Здравствуйте, [ИмяКлиента]! Рады вас видеть."
// При этом "Здравствуйте" должно быть жирным, а Имя - красным.

ЭлементыФорматирования = Новый Массив;

// 1. Добавляем статичную часть с оформлением
ШрифтЖирный = Новый Шрифт(,,Истина);
ЭлементыФорматирования.Добавить(Новый ФорматированнаяСтрока("Здравствуйте, ", ШрифтЖирный));

// 2. Добавляем динамическую часть (параметр) с особым цветом
ЦветИмени = ЦветаСтиля.ОсобыйТекст;
ЭлементыФорматирования.Добавить(Новый ФорматированнаяСтрока(Объект.Клиент, , ЦветИмени));

// 3. Добавляем завершающую часть
ЭлементыФорматирования.Добавить("! Рады вас видеть.");

// 4. Собираем итоговый объект и присваиваем декорации на форме
Элементы.ДекорацияНадпись.Заголовок = Новый ФорматированнаяСтрока(ЭлементыФорматирования);

Этот метод исключает любые ошибки, связанные с потерей данных, так как вы явно контролируете каждый сегмент текста.

Способ №2: Универсальная функция замены в ФорматированнойСтроке

Иногда шаблон текста задается пользователем или хранится в макете, и мы не знаем заранее, где именно находится маркер (например, {КЛИЕНТ}). В этом случае нам потребуется написать вспомогательную функцию, которая будет «умно» обходить элементы исходной строки.

Проанализируем алгоритм работы такой функции:

  1. Функция принимает исходную ФорматированнаяСтрока и структуру параметров замены.
  2. Мы перебираем коллекцию Элементы исходной строки.
  3. Для каждого текстового фрагмента проверяем наличие вхождений наших маркеров.
  4. Если маркер найден, мы разбиваем фрагмент, вставляем значение параметра и сохраняем исходные настройки оформления (шрифт, цвет) для новых частей.
  5. Все части собираются в новый массив, на основе которого создается результирующая ФорматированнаяСтрока.

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


Функция ЗаменитьВФорматированнойСтроке(ИсходнаяФС, ПараметрыЗамены)
    
    РезультатМассив = Новый Массив;
    
    Для Каждого Элемент Из ИсходнаяФС.Элементы Цикл
        
        Если ТипЗнч(Элемент) = Тип("Строка") Тогда
            ТекущийТекст = Элемент;
            Шрифт = Неопределено;
            Цвет  = Неопределено;
        Иначе
            ТекущийТекст = Элемент.Текст;
            Шрифт = Элемент.Шрифт;
            Цвет  = Элемент.ЦветТекста;
        КонецЕсли;
        
        Для Каждого КлючИЗначение Из ПараметрыЗамены Цикл
            Маркер = "{" + КлючИЗначение.Ключ + "}";
            Значение = КлючИЗначение.Значение;
            ТекущийТекст = СтрЗаменить(ТекущийТекст, Маркер, Значение);
        КонецЦикла;
        
        РезультатМассив.Добавить(Новый ФорматированнаяСтрока(ТекущийТекст, Шрифт, Цвет));
        
    КонецЦикла;
    
    Возврат Новый ФорматированнаяСтрока(РезультатМассив);
    
КонецФункции

Важный момент: в данном примере упрощено разбиение строки, если маркер находится внутри фрагмента с уникальным стилем. В реальных задачах может потребоваться более детальный разбор строки с использованием СтрНайти, чтобы не применять цвет маркера к окружающему тексту.

Способ №3: Использование Поля HTML-документа

Если оформление текста очень сложное (много разных цветов, выравниваний, табличных структур), работа с объектом ФорматированнаяСтрока может стать громоздкой. В таких случаях рассмотрим альтернативу — использование элемента формы типа Поле HTML-документа.

Работа с HTML позволяет обойти ограничения 1С и использовать привычные строковые функции:

  1. Создаем строковую переменную с HTML-кодом: HTMLТекст = "<html><body>Привет, <b style='color:red;'>{КЛИЕНТ}</b></body></html>".
  2. Используем стандартную функцию СтрЗаменить(HTMLТекст, "{КЛИЕНТ}", Объект.Клиент).
  3. Присваиваем результат пути к данным поля HTML-документа.

Этот метод значительно гибче, так как СтрЗаменить() работает с HTML как с обычным текстом, а визуализацию берет на себя встроенный движок браузера платформы.

Рекомендации и нюансы

При работе с форматированными строками следует помнить о нескольких нюансах, которые мы сейчас разберем:

Подведем итог: стандартная функция СтрЗаменить() не предназначена для работы со сложными объектами оформления. Для решения задачи используйте либо прямую сборку через массив элементов, либо универсальную функцию-парсер, которая сохранит свойства Шрифт и Цвет для каждого фрагмента вашей надписи.

← На главную