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