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