К статье
Практический материал

Разработка и Конфигурация · 13 мин

Как в запросе 1С сделать условие «содержит»

Как в запросе 1С проверить, что строка содержит подстроку: оператор ПОДОБНО, шаблоны % и _, экранирование, регистр, примеры кода и типичные ошибки.

Задача «проверить, содержит ли строка подстроку» в языке запросов 1С решается не функцией, а специальным оператором сравнения — ПОДОБНО (в английском синтаксисе — LIKE). Он сравнивает строковое поле с шаблоном, в котором символ % означает любую последовательность символов, а _ — ровно один произвольный символ. Именно комбинация «поле ПОДОБНО шаблон» и даёт поведение «содержит».

Типичные сценарии: подобрать контрагентов по фрагменту наименования, найти номенклатуру по части артикула, отобрать документы, у которых в комментарии встречается ключевое слово. Во всех этих случаях условие пишется в секции ГДЕ либо в параметрах виртуальной таблицы, а шаблон удобно передавать параметром, чтобы не собирать строку запроса конкатенацией.

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

Синтаксис оператора ПОДОБНО

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

Ключевой момент: без символа % в начале и конце шаблона сравнение работает как точное совпадение. Условие Наименование ПОДОБНО "Гвоздь" найдёт только элемент с наименованием ровно «Гвоздь», но не «Гвоздь строительный». Чтобы получить поведение «содержит», шаблон должен быть вида "%Гвоздь%".

Пример запроса, который находит контрагентов по фрагменту наименования:

ВЫБРАТЬ

Контрагенты.Ссылка КАК Контрагент,

Контрагенты.Наименование КАК Наименование

ИЗ

Справочник.Контрагенты КАК Контрагенты

ГДЕ

Контрагенты.Наименование ПОДОБНО &Шаблон

Параметр &Шаблон при этом заполняется в коде как "%" + Фрагмент + "%". Такой вариант предпочтительнее прямой подстановки текста в строку запроса: параметр исключает синтаксические ошибки из-за кавычек в искомом тексте и защищает от случайной порчи запроса.

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

Шаблоны: %, _ и квадратные скобки

Оператор ПОДОБНО поддерживает несколько служебных конструкций. Символ % заменяет любую последовательность символов любой длины, включая пустую. Символ _ (подчёркивание) заменяет ровно один произвольный символ. Квадратные скобки [...] задают набор допустимых символов в одной позиции, а вариант [^...] — любой символ, кроме перечисленных.

Комбинируя шаблоны, можно строить точные условия: "А%" — строки, начинающиеся с «А»; "%А" — заканчивающиеся на «А»; "_А%" — «А» стоит вторым символом; "%[0-9][0-9][0-9]%" — строка содержит три цифры подряд.

ШаблонСмыслПример совпадения
%гвоздь%Содержит подстроку«Гвоздь строительный 100 мм»
гвоздь%Начинается с фрагмента«Гвоздь 5х150»
%гвоздьЗаканчивается фрагментом«Крепёж: гвоздь»
А_Т%Второй символ — любой«АКТ сверки», «А2Тест»
%[0-9]%Содержит хотя бы одну цифру«Офис 12»

Для повседневной задачи «содержит» почти всегда достаточно шаблона %...%. Остальные конструкции полезны для валидации форматов: например, проверки, что артикул состоит из букв и цифр в заданном порядке.

Экранирование служебных символов

Если искомый текст сам содержит символы %, _, [ или ], они будут восприняты как часть шаблона, и поиск вернёт лишние строки или не найдёт нужные. Например, поиск товара «Скидка 10%» с шаблоном %Скидка 10%% сработает не так, как ожидается: внутренний % станет подстановкой.

Для экранирования служит конструкция СПЕЦСИМВОЛ (ESCAPE). Она указывает символ, который в шаблоне отменяет служебное значение следующего за ним знака. Перед передачей в запрос исходную строку нужно обработать: заменить служебные символы на их экранированные варианты.

Функция ЭкранироватьДляПодобно(Знач Текст)

Текст = СтрЗаменить(Текст, "~", "~~");

