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

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

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

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

Выясняем причину: как работает "Объединение" в СКД

Появление пустых строк — это не ошибка, а штатное поведение механизма Объединение. Он работает аналогично оператору UNION ALL в языке запросов SQL. Это означает, что система просто "склеивает" таблицы одну под другой.

Представим наши наборы данных в виде таблиц:

Набор 1: Обороты

  1. Сотрудник: Иванов, Номенклатура: Ноутбук, КоличествоОборот: 5
  2. Сотрудник: Петров, Номенклатура: Мышь, КоличествоОборот: 10

Набор 2: Остатки

  1. Сотрудник: Иванов, Номенклатура: Ноутбук, КоличествоОстаток: 2
  2. Сотрудник: Петров, Номенклатура: Мышь, КоличествоОстаток: 3

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

  1. Сотрудник: Иванов, Номенклатура: Ноутбук, КоличествоОборот: 5, КоличествоОстаток: NULL
  2. Сотрудник: Петров, Номенклатура: Мышь, КоличествоОборот: 10, КоличествоОстаток: NULL
  3. Сотрудник: Иванов, Номенклатура: Ноутбук, КоличествоОборот: NULL, КоличествоОстаток: 2
  4. Сотрудник: Петров, Номенклатура: Мышь, КоличествоОборот: NULL, КоличествоОстаток: 3

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

Решение 1: Настройка отбора в структуре отчета (рекомендуемый способ)

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

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

  1. Откройте схему компоновки данных и перейдите на закладку "Настройки".
  2. В дереве структуры отчета выберите нужную группировку (например, по полю Сотрудник) или самый верхний уровень "Отчет", если хотите применить правило ко всему отчету.
  3. В правой части окна перейдите на закладку "Отбор".
  4. Нажмите кнопку "Добавить новый элемент отбора".
  5. В колонке "Левое значение" выберите поле, которое является ключевым и общим для обоих наборов. В нашем случае это Сотрудник.
  6. В колонке "Вид сравнения" установите значение "Заполнено". Это отсечет все строки, где ключевое поле по какой-то причине оказалось пустым.
  7. Если вы хотите убрать строки, где нет данных по оборотам или по остаткам, можно добавить более сложное условие. Например, добавить отбор "КоличествоОборот > 0 ИЛИ КоличествоОстаток > 0". Но чаще всего достаточно отбора по ключевому полю аналитики.

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

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

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

Решение 2: Использование "Связей наборов данных" вместо "Объединения"

Альтернативный подход — не объединять наборы, а связывать их. Этот механизм работает аналогично оператору LEFT JOIN (Левое Соединение) в запросах. Он позволяет "притянуть" данные из одного набора в другой по общим полям.

Как это настроить:

  1. Удалите набор данных типа Объединение. У вас должны остаться два независимых набора: "Обороты" и "Остатки".
  2. Перейдите на закладку "Связи наборов данных" в конструкторе схемы.
  3. Нажмите "Добавить" для создания новой связи.
  4. В качестве "Набора данных-источника" (левая таблица) выберите основной набор, например, "Обороты".
  5. В качестве "Набора данных-приемника" (правая таблица) выберите "Остатки".
  6. Ниже, в таблице связей, укажите поля, по которым будут связываться данные. Например, Источник: Сотрудник, Приемник: Сотрудник.

Проблема с дублированием данных:

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

Как решить проблему дублей:

Чтобы избежать неверных итогов, поля из присоединенного (правого) набора данных нужно выводить не как обычные поля, а как ресурсы с правильно настроенной функцией агрегации.

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

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

Рекомендация по организации наборов данных

В ходе обсуждения на форуме был поднят важный вопрос: стоит ли получать остатки и обороты из одной виртуальной таблицы регистра накопления ОстаткиИОбороты или лучше делать это в разных наборах?

Практика показывает, что разделение на два набора — более надежный подход. Хотя виртуальная таблица ОстаткиИОбороты удобна, в сложных отчетах с разными периодами, дополнительными условиями и связями она может давать непредсказуемый результат. Когда вы делаете два отдельных запроса (один к ВТ Обороты, второй к ВТ Остатки), вы полностью контролируете параметры для каждого из них. Это делает логику отчета более прозрачной и предсказуемой. Так что первоначальный выбор автора создать два набора был абсолютно верным.

← На главную