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