При разработке механизмов поиска в системе 1С:Предприятие часто возникает задача найти элементы справочника не по точному совпадению, а по его части. Например, когда пользователь помнит только часть имени контрагента, сотрудника или фрагмент номера телефона. В этой статье мы подробно разберем, как реализовать такой поиск с помощью запроса, изучим особенности работы оператора ПОДОБНО, а также проанализируем ограничения платформы и альтернативные высокопроизводительные подходы.
Для выполнения поиска по неточному совпадению (или по части строки) в языке запросов 1С предусмотрен специальный оператор ПОДОБНО (аналог оператора LIKE в классическом SQL). Этот оператор сравнивает строковое поле со специальным шаблоном, в котором могут использоваться управляющие спецсимволы.
Давайте рассмотрим практический пример. Предположим, нам необходимо найти физическое лицо, в наименовании или телефоне которого содержится определенная подстрока. Для этого мы напишем следующий код:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ФизическиеЛица.Ссылка КАК Ссылка
|ИЗ
| Справочник.ФизическиеЛица КАК ФизическиеЛица
|ГДЕ
| ФизическиеЛица.Наименование ПОДОБНО &ШаблонНаименования
| И ФизическиеЛица.Телефон ПОДОБНО &ШаблонТелефона
|
|СГРУППИРОВАТЬ ПО
| ФизическиеЛица.Ссылка";
// Формируем шаблоны поиска в коде
СтрокаПоискаИмени = "Иванов";
СтрокаПоискаТелефона = "999";
Запрос.УстановитьПараметр("ШаблонНаименования", "%" + СтрокаПоискаИмени + "%");
Запрос.УстановитьПараметр("ШаблонТелефона", "%" + СтрокаПоискаТелефона + "%");
РезультатЗапроса = Запрос.Выполнить();
В данном примере символ процента (%) в шаблоне означает любую последовательность произвольных символов (включая пустую). Шаблон %Иванов% найдет строки "Иванов", "Иванов Иван Иванович", "Сидоров Александр Иванович" и так далее.
При использовании оператора ПОДОБНО крайне важно учитывать технические ограничения платформы 1С, чтобы избежать ошибок на этапе выполнения кода:
ПОДОБНО к реквизиту с типом "Строка (неограниченной длины)" в запросе нельзя — платформа вернет ошибку. Чтобы обойти это ограничение, мы должны предварительно ограничить длину поля с помощью конструкции ВЫРАЗИТЬ. Например: ГДЕ ВЫРАЗИТЬ(ФизическиеЛица.ДополнительнаяИнформация КАК Строка(1000)) ПОДОБНО &Шаблон.ПОДОБНО &Параметр + "%").%, _, [, ]), это нарушит логику выборки или приведет к ошибкам СУБД (особенно в PostgreSQL). Для предотвращения подобных ситуаций спецсимволы в поисковой строке необходимо экранировать, указав в запросе ключевое слово СПЕЦСИМВОЛ. Например:ГДЕ ФизическиеЛица.Наименование ПОДОБНО &Шаблон СПЕЦСИМВОЛ "~" (в данном случае символ "~" будет указывать СУБД, что следующий за ним спецсимвол нужно трактовать как обычный текст).[А-Я]%) не поддерживается базой данных IBM DB2. Также помните об ограничении на максимальную длину строки самого шаблона (в MS SQL Server оно составляет 1024 символа).Несмотря на простоту реализации, использование оператора ПОДОБНО таит в себе серьезную опасность для производительности вашей информационной базы:
%) находится в самом начале шаблона (например, %Иванов%), СУБД физически не может использовать индексы для поиска. Ей придется выполнить полный перебор (сканирование) всей таблицы справочника строка за строкой. На таблицах объемом в сотни тысяч или миллионы записей такой запрос вызовет критическое падение скорости работы системы и приведет к избыточным блокировкам базы данных.% должен находиться только в конце шаблона (например, Иванов%). В таком случае СУБД выполнит быстрый поиск по началу строки, задействовав индекс по этому реквизиту.Если перед нами стоит задача организовать быстрый поиск по большим объемам данных, стандартных запросов с ПОДОБНО может оказаться недостаточно. Проанализируем альтернативные инструменты платформы:
Для работы с большими таблицами (от сотен тысяч записей и более) рекомендуется использовать штатный механизм полнотекстового поиска платформы 1С. Он работает на основе отдельного индекса, который автоматически обновляется системой в фоновом режиме.
ПТС поддерживает сложную поисковую логику, поиск по словоформам, синонимам и части слова (с использованием символа * в конце слова), при этом скорость выполнения такого поиска в разы выше обычного SQL-запроса.
Если неточный поиск необходим для удобного интерактивного автоподбора при вводе данных пользователем в полях формы, мы можем настроить это без написания сложных ручных запросов. В свойствах поля ввода или программно в коде формы (через параметры получения данных выбора) мы можем:
СпособПоискаСтрокиПриВводеПоСтроке.ЛюбаяЧасть.