Почему в обычных формах 1С не работает способ поиска «Любая часть» и как это исправить?

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

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

Причины и платформенные ограничения обычных форм

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

  1. Ограничение обычного интерфейса: Настройки на вкладке «Поле ввода» объекта метаданных (такие как «Любая часть», использование полнотекстового поиска при вводе по строке и фоновый режим поиска) предназначены исключительно для управляемых форм. Механизм поля ввода обычных форм игнорирует эти параметры и штатно выполняет автоподбор и поиск строго по префиксу (с начала строки).
  2. Особенности полнотекстового поиска: Даже в управляемом интерфейсе поиск по любой части строки опирается на индекс полнотекстового поиска. Если индекс не обновлен, поиск по новым или измененным элементам работать не будет.

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

Решение 1. Перехват события «ОкончаниеВводаТекста»

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

Разберем по шагам создание обработчика в модуле формы:

  1. Откроем свойства нужного поля ввода и перейдем к событию ОкончаниеВводаТекста.
  2. Создадим процедуру-обработчик и отключим стандартное поведение платформы, установив СтандартнаяОбработка = Ложь.
  3. Выполним запрос к справочнику для поиска элементов, содержащих введенный текст в наименовании.
  4. Если найден один элемент — сразу подставим его в значение поля. Если найдено несколько — откроем список для выбора пользователем.

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


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

Решение 2. Формирование выпадающего списка в событии «АвтоПодборТекста»

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

Посмотрим на пример реализации:


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

Важное замечание: При использовании АвтоПодборТекста всегда ограничивайте количество возвращаемых записей конструкцией ПЕРВЫЕ N и устанавливайте минимальную длину искомой строки, чтобы избежать зависания интерфейса на больших справочниках.

Решение 3. Программный вызов полнотекстового поиска

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

Рассмотрим структуру вызова:


СписокПоиска = ПолнотекстовыйПоиск.СоздатьСписок(ТекстПоиска, 20);
СписокПоиска.ОбластьПоиска.Добавить(Метаданные.Справочники.Номенклатура);
СписокПоиска.ПерваяЧасть();

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

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

Решение 4. Переход на управляемые формы

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

← На главную