Как в запросе 1С отфильтровать пустые значения документов и полей?

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

При разработке отчетов и обработок в 1С часто возникает задача скрыть строки, в которых реквизит или документ не заполнен. Начинающие разработчики нередко пытаются применить конструкцию ЕСТЬNULL для любых пустых полей, однако в платформе 1С:Предприятие понятие «пустое значение» может иметь разную природу. Проанализируем ситуацию, выясним причину различий между типами пустых данных и разберем по шагам все способы корректной фильтрации в запросах.

Разновидности пустых значений в 1С

Прежде чем писать условие в секции ГДЕ, необходимо определить, с каким именно видом отсутствия данных мы работаем. В платформе 1С выделяют четыре основных варианта:

  1. NULL — специальный маркер отсутствия значения в базе СУБД. Он возникает исключительно при выполнении операций соединения таблиц (ЛЕВОЕ СОЕДИНЕНИЕ или ПОЛНОЕ СОЕДИНЕНИЕ), когда для записи одной таблицы не нашлось соответствия в другой, либо при выборке полей из виртуальных таблиц. В самой базе данных ссылочные поля никогда не содержат NULL.
  2. Пустая ссылка — реальное валидное значение ссылочного типа, представляющее собой нулевой идентификатор GUID (все нули). Означает, что поле типизировано конкретным документом или справочником, но ссылка ни на какой реальный объект не указывает (поле не заполнено пользователем).
  3. Неопределено — специальное значение, которое может храниться в реквизитах составного типа данных, если значение в поле вообще не было выбрано.
  4. «Битая» ссылка — ситуация, когда в поле сохранен уникальный идентификатор объекта, но сам объект был физически удален из базы данных без контроля ссылочной целостности.

Способ 1. Исключение записей при левом соединении таблиц (предикат ЕСТЬ NULL)

Рассмотрим случай, когда поле документа оказывается пустым в результате соединения двух таблиц, и для строки не нашлось соответствия во второй таблице. В этом случае поле принимает значение NULL.

Обратите внимание на разницу между предикатом ЕСТЬ NULL (пишется раздельно) и функцией ЕСТЬNULL() (пишется слитно):

  1. Предикат ЕСТЬ NULL предназначен для секций ГДЕ и КОГДА.
  2. Функция ЕСТЬNULL(Поле, ЗначениеЗамены) используется в секции ВЫБРАТЬ для подстановки значения по умолчанию, если поле равно NULL. Использовать функцию ЕСТЬNULL в секции ГДЕ не рекомендуется, так как это снижает производительность из-за невозможности СУБД задействовать индексы.

Посмотрим на пример правильного использования предиката в запросе:


ВЫБРАТЬ
    Заказы.Ссылка КАК Заказ,
    Реализации.Ссылка КАК Реализация
ИЗ
    Документ.ЗаказКлиента КАК Заказы
    ЛЕВОЕ СОЕДИНЕНИЕ Документ.РеализацияТоваровУслуг КАК Реализации
        ПО Заказы.Ссылка = Реализации.ЗаказКлиента
ГДЕ
    НЕ Реализации.Ссылка ЕСТЬ NULL

Способ 2. Проверка реквизита на пустую ссылку конкретного типа

Разберем ситуацию, когда реквизит документа или справочника имеет однозначный ссылочный тип (например, ДокументСсылка.РеализацияТоваровУслуг) и физически хранится в таблице. Если пользователь оставил это поле пустым, в базе записана пустая ссылка, а не NULL.

Для отсечения таких незаполненных полей используется прямое сравнение с предопределенным значением пустой ссылки через функцию ЗНАЧЕНИЕ():


ВЫБРАТЬ
    Таблица.Ссылка КАК Документ,
    Таблица.ДокументОснование КАК ДокументОснование
ИЗ
    Документ.СчетНаОплату КАК Таблица
ГДЕ
    Таблица.ДокументОснование <> ЗНАЧЕНИЕ(Документ.РеализацияТоваровУслуг.ПустаяСсылка)

Способ 3. Разыменование поля через точку

Рассмотрим подробнее прием, когда в условии обращаются к реквизиту ссылки через точку, например: НЕ Таблица.Реквизит.Ссылка ЕСТЬ NULL.

Посмотрим на пример такого запроса:


ВЫБРАТЬ
    Таблица.Ссылка КАК Документ,
    Таблица.ДокументОснование КАК ДокументОснование
ИЗ
    Документ.СчетНаОплату КАК Таблица
ГДЕ
    НЕ Таблица.ДокументОснование.Ссылка ЕСТЬ NULL

Проанализируем, как работает данный механизм: при обращении через точку платформа 1С на уровне СУБД неявно строит LEFT JOIN с таблицей адресуемого объекта. Данное условие обладает следующими особенностями:

  1. Преимущество: условие одновременно отсекает значения NULL, пустые ссылки и «битые» ссылки (так как для удаленного объекта соединение вернет NULL).
  2. Ограничение по производительности: если реквизит имеет составной тип данных, платформа сгенерирует неявные соединения со всеми возможными таблицами типов, входящих в состав поля. Это приводит к существенному замедлению выполнения запроса на больших объемах данных.

Способ 4. Фильтрация составных типов данных

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

  1. Исключение значения Неопределено через Таблица.Реквизит <> ЗНАЧЕНИЕ(Неопределено).
  2. Проверка конкретного типа через конструкцию ТИПЗНАЧЕНИЯ(Таблица.Реквизит) = ТИП(Документ.РеализацияТоваровУслуг).
  3. Явное приведение типов с помощью конструкции ВЫРАЗИТЬ перед обращением к свойствам объекта.

Посмотрим на пример комплексной фильтрации составного поля:


ВЫБРАТЬ
    Таблица.Ссылка КАК Документ,
    Таблица.ДокументОснование КАК ДокументОснование
ИЗ
    Документ.РасходныйКассовыйОрдер КАК Таблица
ГДЕ
    Таблица.ДокументОснование <> ЗНАЧЕНИЕ(Неопределено)
    И Таблица.ДокументОснование <> ЗНАЧЕНИЕ(Документ.ПоступлениеТоваровУслуг.ПустаяСсылка)
    И Таблица.ДокументОснование <> ЗНАЧЕНИЕ(Документ.АвансовыйОтчет.ПустаяСсылка)

Фильтрация в Системе компоновки данных (СКД)

Если отчет строится с использованием СКД, писать сложные составные условия в тексте запроса не требуется. В настройках отбора СКД достаточно добавить поле и выбрать стандартный вид сравнения «Заполнено».

Платформа 1С в механизме компоновки данных автоматически обрабатывает этот вид сравнения: отсекаются значения NULL, Неопределено, пустые ссылки любых ссылочных типов, пустые строки и нулевые даты.

← На главную