Как искать по шаблону через ПОДОБНО в языке запросов 1С
Содержание
Оператор ПОДОБНО сравнивает строку с шаблоном, в котором есть подстановочные знаки. Пишется так: Поле ПОДОБНО "Шаблон". Результат — истина, когда значение поля подходит под маску, и ложь, когда не подходит. Это прямой аналог оператора LIKE из SQL: платформа переводит ПОДОБНО именно в LIKE запроса к СУБД.
Два главных знака — % (любое количество любых символов, в том числе ноль) и _ (ровно один любой символ). Ещё есть диапазоны в квадратных скобках и спецсимвол для экранирования — разберём каждый с примерами, покажу отличия от SQL и объясню, почему маска с процентом в начале тормозит запрос.
Базовый синтаксис и где его применяют
ПОДОБНО ставят в условие ГДЕ или ВЫБРАТЬ, в блок ИМЕЮЩИЕ, в соединение — везде, где допустимо логическое выражение. Минимальная конструкция:
ВЫБРАТЬ
Номенклатура.Наименование
ИЗ
Справочник.Номенклатура КАК Номенклатура
ГДЕ
Номенклатура.Наименование ПОДОБНО "Болт%"
Запрос вернёт все элементы, чьё наименование начинается со слова «Болт»: «Болт М6», «Болт М8х40», «Болты в ассортименте».
Выражение слева — не обязательно поле. Это может быть результат функции, например ПОДСТРОКА(Поле, 1, 10) ПОДОБНО "...". Справа обычно строковый литерал в кавычках или параметр. Шаблон всегда строка: сравнивать по маске число или дату нельзя — приведите их к строке функцией ВЫРАЗИТЬ или сразу храните текстом.
Отрицание пишется как НЕ ... ПОДОБНО:
ГДЕ
НЕ Контрагент.ИНН ПОДОБНО "00%"
Регистр букв при сравнении по умолчанию не учитывается: "болт%" и "БОЛТ%" дадут один результат. Это поведение задаётся на уровне СУБД (параметрами сортировки базы), а не самим оператором, поэтому на нестандартно настроенной базе результат может отличаться.
Подстановочные знаки: процент, подчёркивание и скобки
В шаблоне работают четыре конструкции. Все символы, кроме них, трактуются буквально.
- 🔹
%— любая последовательность символов, включая пустую."%кабель%"найдёт строку, где слово «кабель» стоит в любом месте. - 🔹
_— ровно один произвольный символ."А_"подойдёт к «А1», «А7», «Ав», но не к «А» и не к «А12». - 🔹
[...]— один символ из перечисленных в скобках или из диапазона."[АБВ]%"— наименование на А, Б или В;"[0-9]%"— начинается с цифры. - 🔹
[^...]— один символ, которого в скобках нет."[^0-9]%"— первый символ не цифра.
Внутри квадратных скобок работает дефис-диапазон: [0-9] — любая цифра, [А-Я] — любая заглавная буква кириллицы. Можно комбинировать перечисление и диапазон: [0-9А-Я] — цифра или заглавная буква. Крышка сразу после открывающей скобки означает отрицание всего набора.
Несколько примеров, чтобы связать знаки вместе:
| Шаблон | Что ищет | Подходит | Не подходит |
|---|---|---|---|
"Счёт%" | начинается на «Счёт» | «Счёт на оплату» | «Авансовый счёт» |
"%2024%" | содержит «2024» | «Акт 2024-15» | «Акт 2023-15» |
"ТТН-___" | «ТТН-» и три любых знака | «ТТН-045» | «ТТН-7» |
"[МК]-%" | начинается на М- или К- | «М-11», «К-2» | «Т-1» |
"[^0-9]%" | первый символ не цифра | «А-100» | «1С» |
Знак _ — частый источник путаницы. Если в данных встречается настоящее подчёркивание (имена файлов, коды вида ЗАК_0001), искать его напрямую нельзя: _ в шаблоне заменит любой символ. Для буквального поиска нужен спецсимвол — о нём ниже.
Спецсимвол: как искать сам процент или подчёркивание
Когда искомое значение содержит служебный знак (%, _, [), его экранируют. Для этого в конце выражения объявляют спецсимвол ключевым словом СПЕЦСИМВОЛ, а в шаблоне ставят его перед служебным знаком:
ГДЕ
Товар.Наименование ПОДОБНО "%~%%" СПЕЦСИМВОЛ "~"
Разберём шаблон "%~%%" справа налево:
%в начале — любое начало строки.~%— спецсимвол~отменяет служебность, значит ищется буквальный знак процента.%в конце — любое продолжение.
Итог: найдутся наименования, где где-то внутри стоит символ % — например «Скидка 10%». Спецсимволом может быть любой знак, которого заведомо нет в данных: часто берут ~, / или \.
Так же экранируют подчёркивание и открывающую скобку:
ГДЕ
Файл.Имя ПОДОБНО "ЗАК~_%" СПЕЦСИМВОЛ "~"
Этот запрос найдёт имена, начинающиеся ровно с «ЗАК_», а не «ЗАКаз», «ЗАКрыт» и прочих.
Без СПЕЦСИМВОЛ конструкция ПОДОБНО "ЗАК_%" молча вернёт лишние строки — ошибки не будет, просто результат окажется шире, чем вы рассчитывали. Такие промахи трудно заметить на тесте с парой записей.
Параметры запроса и сборка маски в коде
В языке запросов 1С нельзя склеить строку прямо в шаблоне: конкатенации в теле запроса нет. Поэтому маску с процентами собирают в коде и передают параметром.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ Номенклатура.Ссылка
|ИЗ Справочник.Номенклатура КАК Номенклатура
|ГДЕ Номенклатура.Наименование ПОДОБНО &Шаблон";
Запрос.УстановитьПараметр("Шаблон", "%" + СтрокаПоиска + "%");
Результат = Запрос.Выполнить();
Здесь проценты добавляются к искомому тексту до запроса. Пользователь вводит «кабель», в параметр уходит %кабель% — обычный поиск по вхождению.
Важная тонкость. Если пользователь сам может ввести % или _ (например, вставит код ЗАК_0001), эти знаки в параметре тоже станут служебными. Чтобы поиск работал буквально, экранируйте ввод перед подстановкой: замените в строке служебные знаки на «спецсимвол + знак» и добавьте СПЕЦСИМВОЛ в текст запроса.
// Экранируем пользовательский ввод
Текст = СтрЗаменить(СтрокаПоиска, "~", "~~");
Текст = СтрЗаменить(Текст, "%", "~%");
Текст = СтрЗаменить(Текст, "_", "~_");
Текст = СтрЗаменить(Текст, "[", "~[");
Запрос.УстановитьПараметр("Шаблон", "%" + Текст + "%");
// в тексте запроса: ПОДОБНО &Шаблон СПЕЦСИМВОЛ "~"
Сначала удваиваем сам спецсимвол, потом экранируем остальные знаки — порядок важен, иначе второй проход испортит вставленные ~.
Динамическая маска из нескольких слов собирается так же — сцепкой в коде. Для поиска «кабель» И «медь» в любом порядке один ПОДОБНО не годится: нужно два условия через И, каждое со своим параметром.
В отборах системы компоновки данных (СКД) тот же механизм доступен без кода: в настройках отбора у строковых полей есть вид сравнения «Соответствует шаблону» — это и есть ПОДОБНО. В значение отбора вводят маску с теми же знаками % и _. Удобно, когда поиск по шаблону нужен в пользовательском отчёте, а не в коде.
Отличия ПОДОБНО от SQL LIKE
По сути ПОДОБНО и LIKE — одно и то же, но у реализации 1С есть особенности, о которых стоит помнить.
- 🔸 Диапазоны
[a-z]поддерживаются не всегда одинаково.%и_работают на любой СУБД. А квадратные скобки — это расширение, которое по-разному ведёт себя на разных базах; на PostgreSQL их поведение отличается от MS SQL. Если нужна переносимость между СУБД, на скобки лучше не опираться. - 🔸 Пустая строка и NULL. Сравнение
NULL ПОДОБНО "..."даёт не ложь, аNULL, и строка в выборку не попадает. Если поле может быть пустым, оберните его вЕСТЬNULL(Поле, ""). - 🔸 Нет оператора экранирования по умолчанию. В чистом SQL символ экранирования иногда включён неявно; в 1С его всегда объявляют через
СПЕЦСИМВОЛ. - 🔸 Регистр задаётся базой, а не оператором. В SQL регистрозависимость
LIKEзависит от collation столбца; в 1С — от общих настроек сравнения базы, и повлиять на один запрос нельзя.
Для простого поиска «начинается с», «заканчивается на», «содержит» разницы вы не почувствуете. Особенности всплывают на диапазонах и на пустых значениях.
Производительность: почему маска с процентом в начале медленная
Главное правило: ПОДОБНО "%текст%" не использует индекс и приводит к полному перебору таблицы. СУБД умеет быстро искать по индексу только когда известно начало строки.
- ✅
"Болт%"— процент в конце. Индекс работает, поиск быстрый даже на большом справочнике. - ❌
"%болт"и"%болт%"— процент в начале. Индекс бесполезен, СУБД читает всю таблицу построчно.
На справочнике в тысячу строк разницы не видно. На документах за несколько лет (сотни тысяч записей) поиск по вхождению "%...%" ощутимо тормозит и нагружает сервер.
Причина простая. Индекс в базе — это отсортированный список значений, как алфавитный указатель в книге. По началу слова («Болт…») СУБД сразу прыгает в нужное место указателя. А вот найти страницы, где слово стоит в середине («…болт…»), по указателю нельзя — приходится листать всё подряд. Чем больше таблица, тем дороже этот перебор.
Отдельно про поле наименования справочника: по нему в типовых конфигурациях индекс есть, поэтому "текст%" по наименованию быстр. По произвольному реквизиту без индекса даже маска «начинается с» будет перебирать таблицу — учитывайте это, когда фильтруете по дополнительным полям.
Что делать, если нужен поиск именно внутри строки:
- 🔹 Если можно — стройте маску как «начинается с»:
"текст%"вместо"%текст%". - 🔹 Для полноценного поиска по словам используйте механизм полнотекстового поиска (объект
ПолнотекстовыйПоиск), а неПОДОБНО. Он для этого и предназначен, работает по своему индексу и ищет по словоформам. - 🔹 Ограничьте выборку другими условиями (период, организация, вид операции) до того, как применяете
ПОДОБНО— чем меньше строк дойдёт до маски, тем лучше.
Нужен точный поиск по полному значению, а не по части — используйте обычное равенство =, а не ПОДОБНО "значение". Равенство всегда идёт по индексу и быстрее.
Проверьте, усвоился ли материал:
Типичные ошибки и как их избежать
Несколько промахов, которые чаще всего приводят к неверной выборке.
- ❗ Забыли экранировать
_или%из данных. Коды видаЗАК_0001ищут безСПЕЦСИМВОЛ— и получают лишние строки. Решение выше, в разделе про спецсимвол. - ❗ Склеивают строку в тексте запроса. Конкатенации в запросе нет:
ПОДОБНО "%" + &Текст + "%"не скомпилируется. Собирайте маску в коде и передавайте целиком параметром. - ❗ Не обрабатывают пустое поле. Если поле бывает
NULL, строка не попадёт в выборку, даже когда логически должна. Оберните вЕСТЬNULL(Поле, ""). - ❗ Ставят
%в начале на большой таблице. Запрос работает, но медленно. На объёмах переходите на полнотекстовый поиск. - ❗ Путают
ПОДОБНОи=. Для точного совпадения маска не нужна и вредна —=и быстрее, и понятнее.
Частые вопросы
Чем ПОДОБНО отличается от функции СтрНайти?
СтрНайти — функция встроенного языка, она работает уже с загруженными в память значениями. ПОДОБНО — часть запроса, фильтрация идёт на стороне СУБД, до выгрузки данных. В запросе используют ПОДОБНО, в коде над готовой строкой — СтрНайти.Можно ли искать сразу по нескольким словам в любом порядке?
ПОДОБНО — нет. Для «кабель» И «медь» ставят два условия через И, по параметру на слово. Если порядок и словоформы важны, берите полнотекстовый поиск.Как сделать поиск регистрозависимым?
Почему диапазон `[а-я]` иногда не находит нужные буквы?
[абвгд] вместо [а-д].Работает ли ПОДОБНО с числами и датами?
ВЫРАЗИТЬ(... КАК СТРОКА), но учтите: по вычисленному полю индекс не работает, на больших таблицах будет медленно.