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