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

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

В типовых конфигурациях 1С, таких как 1С:Комплексная автоматизация 2 или 1С:ERP, пользователи часто сталкиваются с тем, что стандартный поиск в поле ввода или в форме подбора работает только по началу строки. Это создает неудобства, когда нужно найти товар по фрагменту наименования, находящемуся в середине. В этой статье мы подробно разберем, как изменить это поведение и реализовать поиск по любой части слова.

Анализ стандартного поведения и системных настроек

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

Разберем основные моменты:

  1. Индекс полнотекстового поиска: Если ППС включен и индекс актуален, система автоматически пытается искать по подстроке. Проверим статус индекса в разделе «НСИ и администрирование» — «Поддержка и обслуживание» — «Полнотекстовый поиск». Если индекс не обновлен, поиск по части слова может игнорироваться.
  2. Свойства метаданных: У справочника Номенклатура в конфигураторе есть свойство «Способ поиска при вводе по строке». Оно может иметь значения «Начало строки» или «Любая часть». Если установлено первое, система будет ограничивать выборку.

Если стандартные настройки не помогают, переходим к программному решению задачи.

Программная реализация поиска через событие ИзменениеТекстаРедактирования

Один из эффективных способов — подменить стандартный алгоритм поиска в момент ввода текста пользователем. Для этого мы будем использовать событие элемента формы ИзменениеТекстаРедактирования. Рассмотрим пошагово, как это реализовать.

Нам необходимо создать два метода: один на стороне клиента для перехвата ввода, другой на сервере для выполнения поискового запроса в базе данных. Проанализируем пример кода:


&НаКлиенте
Процедура ТоварыНоменклатураИзменениеТекстаРедактирования(Элемент, Текст, СтандартнаяОбработка)
    // Отключаем стандартный механизм поиска 1С
    СтандартнаяОбработка = Ложь;
    
    // Вызываем серверную функцию для поиска данных
    СписокДанных = ПолучитьДанныеВыбораНаСервере(Текст);
    
    // Выводим список пользователю
    Элемент.ВыбратьИзСписка(СписокДанных);
КонецПроцедуры

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


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

Оптимизация производительности: риски ПОДОБНО "%Текст%"

Рассмотрим важный технический нюанс. Использование конструкции ПОДОБНО "%Текст%" приводит к тому, что СУБД не может использовать индексы по полю Наименование. Это означает, что при каждом вводе символа сервер будет выполнять полное сканирование (Full Scan) таблицы номенклатуры.

Последствия: если в вашей базе данных более 50-100 тысяч позиций номенклатуры, интерфейс пользователя начнет «замирать» при вводе каждой буквы. Проанализируем альтернативы:

  1. Использование Полнотекстового поиска (ППС): Вместо прямого SQL-запроса можно использовать метод ПолнотекстовыйПоиск.Найти(). Это работает значительно быстрее, так как поиск идет по заранее подготовленному индексу.
  2. Ограничение количества выводимых строк: Всегда используйте конструкцию ПЕРВЫЕ... в запросе, чтобы не перегружать память сервера и клиента.
  3. Минимальное количество символов: Рекомендуем начинать поиск только после того, как пользователь ввел хотя бы 3 символа.

Использование события АвтоПодбор

Для более «нативной» работы выпадающего списка лучше использовать событие АвтоПодбор. Основное отличие заключается в параметре ДанныеВыбора, который система ожидает получить для автоматического отображения списка под полем ввода.

Разберем пример реализации через АвтоПодбор:


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

В этом случае ДанныеВыбора — это СписокЗначений, который платформа сама отрисует в удобном для пользователя виде.

Реализация через расширения конфигурации

Поскольку 1С:Комплексная автоматизация 2 является типовым решением, крайне не рекомендуется вносить изменения напрямую в код основной конфигурации. Это затруднит дальнейшие обновления системы.

Выясним, как правильно применить расширение:

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

Поиск по нескольким полям

Для удобства пользователей часто требуется искать не только по наименованию, но и по артикулу или коду товара. В нашем запросе мы уже добавили условие ИЛИ Номенклатура.Артикул ПОДОБНО &Текст. Посмотрим, как можно улучшить этот механизм:

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

Итоги

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

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

← На главную