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

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

Как в запросе 1С найти подстроку в строке

Как найти подстроку в строке в запросе 1С: оператор ПОДОБНО, функция ПОДСТРОКА, спецсимволы, регистр и типичные ошибки с примерами кода.

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

Важно понимать базовое разделение: если нужно отобрать записи, содержащие подстроку, используется ПОДОБНО в секции ГДЕ. Если нужно вырезать часть строки и вывести её в результат — применяется функция ПОДСТРОКА. Эти два приёма не взаимозаменяемы, и путаница между ними — источник большинства ошибок новичков.

Ниже разобраны оба подхода с примерами кода, правила экранирования спецсимволов, особенности регистра, ограничения по производительности и альтернативные варианты для случаев, когда стандартных средств недостаточно.

Оператор ПОДОБНО — основной способ поиска подстроки

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

ВЫБРАТЬ

Контрагенты.Ссылка,

Контрагенты.Наименование

ИЗ

Справочник.Контрагенты КАК Контрагенты

ГДЕ

Контрагенты.Наименование ПОДОБНО "%Ромашка%"

Этот запрос вернёт всех контрагентов, в наименовании которых встречается слово «Ромашка» — независимо от того, стоит оно в начале, середине или конце строки. Именно знаки процента по краям шаблона превращают сравнение в поиск вхождения подстроки.

Шаблон можно передавать параметром — это предпочтительный вариант в реальном коде, поскольку он исключает проблемы с кавычками и упрощает подстановку значений из реквизитов формы:

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

Запрос.Текст =

"ВЫБРАТЬ

| Номенклатура.Ссылка

|ИЗ

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

|ГДЕ

| Номенклатура.Наименование ПОДОБНО &Шаблон";

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

Спецсимволы шаблона и их экранирование

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

СимволЗначениеПример шаблона
%Любая последовательность любых символов, включая пустую"%склад%"
_Ровно один произвольный символ"А-001_"
[...]Один символ из перечисленных в скобках"[АБВ]%"
[^...]Один символ, не входящий в перечисленные"[^0-9]%"

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

ГДЕ

Товары.Наименование ПОДОБНО "%\%%" СПЕЦСИМВОЛ "\"

Здесь обратная косая черта объявлена спецсимволом, а сочетание \% означает буквальный знак процента. Без экранирования запрос нашёл бы вообще все строки, поскольку шаблон из одних процентов совпадает с чем угодно.

Типичные ошибки
01
Передача в параметр текста без процентов — вместо поиска подстроки получается сравнение на полное равенство, и запрос возвращает пустой результат
02
Игнорирование спецсимволов в пользовательском вводе: если пользователь ввёл «50%», запрос интерпретирует процент как шаблон и найдёт лишнее
03
Попытка использовать ПОДСТРОКА для фильтрации вместо ПОДОБНО — функция вырезает фрагмент, но не проверяет вхождение

Функция ПОДСТРОКА: извлечение части строки

Функция ПОДСТРОКА(Строка, НачальнаяПозиция, Длина) решает обратную задачу — не фильтрует записи, а возвращает фрагмент строки в выборку. Нумерация символов начинается с единицы, как и во встроенном языке 1С.

ВЫБРАТЬ

ПОДСТРОКА(Документы.Номер, 1, 3) КАК ПрефиксНомера

ИЗ

Документ.РеализацияТоваровУслуг КАК Документы

Такой запрос выведет первые три символа номера каждого документа. Типичное применение — группировка по префиксу, отсечение служебной части кода, приведение номеров к сопоставимому виду.

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

Регистр символов и точность совпадения

Чувствительность оператора ПОДОБНО к регистру зависит от используемой СУБД и настроек базы данных. В файловом варианте 1С сравнение, как правило, регистронезависимое: шаблон "%ромашка%" найдёт и «Ромашка», и «РОМАШКА». В клиент-серверных базах поведение определяется collation — параметрами сортировки и сравнения, заданными при создании базы.

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

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

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

Запрос с шаблоном "%текст%" на тестовых данных
Норма

Возвращаются записи, где фрагмент есть в любой части строки

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

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

Поиск текста, содержащего % или _
Норма

Находятся только строки с буквальным вхождением символа

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

Находится всё подряд — спецсимвол не экранирован

Регистр букв в искомом фрагменте
Норма

Находятся варианты в любом регистре (или строго в заданном — по требованию)

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

