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

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

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

Выясним причину поведения платформы 1С

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

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

Из-за этого изменения записи основного набора, для которых отсутствуют соответствия в подчиненном наборе, отсекаются еще до момента проверки условия фильтрации. В итоге строки со значениями NULL просто не попадают во временную выборку, и отбор НеЗаполнено или ЕСТЬ NULL возвращает пустой результат.

Способ 1. Перенос отбора на уровень группировки или детальных записей

Рассмотрим наиболее простой вариант настройки без изменения структуры запросов:

  1. Откроем настройки отчета в схеме компоновки данных.
  2. Исключим условие отбора из общих (глобальных) настроек отчета на корневом уровне.
  3. Перейдем в настройки конкретной группировки или элемента Детальные записи.
  4. Установим отбор по полю подчиненного набора данных непосредственно внутри этой группировки.

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

Способ 2. Обработка NULL на уровне запроса (один набор данных)

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

Рассмотрим пример написания запроса:


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

При таком подходе фильтрация выполняется на уровне СУБД, а стандартные виды сравнения СКД (Заполнено / НеЗаполнено) работают корректно.

Способ 3. Создание вспомогательного флага в основном наборе

Проанализируем еще один способ, позволяющий избежать изменения типа связи компоновщиком:

  1. В запрос основного набора данных добавим вычисляемое булево поле или флаг наличия связи (через подзапрос или левое соединение на уровне SQL).
  2. Наложим отбор в настройках отчета на это новое поле главного набора данных.

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

Способ 4. Проверка настройки «Игнорировать значения NULL»

Выясним дополнительный параметр, который может влиять на выводимый результат. В настройках группировки отчета необходимо проверить состояние флага Игнорировать значения NULL. Если этот флаг активен для поля группировки подчиненного набора, платформа 1С будет автоматически скрывать строки без связанных данных вне зависимости от установленных видов сравнения.

← На главную