Как в СКД вывести несколько независимых наборов данных в одну общую таблицу?

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

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

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

Способ 1. Использование «Набора данных — Объединение» с полем-дискриминатором

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

Разберем пошаговый алгоритм реализации:

  1. Перейдем на вкладку Наборы данных и создадим корневой элемент Набор данных - объединение.
  2. Внутрь созданного объединения добавим несколько дочерних наборов данных типа Запрос.
  3. Приведем структуру полей каждого запроса к единому списку колонок. Для полей, которых нет в конкретном источнике, укажем пустые значения (NULL, 0 или пустую строку).
  4. В каждый запрос добавим явное строковое поле-дискриминатор, которое позволит СКД различать строки источников в группировках:

Посмотрим на пример текста первого запроса:


ВЫБРАТЬ
    "Пациенты" КАК ТипДанных,
    Пациенты.Ссылка КАК Объект,
    Пациенты.Количество КАК Количество,
    0 КАК Сумма
ИЗ
    Справочник.Пациенты КАК Пациенты

И пример текста второго запроса, помещенного в то же объединение:


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

После этого на вкладке Настройки добавим группировку по полю ТипДанных или выведем детальные записи. В результате платформа сформирует одну общую таблицу с единым набором заголовков.

Способ 2. Выравнивание отдельных таблиц через макеты оформления

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

Разберем, как реализовать этот подход:

  1. На вкладке Настройки добавим две отдельные таблицы или группировки в структуру отчета друг под другом.
  2. Для нижней таблицы в разделе Другие настройки установим свойство Расположение полей группировки в значение Нет, а параметр Выводить заголовок переключим в Не выводить. Это позволит скрыть дублирующуюся шапку.
  3. Перейдем на вкладку Макеты и создадим пользовательский макет заголовка или группировки, задав фиксированную ширину колонок для обеих таблиц, чтобы визуальные границы ячеек совпадали пиксель в пиксель.
  4. Для удобства пользователей вынесем управление видимостью каждой таблицы в пользовательские настройки (флаг Включать в пользовательские настройки).

Способ 3. Связывание наборов по фиктивному условию

Проанализируем ситуацию, когда необходимо связать два отдельных набора данных на вкладке Связи наборов данных, не имея общих аналитических разрезов.

В этом случае наборы можно связать через константное выражение:

  1. На вкладке Связи наборов данных укажем источник и приемник данных.
  2. В качестве выражения источника и выражения приемника зададим константу 1.
  3. При необходимости передадим параметр периода из первого набора во второй.

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

Способ 4. Сведение данных в модуле через «Набор данных — Объект»

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

Разберем пример программного заполнения таблицы в модуле объекта отчета:


Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
    
    СтандартнаяОбработка = Ложь;
    
    // Получаем данные из разных источников и заполняем Таблицу Значений
    ТаблицаСводная = Новый ТаблицаЗначений;
    ТаблицаСводная.Колонки.Добавить("Раздел", Новый ОписаниеТипов("Строка"));
    ТаблицаСводная.Колонки.Добавить("Показатель", Новый ОписаниеТипов("Строка"));
    ТаблицаСводная.Колонки.Добавить("Значение", Новый ОписаниеТипов("Число"));
    
    // Заполнение структуры таблицы нужными данными
    СтрокаДанных = ТаблицаСводная.Добавить();
    СтрокаДанных.Раздел = "Сведения о пациентах";
    СтрокаДанных.Показатель = "Всего пациентов";
    СтрокаДанных.Значение = 150;
    
    // Передаем внешнюю таблицу в компоновщик
    ВнешниеНаборыДанных = Новый Структура;
    ВнешниеНаборыДанных.Вставить("ТаблицаСводная", ТаблицаСводная);
    
    КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
    МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, КомпоновщикНастроек.ПолучитьНастройки(), ДанныеРасшифровки);
    
    ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
    ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, ВнешниеНаборыДанных, ДанныеРасшифровки, Истина);
    
    ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
    ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
    ПроцессорВывода.Вывести(ПроцессорКомпоновки);
    
КонецПроцедуры

Особенности расчета итогов и ресурсов

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

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

← На главную