Как увеличить количество строк в выпадающем списке при вводе по строке и настроить собственную подсветку?

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

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

Почему платформа ограничивает количество строк?

Прежде чем переходить к коду, проанализируем причины стандартного поведения. Ограничение в 10 строк введено для обеспечения максимальной отзывчивости интерфейса. При каждом нажатии клавиши платформа выполняет запрос к базе данных. Если бы список содержал сотни элементов, отрисовка выпадающего окна и передача данных по сети (особенно в веб-клиенте) вызывали бы заметные задержки. Поэтому, увеличивая лимит, следует соблюдать баланс — оптимальным считается значение от 30 до 50 строк.

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

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

Во-первых, мы должны отключить стандартную обработку поиска, установив параметр СтандартнаяОбработка в значение Ложь. Это скажет системе, что мы сами сформируем список данных для отображения.

Во-вторых, нам нужно проанализировать параметры поиска. В структуре Параметры нам наиболее интересны свойства СтрокаПоиска и ВыборГруппИЭлементов.

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


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

Проблема «лишних» строк из истории выбора

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

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

Реализация полнотекстовой подсветки слов

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

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


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

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


// Внутри цикла выборки
Представление = ПодсветитьСовпадения(Выборка.Наименование, Параметры.СтрокаПоиска);
СписокВыбора.Добавить(Выборка.Ссылка, Представление);

Оптимизация поиска по нескольким словам

Стандартный поиск 1С часто ищет по нескольким словам в произвольном порядке. Чтобы повторить это поведение, нам нужно разбить СтрокаПоиска на массив слов с помощью функции СтрРазделить и динамически сформировать условия ПОДОБНО в запросе.

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

Важное замечание по производительности: Использование конструкции ПОДОБНО %Текст% отключает использование индексов на стороне SQL-сервера. Если ваш справочник содержит миллионы записей, такой поиск будет работать медленно. В этом случае рекомендуется использовать программный доступ к полнотекстовому поиску (ПП) через встроенные средства платформы, которые работают значительно быстрее на больших объемах данных.

Использование системных методов в новых версиях платформы

Если вы работаете на платформе версии 8.3.15 и выше, обратите внимание на метод СтрНайтиИВыделитьОформлением. Он позволяет автоматизировать процесс создания форматированной строки. Хотя он не дает такой гибкой настройки цветов, как ручной метод, он работает быстрее и использует стандартные системные настройки оформления, что делает интерфейс вашего решения более нативным для пользователя.

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

← На главную