При разработке отчетов и обработок в 1С часто возникает задача скрыть строки, в которых реквизит или документ не заполнен. Начинающие разработчики нередко пытаются применить конструкцию ЕСТЬNULL для любых пустых полей, однако в платформе 1С:Предприятие понятие «пустое значение» может иметь разную природу. Проанализируем ситуацию, выясним причину различий между типами пустых данных и разберем по шагам все способы корректной фильтрации в запросах.
Прежде чем писать условие в секции ГДЕ, необходимо определить, с каким именно видом отсутствия данных мы работаем. В платформе 1С выделяют четыре основных варианта:
ЛЕВОЕ СОЕДИНЕНИЕ или ПОЛНОЕ СОЕДИНЕНИЕ), когда для записи одной таблицы не нашлось соответствия в другой, либо при выборке полей из виртуальных таблиц. В самой базе данных ссылочные поля никогда не содержат NULL.Рассмотрим случай, когда поле документа оказывается пустым в результате соединения двух таблиц, и для строки не нашлось соответствия во второй таблице. В этом случае поле принимает значение NULL.
Обратите внимание на разницу между предикатом ЕСТЬ NULL (пишется раздельно) и функцией ЕСТЬNULL() (пишется слитно):
ЕСТЬ NULL предназначен для секций ГДЕ и КОГДА.ЕСТЬNULL(Поле, ЗначениеЗамены) используется в секции ВЫБРАТЬ для подстановки значения по умолчанию, если поле равно NULL. Использовать функцию ЕСТЬNULL в секции ГДЕ не рекомендуется, так как это снижает производительность из-за невозможности СУБД задействовать индексы.Посмотрим на пример правильного использования предиката в запросе:
ВЫБРАТЬ
Заказы.Ссылка КАК Заказ,
Реализации.Ссылка КАК Реализация
ИЗ
Документ.ЗаказКлиента КАК Заказы
ЛЕВОЕ СОЕДИНЕНИЕ Документ.РеализацияТоваровУслуг КАК Реализации
ПО Заказы.Ссылка = Реализации.ЗаказКлиента
ГДЕ
НЕ Реализации.Ссылка ЕСТЬ NULL
Разберем ситуацию, когда реквизит документа или справочника имеет однозначный ссылочный тип (например, ДокументСсылка.РеализацияТоваровУслуг) и физически хранится в таблице. Если пользователь оставил это поле пустым, в базе записана пустая ссылка, а не NULL.
Для отсечения таких незаполненных полей используется прямое сравнение с предопределенным значением пустой ссылки через функцию ЗНАЧЕНИЕ():
ВЫБРАТЬ
Таблица.Ссылка КАК Документ,
Таблица.ДокументОснование КАК ДокументОснование
ИЗ
Документ.СчетНаОплату КАК Таблица
ГДЕ
Таблица.ДокументОснование <> ЗНАЧЕНИЕ(Документ.РеализацияТоваровУслуг.ПустаяСсылка)
Рассмотрим подробнее прием, когда в условии обращаются к реквизиту ссылки через точку, например: НЕ Таблица.Реквизит.Ссылка ЕСТЬ NULL.
Посмотрим на пример такого запроса:
ВЫБРАТЬ
Таблица.Ссылка КАК Документ,
Таблица.ДокументОснование КАК ДокументОснование
ИЗ
Документ.СчетНаОплату КАК Таблица
ГДЕ
НЕ Таблица.ДокументОснование.Ссылка ЕСТЬ NULL
Проанализируем, как работает данный механизм: при обращении через точку платформа 1С на уровне СУБД неявно строит LEFT JOIN с таблицей адресуемого объекта. Данное условие обладает следующими особенностями:
NULL, пустые ссылки и «битые» ссылки (так как для удаленного объекта соединение вернет NULL).Если реквизит имеет составной тип (например, может содержать несколько видов документов или значение Неопределено), прямого сравнения с одной пустой ссылкой недостаточно. В таких ситуациях разберем по шагам следующие подходы:
Неопределено через Таблица.Реквизит <> ЗНАЧЕНИЕ(Неопределено).ТИПЗНАЧЕНИЯ(Таблица.Реквизит) = ТИП(Документ.РеализацияТоваровУслуг).ВЫРАЗИТЬ перед обращением к свойствам объекта.Посмотрим на пример комплексной фильтрации составного поля:
ВЫБРАТЬ
Таблица.Ссылка КАК Документ,
Таблица.ДокументОснование КАК ДокументОснование
ИЗ
Документ.РасходныйКассовыйОрдер КАК Таблица
ГДЕ
Таблица.ДокументОснование <> ЗНАЧЕНИЕ(Неопределено)
И Таблица.ДокументОснование <> ЗНАЧЕНИЕ(Документ.ПоступлениеТоваровУслуг.ПустаяСсылка)
И Таблица.ДокументОснование <> ЗНАЧЕНИЕ(Документ.АвансовыйОтчет.ПустаяСсылка)
Если отчет строится с использованием СКД, писать сложные составные условия в тексте запроса не требуется. В настройках отбора СКД достаточно добавить поле и выбрать стандартный вид сравнения «Заполнено».
Платформа 1С в механизме компоновки данных автоматически обрабатывает этот вид сравнения: отсекаются значения NULL, Неопределено, пустые ссылки любых ссылочных типов, пустые строки и нулевые даты.