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