Поведение отличается от ожидаемого — проверьте collation базы

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

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

Смягчить проблему можно несколькими способами. Если известно, что фрагмент стоит в начале строки, используйте шаблон "фрагмент%" — такой поиск способен задействовать индекс. Дополнительно сужайте выборку другими условиями (по дате, организации, пометке удаления), чтобы движок сначала отфильтровал данные по индексированным полям, а проверка ПОДОБНО применялась уже к небольшому подмножеству.

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

Альтернативы и смежные приёмы

Оператор ПОДОБНО — не единственный способ найти подстроку. В ряде сценариев удобнее или быстрее другие механизмы платформы.

  • Полнотекстовый поиск. Если база работает в клиент-серверном варианте и включено полнотекстовое индексирование, поиск по словам в длинных текстах выполняется значительно быстрее, чем перебор через ПОДОБНО. Подходит для описаний, комментариев, содержания писем.
  • Отборы динамических списков. В интерфейсе пользователь может задать отбор «содержит» без единой строки кода — платформа сама сформирует условие. Для типовых подборов в формах списков это самый простой путь.
  • Обработка результата во встроенном языке. Когда нужна позиция вхождения, замена фрагмента или сложный разбор, выгрузите результат запроса и используйте функции СтрНайти(), СтрЗаменить(), Сред() встроенного языка.

Сравнение вариантов

ПОДОБНО с шаблоном %фрагмент%

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

ПОДОБНО с шаблоном фрагмент%

Поиск по началу строки; может использовать индекс, работает быстро, но не найдёт фрагмент в середине

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

Быстрый поиск по словам в длинных текстах; требует включённого индексирования и клиент-серверного режима, не ищет по части слова

СтрНайти после выборки

Гибкая обработка любой сложности; требует выгрузки данных в память, не подходит для фильтрации больших объёмов

Практический порядок действий

Чтобы надёжно реализовать поиск подстроки в реальной задаче, действуйте последовательно: определите, фильтрация нужна или извлечение; составьте шаблон; проверьте спецсимволы; оцените объём данных; протестируйте запрос на копии базы.

Порядок действий
  1. 1
    Определите задачу: отбор записей (ПОДОБНО) или извлечение фрагмента (ПОДСТРОКА)
  2. 2
    Сформируйте шаблон с процентами по краям для поиска вхождения в любую позицию
  3. 3
    Передайте шаблон параметром запроса, а не конкатенацией в текст
  4. 4
    Проверьте, нет ли в искомом тексте спецсимволов %, _, [ — при наличии настройте СПЕЦСИМВОЛ
  5. 5
    Добавьте дополнительные условия отбора по индексированным полям для ускорения
  6. 6
    Выполните запрос на тестовой копии и сверьте результат с ожидаемым списком записей
При поиске по пользовательскому вводу полезно предварительно обрезать пробелы по краям строки функцией СокрЛП до подстановки в шаблон. Лишний пробел в начале фрагмента не мешает ПОДОБНО, но вводит пользователя в заблуждение при отладке, когда «очевидно верный» запрос ведёт себя неожиданно.
ПЗ
Практическое замечание

Частые вопросы

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

В файловом варианте ПОДОБНО обычно регистронезависим. В клиент-серверной базе поведение задаётся collation при создании базы данных. Если регистронезависимость критична, проверьте поведение на целевой базе тестовым запросом и при необходимости согласуйте настройки с администратором СУБД.

Как найти записи, где подстрока стоит строго в начале строки?

Используйте шаблон без ведущего процента: Наименование ПОДОБНО "Ромашка%". Такое условие найдёт только строки, начинающиеся с указанного фрагмента, и дополнительно сможет задействовать индекс, что ускорит выполнение на больших таблицах.

Почему ПОДОБНО не работает с полем комментария?

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

Как узнать позицию вхождения подстроки в запросе?

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

Чем заменить спецсимвол, если в тексте есть и %, и _?

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

Быстрее ли искать через полнотекстовый поиск, чем через ПОДОБНО?

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

Итог

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

Поиск подстроки в запросе 1С выполняется оператором ПОДОБНО с шаблоном "%фрагмент%", извлечение части строки — функцией ПОДСТРОКА. Экранируйте спецсимволы через СПЕЦСИМВОЛ, помните о зависимости регистра от настроек СУБД и избегайте поиска с ведущим процентом по большим таблицам без дополнительных условий.