Как заменить или проигнорировать символы в строках внутри языка запросов 1С?

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

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

Способ 1. Использование оператора ПОДОБНО в языке запросов

Если требуется найти документ по нескольким ключевым словам или фрагментам текста, не обращая внимания на количество пробелов и спецсимволов между ними, наилучшим решением в самом запросе является оператор ПОДОБНО с шаблоном поиска.

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

Разберем по шагам пример формирования запроса:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	Продажа.Ссылка КАК Ссылка,
    |	Продажа.Комментарий КАК Комментарий
    |ИЗ
    |	Документ.РеализацияТоваровУслуг КАК Продажа
    |ГДЕ
    |	Продажа.Комментарий ПОДОБНО &ШаблонПоиска";

Запрос.УстановитьПараметр("ШаблонПоиска", "%слово1%слово2%слово3%");
РезультатЗапроса = Запрос.Выполнить();

При таком подходе СУБД успешно найдет все документы, в комментарии которых последовательно встречаются указанные ключевые слова, независимо от наличия между ними лишних пробелов или символов перевода строки.

Способ 2. Использование функции СтрЗаменить() в языке запросов (начиная с платформы 8.3.20)

Проанализируем современные возможности платформы. Начиная с версии 8.3.20, в язык запросов 1С была официально добавлена встроенная функция СтрЗаменить(), а также функции СокрЛ(), СокрП(), СокрЛП(), СтрНайти(), ВРег(), НРег() и ДлинаСтроки().

Поиск подстроки внутри СтрЗаменить() в языке запросов выполняется без учета регистра. Если требуется удалить символы перевода строки или пробелы непосредственно в тексте запроса, их можно передать через параметры запроса:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	Док.Ссылка КАК Ссылка
    |ИЗ
    |	Документ.РеализацияТоваровУслуг КАК Док
    |ГДЕ
    |	СтрЗаменить(СтрЗаменить(Док.Комментарий, &Пробел, """"), &СимволПС, """") ПОДОБНО &ИскомыйТекст";

Запрос.УстановитьПараметр("Пробел", " ");
Запрос.УстановитьПараметр("СимволПС", Символы.ПС);
Запрос.УстановитьПараметр("ИскомыйТекст", "%искомоезначение%");

Важно: Использование функций обработки строк к полям таблиц базы данных в секции ГДЕ может предотвращать использование индексов СУБД, что снижает скорость выполнения запроса на больших объемах данных.

Способ 3. Пост-обработка результатов во встроенном языке 1С

Выясним, как поступить, если выборку необходимо выполнять на старых версиях платформы без снижения производительности СУБД. В этом случае мы можем сначала выгрузить первичные результаты запроса во временную таблицу или объект ТаблицаЗначений, после чего обработать текстовые поля стандартными средствами встроенного языка.

Разберем данный подход на примере:

  1. Выполняем запрос с базовым фильтром (например, по периоду или организации) без жесткого ограничения по комментарию.
  2. Выгружаем результат в таблицу значений с помощью метода Выгрузить().
  3. В цикле обходим строки и очищаем поле Комментарий с использованием функции СтрЗаменить().
  4. Отбираем только те строки, которые соответствуют искомому значению.

ТЗРезультат = Запрос.Выполнить().Выгрузить();
ТЗРезультат.Колонки.Добавить("ОчищенныйКомментарий", Новый ОписаниеТипов("Строка"));

Для Каждого Стр Из ТЗРезультат Цикл
    Текст = Стр.Комментарий;
    Текст = СтрЗаменить(Текст, " ", "");
    Текст = СтрЗаменить(Текст, Символы.ПС, "");
    Текст = СтрЗаменить(Текст, Символы.ВК, "");
    Стр.ОчищенныйКомментарий = Текст;
КонецЦикла;

ПараметрыОтбора = Новый Структура("ОчищенныйКомментарий", "ИскомыйТекстБезПробелов");
НайденныеСтроки = ТЗРезультат.НайтиСтроки(ПараметрыОтбора);

Способ 4. Хранение подготовленных данных (Дополнительные реквизиты или Расширение)

Посмотрим на ситуацию со стороны архитектуры системы. Текстовый комментарий предназначен в первую очередь для пользователя, а не для системного поиска. Попытка строить бизнес-логику и отборы на анализе неструктурированного текста часто приводит к замедлению работы системы.

Если типовую конфигурацию нельзя снимать с поддержки, рассмотрим альтернативные варианты оптимизации:

  1. Дополнительные реквизиты и сведения: В большинстве типовых конфигураций 1С (на базе БСП) предусмотрен механизм дополнительных реквизитов. Вы можете хранить ключевой признак в отдельном реквизите с четким типом (например, перечисление или справочник).
  2. Использование расширения конфигурации: Можно создать расширение и подписку на событие ПередЗаписью для нужного документа. При сохранении документа программа автоматически очистит комментарий от лишних символов и запишет его в отдельное поле или в независимый регистр сведений. В дальнейшем запросы будут выполнять отбор по подготовленному индексированному полю мгновенно.
← На главную