Как обработать NULL и сохранить все строки при связывании наборов данных в СКД?

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

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

Проанализируем причину такого поведения платформы 1С и разберем проверенные способы решения этой проблемы.

Причины отсечения строк со значением NULL в СКД

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

  1. Группировка по полю подчиненного набора: Если в структуре отчета в качестве группировки или детальной записи выводится поле непосредственно из второго (подчиненного) набора данных, компоновщик макета отбрасывает строки источника, где значение в приемнике равно NULL.
  2. Порядок вычисления полей: Компоновка данных отсекает отсутствующие записи подчиненного набора еще до того, как рассчитывается выражение на вкладке Вычисляемые поля. По этой причине конструкция ЕСТЬNULL(Поле, Значение) не может вернуть дефолтное значение для отсутствующей строки — самой строки к этому моменту уже нет в выборке.
  3. Отборы по подчиненному набору: Наложение любых пользовательских или системных отборов по полям из второго набора данных автоматически превращает левое соединение во внутреннее.

Способ 1. Выполнение соединения в едином запросе

Самый надежный и быстродействующий способ — отказаться от использования вкладки Связи наборов данных и объединить таблицы непосредственно в тексте запроса. В языке запросов 1С левое соединение и функция ЕСТЬNULL работают предсказуемо и классическим образом.

Рассмотрим пример запроса с левым соединением:


ВЫБРАТЬ
    Набор1.Поле1 КАК Поле1,
    ЕСТЬNULL(Набор2.Количество, 0) КАК Количество
ИЗ
    Таблица1 КАК Набор1
    ЛЕВОЕ СОЕДИНЕНИЕ Таблица2 КАК Набор2
        ПО Набор1.Поле1 = Набор2.Поле2

Способ 2. Подготовка внешнего набора данных в коде

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

Заполним внешнюю таблицу всеми ключами из главного источника, чтобы исключить появление физических NULL при связывании в СКД:


// Заполнение отсутствующих ключей во внешнем наборе данных
Для Каждого СтрокаГлавная Из ТЗ_Главная Цикл
    Отбор = Новый Структура("КлючСвязи", СтрокаГлавная.КлючСвязи);
    НайденныеСтроки = ТЗ_Внешняя.НайтиСтроки(Отбор);
    
    Если НайденныеСтроки.Количество() = 0 Тогда
        НоваяСтрока = ТЗ_Внешняя.Добавить();
        НоваяСтрока.КлючСвязи = СтрокаГлавная.КлючСвязи;
        НоваяСтрока.Количество = 999; // Значение по умолчанию вместо NULL
    КонецЕсли;
КонецЦикла;

Способ 3. Настройка вычисляемых полей и ресурсов СКД

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

  1. Использование ресурсов: Перейдем на вкладку Ресурсы и добавим поле подчиненного набора. В выражении ресурса укажем обработку отсутствующих значений: ЕСТЬNULL(Сумма(Количество), 999). При вычислении ресурсов СКД сохраняет строки основного набора данных.
  2. Корректное построение группировок: В структуре отчета все группировки по строкам и колонкам необходимо строить строго по полям первого (главного) набора данных. Поля подчиненного набора допускается выводить только в секцию Выбранные поля.
  3. Проверка флага отсечения: В настройках конкретной группировки отчета убедимся, что отключено свойство Игнорировать значения NULL.

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

Альтернативный подход заключается в замене связи наборов на Набор данных — Объединение:

  1. В первом наборе выбираем ключевые поля и нулевые (или дефолтные) значения показателей.
  2. Во втором наборе выбираем ключевые поля и фактические значения показателей.
  3. На вкладке Ресурсы настраиваем суммирование показателей. Набор данных типа «Объединение» гарантирует сохранение всех ключей из первого набора без потери строк.
← На главную