Как реализовать отбор строк в табличной части по нескольким колонкам и правильно его очищать?

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

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

Основы механизма ОтборСтрок

Для начала проанализируем, как работает базовый механизм фильтрации строк в таблице формы. У элемента формы типа «Таблица» (связанного с табличной частью объекта или таблицей значений) существует свойство ОтборСтрок. Оно принимает значение типа ФиксированнаяСтруктура.

Важные особенности свойства:

  1. Строгое равенство: Фильтрация работает исключительно по принципу «Равно». Если вы укажете в отборе значение «Москва» для колонки «Город», в таблице останутся только те строки, где значение в точности совпадает. Реализовать отборы типа «Содержит» или «В списке» напрямую через это свойство невозможно.
  2. Неизменяемость структуры: Поскольку свойство требует именно ФиксированнаяСтруктура, вы не можете просто добавить или удалить ключ в уже назначенный отбор. Вам каждый раз придется создавать новую структуру и назначать ее свойству заново.

Реализация отбора по нескольким полям

Разберем ситуацию, когда нам нужно фильтровать таблицу по пяти разным параметрам (например: Город, Вид компании, Отрасль и др.). Для этого на форме создаются реквизиты (поля ввода), в которые пользователь будет вносить значения для фильтрации. Рассмотрим пошаговый алгоритм реализации.

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


&НаКлиенте
Процедура ПриИзмененииФильтра(Элемент)
    УстановитьОтборНаФорме();
КонецПроцедуры

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

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

Использование флагов управления отборами

Иногда требуется более строгий контроль, например, если значение «Пустая ссылка» само по себе является условием отбора. В этом случае, как советуют коллеги, целесообразно добавить на форму дополнительные флаги (типа Булево) рядом с полями ввода — «Использовать отбор по городу» и так далее.

Рассмотрим, как изменится логика формирования структуры в этом случае:


Если ИспользоватьОтборПоГороду Тогда
    НовыйОтбор.Вставить("Город", Объект.ОтборГород);
КонецЕсли;

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

Проблема «исчезновения» или «затирания» данных

Выясним причину, по которой при очистке отборов колонки могут стать пустыми. Если вы столкнулись с тем, что после ОтборСтрок = Неопределено данные в таблице пропали, проверьте следующие моменты:

  1. Тип таблицы: Если вы работаете не с ТабличнойЧастью объекта, а с ТаблицейЗначений (реквизит формы), убедитесь, что при серверных вызовах контекст формы передается корректно.
  2. Ошибки в коде очистки: Убедитесь, что вы не вызываете случайно метод Объект.ТабличнаяЧасть.Очистить() вместо сброса свойства элемента формы. Помните: ОтборСтрок — это свойство элемента формы (визуального представления), а не самой коллекции данных.
  3. Частичный отбор: Если в коде используется перебор строк в цикле для ручного скрытия или изменения данных, это может привести к необратимому изменению значений в колонках.

Правильная очистка отбора

Чтобы корректно сбросить все фильтры и вернуть таблицу в исходное состояние, достаточно одной строки кода. Мы рекомендуем присваивать именно Неопределено, а не пустую структуру, чтобы избежать лишних внутренних проверок платформы:

Элементы.ИмяВашейТаблицы.ОтборСтрок = Неопределено;

Выбор между событием «ПриИзменении» и кнопкой «Применить»

При проектировании интерфейса важно соблюсти баланс между интерактивностью и производительностью. Рассмотрим две ситуации:

Вариант 1: Событие ПриИзменении
Подходит для небольших таблиц (до 1000–2000 строк). Фильтрация происходит мгновенно при каждом вводе значения. Это создает «живой» интерфейс, который очень нравится пользователям.

Вариант 2: Отдельная кнопка «Применить»
Если в таблице десятки тысяч строк, пересчет отбора при каждом изменении может вызывать заметные задержки («фризы»). В этом случае лучше позволить пользователю настроить все пять фильтров и нажать одну кнопку для обновления таблицы.

Сложные отборы через техническую колонку

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


СтруктураОтбора = Новый Структура("ПодходитПодКритерий", Истина);
Элементы.Таблица.ОтборСтрок = Новый ФиксированнаяСтруктура(СтруктураОтбора);

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

← На главную