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