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

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

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

Разберем причину ограничения и основной механизм решения

Стандартная обработка события АвтоПодбор для строковых данных работает по жесткому алгоритму: платформа ищет совпадения в списке выбора, начиная с первого символа. Настройки типа СпособПоискаСтроки.ЛюбаяЧасть, которые мы привыкли видеть в параметрах получения данных выбора, зачастую игнорируются системой, если речь идет не о ссылочном типе.

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

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

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

Проанализируем ситуацию на конкретном примере. Допустим, у нас есть поле ввода, связанное с реквизитом формы ИмяКлиента (тип Строка). Мы хотим, чтобы при вводе части имени система предлагала все подходящие варианты из заранее подготовленного списка.

Для начала создадим обработчик события АвтоПодбор на клиенте. Критически важно в самом начале процедуры установить параметр СтандартнаяОбработка = Ложь. Это скажет платформе, что мы сами сформируем список подсказок.


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

Продвинутый метод: Поиск по нескольким фрагментам

Зачастую пользователю удобнее искать не по одной цельной фразе, а по нескольким словам в произвольном порядке. Например, при вводе «Иван Петр» должны находиться строки «Петров Иван Сидорович» и «Иванов Петр Алексеевич». Разберем, как модифицировать наш алгоритм для такого «умного» поиска.

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


&НаКлиенте
Функция СтрокаСоответствуетПоиску(ЦелеваяСтрока, ТекстПоиска)
    МассивСлов = СтрРазделить(ТекстПоиска, " ", Ложь);
    Для Каждого Слово Из МассивСлов Цикл
        Если СтрНайти(ВРег(ЦелеваяСтрока), ВРег(Слово)) = 0 Тогда
            // Если хотя бы одно слово не найдено, строка не подходит
            Возврат Ложь;
        КонецЕсли;
    КонецЦикла;
    Возврат Истина;
КонецФункции

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

Улучшение визуализации: Использование форматированной строки

Посмотрим на ситуацию с точки зрения UX (пользовательского опыта). Когда пользователь видит список подсказок, ему гораздо проще ориентироваться, если найденный фрагмент выделен жирным шрифтом или цветом. В современных версиях платформы 8.3 объект ДанныеВыбора может содержать не просто строки, а объекты типа ФорматированнаяСтрока.

Проанализируем пример кода, который подсвечивает найденную часть текста:


&НаКлиенте
Функция СоздатьПодсвеченнуюСтроку(ИсходныйТекст, Фрагмент)
    Позиция = СтрНайти(ВРег(ИсходныйТекст), ВРег(Фрагмент));
    Если Позиция = 0 Тогда
        Возврат ИсходныйТекст;
    КонецЕсли;
    
    Результат = Новый Массив;
    Результат.Добавить(Лев(ИсходныйТекст, Позиция - 1));
    // Выделяем найденный кусок жирным шрифтом
    Результат.Добавить(Новый ФорматированнаяСтрока(Сред(ИсходныйТекст, Позиция, СтрДлина(Фрагмент)), Новый Шрифт(,,Истина)));
    Результат.Добавить(Сред(ИсходныйТекст, Позиция + СтрДлина(Фрагмент)));
    
    Возврат Новый ФорматированнаяСтрока(Результат);
КонецФункции

Использование такого метода при заполнении ДанныеВыбора сделает ваш поиск не только функциональным, но и эстетически приятным.

Оптимизация производительности: Кеширование и серверные вызовы

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

Подводя итог, отметим, что хотя платформа 1С не предоставляет встроенного переключателя «Поиск по любой части» для строковых реквизитов, гибкость управляемых форм позволяет реализовать это самостоятельно. Комбинация события АвтоПодбор, ручного заполнения ДанныеВыбора и использования ФорматированнаяСтрока превращает обычное текстовое поле в мощный и удобный инструмент поиска.

← На главную