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

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

ПОДОБНО в запросе 1С 8.3: как задать маску для параметра

Как использовать оператор ПОДОБНО в запросе 1С 8.3 с параметром-маской: спецсимволы %, _, квадратные скобки, СПЕЦСИМВОЛ, примеры кода и типичные ошибки.

Оператор ПОДОБНО в языке запросов 1С 8.3 позволяет сравнивать строковое значение с шаблоном — аналог LIKE в SQL. Чаще всего шаблон передаётся через параметр запроса, чтобы не вставлять строку поиска прямо в текст запроса: это безопаснее, удобнее при повторном выполнении и позволяет формировать маску динамически из пользовательского ввода.

Маска — это строка со специальными символами: знак процента % заменяет любую последовательность символов (в том числе пустую), подчёркивание _ — ровно один произвольный символ, квадратные скобки [...] — один символ из перечисленного набора. Если в искомом тексте сами спецсимволы должны восприниматься буквально, используется служебное слово СПЕЦСИМВОЛ.

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

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

Базовая конструкция в тексте запроса выглядит так:

Выбрать Номенклатура.Ссылка

Из Справочник.Номенклатура КАК Номенклатура

ГДЕ Номенклатура.Наименование ПОДОБНО &Маска

Параметр устанавливается до выполнения запроса методом УстановитьПараметр. Тип параметра — строка, длина не ограничивается автоматически, но слишком длинные маски бессмысленны и замедляют проверку.

Запрос = Новый Запрос;

Запрос.Текст = "ВЫБРАТЬ Ссылка ИЗ Справочник.Номенклатура

|ГДЕ Наименование ПОДОБНО &Маска";

Запрос.УстановитьПараметр("Маска", "%" + СтрокаПоиска + "%");

Результат = Запрос.Выполнить();

Важно: само слово ПОДОБНО работает только со строковыми операндами. Если слева стоит поле нестрокового типа или параметр передан не строкой, запрос завершится с ошибкой либо условие не сработает так, как ожидается. Поля составного типа, включающие строку, обычно обрабатываются корректно, но лучше явно приводить значение через ВЫРАЗИТЬ(... КАК Строка(...)) в неоднозначных случаях.

Спецсимволы маски и их поведение

Набор спецсимволов в языке запросов 1С фиксированный, и его нужно знать точно, потому что неправильное понимание даёт «пустые» результаты:

  • % — любая последовательность символов, включая пустую. Шаблон %кабель% найдёт «Кабель ВВГ 3х2.5», «Кабель», «Провод и кабель».
  • _ — ровно один произвольный символ. Шаблон А_10 найдёт «А-10» и «А510», но не «А10» и не «А--10».
  • [абв] — один символ из перечисленных. Шаблон Т[оа]н совпадёт с «Тон» и «Тан».
  • [а-г] — один символ из диапазона. Диапазон задаётся по кодам символов, поэтому с кириллицей работает, но порядок буквы «ё» в диапазонах неочевиден — лучше перечислять явно.
  • [^аб] — один символ, не входящий в набор (отрицание).

Комбинации допустимы в любом порядке: _%молоток% означает «минимум один символ, затем что угодно, затем слово, затем что угодно». На практике чаще всего используются два шаблона: %текст% (поиск вхождения в любом месте) и текст% (поиск по началу строки).

Формирование маски из пользовательского ввода

Когда строка поиска вводится пользователем, в ней могут встретиться сами спецсимволы: процент, подчёркивание, квадратные скобки. Если передать такой ввод в маску «как есть», эти знаки будут интерпретированы как служебные, и поиск даст неверный результат. Например, пользователь ищет товар «Скидка 10%» — знак процента превратится в «любую последовательность».

Решение — экранирование через предложение СПЕЦСИМВОЛ. В тексте запроса указывается символ-экран, а в маске каждый спецсимвол предваряется этим экраном:

Запрос.Текст = "ВЫБРАТЬ Ссылка ИЗ Справочник.Номенклатура

