Как реализовать быстрый поиск номенклатуры с выпадающим списком и добавлением в таблицу товаров

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

В современной торговле скорость работы кассира или менеджера напрямую зависит от того, насколько быстро он может найти товар в базе. Стандартный выбор из справочника через отдельное окно подбора часто занимает слишком много времени. В этой статье мы разберем, как создать "умное" поле поиска, которое при вводе первых букв предлагает подходящие варианты, как в поисковых системах, и автоматически заполняет табличную часть документа всеми необходимыми данными (цена, количество, остатки).

Метод 1. Использование события «ОбработкаАвтоподбора» на форме

Первый и самый гибкий способ — это перехват ввода пользователя непосредственно в поле ввода на форме. Для этого мы будем использовать событие ОбработкаАвтоподбора. Рассмотрим подробнее, почему этот метод удобен: он позволяет формировать список выбора "на лету", учитывая специфические условия (например, только товары в наличии или только из определенной категории).

Проанализируем алгоритм работы в этом событии:

  1. Пользователь начинает вводить текст в поле.
  2. Программа ожидает ввода определенного количества символов (рекомендуется от 3-х), чтобы не перегружать сервер лишними запросами.
  3. Выполняется запрос к базе данных с использованием оператора ПОДОБНО или механизмов полнотекстового поиска.
  4. Результаты помещаются в параметр ДанныеВыбора, который и отображается пользователю в виде выпадающего списка.

Пример программного кода для реализации этого механизма:


&НаКлиенте
Процедура ПолеПоискаОбработкаАвтоподбора(Элемент, Текст, ДанныеВыбора, Параметры, Ожидание, СтандартнаяОбработка)
    
    // Отключаем стандартный поиск платформы
    СтандартнаяОбработка = Ложь;
    
    // Устанавливаем минимальный порог ввода
    Если СтрДлина(Текст) < 3 Тогда
        Возврат;
    КонецЕсли;
    
    // Получаем данные с сервера
    ДанныеВыбора = ПолучитьСписокНоменклатурыДляПоиска(Текст);
    
КонецПроцедуры

Метод 2. Реализация через «ОбработкаПолученияДанныхВыбора» в модуле менеджера

Если вам нужно, чтобы быстрый поиск работал единообразно во всей системе (и в документах, и в справочниках), правильнее будет переопределить логику на уровне модуля менеджера справочника Номенклатура. Рассмотрим, как использовать обработчик ОбработкаПолученияДанныхВыбора.

Этот метод хорош тем, что он вызывается платформой автоматически, когда кто-то начинает набирать текст в поле типа СправочникСсылка.Номенклатура. Здесь мы можем реализовать сложный поиск сразу по нескольким полям: артикулу, штрихкоду и наименованию.

Разберем пример кода в модуле менеджера:


Процедура ОбработкаПолученияДанныхВыбора(ДанныеВыбора, Параметры, СтандартнаяОбработка)
    
    СтандартнаяОбработка = Ложь;
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ ПЕРВЫЕ 20
        |	Номенклатура.Ссылка КАК Ссылка,
        |	Номенклатура.Наименование КАК Наименование
        |ИЗ
        |	Справочник.Номенклатура КАК Номенклатура
        |ГДЕ
        |	Номенклатура.Наименование ПОДОБНО &СтрокаПоиска
        |	ИЛИ Номенклатура.Артикул ПОДОБНО &СтрокаПоиска";
    
    Запрос.УстановитьПараметр("СтрокаПоиска", "%" + Параметры.СтрокаПоиска + "%");
    
    Выборка = Запрос.Выполнить().Выбрать();
    
    СписокРезультатов = Новый СписокЗначений;
    Пока Выборка.Следующий() Цикл
        СписокРезультатов.Добавить(Выборка.Ссылка, Выборка.Наименование);
    КонецЦикла;
    
    ДанныеВыбора = СписокРезультатов;
    
КонецПроцедуры

Метод 3. Полнотекстовый поиск для больших баз данных

Когда справочник номенклатуры насчитывает десятки тысяч позиций, оператор ПОДОБНО начинает работать медленно. В этом случае выясним причину замедления: поиск по подстроке в начале или середине слова не позволяет эффективно использовать обычные индексы БД. Решением станет Полнотекстовый поиск (ПП).

Для корректной работы ПП выполним следующие шаги:

  1. В конфигураторе у справочника Номенклатура установим свойство ИспользоватьПолнотекстовыйПоиск в значение Использовать.
  2. Убедимся, что регламентное задание по обновлению индекса полнотекстового поиска работает исправно.
  3. В коде будем использовать метод ПолнотекстовыйПоиск.СоздатьСписок().

Преимущество ПП в том, что он поддерживает поиск с опечатками (нечеткий поиск) и работает значительно быстрее на огромных объемах данных. Для более тонкой настройки схожести строк применяют улучшенный алгоритм Левенштейна.

Оптимизация: Поиск по нескольким словам

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

Проанализируем пример построения динамического условия запроса:


// Разбиваем строку "кабель синий" на части
МассивСлов = СтрРазделить(ТекстПоиска, " ", Ложь);
ТекстУсловия = "";

Для Каждого Слово Из МассивСлов Цикл
    Номер = МассивСлов.Найти(Слово);
    ТекстУсловия = ТекстУсловия + " И Номенклатура.Наименование ПОДОБНО &Слово" + Номер;
    Запрос.УстановитьПараметр("Слово" + Номер, "%" + Слово + "%");
КонецЦикла;

Важно: При таком подходе всегда ограничивайте выборку (например, ВЫБРАТЬ ПЕРВЫЕ 20), так как выпадающий список из 100 элементов только запутает пользователя и замедлит работу интерфейса.

Автоматическое заполнение табличной части

После того как пользователь выбрал товар из списка, нам нужно перенести его в табличную часть (ТЧ) и подтянуть данные о цене и остатках. Для этого лучше всего использовать событие ПриИзменении того поля ввода, где осуществлялся поиск.

Посмотрим на пример реализации добавления строки в ТЧ:


&НаКлиенте
Процедура ПолеПоискаПриИзменении(Элемент)
    
    Если ЗначениеЗаполнено(Объект.ПолеПоиска) Тогда
        
        // Добавляем новую строку в ТЧ "Товары"
        НоваяСтрока = Объект.Товары.Добавить();
        НоваяСтрока.Номенклатура = Объект.ПолеПоиска;
        
        // Вызываем серверную процедуру для получения цен и остатков
        ЗаполнитьДанныеСтрокиНаСервере(НоваяСтрока.ПолучитьИдентификатор());
        
        // Очищаем поле поиска для следующего ввода
        Объект.ПолеПоиска = Неопределено;
        
    КонецЕсли;
    
КонецПроцедуры

На стороне сервера мы одним запросом получаем актуальную цену из регистра сведений ЦеныНоменклатуры.СрезПоследних и текущий остаток из регистра накопления. Это обеспечит высокую скорость работы формы без лишних "зависаний".

Краткие итоги и рекомендации

Подведем итог: для реализации качественного поиска в 1С 8.3 следует сочетать удобство интерфейса и производительность кода. Используйте ОбработкаАвтоподбора для динамического списка, ограничивайте количество выводимых результатов и не забывайте про полнотекстовый поиск, если ваша база активно растет. Такая реализация сделает работу пользователей максимально комфортной, напоминая привычный поиск в современных браузерах.

← На главную