Как вывести итоговую сумму в подвал ТабличногоПоля и отловить его обновление в 1С 7.7 (1CPP)?

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

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

Причина проблемы и особенности работы с событиями

Выясним, почему стандартная попытка посчитать итоги прямо в процедуре ЭкранПриВыводеСтроки приводит к ошибкам и зависаниям интерфейса:

  1. Динамическая отрисовка: Событие ПриВыводеСтроки срабатывает исключительно для тех строк, которые видны пользователю на экране в данный момент. Попытка суммировать значения при отрисовке строк посчитает только видимую область, а при скроллинге данные исказятся.
  2. Нагрузка на базу данных: Вызов методов получения остатков регистров вида Регистр.ДолгОтгрузки.Остаток(...) внутри события отрисовки ячейки выполняется при каждом пересчете экрана. Это приводит к задержкам и «зависанию» журнала при прокрутке.
  3. Однократный вывод подвала: Регионы шапки (ТипРегиона = 2) и подвала (ТипРегиона = 4) отрисовываются при инициализации формы. При прокрутке основного списка (ТипРегиона = 3) подвал повторно не вызывается автоматически, поэтому его нужно обновлять программно.

Для понимания логики вывода строк приведем значения типов регионов элемента ТабличноеПоле:

  1. 0 — регион не задан;
  2. 1 — заголовок;
  3. 2 — шапка;
  4. 3 — строки (основная область данных);
  5. 4 — подвал (footer).

Правильная архитектура расчета и вывода итогов

Разберем по шагам корректный алгоритм вычисления и отображения итоговой суммы:

  1. Разделение логики: Расчет общей суммы должен производиться отдельно по всем документам списка (или через прямой SQL-запрос), а результат сохраняться в переменную модуля формы (например, ИтоговыйДолг).
  2. Вывод в событии подвала: В процедуре ЭкранПриВыводеСтроки при обработке ТипРегиона = 4 значение из переменной устанавливается в ячейку подвала.
  3. Принудительное обновление подвала: При изменении отборов, периода или перечитывании данных журнала вызывается программное обновление строк подвала.

Пример реализации кода

Рассмотрим пример добавления колонки и настройки вывода подвала в модуле формы:


// Переменная модуля для хранения итогового значения
Перем ИтоговыйДолг;

Процедура ПриОткрытии()
    // Добавление колонки данных и колонки отображения
    Данные.ДобавитьКолонкуДанных("Долг", "Долг", "''", "Число", 15, 2);
    Данные.НоваяКолонка("Долг", 1);
    
    ИтоговыйДолг = 0;
КонецПроцедуры

Процедура ЭкранПриВыводеСтроки(ТабличноеПоле, ОформлениеСтроки, ДанныеСтроки, ТипРегиона)
    Если ТипРегиона = 3 Тогда
        // Отрисовка основной строки
        ТекДок = ДанныеСтроки.Получить("ТекущийДокумент");
        ОформлениеЯчейки = ОформлениеСтроки.Ячейки.Получить("Долг");
        // Примечание: Для высокой скорости рекомендуем получать Долг в SQL-запросе поставщика
        ОформлениеЯчейки.УстановитьТекст(Регистр.ДолгОтгрузки.Остаток(ТекДок, "Долг"));
        
    ИначеЕсли ТипРегиона = 4 Тогда
        // Отрисовка подвала (footer)
        ОформлениеЯчейки = ОформлениеСтроки.Ячейки.Получить("Долг");
        ОформлениеЯчейки.УстановитьТекст(Строка(ИтоговыйДолг));
    КонецЕсли;
КонецПроцедуры

Как обновлять итоги в подвале

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

Для принудительного обновления визуального состояния подвала используем следующий метод:


Процедура ОбновитьИтогиПодвала()
    // 1. Выполняем полный расчет суммы по всему набору данных
    // Например, с помощью запроса или обхода выборки
    ИтоговыйДолг = РассчитатьОбщуюСуммуДолга(); 
    
    // 2. Принудительно обновляем отображение строк подвала
    ТабличноеПоле.Подвал.ОбновитьСтроки();
КонецПроцедуры

Если для подвала используется отдельный поставщик данных, обновить его строки можно через обращение к источнику:

ПоставщикДанных.ТабличноеПоле.Подвал.ОбновитьСтроки();

Оптимизация через прямой SQL-запрос

Проанализируем наиболее производительный вариант: если ПоставщикДанных работает на базе прямого SQL-запроса (ODBC), вычисление долга по каждому документу и подсчет общей суммы лучше всего вынести на сторону СУБД.

В этом случае колонка «Долг» соединяется с виртуальной таблицей остатков регистра прямо в SQL-запросе. Это полностью исключит задержки при прокрутке журнала, а итоговая сумма будет получаться за один агрегатный запрос с помощью функции SUM().

← На главную