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