Как в 1С найти элемент справочника по части строки или сложному шаблону кода?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

Использование оператора ПОДОБНО в запросах

Оператор ПОДОБНО является аналогом оператора LIKE в языке SQL. Он позволяет сравнивать строковое поле с заданным шаблоном. Разберем базовый пример, когда нам нужно найти в справочнике Номенклатура все позиции, код которых содержит определенную подстроку.

Проанализируем ситуацию: если мы напишем запрос напрямую, он будет выглядеть следующим образом:


ВЫБРАТЬ
    Номенклатура.Ссылка КАК Ссылка,
    Номенклатура.Код КАК Код
ИЗ
    Справочник.Номенклатура КАК Номенклатура
ГДЕ
    Номенклатура.Код ПОДОБНО "%6554%"

В данном примере символ процента % означает любое количество произвольных символов. Таким образом, под условие попадут коды "00-6554-01", "6554/AAA", "ОТ-6554" и так далее.

Синтаксис шаблонов и служебные символы

Для построения сложных условий поиска крайне важно понимать, как работают служебные символы внутри строки шаблона. Выясним, какие возможности предоставляет платформа:

  1. % (процент): Заменяет последовательность любого количества произвольных символов (включая нулевую длину).
  2. _ (подчеркивание): Заменяет ровно один произвольный символ. Это полезно, когда структура кода строго фиксирована по длине.
  3. [...] (квадратные скобки): Позволяют указать один любой символ из перечисленных внутри скобок. Например, [абв] найдет "а", "б" или "в". Можно использовать диапазоны: [0-9] найдет любую цифру.
  4. [^...] (отрицание в скобках): Любой одиночный символ, кроме тех, что перечислены после значка отрицания.

Рассмотрим более сложный пример из практики. Допустим, нам нужно найти код, где третья и четвертая цифры разделены дефисом, а в конце обязательно идет буква. Мы можем составить такой шаблон:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	Контрагенты.Ссылка
    |ИЗ
    |	Справочник.Контрагенты КАК Контрагенты
    |ГДЕ
    |	Контрагенты.Код ПОДОБНО ""__-__[а-яА-Я]""";

Работа со спецсимволами и параметрами запроса

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

Посмотрим на пример, где нужно найти строку, содержащую символ подчеркивания:


// Ищем строку вида "ТЕКСТ_123", где подчеркивание — это часть текста
Запрос.Текст = "ВЫБРАТЬ ... ГДЕ Поле ПОДОБНО ""%#_%"" СПЕЦСИМВОЛ ""#""";

Также хорошей практикой является передача шаблона через параметры запроса. Это делает код чище и позволяет динамически формировать условия поиска:


ИскомыйКод = "6554";
Шаблон = "%-%-" + ИскомыйКод + "-%";
Запрос.УстановитьПараметр("Шаблон", Шаблон);
Запрос.Текст = "ВЫБРАТЬ ... ГДЕ Справочник.Код ПОДОБНО &Шаблон";

Обратный поиск: когда параметр содержит поле

Иногда встречается обратная задача: нужно найти элементы, наименование которых входит в состав длинной внешней строки. Проанализируем решение, предложенное участниками сообщества:


ВЫБРАТЬ
    ФизическиеЛица.Ссылка КАК Ссылка
ИЗ
    Справочник.ФизическиеЛица КАК ФизическиеЛица
ГДЕ
    &ТекстовыйРеквизит ПОДОБНО "%" + ФизическиеЛица.Наименование + "%"

В этом случае 1С будет проверять каждое физическое лицо на предмет того, встречается ли его имя внутри переданного параметра &ТекстовыйРеквизит. Это может быть полезно при разборе входящих текстовых данных или логов. При необходимости можно воспользоваться обработкой для поиска ссылок справочника по схожести наименований.

Проблемы производительности и индексация

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

Рекомендация: если бизнес-логика позволяет, всегда старайтесь использовать поиск по началу строки (текст%). В этом случае система отработает значительно быстрее, используя индекс по коду или наименованию.

Особенности поиска в новых версиях платформы (8.3.24+)

Разберем ситуацию, когда привычный поиск через символ % перестает работать в интерфейсе (в динамических списках). Начиная с версии платформы 8.3.24, логика встроенного поиска была оптимизирована для ускорения работы системы.

Если в списках номенклатуры или клиентов перестал работать поиск "внутри" строки, следует проверить следующие моменты:

  1. Режим поиска в настройках: В параметрах системы или конкретного списка может быть установлен режим "По началу строки". Его можно переключить на "Любая часть" в настройках формы.
  2. Символ "*" (звездочка): В современных интерфейсах 1С часто требуется явно вводить символ * перед поисковым запросом (например, *6554), чтобы принудительно запустить поиск по подстроке, а не по началу.
  3. Полнотекстовый поиск: Если в свойствах динамического списка включено использование полнотекстового поиска, система будет использовать поисковый индекс. Это работает быстрее, чем ПОДОБНО, но требует актуальности индекса (регламентное задание по обновлению ПП должно работать исправно).

Альтернативные методы в коде (СтрНайти)

Если поиск необходимо выполнить не в запросе, а при обработке уже полученных данных или строк во встроенном языке, рекомендуется использовать функцию СтрНайти() (доступна с версии 8.3.6). Она эффективнее старой функции Найти().


Если СтрНайти(Объект.Код, "6554") > 0 Тогда
    // Действие, если подстрока найдена
КонецЕсли;

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

← На главную