В процессе разработки на платформе 1С:Предприятие 8.3 часто возникает задача не просто найти текст, но и визуально акцентировать внимание пользователя на всех найденных вхождениях сразу. Стандартное текстовое поле ввода, к которому мы привыкли, имеет существенные архитектурные ограничения. В этой статье мы подробно разберем, почему штатные методы не всегда подходят, и изучим альтернативные способы реализации множественной подсветки текста.
Начнем с анализа стандартного поведения платформы. Для работы с выделением в 1С существует метод УстановитьГраницыВыделения(). Рассмотрим его синтаксис:
Элементы.ИмяПоляВвода.УстановитьГраницыВыделения(НачалоСтроки, НачалоКолонки, КонецСтроки, КонецКолонки);
Проанализируем ситуацию: данный метод физически перемещает фокус выделения на один конкретный фрагмент текста. Если вы попытаетесь вызвать этот метод в цикле для разных подстрок, вы обнаружите, что в поле останется выделенным только последний найденный фрагмент. Платформа 1С на уровне системных компонентов Windows/Linux (в зависимости от клиента) не поддерживает «разрывное» выделение в обычном текстовом редакторе. Поэтому для решения нашей задачи нам придется использовать другие типы элементов управления.
Это самый гибкий и мощный способ. Поле HTML-документа позволяет отображать текст с использованием любых стилей CSS. Мы можем обернуть каждое вхождение искомой подстроки в HTML-тег <span> или <div> с заданным цветом фона.
Разберем по шагам, как подготовить такой текст. Предположим, у нас есть исходная строка и массив искомых слов. Нам нужно заменить вхождения слов на те же слова, но оформленные стилями.
Функция ПодсветитьТекстHTML(ИсходныйТекст, МассивПодстрок)
Результат = ИсходныйТекст;
Для Каждого Подстрока Из МассивПодстрок Цикл
Стиль = "background-color: #F7EBCC; color: #66BC29; font-weight: bold;";
Замена = "<span style=""" + Стиль + """>" + Подстрока + "</span>";
Результат = СтрЗаменить(Результат, Подстрока, Замена);
КонецЦикла;
// Оборачиваем в базовые теги HTML
Возврат "<html><body><pre>" + Результат + "</pre></body></html>";
КонецФункции
Важный нюанс: использование СтрЗаменить напрямую может быть опасным, если искомая подстрока совпадает с частями HTML-тегов. В профессиональных решениях рекомендуется использовать регулярные выражения VBScript.RegExp для точного поиска без повреждения структуры разметки.
Кроме того, в поле HTML можно встроить JavaScript. Рассмотрим подробнее: вы можете передать в поле чистый текст и массив слов, а поиск и раскрашивание выполнить на стороне JS. Это значительно ускорит работу интерфейса при работе с большими объемами данных.
Объект ФорматированныйДокумент предназначен специально для работы с текстом, имеющим оформление. В отличие от HTML-поля, он более «родной» для 1С, хотя и хранит данные в своем внутреннем формате.
Проанализируем, как это работает программно. Вы не можете просто вызвать метод «подсветить», вам нужно пересобрать документ из фрагментов. Документ состоит из коллекции Элементы. Мы можем итерировать по тексту, находить нужные фрагменты и добавлять их в документ, устанавливая свойства шрифта и цвета для каждого фрагмента отдельно.
// Пример логики работы с ФорматированнымДокументом
ФД = Новый ФорматированныйДокумент;
// Текст разбивается на части: до выделения, само выделение, после него
ТекстДляДобавления = "Найденный товар: Телевизор на складе";
Фрагмент = Новый ФорматированнаяСтрока("Телевизор", , WebЦвета.Красный, WebЦвета.Желтый);
// Далее части собираются в общий документ
Преимущество этого метода в том, что поле остается редактируемым, и пользователь может продолжать вводить текст, при этом оформление фрагментов сохранится.
Если ваша задача — просто вывести текст с подсветкой (без возможности редактирования пользователем), лучше всего подойдет ФорматированнаяСтрока. Она идеально работает в элементах типа «Декорация-надпись».
Посмотрим на пример из практики:
Элементы.НадписьРезультат.Заголовок = Новый ФорматированнаяСтрока(
"Результат поиска: ",
Новый ФорматированнаяСтрока("Объект №1", , WebЦвета.Зеленый),
", ",
Новый ФорматированнаяСтрока("Объект №2", , WebЦвета.Красный)
);
С помощью конструктора Новый ФорматированнаяСтрока мы можем соединять обычные строки и оформленные фрагменты в одну цепочку. Это выглядит очень аккуратно и не требует тяжеловесного HTML-движка.
Выясним причину, почему иногда выбирают ТабличныйДокумент. Если текст представляет собой лог или отчет, где важно сохранять структуру колонок и строк, табличный документ позволяет раскрашивать фон каждой ячейки (Область.ЦветФона) или даже отдельные символы в ячейке, используя расширение для работы с текстом. Это позволяет имитировать выделение как в текстовом редакторе, сохраняя при этом возможность выделения всей строки или копирования данных в Excel.
Чтобы эффективно реализовать любое из вышеперечисленных решений, нам нужно сначала найти все координаты (индексы) вхождений подстрок. Лучше всего для этого использовать объект VBScript.RegExp через COM-соединение.
Разберем пример получения всех вхождений:
RegExp = Новый COMОбъект("VBScript.RegExp");
RegExp.IgnoreCase = Истина;
RegExp.Global = Истина;
RegExp.Pattern = "ИскомоеСлово";
Matches = RegExp.Execute(ИсходныйТекст);
Для Каждого Match Из Matches Цикл
// Match.FirstIndex - позиция начала
// Match.Length - длина вхождения
Сообщить("Найдено на позиции: " + Match.FirstIndex);
КонецЦикла;
Зная точные индексы всех вхождений, вы можете легко реализовать алгоритм «разрезания» строки на части для ФорматированнойСтроки или вставки HTML-тегов в нужные места.
Подведем итог нашему анализу:
ФорматированнаяСтрока в декорациях.ФорматированныйДокумент.Выбор конкретного метода зависит от требований к производительности и необходимости дальнейшего редактирования текста пользователем. Помните, что стандартное поле ввода 1С предназначено для ввода данных, а не для сложной визуализации результатов поиска.