Как реализовать сложный отбор в строках табличной части на управляемой форме 1С?

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

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

Проблема использования свойства ОтборСтрок

Разберем ситуацию, с которой столкнулся автор темы. При попытке программно установить фильтр через свойство ОтборСтрок, многие ожидают поведения, аналогичного работе с динамическими списками. Однако свойство ОтборСтрок имеет существенное ограничение: оно принимает объект типа ФиксированнаяСтруктура. Это означает, что мы можем использовать только строгое равенство.

Проанализируем типичную ошибку. Попытка написать код следующего вида приведет к неудаче:


ЭтаФорма.Элементы.Состав.ОтборСтрок.ВЗаказ.ВидСравнения = ВидСравнения.Больше; // Ошибка!
ЭтаФорма.Элементы.Состав.ОтборСтрок.ВЗаказ.Значение = 0;

Поскольку ФиксированнаяСтруктура — это просто набор пар «Ключ-Значение», у нее нет свойств ВидСравнения или Использование. Платформа просто ищет в колонке «ВЗаказ» точное совпадение со значением. Если нам нужно условие «Больше 0», стандартный ОтборСтрок нам не поможет напрямую. Выясним, как обойти это ограничение.

Способ №1: Использование вспомогательного реквизита (Флаг фильтрации)

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

Пошаговый алгоритм реализации:

  1. Добавление реквизита: В табличную часть объекта (или в реквизиты формы, если таблица создана программно) добавим колонку ПодходитПодОтбор с типом Булево.
  2. Заполнение признака: Напишем процедуру, которая обходит строки таблицы и устанавливает истину там, где выполняется наше условие (например, ВЗаказ > 0).
  3. Установка отбора: Применим ФиксированнуюСтруктуру к этому новому полю.

Рассмотрим пример кода для реализации этого метода:


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

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

Способ №2: Использование Динамического списка для отображения ТЧ

Если ваша задача — отображать состав документа в форме списка (как в исходном вопросе), то использование прямой привязки к ТекущиеДанные.Товары не всегда является оптимальным. Рассмотрим более профессиональный подход — использование Динамического списка. Для реализации логических полей в интерфейсе пригодится пример настройки флажков в динамическом списке.

Динамический список позволяет использовать всю мощь языка запросов и полноценную систему компоновки данных (СКД). Посмотрим, как это настроить:

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


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

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

Способ №3: Выгрузка в Таблицу Значений

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

Разберем, как это работает по шагам:

  1. При смене строки в основном списке (событие ПриАктивизацииСтроки) мы вызываем серверный метод.
  2. На сервере получаем объект документа или его ТЧ через запрос.
  3. Выгружаем только нужные строки (согласно условию) в реквизит формы типа ТаблицаЗначений.
  4. Отображаем эту ТЗ пользователю.

Пример реализации переноса данных:


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

Преимущество: Полная гибкость. Вы можете применять любые условия, группировки и сортировки. Недостаток: Если данные нужно редактировать и сохранять обратно в документ, потребуется написание сложной логики синхронизации между ТЗ формы и реальной ТЧ документа.

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

Подводя итог нашему анализу, можно выделить следующие рекомендации для выбора метода:

1. Если вам нужно быстро внедрить фильтр в существующую табличную часть с возможностью редактирования — используйте Способ №1 (вспомогательная колонка Булево). Это стандарт индустрии для небольших объемов данных.

2. Если вы проектируете сложный интерфейс (например, АРМ менеджера) и данных много — выбирайте Способ №2 (Динамический список). Это обеспечит максимальную производительность и удобство настройки отборов пользователем.

3. Помните, что Условное оформление (скрытие текста или покраска фона) не заменяет отбор. Строки все равно останутся в списке, создавая "пустоты", что обычно неудобно для пользователя. Всегда стремитесь именно к фильтрации данных, а не к их визуальной маскировке.

← На главную