1с как в запросе написать содержит

Разбираем, как в запросе 1С написать "Содержит" для строки. Примеры синтаксиса, лайфхаки с LIKE и ПОДОБНО — ищите подстроки как профи!

Бесплатная консультация юриста

+7 (800) 301-07-30

Реклама jurik.ru

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

Основной способ: Оператор ПОДОБНО (LIKE)

Главный инструмент для проверки вхождения подстроки в 1С — это оператор ПОДОБНО (аналог LIKE в SQL). Он используется в секции ГДЕ (WHERE).

Синтаксис

<Выражение> ПОДОБНО <Маска> [ЕСЦЕЙП <СимволЭкранирования>]

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

  • % (процент) — заменяет любое количество любых символов (в т.ч. ноль символов).
  • _ (подчеркивание) — заменяет ровно один любой символ.
  • […], перечисление допустимых символов (например, [абв]).
  • [^…] — перечисление недопустимых символов.

Примеры использования

Строка содержит подстроку «Товар» в любом месте

ГДЕ Наименование ПОДОБНО "%Товар%"

Здесь знаки % до и после слова означают, что до и после «Товар» может быть любой набор символов.

Строка начинается с «Код_»

ГДЕ Артикул ПОДОБНО "Код_%"

Строка заканчивается на «_2024»

ГДЕ НомерДок ПОДОБНО "%_2024"

Поиск с учетом регистра (важно!)

По умолчанию оператор ПОДОБНО в 1С нечувствителен к регистру (Case Insensitive) для кириллицы и латиницы, если только не включена специальная настройка СУБД или используется двоичное сравнение. Однако поведение может зависеть от коллации (Collation) базы данных (MS SQL, PostgreSQL, IBM DB2).

Для гарантированного регистронезависимого поиска часто приводят обе части к одному регистру:

ГДЕ ВРЕГ(Наименование) ПОДОБНО ВРЕГ("%товар%")

ВРЕГ — функция приведения к верхнему регистру. Также есть НРЕГ (к нижнему).

Работа с спецсимволами: ЕСЦЕЙП (ESCAPE)

Что делать, если нужно найти буквальный символ % или _ внутри строки? Например, искать строку «100% качества».

Для этого используется ключевое слово ЕСЦЕЙП, задающее символ экранирования.

Пример: Поиск строки, содержащей «50%»

ГДЕ Описание ПОДОБНО "%50#%%" ЕСЦЕЙП "#"
  • Символ # объявлен как экранирующий.
  • #% в маске означает буквальный символ процента.
  • Обычные % по краям означают «любые символы до и после».

Альтернативный способ: Функция НАЙТИ (FIND)

Начиная с платформы 1С:Предприятие 8.3.10 (и выше) в языке запросов доступна функция НАЙТИ(Строка, Подстрока, НачальнаяПозиция). Она возвращает номер позиции первого вхождения подстроки (начиная с 1) или 0, если подстрока не найдена.

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

ГДЕ НАЙТИ(Наименование, "Товар") > 0

Преимущества НАЙТИ перед ПОДОБНО:

  1. Читаемость: Код выглядит понятнее для программистов, привыкших к процедурному стилю.
  2. Отсутствие спецсимволов: Не нужно экранировать % и _. Искомая строка воспринимается буквально.
  3. Параметризация: Удобнее передавать искомую строку через параметр запроса без конкатенации % в коде модуля.

Недостатки:

  • Производительность: На некоторых СУБД (особенно MS SQL Server) НАЙТИ может транслироваться в менее оптимальный план выполнения, чем LIKE с префиксной маской (например, 'Товар%').
  • Регистр: Чувствительность к регистру также зависит от коллации БД. Часто требуется оборачивать в ВРЕГ.

Сравнение подходов: Что выбрать?

Критерий ПОДОБНО (LIKE) НАЙТИ (FIND)
Стандартность Стандарт языка запросов 1С (все версии) Доступно с 8.3.10+
Спецсимволы (% _) Поддерживаются (нужен ЕСЦЕЙП для экранирования) Не поддерживаются (ищет буквально)
Использование индексов (MS SQL) Хорошо для префиксного поиска (Товар%). Плохо для %Товар% (Index Scan) Часто приводит к Index Scan / Table Scan
Удобство параметров Требует склеивания % + &Парам + % в коде или в запросе Прямая передача параметра

