Как получить строки таблицы значений, отобранные пользователем с помощью Ctrl+F или Alt+F?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке интерфейсов на управляемых формах 1С часто возникает задача: пользователь применяет стандартный интерактивный поиск (комбинации клавиш Ctrl+F, Alt+F или строку поиска в шапке таблицы), а разработчику необходимо программно обработать только те строки, которые остались видимыми на экране. Разберем, почему стандартные свойства отбора не содержат этих данных и как правильно получить видимые строки таблицы формы.

В чем сложность: данные против визуального отображения

Проанализируем архитектуру управляемой формы. В платформе 1С существует строгое разделение между источником данных (коллекцией ДанныеФормыКоллекция, представляющей таблицу значений) и элементом интерфейса (ТаблицаФормы).

Когда разработчик программно устанавливает свойство Элементы.ИмяТаблицы.ОтборСтрок, передавая туда объект ФиксированнаяСтруктура, фильтрация жестко фиксируется в параметрах элемента. Однако интерактивный поиск через Ctrl+F или Alt+F работает иначе: он относится исключительно к уровню клиентского отображения. Платформа 1С не помещает критерии интерактивного поиска в ОтборСтрок и не предоставляет прямого API для чтения введенной пользователем строки поиска или выбранной колонки.

Основное решение: использование метода ПроверитьСтроку

Для проверки того, видна ли конкретная строка пользователю с учетом всех примененных фильтров и интерактивного поиска, в объекте ТаблицаФормы реализован метод ПроверитьСтроку(). Рассмотрим особенности его использования:

  1. Метод доступен только на клиенте. На стороне сервера вызвать его невозможно.
  2. В качестве параметра метод принимает не саму строку и не её порядковый номер в коллекции, а числовой идентификатор строки, который возвращается вызовом ПолучитьИдентификатор().
  3. Метод возвращает булево значение: Истина, если строка отображается в интерфейсе (проходит все условия поиска и отбора), и Ложь, если строка скрыта.

Посмотрим на практический пример обхода таблицы на клиенте и отбора видимых строк:


&НаКлиенте
Процедура ОбработатьВидимыеСтроки(Команда)
    
    МассивВидимыхИдентификаторов = Новый Массив;
    
    Для Каждого Стр Из ТаблицаДанных Цикл
        Идентификатор = Стр.ПолучитьИдентификатор();
        Если Элементы.ТаблицаДанных.ПроверитьСтроку(Идентификатор) Тогда
            МассивВидимыхИдентификаторов.Добавить(Идентификатор);
        КонецЕсли;
    КонецЦикла;
    
    // Передаем отобранные идентификаторы на сервер для дальнейшей обработки
    ОбработатьСтрокиНаСервере(МассивВидимыхИдентификаторов);
    
КонецПроцедуры

Важные ограничения метода ПроверитьСтроку

Разберем нюансы, о которых необходимо помнить при реализации такого алгоритма:

  1. Производительность: Метод вызывается синхронно в интерфейсном потоке клиента. Если таблица значений содержит десятки тысяч строк, поочередная проверка каждой строки в цикле вызовет заметное зависание формы.
  2. Отсутствие событий поиска: В платформе нет отдельного события на изменение или очистку интерактивного поиска Ctrl+F. Запустить цикл проверки можно только по явному действию пользователя (например, при нажатии специализированной кнопки) либо косвенно (например, в событии ПриАктивизацииСтроки).
  3. Передача на сервер: Поскольку сам метод серверу недоступен, собрать массив идентификаторов или индексов необходимо на клиенте, после чего передать его параметром в серверную процедуру для чтения исходных данных.

Альтернативные подходы к решению задачи

Рассмотрим другие варианты реализации, которые позволяют избежать клиентского перебора или полностью снять ограничения интерактивного поиска.

1. Использование динамического списка с корректным запросом

Нередко отказ от ДинамическийСписок в пользу таблицы значений происходит из-за заблуждения, что в произвольном запросе динамического списка нельзя обратиться через точку к полям родительских элементов. Это ограничение легко обходится двумя способами:

  1. Явное приведение типа: Если поле составного типа, используем конструкцию ВЫРАЗИТЬ(Поле КАК Справочник.Номенклатура).Родитель. После явного указания типа платформа позволяет обращаться через точку к любым реквизитам.
  2. Левое соединение: В тексте запроса можно связать таблицу саму с собой по полю Родитель через ЛЕВОЕ СОЕДИНЕНИЕ.

Оставаясь на динамическом списке, мы получаем возможность использовать ПолучитьИсполняемыеНастройкиКомпоновкиДанных(), перекладывая всю фильтрацию на СУБД и получая прозрачный доступ к примененным отборам.

2. Считывание через множественное выделение строк

Если пользователю требуется выполнить операцию над отображаемыми данными, можно задействовать стандартное свойство элемента формы ВыделенныеСтроки. Разберем порядок действий:

  1. Пользователь накладывает фильтр через Ctrl+F.
  2. Пользователь выделяет все видимые строки комбинацией клавиш Ctrl+A.
  3. В коде мы сразу считываем Элементы.ТаблицаДанных.ВыделенныеСтроки, получая готовый массив идентификаторов без циклической проверки всей таблицы.

3. Организация собственного поля поиска на форме

Если требуется полный программный контроль над введенным значением, лучше отказаться от стандартного окна поиска Ctrl+F в пользу отдельного реквизита формы «СтрокаПоиска». В обработчике ПриИзменении этого поля разработчик может:

  1. Программно устанавливать Элементы.ТаблицаДанных.ОтборСтрок при строгом совпадении значений.
  2. Использовать метод коллекции НайтиСтроки() для точного поиска.
  3. Явно сохранять введенную строку в контексте формы и использовать её в любых серверных алгоритмах без обхода визуальных элементов.
← На главную