Как рассчитать сумму только по видимым строкам в подвале таблицы значений после стандартного поиска в 1С 8.3

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

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

Почему стандартные методы не работают

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

Решение №1: Использование метода ПроверитьСтроку() и обработчика ожидания

Наиболее надежным способом определить, какие строки видит пользователь в данный момент, является использование метода ПроверитьСтроку(). Этот метод проверяет, соответствует ли строка текущим настройкам отбора и поиска. Разберем по шагам, как реализовать автоматический пересчет.

Поскольку мы не можем «поймать» момент нажатия кнопки «Найти», нам придется использовать ПодключитьОбработчикОжидания. Это позволит системе периодически проверять состояние таблицы и обновлять итоги.

Шаг 1. Создание процедуры пересчета на клиенте

Нам необходимо обойти все строки таблицы и вызвать метод ПроверитьСтроку() для каждой из них. Рассмотрим пример кода:


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

Шаг 2. Подключение обработчика ожидания

Чтобы сумма обновлялась «сама собой», подключим эту процедуру в событии формы ПриОткрытии или ПриСозданииНаСервере (через клиентский вызов):


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

Решение №2: Использование события ПриОбновленииОтображения

Если использование обработчика ожидания кажется вам не слишком изящным решением (например, из-за лишних срабатываний), проанализируем событие формы ПриОбновленииОтображения. Это событие вызывается платформой всякий раз, когда форма перерисовывается, в том числе после применения поиска.

Важное предостережение: это событие срабатывает очень часто (при шевелении мышью, смене фокуса). Чтобы избежать «тормозов» интерфейса, внутри этого события нужно обязательно проверять, изменились ли условия, прежде чем запускать тяжелый цикл обхода строк.


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

Решение №3: Суммирование по выделенным строкам (альтернативный подход)

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


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

Проблема программной очистки поиска

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

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

  1. Перезаполнение таблицы: Полная очистка и загрузка данных в ТЗ иногда сбрасывает визуальный фильтр, но это ведет к потере позиции курсора.
  2. Использование команд: Можно попытаться вызвать стандартную команду отмены поиска через ВыполнитьКоманду("StdCommand.FilterByCurrentValueCancel"), однако это требует точной установки фокуса в нужную колонку, что не всегда надежно.
  3. Замена ТЗ на Динамический список: Если фильтрация и итоги являются критически важной частью бизнес-логики, рассмотрим возможность использования ДинамическогоСписка с источником данных «Временная таблица». У динамического списка есть программный доступ к отборам и поиску, что решает все описанные проблемы.

Итоги и рекомендации

Мы рассмотрели несколько способов обхода ограничений платформы 1С при работе со стандартным поиском в таблицах значений. Подведем итоги:

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

← На главную