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

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

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

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

Способ 1. Объединение запросов с помощью конструкции ОБЪЕДИНИТЬ ВСЕ (Рекомендуемый)

Если оба источника данных представляют собой запросы к базе данных 1С, наиболее производительным и правильным решением является объединение выборок непосредственно в тексте одного запроса внутри набора данных НаборДанных1.

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


ВЫБРАТЬ
    ПродажиОбороты.Номенклатура КАК Номенклатура,
    ПродажиОбороты.КоличествоОборот КАК Количество,
    ПродажиОбороты.СуммаОборот КАК Сумма
ИЗ
    РегистрНакопления.Продажи.Обороты(&НачалоПериода, &КонецПериода, , ) КАК ПродажиОбороты

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

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

Рассмотрим преимущества такого подхода:

  1. Производительность: СУБД самостоятельно объединяет выборки, производит первичную фильтрацию и передает в платформу уже оптимизированный результат.
  2. Экономия памяти: Серверу 1С не требуется хранить в памяти промежуточные таблицы каждого набора данных.
  3. Простота отладки: Текст запроса легко проверить в консоли запросов.

Способ 2. Использование типа «Набор данных – Объединение»

В схеме компоновки данных предусмотрен специальный тип набора — «Набор данных – Объединение». Он выступает в роли папки-контейнера, в которую можно вложить несколько подчиненных наборов данных (например, НаборДанныхЗапрос1 и НаборДанныхЗапрос2 или набор типа Объект).

Разберем порядок настройки:

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

Обратите внимание: использование набора-объединения оправдано в первую очередь тогда, когда объединяются разнородные источники — например, результат запроса к базе данных и внешняя таблица значений, переданная через набор данных типа Объект.

Почему строки не группируются и выводятся последовательно?

Выясним причину ситуации, когда данные объединяются, но не схлопываются в одну строку. В СКД сам по себе факт объединения (как через ОБЪЕДИНИТЬ ВСЕ, так и через Набор данных - Объединение) просто формирует общий массив строк. Для их объединения и агрегации необходимо настроить структуру схемы:

  1. Настройка вкладки «Ресурсы»: Числовые показатели (например, Количество, Сумма), которые должны складываться при совпадении ключевых полей, обязательно должны быть добавлены на вкладку «Ресурсы» с агрегатными функциями вида Сумма(Количество) и Сумма(Сумма). Если поле не является ресурсом, СКД будет пытаться группировать по нему или выводить его построчно.
  2. Настройка структуры отчета (вкладка «Настройки»): Если в структуре отчета добавлены Детальные записи, компоновщик выведет каждую запись каждого набора отдельно. Чтобы строки объединились, необходимо заменить Детальные записи на группировку по нужным полям (например, по полю Номенклатура).

Как разделить данные, если запросы отличаются только параметрами?

Проанализируем задачу, когда требуется выбрать данные по разным условиям или параметрам без их непреднамеренного суммирования:

  1. Добавление поля-дискриминатора: В каждый подзапрос добавляется строковая метка или значение параметра, идентифицирующее выборку. Например, в первом запросе пишем "Основной склад" КАК ВидСклада, а во втором — "Удаленный склад" КАК ВидСклада. В настройках структуры отчета поле ВидСклада можно поместить в строки или колонки таблицы, разделив показатели.
  2. Использование условий в ресурсах или пользовательских полях: Если показатели должны выводиться в разные колонки, на вкладке «Настройки» создаются пользовательские поля с конструкцией ВЫБОР КОГДА ... ТОГДА ... ИНАЧЕ ... КОНЕЦ, либо настраивается отбор по спискам значений вместо дублирования текстов запросов.
← На главную