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