Текст = СтрЗаменить(Текст, "%", "~%");

Текст = СтрЗаменить(Текст, "_", "~_");

Текст = СтрЗаменить(Текст, "[", "~[");

Текст = СтрЗаменить(Текст, "]", "~]");

Возврат Текст;

КонецФункции

// В запросе:

// ГДЕ Наименование ПОДОБНО &Шаблон СПЕЦСИМВОЛ "~"

Запрос.УстановитьПараметр("Шаблон", "%" + ЭкранироватьДляПодобно(Фрагмент) + "%");

Порядок замен важен: сначала экранируется сам спецсимвол (в примере — тильда), и только потом остальные. Если сделать наоборот, добавленные тильды будут удвоены повторно, и шаблон испортится.

Типичные ошибки
01
Шаблон без % по краям — условие работает как точное равенство, и «содержит» не получается
02
Не экранируются % и _ в пользовательском вводе — находятся лишние строки или теряются нужные
03
Параметр объявлен строкой фиксированной длины — значение обрезается, и поиск идёт по усечённому фрагменту
04
ПОДОБНО применяется к числовому или составному полю — запрос падает с ошибкой или возвращает пустой результат
05
Поиск по наименованию вместо полнотекстового поиска на больших таблицах — запрос выполняется секундами и блокирует работу

Регистр букв и типы данных

Чувствительность к регистру при сравнении ПОДОБНО зависит от настроек СУБД и collation базы данных. В типовых установках MS SQL Server и PostgreSQL с русской collation сравнение обычно регистронезависимое: шаблон %гвоздь% найдёт и «Гвоздь», и «ГВОЗДЬ». Однако на файловом варианте и при нестандартных настройках СУБД поведение может отличаться, поэтому на новом окружении стоит проверить поиск по фрагменту в другом регистре.

Если требуется гарантированно регистронезависимый поиск независимо от настроек базы, применяйте функцию ВРЕГ() или НРЕГ() к обеим сторонам сравнения: ГДЕ ВРЕГ(Наименование) ПОДОБНО ВРЕГ(&Шаблон). Учтите, что обёртка поля в функцию отключает использование индекса по этому полю.

ПОДОБНО применимо только к строкам. Если поле числовое, дата или ссылка, сначала приведите его к строке — например, поиск по фрагменту номера документа делается через ПОДСТРОКА или через сравнение строкового представления номера, которое у документов уже строковое. Для полей неограниченной длины (строка неограниченной длины, ХранилищеЗначения) ПОДОБНО может не поддерживаться — такие поля придётся обрабатывать в коде после выборки.

Поиск в динамических списках и формах

В управляемых формах подбор по подстроке часто реализуется не ручным запросом, а настройкой динамического списка. Если список построен на произвольном запросе, условие ПОДОБНО добавляется в текст запроса, а значение вводимого пользователем фрагмента передаётся параметром через Список.Параметры.УстановитьЗначениеПараметра("Шаблон", "%" + СтрокаПоиска + "%").

Второй вариант — отбор через ЭлементыОтбора динамического списка с видом сравнения ВидСравненияКомпоновкиДанных.Содержит. Платформа сама преобразует его в ПОДОБНО с нужным шаблоном и выполнит экранирование служебных символов. Это удобно, когда список строится без произвольного запроса.

ЭлементОтбора = Список.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));

ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Наименование");

ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Содержит;

ЭлементОтбора.ПравоеЗначение = СтрокаПоиска;

ЭлементОтбора.Использование = Истина;

Вид сравнения «Содержит» предпочтителен в пользовательских сценариях: он не требует от пользователя знания шаблонов, корректно обрабатывает спецсимволы и одинаково работает в форме списка, в отчётах на СКД и в настройках отбора.

Способы поиска по подстроке

ПОДОБНО с шаблоном %...%

Полный контроль над шаблоном в произвольном запросе; нужно вручную экранировать спецсимволы, на больших таблицах медленно

Отбор СКД «Содержит»

Подходит для динамических списков и отчётов; платформа сама строит шаблон и экранирует ввод, меньше гибкости

