При работе с управляемыми формами программисты часто сталкиваются с существенным ограничением стандартного механизма отбора строк. В отличие от обычных форм, где объект Отбор позволял гибко настраивать виды сравнения (больше, меньше, в списке и т.д.), свойство управляемого элемента ОтборСтрок принимает только объект типа ФиксированнаяСтруктура. Это означает, что «из коробки» мы можем фильтровать данные только по строгому равенству. В этой статье мы подробно разберем, как обойти это ограничение и реализовать сложные условия фильтрации для таблиц значений.
Рассмотрим стандартный подход, который работает только для равенства. Когда мы пишем код Элементы.Таблица.ОтборСтрок = Новый ФиксированнаяСтруктура("Сумма", 100);, система ищет строки, где значение в колонке Сумма равно точно 100. Мы не можем передать в структуру объект ВидСравнения или использовать операторы сравнения. Чтобы реализовать условие «Больше» или «Меньше», нам придется использовать обходные пути.
Этот метод является наиболее надежным и простым в реализации. Суть его заключается в создании невидимой для пользователя служебной колонки булевого типа, которая будет служить индикатором того, должна ли строка отображаться на экране.
Разберем реализацию этого метода по шагам:
ТаблицаЗначений) и добавим в неё новую колонку, например, с именем ПодходитПодФильтр (тип Булево). Добавлять этот реквизит на саму форму (в дерево элементов) не обязательно, он должен существовать только в данных.ОтборСтрок по нашей новой колонке.Проанализируем пример кода для реализации этого подхода:
&НаСервере
Процедура ОбновитьОтборНаСервере(МинимальнаяЦена)
// 1. Проходим циклом по всей таблице и проверяем условие "Больше"
Для Каждого СтрокаТЗ Из Объект.Товары Цикл
Если СтрокаТЗ.Цена > МинимальнаяЦена Тогда
СтрокаТЗ.ПодходитПодФильтр = Истина;
Иначе
СтрокаТЗ.ПодходитПодФильтр = Ложь;
КонецЕсли;
КонецЦикла;
// 2. Накладываем фиксированную структуру отбора по булевой колонке
Отбор = Новый Структура("ПодходитПодФильтр", Истина);
Элементы.Товары.ОтборСтрок = Новый ФиксированнаяСтруктура(Отбор);
КонецПроцедуры
Преимущества метода: Высокая скорость работы на небольших и средних таблицах, простота отладки и возможность реализации условий любой сложности (включая проверку вхождения в массивы или сложные логические выражения И / ИЛИ).
Иногда программисты пытаются использовать УсловноеОформление для управления видимостью строк. Рассмотрим подробнее, как это реализовать программно, и выясним причину, по которой этот метод не всегда подходит.
Посмотрим на пример настройки условного оформления для скрытия строк, где значение меньше заданного:
ЭлементОформления = УсловноеОформление.Элементы.Добавить();
ЭлементОформления.Использование = Истина;
// Устанавливаем свойство "Видимость" в Ложь для строк, не подходящих под условие
ЭлементОформления.Оформление.УстановитьЗначениеПараметра("Видимость", Ложь);
// Настраиваем условие: Цена < 30
ЭлементУсловия = ЭлементОформления.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементУсловия.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Объект.Товары.Цена");
ЭлементУсловия.ВидСравнения = ВидСравненияКомпоновкиДанных.Меньше;
ЭлементУсловия.ПравоеЗначение = 30;
// Указываем, какие поля нужно скрыть (все колонки таблицы)
Для Каждого Колонка Из Элементы.Товары.ПодчиненныеЭлементы Цикл
ОформляемоеПоле = ЭлементОформления.Поля.Элементы.Добавить();
ОформляемоеПоле.Поле = Новый ПолеКомпоновкиДанных(Колонка.Имя);
КонецЦикла;
Важное замечание: При использовании Условного оформления строки не исчезают из таблицы физически. В зависимости от версии платформы и настроек интерфейса, строки могут просто стать «пустыми» (без текста), но продолжать занимать место в списке. Если ваша цель — полное схлопывание списка, используйте первый способ с вспомогательной колонкой.
Если таблица содержит тысячи строк, перебор в цикле может замедлить работу интерфейса. В таких случаях мы можем воспользоваться мощью языка запросов 1С. Рассмотрим алгоритм:
ТаблицуЗначений из реквизита формы в обычную ТаблицуЗначений на сервере.ГДЕ для фильтрации по условию Больше, Меньше или МЕЖДУ.Проанализируем пример кода:
&НаСервере
Процедура ПрименитьФильтрЗапросом(ПорогСуммы)
ТЗ = Объект.ИтоговаяТаблица.Выгрузить();
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ * ПОМЕСТИТЬ ВТ ИЗ &ТЗ КАК ТЗ;
|ВЫБРАТЬ * ИЗ ВТ ГДЕ Сумма >= &ПорогСуммы";
Запрос.УстановитьПараметр("ТЗ", ТЗ);
Запрос.УстановитьПараметр("ПорогСуммы", ПорогСуммы);
Объект.ИтоговаяТаблица.Загрузить(Запрос.Выполнить().Выгрузить());
КонецПроцедуры
Нюанс этого метода: Метод Загрузить() полностью перезаписывает данные таблицы. Это может привести к тому, что у пользователя «собьется» текущая строка (фокус) или выделение. Перед использованием этого метода стоит сохранить текущий индекс строки и восстановить его после загрузки данных.
Если данные в таблице не редактируются пользователем напрямую, а служат только для просмотра, удобно использовать две таблицы в реквизитах формы:
При каждом изменении условий фильтра мы очищаем ОтображаемыеДанные и заполняем их из ПолныеДанные методом НайтиСтроки() (если условия на равенство) или простым перебором (для условий больше/меньше). Это гарантирует, что исходные данные всегда под рукой и нам не нужно обращаться к базе данных для повторного получения информации.
Мы выяснили, что прямого способа использовать ВидСравнения.Больше в свойстве ОтборСтрок управляемой формы не существует. Однако, комбинируя программный перебор и флаг-индикатор, можно добиться того же результата. Для большинства задач оптимальным выбором будет Способ №1 (Вспомогательная колонка), так как он сохраняет целостность данных в таблице и корректно работает с интерфейсом платформы 8.3.