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