Как определить наличие отбора в табличной части и обработать только видимые строки

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

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

Анализ механизма фильтрации в обычных формах

Прежде всего, разберем ситуацию. Когда пользователь нажимает правую кнопку мыши на ячейке и выбирает «Отбор по текущему значению» или использует кнопку «Установить отбор», платформа не удаляет строки из коллекции табличной части. Она лишь накладывает визуальный фильтр на элемент управления ТабличноеПоле.

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

Проанализируем пример кода, который позволяет определить, активен ли хотя бы один фильтр:


Функция ЕстьАктивныйОтбор(ЭлементТабличноеПоле)
    Для Каждого ЭлементОтбора Из ЭлементТабличноеПоле.ОтборСтрок Цикл
        Если ЭлементОтбора.Использование Тогда
            Возврат Истина;
        КонецЕсли;
    КонецЦикла;
    Возврат Ложь;
КонецФункции

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

Способ 1. Использование метода НайтиСтроки

Если нам нужно просто пометить строки, соответствующие простейшим условиям (вид сравнения «Равно»), мы можем использовать метод НайтиСтроки() самой табличной части. Это наиболее быстрый и лаконичный способ, если отбор не является сложным (например, не используются интервалы «Больше» или «Меньше»).

Разберем алгоритм по шагам:

  1. Создадим структуру для поиска.
  2. Переберем активные элементы отбора из ОтборСтрок.
  3. Заполним структуру только теми полями, где ВидСравнения равен Равно.
  4. Вызовем метод НайтиСтроки() и обработаем результат.

Посмотрим на пример реализации:


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

Важное ограничение: этот метод не сработает, если пользователь применил сложные условия, такие как «В списке», «Не равно» или «Содержит». В таких случаях нам потребуется более мощный инструмент.

Способ 2. Использование Построителя Запроса

Наиболее универсальный и надежный метод — это использование объекта ПостроительЗапроса. Он позволяет скопировать настройки отбора из экранной формы и применить их к источнику данных. Это гарантирует, что программная выборка будет на 100% совпадать с тем, что пользователь видит в таблице.

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

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

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

Пример программного кода для решения задачи:


Процедура ПометитьСтрокиПостроителем()
    // 1. Подготовка данных
    ТаблицаДанных = Объект.Товары.Выгрузить();
    
    // 2. Настройка построителя
    Построитель = Новый ПостроительЗапроса;
    Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(ТаблицаДанных);
    
    // 3. Копирование отборов из формы
    Для Каждого ЭлементОтбораФормы Из ЭлементыФормы.Товары.ОтборСтрок Цикл
        Если ЭлементОтбораФормы.Использование Тогда
            ИмяПоля = ЭлементОтбораФормы.Имя;
            НовыйОтбор = Построитель.Отбор.Добавить(ИмяПоля);
            ЗаполнитьЗначенияСвойств(НовыйОтбор, ЭлементОтбораФормы);
        КонецЕсли;
    КонецЦикла;
    
    // 4. Получение результата
    Построитель.Выполнить();
    Результат = Построитель.Результат.Выгрузить();
    
    // 5. Обработка строк основной ТЧ на основании результата
    // Для идентификации строк удобно использовать номер строки или уникальный идентификатор
    Для Каждого СтрокаРезультата Из Результат Цикл
        // Находим строку в исходной табличной части по номеру строки
        // (Предполагается, что в ТЗ есть колонка НомерСтроки)
        ТекущаяСтрока = Объект.Товары.Найти(СтрокаРезультата.НомерСтроки, "НомерСтроки");
        Если ТекущаяСтрока <> Неопределено Тогда
            ТекущаяСтрока.Пометка = Истина;
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры

Отличие Отбора от Поиска

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

В такой ситуации мы можем предложить пользователю два варианта:

Работа с выделенными строками

Иногда самым простым решением является работа с коллекцией ВыделенныеСтроки. Если пользователь отфильтровал таблицу и хочет совершить действие, он может выделить нужные строки мышкой или через Ctrl+A.

Проанализируем, как работать с этим свойством:


Процедура ОбработатьВыделенные()
    Для Каждого Строка Из ЭлементыФормы.Товары.ВыделенныеСтроки Цикл
        Строка.Пометка = Истина;
    КонецЦикла;
КонецПроцедуры

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

Недостаток: если пользователь забыл нажать Ctrl+A после применения фильтра, код обработает только ту строку, на которой стоит курсор.

Обновление интерфейса

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

Для принудительной перерисовки строк используем следующий метод:

ЭлементыФормы.Товары.ОбновитьСтроки();

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

Резюме

Мы рассмотрели три основных подхода к решению задачи. Выбор метода зависит от сложности задачи:

  1. Для простых отборов (равенство) — используйте НайтиСтроки().
  2. Для сложных условий и полной идентичности с экранным фильтром — используйте ПостроительЗапроса.
  3. Для гибкого взаимодействия, когда пользователь сам решает, что пометить — используйте работу с ВыделенныеСтроки.

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

← На главную