Как реализовать быстрый поиск номенклатуры по любой части строки в 1С

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

При работе с большими справочниками номенклатуры пользователи часто сталкиваются с тем, что стандартный поиск по началу строки неудобен. Например, если товар называется «Перосъемная машина», пользователь может захотеть найти его, введя просто «машина», «ашина» или использовать поиск номенклатуры по отсканированному штрихкоду. В этой статье мы разберем несколько способов реализации такого поиска: от самых простых встроенных настроек до продвинутых методов с использованием суффиксных индексов. Для этой задачи есть ускорение поиска и автоподбора в полях ввода.

Способ 1. Использование стандартного свойства «Любая часть»

Прежде чем приступать к сложному программированию, проанализируем возможности самой платформы 1С. В последних версиях платформы 8.3 реализован встроенный механизм поиска по подстроке — есть ускорение работы и расширенный поиск в 1С.

Для активации этого механизма нам необходимо выполнить следующие действия:

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

Важное замечание: этот способ отлично работает в простых конфигурациях. Однако в типовых решениях (УТ 11, ERP, КА) разработчики часто переопределяют стандартную логику в модуле менеджера (поможет модуль настройки поиска и поведения списков 1С), из-за чего эта настройка может игнорироваться. Если после установки свойства поиск не изменился, перейдем к программным методам.

Способ 2. Программная обработка в модуле менеджера

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

Рассмотрим пример кода, который разбивает поисковый запрос на слова и ищет вхождения каждого слова в наименовании:


Процедура ОбработкаПолученияДанныхВыбора(ДанныеВыбора, Параметры, СтандартнаяОбработка)
    
    Если ПустаяСтрока(Параметры.СтрокаПоиска) Тогда
        Возврат;
    КонецЕсли;

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

КонецПроцедуры

Проанализируем этот код. Мы используем оператор ПОДОБНО с процентами с обеих сторон (%Текст%). Это позволяет СУБД найти вхождение строки в любом месте. Однако при объеме справочника в сотни тысяч записей такой поиск может начать «подтормаживать», так как СУБД не сможет эффективно использовать обычные индексы.

Способ 3. Создание суффиксного индекса через Регистр сведений

Выясним, как реализовать «мгновенный» поиск, о котором упоминал Илья Низамов. Метод заключается в создании вспомогательной таблицы (регистра сведений), которая будет хранить все возможные окончания (суффиксы) слов.

Разберем алгоритм по шагам:

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

Теперь при записи номенклатуры нам нужно разбивать наименование на части. Например, для слова «Машина» мы запишем в регистр записи: «Машина», «ашина», «шина», «ина», «на», «а».

Рассмотрим пример функции для заполнения такого индекса:


Процедура ЗаполнитьИндексНоменклатуры(СсылкаНоменклатуры)
    
    Наименование = СсылкаНоменклатуры.Наименование;
    НаборЗаписей = РегистрыСведений.ИндексыДляПоиска.СоздатьНаборЗаписей();
    НаборЗаписей.Отбор.Номенклатура.Установить(СсылкаНоменклатуры);
    
    Слова = СтрРазделить(Наименование, " ");
    Для Каждого Слово Из Слова Цикл
        Пока СтрДлина(Слово) > 2 Цикл // Индексируем фрагменты от 3-х символов
            НоваяЗапись = НаборЗаписей.Добавить();
            НоваяЗапись.Номенклатура = СсылкаНоменклатуры;
            НоваяЗапись.Подстрока = Слово;
            Слово = Сред(Слово, 2); // Отсекаем первую букву
        КонецЦикла;
    КонецЦикла;
    
    НаборЗаписей.Записать();
    
КонецПроцедуры

При поиске мы будем обращаться к этому регистру с условием ГДЕ Подстрока ПОДОБНО &СтрокаПоиска + "%". Обратите внимание: процент ставится только в конце. Это критически важно, так как такой запрос SQL-сервер выполняет по индексу мгновенно. Это и есть секрет высокой скорости.

Способ 4. Полнотекстовый поиск (ППС)

Посмотрим на штатный механизм полнотекстового поиска, который часто недооценивают. Платформа 1С содержит встроенный движок индексации, который умеет искать по частям слов, учитывая морфологию.

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

Преимущества ППС:

Недостаток лишь в том, что индекс ППС обновляется не мгновенно, а регламентным заданием, поэтому только что созданный товар может быть не найден сразу.

Способ 5. Визуальное выделение найденного текста

Проанализируем ситуацию с точки зрения пользователя. Очень удобно, когда найденные части слова подсвечиваются в списке выбора. В современных версиях платформы (8.3.15+) мы можем использовать ФорматированнаяСтрока.

В обработчике ОбработкаПолученияДанныхВыбора мы можем заполнить ДанныеВыбора не просто списком ссылок, а списком значений, где в поле Текст будет объект форматированной строки с выделенным цветом фрагментом. Это делает интерфейс профессиональным и «штатным».

Заключение

Выбор метода зависит от ваших задач. Если база небольшая — достаточно настройки Любая часть. Если справочник огромен и важна скорость — используйте метод суффиксного индекса в регистре сведений. Если же вам нужен интеллектуальный поиск с учетом опечаток — внедряйте полнотекстовый поиск. Сочетание этих подходов позволит создать максимально удобный инструмент для пользователей вашей системы.

← На главную