В процессе разработки часто возникает задача поиска данных не по полному совпадению, а по определенной части строки или сложному шаблону. Например, когда код справочника имеет структуру типа *-*-___-*, и нам нужно найти все элементы, содержащие определенную комбинацию символов в середине. В языке запросов 1С для этих целей предусмотрен мощный инструмент — оператор ПОДОБНО. Рассмотрим подробно, как им пользоваться, какие есть ограничения и как оптимизировать такие запросы. Для этой задачи можно использовать универсальную обработку для поиска данных в справочниках по части строкового реквизита.
Оператор ПОДОБНО является аналогом оператора LIKE в языке SQL. Он позволяет сравнивать строковое поле с заданным шаблоном. Разберем базовый пример, когда нам нужно найти в справочнике Номенклатура все позиции, код которых содержит определенную подстроку.
Проанализируем ситуацию: если мы напишем запрос напрямую, он будет выглядеть следующим образом:
ВЫБРАТЬ
Номенклатура.Ссылка КАК Ссылка,
Номенклатура.Код КАК Код
ИЗ
Справочник.Номенклатура КАК Номенклатура
ГДЕ
Номенклатура.Код ПОДОБНО "%6554%"
В данном примере символ процента % означает любое количество произвольных символов. Таким образом, под условие попадут коды "00-6554-01", "6554/AAA", "ОТ-6554" и так далее.
Для построения сложных условий поиска крайне важно понимать, как работают служебные символы внутри строки шаблона. Выясним, какие возможности предоставляет платформа:
[абв] найдет "а", "б" или "в". Можно использовать диапазоны: [0-9] найдет любую цифру.Рассмотрим более сложный пример из практики. Допустим, нам нужно найти код, где третья и четвертая цифры разделены дефисом, а в конце обязательно идет буква. Мы можем составить такой шаблон:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Контрагенты.Ссылка
|ИЗ
| Справочник.Контрагенты КАК Контрагенты
|ГДЕ
| Контрагенты.Код ПОДОБНО ""__-__[а-яА-Я]""";
Иногда сам символ поиска (например, процент или подчеркивание) является частью данных. Чтобы система не восприняла его как служебный, используется ключевое слово СПЕЦСИМВОЛ. Мы указываем символ экранирования, который стоит перед искомым знаком.
Посмотрим на пример, где нужно найти строку, содержащую символ подчеркивания:
// Ищем строку вида "ТЕКСТ_123", где подчеркивание — это часть текста
Запрос.Текст = "ВЫБРАТЬ ... ГДЕ Поле ПОДОБНО ""%#_%"" СПЕЦСИМВОЛ ""#""";
Также хорошей практикой является передача шаблона через параметры запроса. Это делает код чище и позволяет динамически формировать условия поиска:
ИскомыйКод = "6554";
Шаблон = "%-%-" + ИскомыйКод + "-%";
Запрос.УстановитьПараметр("Шаблон", Шаблон);
Запрос.Текст = "ВЫБРАТЬ ... ГДЕ Справочник.Код ПОДОБНО &Шаблон";
Иногда встречается обратная задача: нужно найти элементы, наименование которых входит в состав длинной внешней строки. Проанализируем решение, предложенное участниками сообщества:
ВЫБРАТЬ
ФизическиеЛица.Ссылка КАК Ссылка
ИЗ
Справочник.ФизическиеЛица КАК ФизическиеЛица
ГДЕ
&ТекстовыйРеквизит ПОДОБНО "%" + ФизическиеЛица.Наименование + "%"
В этом случае 1С будет проверять каждое физическое лицо на предмет того, встречается ли его имя внутри переданного параметра &ТекстовыйРеквизит. Это может быть полезно при разборе входящих текстовых данных или логов. При необходимости можно воспользоваться обработкой для поиска ссылок справочника по схожести наименований.
Важно помнить, что использование ПОДОБНО с процентом в начале строки (%текст) — это одна из самых "тяжелых" операций для базы данных. Проблема заключается в том, что СУБД не может использовать индекс для поиска, если начало строки неизвестно. Это приводит к полному сканированию таблицы (Full Scan), что на больших объемах данных (сотни тысяч записей) вызовет значительные задержки.
Рекомендация: если бизнес-логика позволяет, всегда старайтесь использовать поиск по началу строки (текст%). В этом случае система отработает значительно быстрее, используя индекс по коду или наименованию.
Разберем ситуацию, когда привычный поиск через символ % перестает работать в интерфейсе (в динамических списках). Начиная с версии платформы 8.3.24, логика встроенного поиска была оптимизирована для ускорения работы системы.
Если в списках номенклатуры или клиентов перестал работать поиск "внутри" строки, следует проверить следующие моменты:
* перед поисковым запросом (например, *6554), чтобы принудительно запустить поиск по подстроке, а не по началу.ПОДОБНО, но требует актуальности индекса (регламентное задание по обновлению ПП должно работать исправно).Если поиск необходимо выполнить не в запросе, а при обработке уже полученных данных или строк во встроенном языке, рекомендуется использовать функцию СтрНайти() (доступна с версии 8.3.6). Она эффективнее старой функции Найти().
Если СтрНайти(Объект.Код, "6554") > 0 Тогда
// Действие, если подстрока найдена
КонецЕсли;
Подводя итог, можно сказать, что оператор ПОДОБНО — основной инструмент гибкого поиска в 1С. Однако его использование требует осторожности при работе с большими таблицами. Всегда анализируйте, можно ли заменить поиск по маске на полнотекстовый поиск или поиск по началу строки для обеспечения стабильной скорости работы программы.