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

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

При разработке интерфейсов на управляемых формах 1С программисты часто сталкиваются с ограничением стандартного механизма поиска (вызываемого по Ctrl+F или через строку поиска). Проблема заключается в том, что платформа индексирует для быстрого поиска только те данные, которые непосредственно выведены на форму в виде колонок таблицы. Если нам необходимо осуществлять поиск по служебному полю (например, по строке, содержащей склеенные значения нескольких реквизитов или скрытые артикулы), которое не должно загромождать интерфейс пользователя, стандартные средства перестают работать.

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

Почему стандартный поиск игнорирует скрытые поля?

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

Способ 1. Метод визуальной маскировки ("Скрытое-видимое" поле)

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

Разберем по шагам, как настроить такое поле:

  1. Добавим наше служебное поле в таблицу формы (перетащим его из реквизитов динамического списка в элементы таблицы).
  2. В свойствах добавленного элемента (поля) не снимаем галочку Видимость, иначе поиск перестанет по нему работать.
  3. Установим свойство РастягиватьПоГоризонтали в значение Нет.
  4. Установим Ширина в минимальное значение, например 1.
  5. Удалим текст в свойстве Заголовок.
  6. Чтобы данные окончательно слились с фоном, воспользуемся Условным оформлением формы. Создадим правило, где для этой колонки установим цвет текста, совпадающий с цветом фона (обычно это стиль ЦветФонаФормы или белый).

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

Способ 2. Программная имитация поиска через отборы

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

Выясним алгоритм реализации:

  1. Создадим на форме реквизит (не в списке, а просто реквизит формы) с именем СтрокаПоискаПользователя (тип Строка).
  2. Выведем его в шапку формы.
  3. В обработчике события ПриИзменении этого поля пропишем логику установки отбора.

Посмотрим на пример кода, который позволяет искать по скрытому полю СлужебноеОписание:


&НаКлиенте
Процедура СтрокаПоискаПользователяПриИзменении(Элемент)
    УстановитьПоискПоСкрытомуПолю(СтрокаПоискаПользователя);
КонецПроцедуры

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

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

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

Способ 3. Использование полнотекстового поиска (ППИ)

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

Для этого необходимо:

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

Способ 4. Метод через "Обязательное использование"

Выясним роль метода УстановитьОбязательноеИспользование(). Многие начинающие разработчики путают его назначение. Если мы напишем в ПриСозданииНаСервере:

Список.УстановитьОбязательноеИспользование("СлужебноеПоле", Истина);

Это не сделает поле доступным для стандартного Ctrl+F. Этот метод гарантирует, что данные поля будут переданы с сервера на клиент, даже если поле не выведено в таблицу. Это полезно, если вы программно перехватываете стандартный поиск или используете данные в обработчиках событий (например, при активации строки). Но для включения в автоматический индекс поиска формы поле все равно должно физически присутствовать в коллекции Элементы.

Резюме и рекомендации

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

  1. Если нужно быстрое решение "малой кровью" — используйте метод визуальной маскировки (минимальная ширина и прозрачный текст). Это самый надежный способ заставить работать стандартный Ctrl+F.
  2. Если требуется сложная логика поиска (по нескольким скрытым полям, с особыми условиями) — создавайте собственную строку поиска и управляйте отборами через Группу ИЛИ в компоновке данных динамического списка.
  3. Для высоконагруженных систем с огромными объемами текстовых данных — настраивайте полнотекстовый поиск на уровне метаданных.

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

← На главную