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