При разработке отчетов на базе системы компоновки данных (СКД) часто возникает задача совместить в одном отчете динамические колонки (например, меняющиеся статусы или визы документов с датами их установки) и фиксированные числовые показатели (сумма документа), по которым требуется рассчитать общий вертикальный итог. Если подойти к настройке стандартной кросс-таблицы без учета специфики группировок, сумма документа начнет дублироваться под каждым статусом либо отобразятся лишние горизонтальные итоги.
Разберем детально, как правильно настроить схему компоновки данных, структуру группировок, вычисление ресурсов и параметры вывода для получения корректного отчета.
Представим типовую структуру исходных данных, когда у нас есть два логических набора или две таблицы:
Документ и СуммаДокумента.Документ, Статус и Период.На выходе необходимо получить таблицу следующего вида:
В строках выводятся документы. Первой числовой колонкой идет СуммаДокумента, за ней следуют динамические колонки по каждому встреченному статусу (например, «Принят в работу», «Оплачен»), внутри которых отображается дата (Период). В самом низу отчета в строке «Итого» должен быть рассчитан вертикальный итог только по сумме, без пустых или некорректных итоговых значений по колонкам дат.
Рассмотрим основной способ, позволяющий вывести фиксированную колонку с ресурсом суммы и динамические колонки без дублирования. Данное решение базируется на создании двух параллельных веток в секции колонок таблицы настроек СКД.
Разберем по шагам порядок настройки:
На вкладке Ресурсы добавляем два поля:
СуммаДокумента задаем выражение: Сумма(СуммаДокумента). В колонке Рассчитывать по... выбираем ОбщийИтог и группировку Документ (исключая группировку Статус).Период задаем выражение: Максимум(Период). В колонке Рассчитывать по... указываем только группировки Документ и Статус, чтобы исключить вывод максимальной даты в строке общего итога отчета.Добавляем в структуру элемент Таблица.
В секцию Строки таблицы добавляем группировку по полю Документ.
В секцию Колонки таблицы добавляем на одном уровне две независимые параллельные группировки:
СуммаДокумента.Статус. В её Выбранные поля отключаем автополе и добавляем только ресурс Период.Выделим корневой элемент Таблица и в панели Другие настройки установим следующие параметры:
Нет (это действие скрывает ненужную правую итоговую колонку по статусам).Конец (обеспечивает расчет нижнего общего итога по сумме документов).Для группировки колонок Статус в параметрах вывода также можно задать Расположение итогов в значение Нет, чтобы избежать промежуточных подтогов.
Проанализируем важную особенность: если исходные таблицы документов и статусов соединяются в одном наборе данных типа «Запрос» через ЛЕВОЕ СОЕДИНЕНИЕ, то при наличии нескольких статусов у одного документа строка с суммой документа размножится. При стандартном суммировании Сумма(СуммаДокумента) итог будет рассчитан неверно.
Для предотвращения задвоения сумм выделим два проверенных решения:
Создаем НаборДанных1 (список документов и их сумм) и НаборДанных2 (регистр сведений со статусами). На вкладке Связи наборов данных связываем их по полю Документ. В этом случае СКД самостоятельно контролирует контекст суммирования, и итоги по сумме рассчитываются строго по записям первого набора.
Если запрос единый, формулу ресурса СуммаДокумента на вкладке Ресурсы следует переопределить с использованием функции агрегации по массиву:
Сумма(ВычислитьВыражениеСГруппировкойМассив("Максимум(СуммаДокумента)", "Документ"))
Данная конструкция сначала определяет максимальную (уникальную) сумму в рамках каждого документа, а затем вычисляет общую сумму по всем документам в итоговой строке.
Рассмотрим альтернативную ситуацию: если список возможных статусов строго регламентирован и заранее известен (например, существуют только статусы «Принят в работу» и «Оплачен»), задачу можно решить без применения кросс-таблицы, используя обычную группировку списка.
Посмотрим на пример формирования полей в тексте запроса:
ВЫБРАТЬ
Документы.Ссылка КАК Документ,
Документы.Сумма КАК СуммаДокумента,
МАКСИМУМ(ВЫБОР
КОГДА Статусы.Статус = ЗНАЧЕНИЕ(Перечисление.СтатусыДокументов.ПринятВРаботу)
ТОГДА Статусы.Период
ИНАЧЕ NULL
КОНЕЦ) КАК ДатаПринятияВРаботу,
МАКСИМУМ(ВЫБОР
КОГДА Статусы.Статус = ЗНАЧЕНИЕ(Перечисление.СтатусыДокументов.Оплачен)
ТОГДА Статусы.Период
ИНАЧЕ NULL
КОНЕЦ) КАК ДатаОплаты
ИЗ
Документ.ЗаказКлиента КАК Документы
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.СтатусыДокументов КАК Статусы
ПО Документы.Ссылка = Статусы.Документ
СГРУППИРОВАТЬ ПО
Документы.Ссылка,
Документы.Сумма
При таком подходе структура отчета в СКД представляет собой простой список с одной группировкой по полю Документ. В выбранные поля добавляются поля СуммаДокумента, ДатаПринятияВРаботу и ДатаОплаты. Единственным ресурсом отчета выступает СуммаДокумента с выражением Сумма(СуммаДокумента), что гарантирует правильный вывод вертикального итога без необходимости сложной настройки кросс-таблицы.