При работе с большими справочниками номенклатуры пользователи часто сталкиваются с тем, что стандартный поиск по началу строки неудобен. Например, если товар называется «Перосъемная машина», пользователь может захотеть найти его, введя просто «машина», «ашина» или использовать поиск номенклатуры по отсканированному штрихкоду. В этой статье мы разберем несколько способов реализации такого поиска: от самых простых встроенных настроек до продвинутых методов с использованием суффиксных индексов. Для этой задачи есть ускорение поиска и автоподбора в полях ввода.
Прежде чем приступать к сложному программированию, проанализируем возможности самой платформы 1С. В последних версиях платформы 8.3 реализован встроенный механизм поиска по подстроке — есть ускорение работы и расширенный поиск в 1С.
Для активации этого механизма нам необходимо выполнить следующие действия:
Номенклатура.Любая часть (это полезно при отображении по всей иерархии группы).Важное замечание: этот способ отлично работает в простых конфигурациях. Однако в типовых решениях (УТ 11, ERP, КА) разработчики часто переопределяют стандартную логику в модуле менеджера (поможет модуль настройки поиска и поведения списков 1С), из-за чего эта настройка может игнорироваться. Если после установки свойства поиск не изменился, перейдем к программным методам.
Разберем ситуацию, когда нам нужно программно управлять списком выбора. Основным инструментом здесь выступает событие ОбработкаПолученияДанныхВыбора в модуле менеджера справочника. Это событие срабатывает каждый раз, когда пользователь начинает вводить текст в поле выбора.
Рассмотрим пример кода, который разбивает поисковый запрос на слова и ищет вхождения каждого слова в наименовании:
Процедура ОбработкаПолученияДанныхВыбора(ДанныеВыбора, Параметры, СтандартнаяОбработка)
Если ПустаяСтрока(Параметры.СтрокаПоиска) Тогда
Возврат;
КонецЕсли;
СтандартнаяОбработка = Ложь;
Запрос = Новый Запрос;
ТекстЗапроса =
"ВЫБРАТЬ РАЗРЕШЕННЫЕ ПЕРВЫЕ 20
| Номенклатура.Ссылка КАК Ссылка,
| Номенклатура.Наименование КАК Наименование
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| Номенклатура.Наименование ПОДОБНО &СтрокаПоиска";
// Формируем шаблон для поиска по любой части
Запрос.УстановитьПараметр("СтрокаПоиска", "%" + Параметры.СтрокаПоиска + "%");
Запрос.Текст = ТекстЗапроса;
РезультатЗапроса = Запрос.Выполнить();
СписокВыбора = Новый СписокЗначений;
СписокВыбора.ЗагрузитьЗначения(РезультатЗапроса.Выгрузить().ВыгрузитьКолонку("Ссылка"));
ДанныеВыбора = СписокВыбора;
КонецПроцедуры
Проанализируем этот код. Мы используем оператор ПОДОБНО с процентами с обеих сторон (%Текст%). Это позволяет СУБД найти вхождение строки в любом месте. Однако при объеме справочника в сотни тысяч записей такой поиск может начать «подтормаживать», так как СУБД не сможет эффективно использовать обычные индексы.
Выясним, как реализовать «мгновенный» поиск, о котором упоминал Илья Низамов. Метод заключается в создании вспомогательной таблицы (регистра сведений), которая будет хранить все возможные окончания (суффиксы) слов.
Разберем алгоритм по шагам:
ИндексыДляПоиска.Подстрока (Строка, длина 100, индексировать).Номенклатура (СправочникСсылка.Номенклатура).Теперь при записи номенклатуры нам нужно разбивать наименование на части. Например, для слова «Машина» мы запишем в регистр записи: «Машина», «ашина», «шина», «ина», «на», «а».
Рассмотрим пример функции для заполнения такого индекса:
Процедура ЗаполнитьИндексНоменклатуры(СсылкаНоменклатуры)
Наименование = СсылкаНоменклатуры.Наименование;
НаборЗаписей = РегистрыСведений.ИндексыДляПоиска.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Номенклатура.Установить(СсылкаНоменклатуры);
Слова = СтрРазделить(Наименование, " ");
Для Каждого Слово Из Слова Цикл
Пока СтрДлина(Слово) > 2 Цикл // Индексируем фрагменты от 3-х символов
НоваяЗапись = НаборЗаписей.Добавить();
НоваяЗапись.Номенклатура = СсылкаНоменклатуры;
НоваяЗапись.Подстрока = Слово;
Слово = Сред(Слово, 2); // Отсекаем первую букву
КонецЦикла;
КонецЦикла;
НаборЗаписей.Записать();
КонецПроцедуры
При поиске мы будем обращаться к этому регистру с условием ГДЕ Подстрока ПОДОБНО &СтрокаПоиска + "%". Обратите внимание: процент ставится только в конце. Это критически важно, так как такой запрос SQL-сервер выполняет по индексу мгновенно. Это и есть секрет высокой скорости.
Посмотрим на штатный механизм полнотекстового поиска, который часто недооценивают. Платформа 1С содержит встроенный движок индексации, который умеет искать по частям слов, учитывая морфологию.
Чтобы использовать его в подборе, в той же процедуре ОбработкаПолученияДанныхВыбора можно применить объект ПолнотекстовыйПоиск. Нам нужно сформировать поисковый запрос, добавив символ * к искомому слову (например, *ашина*).
Преимущества ППС:
Недостаток лишь в том, что индекс ППС обновляется не мгновенно, а регламентным заданием, поэтому только что созданный товар может быть не найден сразу.
Проанализируем ситуацию с точки зрения пользователя. Очень удобно, когда найденные части слова подсвечиваются в списке выбора. В современных версиях платформы (8.3.15+) мы можем использовать ФорматированнаяСтрока.
В обработчике ОбработкаПолученияДанныхВыбора мы можем заполнить ДанныеВыбора не просто списком ссылок, а списком значений, где в поле Текст будет объект форматированной строки с выделенным цветом фрагментом. Это делает интерфейс профессиональным и «штатным».
Выбор метода зависит от ваших задач. Если база небольшая — достаточно настройки Любая часть. Если справочник огромен и важна скорость — используйте метод суффиксного индекса в регистре сведений. Если же вам нужен интеллектуальный поиск с учетом опечаток — внедряйте полнотекстовый поиск. Сочетание этих подходов позволит создать максимально удобный инструмент для пользователей вашей системы.