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