Как реализовать горизонтальное расположение независимых группировок в СКД?

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

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

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

Почему СКД выводит группировки вертикально?

Прежде чем переходить к решениям, проанализируем механику работы ПроцессораВыводаРезультатаКомпоновкиДанных. Основной алгоритм СКД ориентирован на последовательное чтение дерева настроек. Когда процессор встречает новую группировку в корне отчета, он завершает вывод предыдущей и начинает новую с новой строки. Прямой настройки "Выводить следующую группировку справа" в интерфейсе настроек не существует.

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

Способ 1. Искусственное соединение наборов данных по номеру строки

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

Алгоритм реализации:

  1. В каждом из ваших запросов (наборов данных) необходимо сформировать поле НомерСтроки. В 1С это удобнее всего сделать через временные таблицы и АВТОНОМЕРЗАПИСИ() или путем соединения таблицы самой с собой по условию "больше".
  2. В схеме компоновки данных на закладке Связи наборов данных установите связь между Набором1 и Набором2 по полю НомерСтроки.
  3. Тип связи должен быть Полное соединение (если это возможно в контексте ваших данных) или создайте фиктивный набор данных "НомераСтрок", который будет содержать числа от 1 до N, и присоедините к нему оба ваших набора левым соединением.
  4. В настройках отчета вместо двух группировок создайте одну группировку Детальные записи.
  5. В Выбранные поля добавьте поля из обоих наборов данных.

Проанализируем результат: СКД выведет одну таблицу. В левых колонках будут данные первого набора, в правых — второго. Если в первом наборе 10 строк, а во втором 20, то в первых десяти строках будут заполнены обе части, а в последующих десяти — только правая. Визуально это выглядит как две таблицы, расположенные вплотную друг к другу.

Способ 2. Использование структуры "Таблица" с группировками в колонках

Этот метод позволяет использовать стандартный функционал Cross-tab (Перекрестная таблица) для имитации параллельного вывода.

Разберем по шагам:

  1. Объедините ваши данные в один набор через ОБЪЕДИНИТЬ ВСЕ.
  2. Добавьте в запрос служебное поле ИмяТаблицы. Для записей первого набора значение будет "Таблица А", для второго — "Таблица Б".
  3. В настройках СКД добавьте элемент Таблица.
  4. В Строки таблицы добавьте группировку по номеру строки (как в первом способе).
  5. В Колонки таблицы добавьте группировку по полю ИмяТаблицы.
  6. В Выбранные поля поместите нужные ресурсы или реквизиты.

В этом случае поле ИмяТаблицы разнесет данные по разным горизонтальным секциям, создавая эффект двух независимых блоков данных, идущих в ряд.

Способ 3. Использование вложенных отчетов и макетов

Если таблицы имеют принципиально разную структуру и сложные заголовки, рассмотрим вариант с использованием макета оформления.

Мы можем создать макет табличного документа, в котором в одной строке будут определены две именованные области (например, ОбластьЛево и ОбластьПраво). В эти области программно или через настройки вложенных отчетов выводятся данные. Однако, более простым вариантом в рамках только СКД является использование вложенных схем.

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

Способ 4. Программный вывод с использованием метода Присоединить()

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

Рассмотрим пример кода:


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

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

// Начинаем вывод
ПроцессорВывода.НачатьВывод();

// Цикл обхода элементов результата первого набора
Пока Истина Цикл
    ЭлементРезультата = ПроцессорКомпоновки.Следующий();
    Если ЭлементРезультата = Неопределено Тогда
        Прервать;
    КонецЕсли;
    ПроцессорВывода.Вывести(ЭлементРезультата);
КонецЦикла;

// Теперь нам нужно "вернуться" вверх и пристыковать вторую таблицу справа
// Для этого используется метод Присоединить(), но важно помнить, 
// что он работает в контексте текущей выведенной строки.

Важный нюанс: метод ПроцессорВывода.Вывести() всегда переходит на новую строку. Чтобы вывести вторую таблицу "справа", нам придется либо формировать два отдельных табличных документа и затем объединять их построчно, либо использовать метод Присоединить() для каждой области ТабличногоДокумента.

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


Для НомерСтроки = 1 По Макс(ТД1.ВысотаТаблицы, ТД2.ВысотаТаблицы) Цикл
    ОбластьИсточник = ТД2.Область(НомерСтроки, 1, НомерСтроки, ТД2.ШиринаТаблицы);
    ТД1.Область(НомерСтроки, ТД1.ШиринаТаблицы + 1).Присоединить(ОбластьИсточник);
КонецЦикла;

Способ 5. Манипуляция с ресурсами и вертикальная группировка

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

Чтобы ресурсы разных наборов не перемешивались, используйте группировку по фиктивному полю (как в Способе 2). Это позволит разделить блоки ресурсов визуальным разрывом или заголовком группировки.

Подведение итогов

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

Основные выводы:

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

← На главную