|ГДЕ Наименование ПОДОБНО &Маска СПЕЦСИМВОЛ ""~""";

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

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

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

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

Запрос.УстановитьПараметр("Маска", "%" + СтрокаПоиска + "%");

Порядок замен важен: сначала экранируется сам символ экрана, и только потом остальные спецсимволы, иначе получится двойное экранирование. В качестве символа экрана удобно брать знак, который редко встречается в данных: тильду, обратную косую черту или символ «^».

Регистр символов и сравнение

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

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

Ещё один тонкий момент — буквы «е» и «ё». ПОДОБНО не выполняет лингвистической нормализации: шаблон с «е» не найдёт строку с «ё» и наоборот. Если в данных встречаются оба варианта, маску придётся строить с учётом обоих написаний, например через объединение двух условий ПОДОБНО оператором ИЛИ.

Производительность и ограничения

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

Практические рекомендации по снижению нагрузки:

  • по возможности формируйте маску без ведущего процента, если бизнес-задача позволяет искать по началу строки;
  • добавляйте в запрос дополнительные ограничивающие условия (по периоду, организации, виду номенклатуры), чтобы уменьшить объём сканируемых записей;
  • для регулярного поиска по подстроке в больших справочниках рассмотрите полнотекстовый поиск — он индексируется и работает существенно быстрее;
  • не применяйте ПОДОБНО к вычисляемым выражениям внутри запроса без необходимости: выражение слева от оператора почти гарантированно отключает индекс.

Также помните, что ПОДОБНО работает только со строками. Числовые коды, даты и ссылки сначала нужно привести к строковому представлению, но такое приведение в условии запроса — тоже удар по производительности. Для поиска по коду справочника обычно достаточно маски по строковому полю Код, если код хранится как строка.

Сравнение вариантов поиска

ПОДОБНО с шаблоном "текст%"

Поиск по началу строки. Может использовать индекс, быстрый вариант. Не найдёт вхождение в середине строки.

ПОДОБНО с шаблоном "%текст%"

Поиск вхождения в любом месте. Универсально, но приводит к полному сканированию таблицы на больших данных.

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

Подходит для регулярного поиска по словам в больших объёмах. Требует включения полнотекстового индекса и имеет собственный синтаксис.

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

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

Частая ситуация: в параметр передали строку с уже добавленными процентами, а в коде проценты добавляются повторно — получается маска %%текст%%, которая, кстати, работает, но путает при чтении. Хуже, когда маска формируется в одном месте, а текст запроса уже содержит конкатенацию с процентами — тогда шаблон собирается дважды.

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

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

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

Значение параметра маски
Норма

Маска содержит ровно те спецсимволы, что задуманы, например %кабель%

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

Двойные проценты, неэкранированный ввод пользователя, пустая строка

Результат запроса в консоли
Норма

Возвращаются записи, содержащие искомый фрагмент в нужной позиции

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

Пусто при заведомо существующих данных или возвращается вся таблица

План выполнения на большой таблице
Норма

Запрос отрабатывает за приемлемое время, при шаблоне "текст%" используется индекс

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

Длительное полное сканирование при маске с ведущим процентом

Типичные ошибки при работе с маской

Первая ошибка — передача в параметр не строки, а, например, значения неопределённого типа из поля формы. Если реквизит формы составного типа, перед установкой параметра приведите значение функцией Строка() или гарантируйте строковый тип реквизита.

Вторая ошибка — забытый СПЕЦСИМВОЛ при экранировании. Если в коде спецсимволы заменяются на «~%», а в тексте запроса нет предложения СПЕЦСИМВОЛ "~", тильда станет обычным символом маски, и поиск ничего не найдёт.

Третья — попытка использовать ПОДОБНО для проверки точного равенства или сравнения чисел. Для равенства есть обычное сравнение =, для чисел — числовые условия; ПОДОБНО здесь избыточен и медленнее.

Типичные ошибки
01
Неэкранированный ввод пользователя: символы % и _ в строке поиска ломают логику маски и возвращают лишние записи.
02
Экранирование без СПЕЦСИМВОЛ в тексте запроса: маска содержит символы экрана, но запрос о них не знает — результат пустой.
03
Двойное добавление процентов: маска собирается и в коде, и в тексте запроса, шаблон получается нечитаемым.
04
Маска с ведущим % на большой таблице без дополнительных условий: полное сканирование и таймауты.
05
Применение ПОДОБНО к числам и датам без приведения к строке: ошибка запроса или непредсказуемый результат.

FAQ

Можно ли передать в параметр маску без спецсимволов для точного совпадения?

Да, строка без спецсимволов в ПОДОБНО означает точное совпадение с учётом правил регистра СУБД. Но для точного равенства правильнее использовать обычное сравнение «=» — оно читаемее и лучше оптимизируется.

Как найти строки, где есть сам символ процента?

Добавьте в текст запроса предложение СПЕЦСИМВОЛ, например СПЕЦСИМВОЛ "\", а в маске запишите символ как \%. Тогда процент будет воспринят буквально, а не как «любая последовательность».

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

Чаще всего причины три: лишние пробелы в данных или маске (используйте СокрЛП при формировании маски), различие «е» и «ё», либо неэкранированные спецсимволы в искомой строке. Проверьте маску литералом в консоли запросов.

Работает ли ПОДОБНО в динамических списках и СКД?

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

Чем заменить ПОДОБНО для поиска с опечатками?

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

Можно ли задать несколько масок для одного поля?

Да, условия комбинируются: (Наименование ПОДОБНО &Маска1) ИЛИ (Наименование ПОДОБНО &Маска2). Каждой маске нужен свой параметр. Учитывайте, что несколько условий ПОДОБНО увеличивают нагрузку на запрос.

Итог

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

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