Как вывести сумму табличной части в форму списка документов?

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

Часто перед разработчиками 1С встает задача отобразить в форме списка документов итоговую сумму по табличной части. Используя проверенные методы доработки динамических списков, можно обойти ограничения платформы. Прямая попытка решить это через запрос в ДинамическийСписок с использованием СУММА() и соединения с табличной частью приводит к ошибке «нельзя группировать по полям внешних таблиц при наличии вложенных таблиц». Давайте разберем, почему возникает эта проблема и как ее эффективно решить.

Почему не работает прямая группировка в запросе?

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

Решение 1: Добавление реквизита в шапку документа

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

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

Решение 2: Использование события ПриПолученииДанныхНаСервере

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

Для реализации этого метода:

  1. В ДинамическийСписок формы добавьте новый элемент управления — колонку (например, СуммаМатериалов) с типом Число.
  2. В свойствах формы включите использование события ПриПолученииДанныхНаСервере.
  3. В обработчике события вычислите сумму для каждой отображаемой строки:
    
    &НаСервере
    Процедура СписокПриПолученииДанныхНаСервере(ИмяЭлемента, Настройки, Строки)
        Для Каждого СтрокаСписка Из Строки Цикл
            ДанныеОбъекта = СтрокаСписка.Значение.ПолучитьОбъект();
            Если ДанныеОбъекта <> Неопределено Тогда
                СтрокаСписка.Данные.СуммаМатериалов = ДанныеОбъекта.Материалы.Итог("Сумма");
            КонецЕсли;
        КонецЦикла;
    КонецПроцедуры
    

Важно: Этот метод удобен для небольших выборок, но при отображении больших списков он может вызывать задержки, так как для каждой записи будет вызываться серверный метод. Применяйте его осторожно.

Решение 3: Использование регистра сведений

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

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

Мы рассмотрели основные подходы для вывода агрегированных данных табличной части в список:

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

← На главную