Как посчитать итоги по строкам табличной части, попавшим в отбор или поиск в управляемых формах 1С?

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

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

Механизм работы с видимыми строками: метод ПроверитьСтроку

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

Разберем синтаксис и особенности этого метода. Он принимает идентификатор строки и возвращает булево значение: Истина, если строка отображается в данный момент, и Ложь, если она скрыта фильтром. Если таблица пуста или не отображается, метод может вернуть Неопределено.

Алгоритм расчета итогов по отфильтрованным строкам

Давайте вместе составим пошаговый план реализации этой функции. Нам потребуется обойти всю коллекцию строк табличной части на клиенте, проверить каждую строку на соответствие фильтру и, если условие выполняется, прибавить значение к общей сумме.

Рассмотрим пример кода, который выполняет такой расчет:


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

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

Проблема отсутствия события изменения отбора

Выясним причину основной сложности: платформа 1С не предоставляет штатного события, такого как "ПриИзмененииОтбора" или "ПослеПоиска". Это означает, что программа не "знает" автоматически, когда именно пользователь ввел текст в строку поиска или нажал "Искать". Чтобы итоги всегда оставались актуальными, нам нужно проявить изобретательность.

Проанализируем основные способы "подцепить" вызов пересчета:

  1. Обработчик ожидания. Это наиболее надежный способ для работы со стандартным поиском. Мы можем подключить процедуру, которая будет срабатывать раз в 1-2 секунды и обновлять итог.
  2. Событие ПриАктивизацииСтроки. Когда пользователь ищет данные, он обычно перемещается по результатам. В этот момент срабатывает активация строки, где мы можем вызвать наш расчет.
  3. Использование свойства СтрокаПоиска. В современных версиях платформы (начиная с 8.3.15) у элемента формы "Таблица" появилось свойство СтрокаПоиска. Мы можем анализировать его изменение.

Посмотрим на пример реализации через обработчик ожидания, чтобы автоматизировать процесс:


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

&НаКлиенте
Процедура ОбновитьИтогиСУчетомФильтра()
    // Вызываем нашу процедуру расчета
    ПосчитатьИтогиПоОтбору();
КонецПроцедуры

Оптимизация производительности

При работе с большими табличными частями (более 500-1000 строк) постоянный перебор всех элементов в цикле на клиенте может привести к заметным задержкам интерфейса ("фризам"). В таких случаях рекомендуется внедрить проверку на необходимость пересчета. Например, хранить предыдущее значение строки поиска и выполнять цикл только в том случае, если строка поиска изменилась.

Также следует помнить, что стандартный "подвал" таблицы (Footer) не умеет автоматически показывать итог только по отфильтрованным строкам — он всегда показывает сумму по всей коллекции Объект.Товары. Поэтому для вывода "динамического" итога лучше использовать отдельное поле надписи (Label) или декорацию, размещенную непосредственно под таблицей — для этого подойдёт расчет итоговых сумм по видимым строкам 1С.

Различие между ОтборСтрок и стандартным поиском

Разберем важный нюанс, упомянутый в обсуждении. Существует программный ОтборСтрок (структура, ограничивающая видимость данных) и интерактивный поиск (Ctrl+F). Метод ПроверитьСтроку() универсален — он учитывает оба этих фактора одновременно. Если же вы используете только программный ОтборСтрок, вы можете вручную перебирать структуру отбора, но это не поможет, если пользователь воспользуется желтой строкой поиска. Поэтому использование ПроверитьСтроку() является наиболее предпочтительным и безопасным методом.

Особенности для динамических списков

Важно не путать табличные части с динамическими списками. Если ваша задача — посчитать итоги в списке (например, в списке документов), то метод ПроверитьСтроку() там недоступен. Для динамических списков решение строится совершенно иначе: на сервере выполняется запрос к базе данных, в который передаются параметры отбора из КомпоновщикаНастроек этого списка. Но для обычных табличных частей документов и справочников наш разобранный метод является стандартом разработки.

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

← На главную