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

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

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

Разберем детально, почему это происходит и какими штатными и надежными инструментами платформы «1С:Предприятие 8» можно реализовать полноценный поиск по вхождению в выпадающем списке.

Причина поведения: разница между СписокВыбора и механизмом автоподбора

Проанализируем механику работы клиентского поля ввода в 1С. Свойство СписокВыбора предназначено главным образом для фиксированных списков (например, выбор из 3–5 предопределенных перечислений или состояний). Когда пользователь вводит символы в поле, платформа на клиенте берет коллекцию СписокВыбора и локально фильтрует ее элементы, оставляя только те, представление которых начинается с введенных символов. Даже если динамически перезаполнять коллекцию в событии ИзменениеТекстаРедактирования, клиентский движок платформы всё равно наложит префиксный фильтр.

Для поиска по вхождению подстроки в платформе предусмотрена совершенно другая механика — динамическая генерация коллекции ДанныеВыбора.

Решение 1. Использование клиентского события АвтоПодбор (быстрый поиск без сервера)

Если данные для выбора уже собраны на клиенте (например, таблица или массив загружены в форму при открытии), наиболее производительным и простым решением будет обработчик события АвтоПодбор у поля ввода.

Рассмотрим, как устроен этот механизм:

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

Посмотрим на пример клиентского кода:


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

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

Решение 2. Передача контекстного отбора в ОбработкаПолученияДанныхВыбора

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

Разберем по шагам реализацию передачи параметров из формы в модуль менеджера:

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

Посмотрим на код обработчика в форме:


&НаКлиенте
Процедура ТоварыНоменклатураАвтоПодбор(Элемент, Текст, ДанныеВыбора, ПараметрыПолученияДанных, Ожидание, СтандартнаяОбработка)
    
    // Передаем контекст текущего документа или обработки в менеджер объекта
    ПараметрыПолученияДанных.Отбор.Вставить("Склад", Объект.Склад);
    ПараметрыПолученияДанных.Отбор.Вставить("ТолькоВНаличии", Истина);
    
    // Если требуется ограничить выбор заранее известным массивом:
    // ПараметрыПолученияДанных.Отбор.Вставить("МассивРазрешенных", СписокСсылок);
    
КонецПроцедуры

Теперь посмотрим на реализацию серверной части в модуле менеджера справочника Номенклатура:


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

Решение 3. Настройка свойств метаданных объекта

Если необходимо включить поиск по любой части строки глобально для всего справочника во всех формах конфигурации без написания программного кода, проверим настройки самого объекта метаданных в дереве конфигурации:

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

После этой настройки типовой механизм платформы автоматически будет искать введенный текст как подстроку в середине наименования.

Важные нюансы и дополнительные настройки формы

При тонкой настройке выпадающих списков обратим внимание на следующие параметры элементов формы:

  1. История выбора при вводе: Если в выпадающем списке появляются неактуальные или лишние строки, у элемента формы следует установить свойство ИсторияВыбораПриВводе в значение НеИспользовать. Это предотвратит подмешивание ранее выбранных позиций пользователем в начало списка.
  2. Ограничение количества строк: При переопределении ДанныеВыбора всегда ограничиваем количество возвращаемых записей (в запросе конструкцией ПЕРВЫЕ N или счетчиком цикла на клиенте), чтобы избежать подвисания интерфейса при вводе одной популярной буквы.
← На главную