Как настроить отбор в форме списка с условием ИЛИ в 1С?

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

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

Рассмотрим особенности работы со стандартными отборами платформы 1С:Предприятие, проанализируем ограничения обычных форм и разберем по шагам правильные способы реализации такого отбора.

Ограничение коллекции Отбор в обычных формах

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

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

Решение задачи через запрос и отбор по списку ссылок

Разберем рабочий алгоритм решения задачи. Чтобы отобразить элементы, подходящие хотя бы под одно из условий, мы сначала выполняем запрос к базе данных, получаем ссылки на найденные объекты, а затем устанавливаем отбор по полю Ссылка с видом сравнения ВидСравнения.ВСписке.

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


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

Важные технические нюансы реализации

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

  1. Отбор накладывается на поле Ссылка, а не на строковые реквизиты. Использование отбора по полю Ссылка гарантирует однозначную идентификацию записей и работает быстрее, чем фильтрация по строковым неиндексированным полям.
  2. Порядок установки свойств отбора. При программной настройке отбора обязательно сначала устанавливайте свойство ВидСравнения = ВидСравнения.ВСписке, и только после этого присваивайте Значение типа СписокЗначений. Если попытаться присвоить список значений при стандартном виде сравнения Равно, платформа вызовет исключение «Неверный тип значения».
  3. Формирование шаблона для оператора ПОДОБНО. Конструкция ПОДОБНО в языке запросов без спецсимволов ищет точное совпадение. Чтобы реализовать поиск по вхождению подстроки, оборачивайте значение в знаки процента: "%" + СтрокаПоиска + "%".
  4. Обработка пустого результата. Если запрос не вернул ни одной строки, пустой СписокЗначений в некоторых версиях платформы может сбросить фильтрацию и отобразить все элементы справочника. Добавление пустой ссылки (Справочники.Номенклатура.ПустаяСсылка()) исключает показ лишних данных.
  5. Производительность на больших объемах данных. Если запрос возвращает десятки тысяч записей, передача огромного списка значений в отбор формы может существенно замедлить работу СУБД. В таких сценариях рекомендуется использовать полнотекстовый поиск либо ограничивать максимальное количество строк в запросе с помощью конструкции ВЫБРАТЬ ПЕРВЫЕ.

Как условие ИЛИ реализуется в управляемых формах

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

В управляемой форме условие ИЛИ настраивается созданием группы элементов отбора:


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

Таким образом, в обычных формах отбор по условию ИЛИ реализуется через выборку ссылок отдельным запросом и установку вида сравнения ВСписке, а в управляемых формах — через встроенные группы компоновки данных ГруппаИЛИ.

← На главную