Оптимизация запросов с «Содержит»

Поиск по маске %Подстрока% (вхождение в середину строки), одна из самых тяжелых операций для СУБД, так как она не может использовать стандартные B-Tree индексы эффективно (происходит полное сканирование таблицы/индекса, Full Scan).

Советы по ускорению:

  1. Префиксный поиск: Если бизнес-логика позволяет, ищите по началу строки: ПОДОБНО "Товар%". Это позволяет СУБД использовать индекс (Index Seek).
  2. Полнотекстовый поиск (Full-Text Search): Для частых и сложных поисков по текстам (описания, комментарии) настройте полнотекстовый индекс на уровне СУБД (MS SQL Full-Text Catalog, PostgreSQL GIN/Tsvector) и используйте специальные конструкции или хранимые процедуры, вызываемые из 1С.
  3. Денормализация: Создайте отдельное поле/таблицу для хранения ключевых слов или n-грамм, по которым можно строить точные совпадения (оператор В / IN).
  4. Ограничение выборки: Всегда добавляйте дополнительные условия отбора (по дате, организации, виду номенклатуры), чтобы отсечь максимум строк до применения функции поиска по строке.

Типичные ошибки и лайфхаки

Конкатенация маски в тексте запроса (Плохая практика)

// НЕ ДЕЛАЙТЕ ТАК (риск инъекций, плохое кэширование планов)
Запрос.Текст = "ВЫБРАТЬ ... ГДЕ Наименование ПОДОБНО '%" + СтрокаПоиска + "%'";

Передача маски через параметр (Хорошая практика для ПОДОБНО)

В модуле:

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

В тексте запроса:

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

Использование НАЙТИ с параметром (Лучшая практика для точного вхождения)

В модуле:

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

В тексте запроса:

ГДЕ НАЙТИ(Наименование, &Подстрока) > 0

Поиск по полю типа «ХранилищеЗначения» или «БольшойОбъект»

Оператор ПОДОБНО и функция НАЙТИ не работают напрямую с полями типа ХранилищеЗначения, ДвоичныеДанные или очень длинными строками (зависит от СУБД).

Решение: хранение поисковой копии в отдельном строковом поле ограниченной длины (например, 1000-) при записи объекта.

Пример комплексного запроса

Поиск номенклатуры по части наименования или артикула с учетом регистра и дополнительными условиями.

ВЫБРАТЬ
 Номенклатура.Ссылка КАК Ссылка,
 Номенклатура.Наименование КАК Наименование,
 Номенклатура.Артикул КАК Артикул
ИЗ
 Справочник.Номенклатура КАК Номенклатура
ГДЕ
 (Номенклатура.ПометкаУдаления = ЛОЖЬ)
 И (Номенклатура.ЭтоГруппа = ЛОЖЬ)
 И (
 ВРЕГ(Номенклатура.Наименование) ПОДОБНО ВРЕГ("%" + &СтрокаПоиска + "%")
 ИЛИ ВРЕГ(Номенклатура.Артикул) ПОДОБНО ВРЕГ("%" + &СтрокаПоиска + "%")
 )
УПОРЯДОЧИТЬ ПО
 Номенклатура.Наименование

Для реализации логики «содержит» в запросах 1С основным инструментом остается оператор ПОДОБНО с маской %текст%. Функция НАЙТИ является удобной современной альтернативой, избавляющей от необходимости экранировать спецсимволы, однако требует внимания к производительности на больших объемах данных.

Главные правила:

  • Всегда используйте параметры запроса, а не склеивание строк.
  • Помните о регистре, используйте ВРЕГ / НРЕГ для единообразия.
  • Избегайте %...% на больших таблицах без дополнительных фильтров — это гарантированное сканирование всей таблицы.
  • Для поиска по спецсимволам (%, _) используйте конструкцию ЕСЦЕЙП.

Грамотное применение этих техник позволит писать быстрые, читаемые и безопасные запросы в конфигурациях на платформе 1С:Предприятие 8.