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