Как получить итоги по строкам, отобранным с помощью стандартного поиска (Ctrl+F) в 1С

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

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

Почему стандартный поиск не позволяет легко посчитать итоги?

Проанализируем ситуацию: когда пользователь нажимает Ctrl+F и вводит значение, платформа скрывает строки, не соответствующие критерию, непосредственно в графическом интерфейсе клиента. При этом сама коллекция данных (например, ТаблицаЗначений или ТабличнаяЧасть), находящаяся в памяти сервера, остается неизменной. Поскольку состав строк в объекте данных не меняется, серверные события не вызываются, и мы не можем простым способом перехватить момент окончания фильтрации.

Тем не менее, существует несколько проверенных способов решения этой проблемы. Выясним, какой из них лучше подходит для ваших задач.

Решение 1: Использование программного фильтра вместо стандартного поиска

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

  1. Добавим на форму реквизит ТекстПоиска (тип Строка).
  2. Вынесем его на форму и установим режим ОтображениеКнопкиВыбора в значение «Нет», а РежимИзмененияТекста — «ПриНабореТекста».
  3. В событии ПриИзменении или через обработчик ожидания будем накладывать фильтр на таблицу.

Рассмотрим пример кода для фильтрации ТаблицыЗначений:


&НаКлиенте
Процедура ТекстПоискаПриИзменении(Элемент)
    
    // Устанавливаем отбор для элемента формы "Таблица"
    ЭлементОтбора = Элементы.ТаблицаДанных.ОтборСтрок;
    
    // Если поиск пустой - очищаем отбор
    Если ПустаяСтрока(ТекстПоиска) Тогда
        Элементы.ТаблицаДанных.ОтборСтрок = Неопределено;
    Иначе
        // Создаем структуру отбора (например, по колонке "Наименование")
        НовыйОтбор = Новый ФиксированнаяСтруктура("Наименование", ТекстПоиска);
        Элементы.ТаблицаДанных.ОтборСтрок = НовыйОтбор;
    КонецЕсли;
    
    // Теперь мы можем точно посчитать итоги, так как сами инициировали поиск
    РассчитатьИтогиПо ВидимымСтрокам();
    
КонецПроцедуры

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

Решение 2: Переход на использование Динамического списка

Если данные в вашей таблице позволяют, стоит рассмотреть замену ТаблицыЗначений на ДинамическийСписок. Даже если данные не хранятся в базе данных, их можно загрузить во временную таблицу и отобразить через список.

Разберем, почему это удобно: У Динамического списка есть встроенный механизм КомпоновщикНастроек. Когда пользователь применяет стандартный поиск, платформа автоматически модифицирует отбор в компоновщике. Мы можем программно обратиться к схеме компоновки, получить исполняемый запрос с учетом всех фильтров пользователя и выполнить агрегатные функции (СУММА, КОЛИЧЕСТВО) прямо на сервере.

Решение 3: Использование обработчика ожидания для отслеживания изменений

Если использование стандартного Ctrl+F принципиально, мы можем применить «хитрость» с обработчиком ожидания. Посмотрим на алгоритм:

В управляемой таблице есть свойство ОтборСтрок. Хотя оно не всегда заполняется при простом поиске Ctrl+F, оно активно используется при расширенном поиске. Для отслеживания состояния видимости строк можно использовать событие ОбновлениеОтображения или ПодключитьОбработчикОжидания.


&НаКлиенте
Процедура ПриОткрытии(Отказ)
    // Запускаем проверку каждые 2 секунды (или реже, чтобы не нагружать систему)
    ПодключитьОбработчикОжидания("ПроверитьИзменениеПоиска", 2);
КонецПроцедуры

&НаКлиенте
Процедура ПроверитьИзменениеПоиска()
    // Метод "ВывестиСписок" видит только отфильтрованные строки. 
    // Мы можем использовать это для анализа.
    // Однако программный вызов "ВывестиСписок" сложен, поэтому лучше 
    // проверять количество строк через свойство элементов формы, если оно доступно.
    
    РассчитатьИтоги();
КонецПроцедуры

Важный момент: Событие ПриАктивизацииСтроки также срабатывает после того, как поиск скрыл лишние данные и фокус переместился на первую найденную строку. Это подходящий момент для разового пересчета.

Решение 4: Встроенный автоподсчет итогов в платформе

Начиная с современных релизов платформы 8.3, для элементов типа «Таблица» предусмотрено свойство «Автоподсчет итогов в подвале». Разберем, как его включить:

  1. В свойствах таблицы на форме установите галочку Подвал.
  2. Для конкретной колонки (например, «Сумма») найдите свойство ПутьКДаннымПодвала.
  3. Укажите агрегатную функцию (например, Сумма).

Проанализируем поведение: в некоторых случаях платформа сама пересчитывает значение в подвале при изменении видимых строк. Однако, как отмечают разработчики, для Таблиц Значений этот механизм при использовании Ctrl+F может работать нестабильно. Рекомендуется проверять это поведение на конкретной версии платформы.

Решение 5: Создание кнопки «Пересчитать итоги»

Как предлагалось в сообщениях №5 и №14 обсуждения, если автоматизация слишком трудозатратна, можно пойти по пути наименьшего сопротивления — добавить кнопку (например, с иконкой обновления или калькулятора). При нажатии на нее программно обходятся строки таблицы.

Но как понять, какие строки видны? Здесь поможет метод ВывестиСписок. Если пользователь выберет команду «Еще — Вывести список», в результат попадут только отфильтрованные строки. Программная имитация этого процесса через построитель отчета или систему компоновки данных позволит получить точный результат, идентичный тому, что видит пользователь на экране.

Подведем итоги

Выбор метода зависит от критичности автоматизации:

Помните, что избыточное использование тяжелых вычислений в событиях типа ОбновлениеОтображения может привести к значительному замедлению интерфейса, поэтому всегда ограничивайте частоту вызовов или выполняйте расчеты на стороне сервера.

← На главную