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