Разработка и Конфигурация · 13 мин
Как в запросе 1С сделать условие «содержит»
Как в запросе 1С проверить, что строка содержит подстроку: оператор ПОДОБНО, шаблоны % и _, экранирование, регистр, примеры кода и типичные ошибки.
Задача «проверить, содержит ли строка подстроку» в языке запросов 1С решается не функцией, а специальным оператором сравнения — ПОДОБНО (в английском синтаксисе — LIKE). Он сравнивает строковое поле с шаблоном, в котором символ % означает любую последовательность символов, а _ — ровно один произвольный символ. Именно комбинация «поле ПОДОБНО шаблон» и даёт поведение «содержит».
Типичные сценарии: подобрать контрагентов по фрагменту наименования, найти номенклатуру по части артикула, отобрать документы, у которых в комментарии встречается ключевое слово. Во всех этих случаях условие пишется в секции ГДЕ либо в параметрах виртуальной таблицы, а шаблон удобно передавать параметром, чтобы не собирать строку запроса конкатенацией.
Важно понимать ограничения: ПОДОБНО работает только со строковыми типами, сравнение нечувствительно к регистру в большинстве конфигураций, а шаблон с начальным символом % не может использовать индекс и приводит к полному сканированию таблицы. Ниже разобраны синтаксис, шаблоны, экранирование служебных символов, передача параметров из кода и способы ускорить поиск.
Синтаксис оператора ПОДОБНО
Общая форма условия выглядит так: <СтроковоеПоле> ПОДОБНО <Шаблон>. Шаблон — это строка, в которой обычные символы сравниваются как есть, а служебные символы задают правила подстановки. Условие истинно, если значение поля целиком соответствует шаблону.
Ключевой момент: без символа % в начале и конце шаблона сравнение работает как точное совпадение. Условие Наименование ПОДОБНО "Гвоздь" найдёт только элемент с наименованием ровно «Гвоздь», но не «Гвоздь строительный». Чтобы получить поведение «содержит», шаблон должен быть вида "%Гвоздь%".
Пример запроса, который находит контрагентов по фрагменту наименования:
ВЫБРАТЬ
Контрагенты.Ссылка КАК Контрагент,
Контрагенты.Наименование КАК Наименование
ИЗ
Справочник.Контрагенты КАК Контрагенты
ГДЕ
Контрагенты.Наименование ПОДОБНО &Шаблон
Параметр &Шаблон при этом заполняется в коде как "%" + Фрагмент + "%". Такой вариант предпочтительнее прямой подстановки текста в строку запроса: параметр исключает синтаксические ошибки из-за кавычек в искомом тексте и защищает от случайной порчи запроса.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Контрагенты.Ссылка КАК Контрагент
|ИЗ
| Справочник.Контрагенты КАК Контрагенты
|ГДЕ
| Контрагенты.Наименование ПОДОБНО &Шаблон";
Запрос.УстановитьПараметр("Шаблон", "%" + ФрагментПоиска + "%");
Результат = Запрос.Выполнить().Выбрать();Шаблоны: %, _ и квадратные скобки
Оператор ПОДОБНО поддерживает несколько служебных конструкций. Символ % заменяет любую последовательность символов любой длины, включая пустую. Символ _ (подчёркивание) заменяет ровно один произвольный символ. Квадратные скобки [...] задают набор допустимых символов в одной позиции, а вариант [^...] — любой символ, кроме перечисленных.
Комбинируя шаблоны, можно строить точные условия: "А%" — строки, начинающиеся с «А»; "%А" — заканчивающиеся на «А»; "_А%" — «А» стоит вторым символом; "%[0-9][0-9][0-9]%" — строка содержит три цифры подряд.
| Шаблон | Смысл | Пример совпадения |
|---|---|---|
%гвоздь% | Содержит подстроку | «Гвоздь строительный 100 мм» |
гвоздь% | Начинается с фрагмента | «Гвоздь 5х150» |
%гвоздь | Заканчивается фрагментом | «Крепёж: гвоздь» |
А_Т% | Второй символ — любой | «АКТ сверки», «А2Тест» |
%[0-9]% | Содержит хотя бы одну цифру | «Офис 12» |
Для повседневной задачи «содержит» почти всегда достаточно шаблона %...%. Остальные конструкции полезны для валидации форматов: например, проверки, что артикул состоит из букв и цифр в заданном порядке.
Экранирование служебных символов
Если искомый текст сам содержит символы %, _, [ или ], они будут восприняты как часть шаблона, и поиск вернёт лишние строки или не найдёт нужные. Например, поиск товара «Скидка 10%» с шаблоном %Скидка 10%% сработает не так, как ожидается: внутренний % станет подстановкой.
Для экранирования служит конструкция СПЕЦСИМВОЛ (ESCAPE). Она указывает символ, который в шаблоне отменяет служебное значение следующего за ним знака. Перед передачей в запрос исходную строку нужно обработать: заменить служебные символы на их экранированные варианты.
Функция ЭкранироватьДляПодобно(Знач Текст)
Текст = СтрЗаменить(Текст, "~", "~~");
Текст = СтрЗаменить(Текст, "%", "~%");
Текст = СтрЗаменить(Текст, "_", "~_");
Текст = СтрЗаменить(Текст, "[", "~[");
Текст = СтрЗаменить(Текст, "]", "~]");
Возврат Текст;
КонецФункции
// В запросе:
// ГДЕ Наименование ПОДОБНО &Шаблон СПЕЦСИМВОЛ "~"
Запрос.УстановитьПараметр("Шаблон", "%" + ЭкранироватьДляПодобно(Фрагмент) + "%");
Порядок замен важен: сначала экранируется сам спецсимвол (в примере — тильда), и только потом остальные. Если сделать наоборот, добавленные тильды будут удвоены повторно, и шаблон испортится.
Регистр букв и типы данных
Чувствительность к регистру при сравнении ПОДОБНО зависит от настроек СУБД и collation базы данных. В типовых установках MS SQL Server и PostgreSQL с русской collation сравнение обычно регистронезависимое: шаблон %гвоздь% найдёт и «Гвоздь», и «ГВОЗДЬ». Однако на файловом варианте и при нестандартных настройках СУБД поведение может отличаться, поэтому на новом окружении стоит проверить поиск по фрагменту в другом регистре.
Если требуется гарантированно регистронезависимый поиск независимо от настроек базы, применяйте функцию ВРЕГ() или НРЕГ() к обеим сторонам сравнения: ГДЕ ВРЕГ(Наименование) ПОДОБНО ВРЕГ(&Шаблон). Учтите, что обёртка поля в функцию отключает использование индекса по этому полю.
ПОДОБНО применимо только к строкам. Если поле числовое, дата или ссылка, сначала приведите его к строке — например, поиск по фрагменту номера документа делается через ПОДСТРОКА или через сравнение строкового представления номера, которое у документов уже строковое. Для полей неограниченной длины (строка неограниченной длины, ХранилищеЗначения) ПОДОБНО может не поддерживаться — такие поля придётся обрабатывать в коде после выборки.
Поиск в динамических списках и формах
В управляемых формах подбор по подстроке часто реализуется не ручным запросом, а настройкой динамического списка. Если список построен на произвольном запросе, условие ПОДОБНО добавляется в текст запроса, а значение вводимого пользователем фрагмента передаётся параметром через Список.Параметры.УстановитьЗначениеПараметра("Шаблон", "%" + СтрокаПоиска + "%").
Второй вариант — отбор через ЭлементыОтбора динамического списка с видом сравнения ВидСравненияКомпоновкиДанных.Содержит. Платформа сама преобразует его в ПОДОБНО с нужным шаблоном и выполнит экранирование служебных символов. Это удобно, когда список строится без произвольного запроса.
ЭлементОтбора = Список.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Наименование");
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Содержит;
ЭлементОтбора.ПравоеЗначение = СтрокаПоиска;
ЭлементОтбора.Использование = Истина;
Вид сравнения «Содержит» предпочтителен в пользовательских сценариях: он не требует от пользователя знания шаблонов, корректно обрабатывает спецсимволы и одинаково работает в форме списка, в отчётах на СКД и в настройках отбора.
Способы поиска по подстроке
Полный контроль над шаблоном в произвольном запросе; нужно вручную экранировать спецсимволы, на больших таблицах медленно
Подходит для динамических списков и отчётов; платформа сама строит шаблон и экранирует ввод, меньше гибкости
Быстрый поиск по словам в больших объёмах данных; требует включения полнотекстового индекса и ищет по словам, а не по произвольной подстроке
Производительность и полнотекстовый поиск
Шаблон вида текст% (префиксный поиск) способен использовать индекс по строковому полю, поэтому работает быстро даже на крупных таблицах. Шаблон %текст% индекс использовать не может: сервер перебирает все строки и проверяет каждую. Если справочник содержит сотни тысяч записей и поиск выполняется часто, такой запрос станет узким местом.
Для тяжёлых сценариев платформа предлагает встроенный полнотекстовый поиск. Он включается в свойствах конфигурации и для нужных полей объектов, строит отдельный индекс и позволяет искать по словам с учётом морфологии. В запросах и коде используется метод НайтиПоПолнотекстовомуПоиску менеджера полнотекстового поиска, а не ПОДОБНО.
Практический подход такой: для редких подборов и небольших справочников достаточно ПОДОБНО; для строки поиска, которой пользователи пользуются постоянно по крупным справочникам и документам, включайте полнотекстовый поиск и ограничивайте ПОДОБНО префиксными шаблонами там, где это допустимо по логике.
Как выбрать подход
Проверка результата
После внедрения условия проверьте его на контрольных примерах: строка, которая точно содержит фрагмент, должна попасть в выборку; строка без фрагмента — не попасть; фрагмент в другом регистре — поведение должно соответствовать ожиданиям вашей базы. Отдельно протестируйте ввод со спецсимволами: процент, подчёркивание, кавычка.
Полезно проверить и граничные случаи: пустая строка поиска (шаблон %% вернёт все записи — решите, допустимо ли это, или блокируйте пустой ввод), очень длинный фрагмент, фрагмент с пробелами по краям. Пробелы в наименованиях встречаются часто, поэтому перед поиском разумно применять СокрЛП() к введённому тексту.
Как проверить результат
Запись с этим фрагментом в наименовании найдена
Запись не найдена — проверьте шаблон и обрезку параметра
Ищется буквально этот символ
Найдены лишние строки — нет экранирования СПЕЦСИМВОЛ
Поиск заблокирован или осознанно возвращает всё
Неожиданно возвращается вся таблица
Выборка приходит быстро
Запрос выполняется секундами — нужен индекс или полнотекстовый поиск
Частые вопросы
Как сделать условие «не содержит»?
Используйте отрицание: ГДЕ НЕ Наименование ПОДОБНО &Шаблон. Учтите, что записи, у которых поле имеет значение NULL (например, в левом соединении), в результат не попадут — при необходимости добавьте обработку NULL через ЕСТЬNULL или отдельное условие.
Почему ПОДОБНО не находит запись, хотя фрагмент точно есть?
Чаще всего причины три: фрагмент содержит служебные символы % или _ без экранирования; параметр объявлен строкой фиксированной длины и обрезает значение; в искомом тексте или в данных есть неразрывные пробелы вместо обычных. Проверьте шаблон в консоли запросов и тип параметра.
Можно ли искать по нескольким словам сразу?
В одном ПОДОБНО — только одним шаблоном. Для нескольких слов строят цепочку условий через И: ПОДОБНО "%слово1%" И ПОДОБНО "%слово2%", генерируя текст запроса в цикле по массиву слов. Либо используйте полнотекстовый поиск, который изначально рассчитан на запросы из нескольких слов.
Работает ли ПОДОБНО в параметрах виртуальных таблиц?
Да, условие с ПОДОБНО допустимо в параметрах виртуальных таблиц регистров там, где платформа разрешает отбор по измерениям и реквизитам. Однако накладывать отбор по подстроке на виртуальную таблицу стоит осторожно: это может заметно увеличить стоимость запроса. Часто надёжнее отобрать ссылки отдельным запросом и передать их через временную таблицу.
Чем отличается ПОДОБНО от функции СТРНАЙТИ?
В языке запросов 1С функции СТРНАЙТИ нет — поиск подстроки возможен только через ПОДОБНО. СТРНАЙТИ существует во встроенном языке и применяется к строкам в коде после выборки данных. Если нужно отфильтровать на стороне СУБД, используйте ПОДОБНО; если обрабатываете уже полученные строки — СТРНАЙТИ.
Что важно запомнить
Условие «содержит» — это ПОДОБНО с шаблоном %фрагмент%, переданным параметром. Экранируйте %, _ и скобки через СПЕЦСИМВОЛ, помните про регистр и отсутствие индекса у шаблона с начальным %, а для частого поиска по большим таблицам применяйте полнотекстовый поиск или отбор СКД «Содержит».