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