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