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

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

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

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

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

Основной способ: использование метода «ПроверитьСтроку»

Проанализируем возможности элемента формы ТаблицаФормы. В синтакс-помощнике присутствует клиентский метод ПроверитьСтроку(), который проверяет, соответствует ли конкретная строка установленному в таблице отбору (в том числе интерактивному пользовательскому поиску).

Обратите внимание на ключевую особенность: метод принимает в качестве параметра не порядковый индекс строки, а ее идентификатор (тип Число). Если в коде использовать индекс из цикла, возникнет логическая ошибка при любых интерактивных перемещениях или удалениях строк. Правильный идентификатор следует получать с помощью метода ПолучитьИдентификатор() у строки коллекции.

Посмотрим на пример правильного обхода строк на клиенте:


&НаКлиенте
Процедура ОбработатьВидимыеСтроки()

    МассивИдентификаторов = Новый Массив;

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

    // Передаем полученные данные для дальнейшей обработки
    ПараметрыФормы = Новый Структура("ОтфильтрованныеСтроки", МассивИдентификаторов);
    ОткрытьФорму("Обработка.МояОбработка.Форма.Форма", ПараметрыФормы);

КонецПроцедуры

Разберем важные нюансы работы этого метода:

  1. Метод ПроверитьСтроку доступен только на клиенте, так как визуальное представление фильтра существует исключительно в контексте клиентского интерфейса.
  2. Если строка не найдена или таблица не отображается на форме, функция возвращает Неопределено. Поэтому проверка условия должна выполняться строго на равенство Истина.
  3. При передаче данных через параметры метода ОткрытьФорму нельзя передавать сами элементы типа ДанныеФормыЭлементКоллекции, так как они не сериализуются. Рекомендуется передавать массив идентификаторов, номеров строк или ключевых реквизитов.

Как определить факт наличия отбора или поиска в таблице

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

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

  1. Подсчитываем количество строк, для которых ПроверитьСтроку() = Истина.
  2. Сравниваем полученное число с общим количеством строк в коллекции Объект.ИмяТЧ.Количество().
  3. Если число прошедших проверку строк меньше общего объема строк, делаем вывод: в таблице активен поиск или отбор.

Посмотрим на пример функции проверки:


&НаКлиенте
Функция УстановленОтборВТаблице()

    ВсегоСтрок = Объект.Товары.Количество();
    ВидимыхСтрок = 0;

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

    Возврат ВидимыхСтрок < ВсегоСтрок;

КонецФункции

Альтернативные варианты решения

Рассмотрим другие сценарии работы, если поведение стандартного диалога поиска не подходит для архитектуры решения:

  1. Управляемый программный отбор:
    Вместо стандартного окна «Найти» можно разместить над таблицей отдельное поле ввода для поиска и накладывать фильтрацию программно через свойство элемента управления ОтборСтрок. В управляемых формах для этого используется объект ФиксированнаяСтруктура:
    
    Элементы.Товары.ОтборСтрок = Новый ФиксированнаяСтруктура("Номенклатура", ИскомоеЗначение);
    
    Для сброса такого фильтра достаточно присвоить свойству пустую структуру или Неопределено. При таком подходе критерии отбора всегда хранятся в реквизитах формы и точно известны разработчику.
  2. Использование свойства «ВыделенныеСтроки»:
    Если на таблицу наложен интерактивный поиск, пользователь может нажать сочетание клавиш Ctrl + A (Выделить все). В этом случае выделятся только видимые на экране строки. После этого список их идентификаторов можно сразу прочитать из свойства Элементы.Товары.ВыделенныеСтроки. Однако такой подход требует дополнительных действий от пользователя и не всегда удобен.

Таким образом, для получения отфильтрованных строк наиболее надежным и универсальным решением является обход коллекции с передачей идентификатора каждой строки в клиентский метод Элементы.ИмяТаблицы.ПроверитьСтроку().

← На главную