При разработке отчетов на базе Системы компоновки данных (СКД) программисты часто сталкиваются с ограничением: платформа напрямую запрещает использовать агрегатные функции (такие как Максимум, Сумма или Количество) непосредственно в полях группировки. Типичный пример — необходимость вывести в заголовке группировки «Упаковка» информацию о максимальной длине изделия внутри этой упаковки. Рассмотрим, как обойти этот запрет и реализовать сложную логику отображения данных.
Представим ситуацию: у нас есть набор данных, содержащий информацию о ящиках, номенклатуре и физических характеристиках (длине). Стандартное поведение СКД предполагает, что группировка происходит по статичным значениям полей. Если мы попытаемся в настройках группировки указать выражение типа "Ящик: " + Упаковка + " Макс. длина: " + Максимум(Длина), система выдаст ошибку, так как расчет итогов (агрегатов) происходит на этапе после формирования структуры группировок.
Разберем по шагам доступные методы решения этой задачи — от простых правок в запросе до продвинутых механизмов выражений представления СКД.
Это один из самых эффективных и «чистых» способов решения задачи средствами СКД, не требующий модификации исходного SQL-запроса. Суть метода заключается в том, что технически группировка остается простой (по полю Упаковка), но визуально пользователь видит в отчете вычисленную строку с агрегатом.
Проанализируем алгоритм настройки:
Упаковка (или то поле, по которому осуществляется группировка).В этом выражении мы можем использовать функцию ВычислитьВыражение, которая позволяет обращаться к контексту группировки. Пример выражения:
Упаковка + " с Номенклатурой максимальной длины " + Строка(ВычислитьВыражение("Максимум(Длина)", "Упаковка"))
Почему это работает: СКД сначала группирует данные по физическому значению поля Упаковка, а затем, при выводе в макет, вызывает это выражение для формирования текстовой строки. Функция ВычислитьВыражение с указанием области "Упаковка" корректно рассчитывает максимум по всей группе строк, относящихся к текущему ящику.
В современных версиях платформы 8.3 (начиная с 8.3.15) появились расширенные функции, позволяющие работать с коллекциями значений внутри выражений. Выясним, как применить ВычислитьВыражениеСГруппировкойМассив для нашей задачи.
Мы можем создать Вычисляемое поле, например, ЗаголовокГруппировки, и в его выражении использовать следующую логику:
Упаковка + " (макс: " + Строка(ВычислитьВыражение("Максимум(Длина)", "Упаковка")) + ")"
Важный момент: если нам нужно использовать это поле именно как элемент иерархии, по которому можно сворачивать данные, нам следует убедиться, что тип возвращаемого значения — строка, иначе возникнут конфликты при сопоставлении типов в группировках.
Если решение только средствами СКД кажется избыточным или требуется высокая производительность на огромных объемах данных, рассмотрим вариант с временными таблицами. Это позволит подготовить агрегаты заранее на уровне СУБД.
Разберем пример запроса, который можно использовать в наборе данных:
ВЫБРАТЬ
Т.Упаковка,
МАКСИМУМ(Т.Длина) КАК МаксимальнаяДлина
ПОМЕСТИТЬ ВТ_МаксимальныеЗначения
ИЗ
ТаблицаДанных КАК Т
СГРУППИРОВАТЬ ПО
Т.Упаковка
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
Т.Упаковка,
Т.Номенклатура,
Т.Длина,
"Ящик " + Т.Упаковка + " макс. длина " + ПРЕДСТАВЛЕНИЕ(ВТ.МаксимальнаяДлина) КАК ПолеГруппировки
ИЗ
ТаблицаДанных КАК Т
ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_МаксимальныеЗначения КАК ВТ
ПО Т.Упаковка = ВТ.Упаковка
В данном случае мы создаем готовое строковое поле ПолеГруппировки уже в запросе. В настройках СКД достаточно просто выбрать это поле в качестве группировки. Однако помните, что это делает отчет менее гибким, если пользователь захочет изменить состав полей группировки в режиме «1С:Предприятие».
Если отчет уже внедрен и у нас нет доступа к конфигуратору, или мы хотим дать пользователю возможность самому конструировать такие заголовки, воспользуемся Пользовательскими полями.
Проанализируем ситуацию настройки в режиме «Предприятие»:
Упаковка.Упаковка + " [Max: " + Строка(Максимум(Длина)) + "]".При использовании этого пользовательского поля в качестве группировки, СКД автоматически применит «Выражение итогов» для строк-заголовков и «Выражение детальных записей» для нижнего уровня иерархии.
Одной из самых частых причин ошибок при попытке «запихнуть» агрегат в группировку является несовметсимость типов данных. Рассмотрим типичную ситуацию: поле Длина имеет числовой тип, а Упаковка — строковый или ссылочный. При сложении их в выражениях СКД обязательным является использование функции Строка().
Пример правильного приведения типов в вычисляемом поле:
Представление(Упаковка) + " - " + Формат(Максимум(Длина), "ЧЦ=10; ЧДЦ=2")
Использование Формат() предпочтительнее обычной Строка(), так как позволяет избежать появления неразрывных пробелов в числах (например, "1 000" превратится в "1000"), что критично для конкатенации строк в заголовках группировок.
Мы проанализировали несколько путей решения задачи. Выбор конкретного метода зависит от требований к гибкости отчета:
Использование функций ВычислитьВыражение открывает широкие возможности для вывода любой аналитической информации прямо в строках группировок, делая отчеты максимально информативными для конечного пользователя.