Как программно получить сумму колонки или итоги динамического списка в 1С 8.3?

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

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

Анализ проблемы и выбор стратегии

Прежде всего, проанализируем ситуацию: почему стандартный обход строк формы не работает? Динамический список — это не таблица значений, а механизм отображения данных, полученных в результате выполнения запроса. На стороне клиента доступны только те данные, которые видны пользователю в данный момент. Если в списке 10 000 записей, а на экране 20, клиент "знает" только об этих двадцати. В некоторых случаях разработчикам требуется специфический функционал, например, подсчет итогов по выделенным строкам, но для получения общей суммы по всему фильтру нужен запрос к БД.

Для решения задачи нам необходимо выполнить запрос к базе данных, который будет полностью идентичен запросу динамического списка, включая все пользовательские настройки: отборы, группировки и параметры. Разберем по шагам, как рассчитать сумму колонки с учетом установленных фильтров на серверной стороне.

Способ 1: Использование Схемы Компоновки Данных (СКД)

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


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

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

Способ 2: Прямое формирование запроса (через Компоновщик настроек)

Иногда использование полной схемы компоновки может быть избыточным. В таком случае мы можем проанализировать ситуацию и фактически преобразовать динамический список в отчет СКД, используя только необходимые части компоновщика настроек для формирования текста запроса с учетом отборов пользователя.

Рассмотрим подробнее алгоритм действий:

  1. Получаем текст запроса из динамического списка.
  2. Инициализируем ПостроительЗапроса или используем временную схему СКД только для получения текста ГДЕ.
  3. Добавляем агрегатную функцию СУММА() к исходному тексту запроса.

&НаСервере
Функция РассчитатьИтогСУчетомФильтров(ТекстЗапросаСписка)
    
    Схема = Новый СхемаКомпоновкиДанных;
    Источник = Схема.ИсточникиДанных.Добавить();
    Источник.Имя = "ИсточникДанных1";
    Источник.ТипИсточникаДанных = "Local";
    
    НаборДанных = Схема.НаборыДанных.Добавить(Тип("НаборДанныхЗапросСхемыКомпоновкиДанных"));
    НаборДанных.Имя = "Набор1";
    НаборДанных.Запрос = ТекстЗапросаСписка;
    НаборДанных.ИсточникДанных = "ИсточникДанных1";
    
    // Добавляем поле для итога
    ПолеИтога = НаборДанных.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
    ПолеИтога.ПутьКДанным = "СуммаДокумента";
    ПолеИтога.Поле = "СуммаДокумента";
    
    // Используем настройки текущего списка
    Компоновщик = Новый КомпоновщикНастроекКомпоновкиДанных;
    Компоновщик.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(Схема));
    Компоновщик.ЗагрузитьНастройки(Список.КомпоновщикНастроек.ПолучитьНастройки());
    
    // Далее выполняем аналогично первому способу через КомпоновщикМакета
    // ...
КонецФункции

Важные нюансы и оптимизация

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

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

Также стоит помнить об объекте ДанныеФормыСтруктураСПолямиСостава. В некоторых случаях, если вам нужно получить только количество записей, Платформа 8.3 позволяет сделать это проще через свойства самого списка. Однако, если ваша цель — вывести итоги в подвале динамического списка программными методами, вышеописанные подходы через СКД остаются наиболее гибкими.

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

Таким образом, мы разобрали по шагам процесс получения итогов. Использование исполняемой схемы компоновки — наиболее "чистый" путь, так как он автоматически учитывает параметры, наложенные системой (например, параметры функциональных опций или ограничения прав доступа RLS), которые вы могли бы упустить при ручном написании запроса.

← На главную