При разработке интерфейсов на управляемых формах 1С:Предприятие часто возникает задача вывода динамического текста с разным оформлением (цветами, шрифтами или гиперссылками). Для этих целей используется объект ФорматированнаяСтрока. Однако многие разработчики сталкиваются с неприятной особенностью: при попытке использовать стандартную функцию СтрЗаменить() для подстановки параметров (например, имени клиента) всё визуальное оформление исчезает, и строка превращается в обычный текст.
В этой статье мы подробно разберем, почему так происходит, и изучим несколько способов, позволяющих выполнить замену текста с сохранением всех стилей оформления.
Выясним причину такого поведения платформы. Объект ФорматированнаяСтрока — это не просто массив символов, а сложный объект, содержащий коллекцию элементов, каждый из которых обладает своими свойствами: шрифт, цвет текста, цвет фона и наличие гиперссылки. Когда мы передаем этот объект в функцию СтрЗаменить(), платформа выполняет неявное преобразование типа. Функция ожидает на вход значение типа Строка, поэтому она извлекает из сложного объекта только его текстовое содержимое, отбрасывая все метаданные о стилях. Результатом работы функции всегда является обычная Строка.
Проанализируем ситуацию: поскольку объект ФорматированнаяСтрока является неизменяемым (read-only), мы не можем просто «зайти» внутрь и поменять часть текста. Нам необходимо создать новый объект ФорматированнаяСтрока, собрав его из нужных фрагментов.
Рассмотрим самый надежный и производительный метод. Если шаблон текста заранее известен, мы можем не использовать поиск и замену, а собрать итоговую строку из массива элементов. Конструктор объекта ФорматированнаяСтрока позволяет передавать в него массив, состоящий из обычных строк и других объектов ФорматированнаяСтрока.
Разберем по шагам, как это реализовать в коде:
// Предположим, нам нужно вывести: "Здравствуйте, [ИмяКлиента]! Рады вас видеть."
// При этом "Здравствуйте" должно быть жирным, а Имя - красным.
ЭлементыФорматирования = Новый Массив;
// 1. Добавляем статичную часть с оформлением
ШрифтЖирный = Новый Шрифт(,,Истина);
ЭлементыФорматирования.Добавить(Новый ФорматированнаяСтрока("Здравствуйте, ", ШрифтЖирный));
// 2. Добавляем динамическую часть (параметр) с особым цветом
ЦветИмени = ЦветаСтиля.ОсобыйТекст;
ЭлементыФорматирования.Добавить(Новый ФорматированнаяСтрока(Объект.Клиент, , ЦветИмени));
// 3. Добавляем завершающую часть
ЭлементыФорматирования.Добавить("! Рады вас видеть.");
// 4. Собираем итоговый объект и присваиваем декорации на форме
Элементы.ДекорацияНадпись.Заголовок = Новый ФорматированнаяСтрока(ЭлементыФорматирования);
Этот метод исключает любые ошибки, связанные с потерей данных, так как вы явно контролируете каждый сегмент текста.
Иногда шаблон текста задается пользователем или хранится в макете, и мы не знаем заранее, где именно находится маркер (например, {КЛИЕНТ}). В этом случае нам потребуется написать вспомогательную функцию, которая будет «умно» обходить элементы исходной строки.
Проанализируем алгоритм работы такой функции:
ФорматированнаяСтрока и структуру параметров замены.Элементы исходной строки.ФорматированнаяСтрока.Посмотрим на пример реализации такой логики:
Функция ЗаменитьВФорматированнойСтроке(ИсходнаяФС, ПараметрыЗамены)
РезультатМассив = Новый Массив;
Для Каждого Элемент Из ИсходнаяФС.Элементы Цикл
Если ТипЗнч(Элемент) = Тип("Строка") Тогда
ТекущийТекст = Элемент;
Шрифт = Неопределено;
Цвет = Неопределено;
Иначе
ТекущийТекст = Элемент.Текст;
Шрифт = Элемент.Шрифт;
Цвет = Элемент.ЦветТекста;
КонецЕсли;
Для Каждого КлючИЗначение Из ПараметрыЗамены Цикл
Маркер = "{" + КлючИЗначение.Ключ + "}";
Значение = КлючИЗначение.Значение;
ТекущийТекст = СтрЗаменить(ТекущийТекст, Маркер, Значение);
КонецЦикла;
РезультатМассив.Добавить(Новый ФорматированнаяСтрока(ТекущийТекст, Шрифт, Цвет));
КонецЦикла;
Возврат Новый ФорматированнаяСтрока(РезультатМассив);
КонецФункции
Важный момент: в данном примере упрощено разбиение строки, если маркер находится внутри фрагмента с уникальным стилем. В реальных задачах может потребоваться более детальный разбор строки с использованием СтрНайти, чтобы не применять цвет маркера к окружающему тексту.
Если оформление текста очень сложное (много разных цветов, выравниваний, табличных структур), работа с объектом ФорматированнаяСтрока может стать громоздкой. В таких случаях рассмотрим альтернативу — использование элемента формы типа Поле HTML-документа.
Работа с HTML позволяет обойти ограничения 1С и использовать привычные строковые функции:
HTMLТекст = "<html><body>Привет, <b style='color:red;'>{КЛИЕНТ}</b></body></html>".СтрЗаменить(HTMLТекст, "{КЛИЕНТ}", Объект.Клиент).Этот метод значительно гибче, так как СтрЗаменить() работает с HTML как с обычным текстом, а визуализацию берет на себя встроенный движок браузера платформы.
При работе с форматированными строками следует помнить о нескольких нюансах, которые мы сейчас разберем:
Символы.ПС. Если вы собираете строку из массива, убедитесь, что символы перевода строк корректно добавлены в нужные места, иначе текст «слипнется».Неопределено или NULL, преобразуя их в пустые строки, чтобы избежать падения кода.ФорматированнаяСтрока в цикле (например, в динамическом списке) может быть ресурсоемким. Старайтесь выполнять такие операции только при необходимости обновления интерфейса.Подведем итог: стандартная функция СтрЗаменить() не предназначена для работы со сложными объектами оформления. Для решения задачи используйте либо прямую сборку через массив элементов, либо универсальную функцию-парсер, которая сохранит свойства Шрифт и Цвет для каждого фрагмента вашей надписи.