При разработке отчетов на базе системы компоновки данных (СКД) разработчики часто сталкиваются с ситуацией, когда при связывании двух наборов данных левое соединение начинает работать как внутреннее. В результате из итогового отчета выпадают строки основного набора данных, для которых не нашлось совпадений в подчиненном наборе, а выражение ЕСТЬNULL в вычисляемых полях не срабатывает так, как ожидается.
Проанализируем причину такого поведения платформы 1С и разберем проверенные способы решения этой проблемы.
Рассмотрим, почему происходит выпадение строк при соединении наборов данных на вкладке Связи наборов данных:
NULL.ЕСТЬNULL(Поле, Значение) не может вернуть дефолтное значение для отсутствующей строки — самой строки к этому моменту уже нет в выборке.Самый надежный и быстродействующий способ — отказаться от использования вкладки Связи наборов данных и объединить таблицы непосредственно в тексте запроса. В языке запросов 1С левое соединение и функция ЕСТЬNULL работают предсказуемо и классическим образом.
Рассмотрим пример запроса с левым соединением:
ВЫБРАТЬ
Набор1.Поле1 КАК Поле1,
ЕСТЬNULL(Набор2.Количество, 0) КАК Количество
ИЗ
Таблица1 КАК Набор1
ЛЕВОЕ СОЕДИНЕНИЕ Таблица2 КАК Набор2
ПО Набор1.Поле1 = Набор2.Поле2
Если один из наборов данных является внешним (передается программно как ТаблицаЗначений), объединить их в одном запросе на стороне СКД напрямую нельзя. В этом случае проанализируем подход с дозаполнением внешней таблицы перед передачей в компоновщик.
Заполним внешнюю таблицу всеми ключами из главного источника, чтобы исключить появление физических NULL при связывании в СКД:
// Заполнение отсутствующих ключей во внешнем наборе данных
Для Каждого СтрокаГлавная Из ТЗ_Главная Цикл
Отбор = Новый Структура("КлючСвязи", СтрокаГлавная.КлючСвязи);
НайденныеСтроки = ТЗ_Внешняя.НайтиСтроки(Отбор);
Если НайденныеСтроки.Количество() = 0 Тогда
НоваяСтрока = ТЗ_Внешняя.Добавить();
НоваяСтрока.КлючСвязи = СтрокаГлавная.КлючСвязи;
НоваяСтрока.Количество = 999; // Значение по умолчанию вместо NULL
КонецЕсли;
КонецЦикла;
Если изменить структуру наборов данных невозможно, настроим обработку значений средствами самого компоновщика данных:
ЕСТЬNULL(Сумма(Количество), 999). При вычислении ресурсов СКД сохраняет строки основного набора данных.Альтернативный подход заключается в замене связи наборов на Набор данных — Объединение: