Как реализовать сложную иерархическую шапку в отчете СКД с типом Таблица

Программист 1С v8.3 (Управляемые формы) Управленческий учет
← На главную

При разработке отчетов в системе компоновки данных (СКД) часто возникает задача создания сложных кросс-таблиц. Типичный пример — отчет, где в строках отображается Номенклатура, а в колонках выстроена многоуровневая иерархия, например: Тип плана (Продажи/Сдача) — Период (Месяц) — Регистратор (Документ). Основная сложность заключается в том, чтобы заставить СКД объединять ячейки верхнего уровня (например, «План продаж») над всеми вложенными колонками периодов и документов, не дублируя заголовок для каждой отдельной колонки.

Рассмотрим подробнее, почему стандартные настройки иногда не дают нужного результата и как правильно спроектировать структуру отчета, чтобы получить корректный внешний вид.

Анализ структуры данных и типичных ошибок

Разберем ситуацию: часто разработчики пытаются создать две параллельные группировки в колонках — одну для «Плана продаж» и другую для «Плана сдачи». Однако в отчете типа Таблица параллельные группировки в одной секции колонок будут выводиться последовательно друг за другом (слева направо), но они не будут иметь общего родительского заголовка, если данные в них логически разделены. Если мы используем макеты для таких «статичных» группировок, СКД может начать применять макет к каждой дочерней колонке в отдельности, что приводит к разрыву шапки.

Выясним причину такого поведения. СКД работает максимально эффективно, когда иерархия данных определена в самом запросе или в настройках группировок. Для создания единой красивой шапки нам нужно уйти от идеи «двух разных колонок» и перейти к идее «одной иерархической ветки».

Способ 1: Правильная иерархия группировок в колонках

Проанализируем самый правильный с точки зрения архитектуры СКД подход. Вместо того чтобы пытаться вручную «рисовать» шапку, мы должны заставить систему саму рассчитать объединение ячеек. Для этого выполним следующие шаги:

  1. Подготовка данных в запросе. Если данные по продажам и сдаче находятся в разных таблицах, их необходимо объединить с помощью оператора ОБЪЕДИНИТЬ ВСЕ. При этом нужно добавить синтетическое поле, например, ВидПоказателя.
  2. Создание иерархии в настройках. В окне настроек отчета на вкладке «Настройки» переходим к разделу «Колонки». Здесь мы строим дерево:
    • Верхний уровень: Группировка по полю ВидПоказателя.
    • Вложенный уровень: Группировка по полю Период.
    • Самый глубокий уровень: Группировка по полю Документ.

При такой структуре СКД автоматически поймет, что ВидПоказателя является родителем для всех периодов и документов внутри него, и растянет заголовок «План продаж» на всю ширину соответствующих колонок. Посмотрим на пример того, как может выглядеть запрос для такой подготовки данных:


ВЫБРАТЬ
    "Планы продаж" КАК ВидПоказателя,
    Продажи.Номенклатура,
    Продажи.Период,
    Продажи.Регистратор КАК Документ,
    Продажи.Количество КАК Количество
ИЗ
    РегистрНакопления.Продажи КАК Продажи

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
    "Планы сдачи" КАК ВидПоказателя,
    Сдача.Номенклатура,
    Сдача.Период,
    Сдача.Регистратор КАК Документ,
    Сдача.Количество КАК Количество
ИЗ
    РегистрНакопления.ПланыСдачи КАК Сдача

Способ 2: Настройка расположения группировок и заголовков

Иногда даже при правильной иерархии заголовки выглядят не так, как ожидается. Рассмотрим дополнительные параметры на вкладке «Другие настройки», которые влияют на отображение таблицы:

  1. Расположение полей группировок. Установите значение Вместе. Это заставляет систему объединять зависимые ячейки в шапке.
  2. Расположение заголовков полей. Выберите В шапке.
  3. Тип заголовка полей. Попробуйте значение Краткий. Это избавит от лишних повторений имен полей (например, вместо «Период: Январь» будет просто «Январь»).
  4. Выводить общие итоги по горизонтали. Если для верхнего уровня («Вид показателя») итоги не нужны, их следует отключить в настройках конкретной группировки, чтобы они не загромождали отчет справа.

Способ 3: Использование макетов для группировок

Если стандартных средств недостаточно и требуется специфическое оформление (например, особый цвет или шрифт для заголовка «Планы продаж»), воспользуемся вкладкой «Макеты». Разберем этот процесс по шагам:

Важно понимать: чтобы заголовок объединялся, макет нужно создавать не для каждой колонки по отдельности, а для Заголовка группировки.

  1. Переходим на вкладку Макеты и нажимаем «Добавить макет группировки».
  2. Выбираем имя группировки (например, ВидПоказателя) и тип макета — Заголовок.
  3. В области макета указываем ячейку, где будет выводиться название. Важный момент: не нужно пытаться объединять ячейки в самом конфигураторе на этом этапе. СКД сама растянет эту ячейку на ширину всех подчиненных колонок, если в параметрах макета правильно указаны границы.
  4. В ячейке макета укажите параметр (например, ВидПоказателя) и в свойствах ячейки свяжите его с соответствующим полем компоновки.

Проанализируем ситуацию, когда макет «разваливается». Это происходит, если вы задали макет для Области, которая жестко фиксирована по ширине. Используя макет именно для группировки, вы сохраняете динамическую природу таблицы.

Способ 4: Использование вычисляемых полей для статических заголовков

Если вам нужно вывести в шапку текст, которого нет в базе данных, мы можем использовать Вычисляемые поля. Рассмотрим этот вариант:

  1. На вкладке Вычисляемые поля добавим новое поле ЗаголовокРаздела.
  2. В поле «Выражение» напишем строковую константу, например: "Мой сложный заголовок".
  3. В настройках колонок сделаем это поле самым верхним уровнем иерархии.

Это позволит создать дополнительный «слой» в шапке таблицы, который будет визуально объединять все данные под собой. Посмотрим на настройки оформления: для такого поля можно задать Минимальную ширину или Ориентацию текста, чтобы шапка выглядела профессионально.

Программный метод объединения ячеек (для исключительных случаев)

В самых сложных случаях, когда средствами СКД не удается добиться идеального объединения (например, требуется сложная «шахматная» шапка с разным количеством уровней в разных секциях), мы можем прибегнуть к программному выводу. Рассмотрим этот алгоритм:

Сначала отчет формируется в память, а затем выводится в ТабличныйДокумент с последующей постобработкой. Мы можем использовать следующий подход:


// Получаем результат компоновки
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, ВнешниеНаборыДанных);

ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ТабличныйДокумент);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);

// Постобработка: поиск и объединение ячеек в шапке
Для НомерСтроки = 1 По ВысотаШапки Цикл
    ТекущееЗначение = "";
    НачалоОбъединения = 0;
    Для НомерКолонки = 1 По ТабличныйДокумент.ШиринаТаблицы Цикл
        ЗначениеЯчейки = ТабличныйДокумент.Область(НомерСтроки, НомерКолонки).Текст;
        Если ЗначениеЯчейки = ТекущееЗначение И ЗначениеЯчейки <> "" Тогда
            // Продолжаем область для объединения
        Иначе
            Если НачалоОбъединения > 0 И НомерКолонки - НачалоОбъединения > 1 Тогда
                ТабличныйДокумент.Область(НомерСтроки, НачалоОбъединения, НомерСтроки, НомерКолонки - 1).Объединить();
            КонецЕсли;
            ТекущееЗначение = ЗначениеЯчейки;
            НачалоОбъединения = НомерКолонки;
        КонецЕсли;
    КонецЦикла;
КонецЦикла;

Этот метод гарантирует, что все одинаковые идущие подряд заголовки в шапке будут объединены. Однако стоит помнить, что это требует написания кода в модуле объекта отчета и лишает пользователей возможности использовать стандартные функции автоматического формирования без участия программиста.

Рекомендации по оформлению

Чтобы отчет был читаемым, воспользуемся следующими советами:

Мы проанализировали ситуацию с иерархическими шапками в СКД и выяснили, что ключ к успеху лежит в правильном проектировании дерева группировок в колонках. Используя подчиненные группировки и настройки расположения полей, вы сможете реализовать практически любую структуру заголовков без написания сложного программного кода.

← На главную