Полнотекстовый поиск

Быстрый поиск по словам в больших объёмах данных; требует включения полнотекстового индекса и ищет по словам, а не по произвольной подстроке

Производительность и полнотекстовый поиск

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

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

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

Маршрут решения

Как выбрать подход

Поиск редкий, таблица небольшаяИспользуйте ПОДОБНО с шаблоном %текст% и параметром
Поиск по началу строки допустимОграничьтесь шаблоном текст% — он использует индекс
Отбор в динамическом списке или отчёте СКДПрименяйте вид сравнения «Содержит» вместо ручного ПОДОБНО
Частый поиск по таблице в сотни тысяч записейВключите полнотекстовый поиск и ищите через него

Проверка результата

После внедрения условия проверьте его на контрольных примерах: строка, которая точно содержит фрагмент, должна попасть в выборку; строка без фрагмента — не попасть; фрагмент в другом регистре — поведение должно соответствовать ожиданиям вашей базы. Отдельно протестируйте ввод со спецсимволами: процент, подчёркивание, кавычка.

Полезно проверить и граничные случаи: пустая строка поиска (шаблон %% вернёт все записи — решите, допустимо ли это, или блокируйте пустой ввод), очень длинный фрагмент, фрагмент с пробелами по краям. Пробелы в наименованиях встречаются часто, поэтому перед поиском разумно применять СокрЛП() к введённому тексту.

Контрольные точки

Как проверить результат

Поиск известного фрагмента
Норма

Запись с этим фрагментом в наименовании найдена

Тревожный признак

Запись не найдена — проверьте шаблон и обрезку параметра

Ввод символа % или _
Норма

Ищется буквально этот символ

Тревожный признак

Найдены лишние строки — нет экранирования СПЕЦСИМВОЛ

Пустая строка поиска
Норма

Поиск заблокирован или осознанно возвращает всё

Тревожный признак

Неожиданно возвращается вся таблица

Время выполнения на рабочей базе
Норма

Выборка приходит быстро

Тревожный признак

Запрос выполняется секундами — нужен индекс или полнотекстовый поиск

Частые вопросы

Как сделать условие «не содержит»?

Используйте отрицание: ГДЕ НЕ Наименование ПОДОБНО &Шаблон. Учтите, что записи, у которых поле имеет значение NULL (например, в левом соединении), в результат не попадут — при необходимости добавьте обработку NULL через ЕСТЬNULL или отдельное условие.

Почему ПОДОБНО не находит запись, хотя фрагмент точно есть?

Чаще всего причины три: фрагмент содержит служебные символы % или _ без экранирования; параметр объявлен строкой фиксированной длины и обрезает значение; в искомом тексте или в данных есть неразрывные пробелы вместо обычных. Проверьте шаблон в консоли запросов и тип параметра.

Можно ли искать по нескольким словам сразу?

В одном ПОДОБНО — только одним шаблоном. Для нескольких слов строят цепочку условий через И: ПОДОБНО "%слово1%" И ПОДОБНО "%слово2%", генерируя текст запроса в цикле по массиву слов. Либо используйте полнотекстовый поиск, который изначально рассчитан на запросы из нескольких слов.

Работает ли ПОДОБНО в параметрах виртуальных таблиц?

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

Чем отличается ПОДОБНО от функции СТРНАЙТИ?

В языке запросов 1С функции СТРНАЙТИ нет — поиск подстроки возможен только через ПОДОБНО. СТРНАЙТИ существует во встроенном языке и применяется к строкам в коде после выборки данных. Если нужно отфильтровать на стороне СУБД, используйте ПОДОБНО; если обрабатываете уже полученные строки — СТРНАЙТИ.

Итог

Что важно запомнить

Условие «содержит» — это ПОДОБНО с шаблоном %фрагмент%, переданным параметром. Экранируйте %, _ и скобки через СПЕЦСИМВОЛ, помните про регистр и отсутствие индекса у шаблона с начальным %, а для частого поиска по большим таблицам применяйте полнотекстовый поиск или отбор СКД «Содержит».