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