Почему в СКД данные из разных наборов данных выводятся в разных строках и как это исправить?

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

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

Причина разделения строк в наборе данных «Объединение»

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

  1. Совпадение нересурсных полей: Все поля, которые не являются ресурсами (Номенклатура, Характеристика, Склад и т.д.), в обоих запросах должны иметь абсолютно идентичные значения. Если в одном запросе Характеристика заполнена, а во втором на ее месте стоит NULL или пустая ссылка — для СКД это разные аналитические разрезы, и она выведет их в две разные строки.
  2. Правильная настройка ресурсов: Числовые показатели (Количество, Сумма) должны быть добавлены на вкладку Ресурсы. Только в этом случае компоновщик данных применит к ним функцию агрегации (например, СУММА()) при группировке по общим полям.

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

Решение 1: Использование одного запроса с ОБЪЕДИНИТЬ ВСЕ

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


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

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

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

Важный нюанс: Чтобы данные объединились корректно, во втором запросе мы «подставляем» нули в колонки, которые заполняются только в первом запросе, и наоборот. Затем на вкладке Ресурсы мы указываем СУММА(Произведено) и СУММА(Заказано). В настройках отчета, при группировке по полю Номенклатура, СКД автоматически сложит эти значения в одну строку.

Решение 2: Использование связей наборов данных

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

Разберем алгоритм настройки:

  1. Создаем НаборДанных1 (Ведущий, например, список всей номенклатуры).
  2. Создаем НаборДанных2 (Ведомый, например, остатки).
  3. На вкладке Связи наборов данных указываем Источник связи: НаборДанных1, Приемник связи: НаборДанных2.
  4. В колонке Условие связи выбираем общие поля (например, Номенклатура).

Внимание: Если записи есть только во втором наборе, но отсутствуют в первом (ведущем), в отчет они не попадут. Чтобы имитировать «Полное соединение», часто создают вспомогательный набор данных, который выбирает уникальный перечень ключевых полей из всех используемых таблиц, и уже к нему привязывают остальные наборы.

Проблема детализации до регистратора

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

Чтобы сохранить читаемость отчета, проанализируем следующие шаги:

Когда действительно нужны разные наборы данных?

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

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

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

← На главную