К статье
Практический материал

Разработка и Конфигурация · 10 мин

Как в запросе 1С проверить поле на пустую ссылку

Способы проверки на пустую ссылку в запросе 1С: ЗНАЧЕНИЕ с пустой ссылкой, ЕСТЬ NULL, сравнение с Неопределено. Примеры кода, ошибки и рекомендации.

Проверка на пустую ссылку — одна из самых частых операций при написании запросов в 1С. Незаполненные реквизиты встречаются в документах, справочниках и регистрах, и если их не отфильтровать, в отчётах появляются строки с пустыми значениями, а в соединениях — неожиданные NULL.

Язык запросов 1С не поддерживает прямое сравнение Ссылка = NULL для пустых ссылок: NULL и пустая ссылка — разные вещи. Для проверки используется функция ЗНАЧЕНИЕ() с указанием пустой ссылки конкретного типа, например ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка). Выбор конструкции зависит от типа поля: составной реквизит, результат соединения или обычная ссылка требуют разных подходов.

Ниже разобраны все рабочие способы проверки: от простого сравнения до обработки NULL после левого соединения, а также типичные ошибки, из-за которых условие «молча» не срабатывает.

Чем пустая ссылка отличается от NULL и Неопределено

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

Пустая ссылка — это реальное значение ссылочного типа, которое хранится в базе данных. У реквизита типа «СправочникСсылка.Номенклатура» пустая ссылка имеет вполне определённое внутреннее представление (нулевой уникальный идентификатор). Она сравнивается оператором равенства и участвует в соединениях как обычное значение.

NULL — результат отсутствия строки при левом или правом соединении, а также значение по умолчанию в некоторых виртуальных таблицах. NULL не равен ничему, включая сам себя: условие Поле = NULL никогда не вернёт Истина. Проверять его нужно только оператором ЕСТЬ NULL.

Неопределено — значение встроенного языка, а не языка запросов. В тексте запроса использовать Неопределено напрямую нельзя; его можно передать только как параметр, но и тогда сравнение с пустой ссылкой не сработает так, как ожидается.

Основной способ: функция ЗНАЧЕНИЕ с пустой ссылкой

Стандартный и рекомендуемый способ — сравнение поля с литералом пустой ссылки через функцию ЗНАЧЕНИЕ(). Функция принимает полное имя предопределённого значения, включая служебное имя ПустаяСсылка, которое есть у любого ссылочного типа.

ВЫБРАТЬ

РеализацияТоваров.Ссылка,

РеализацияТоваров.Контрагент

ИЗ

Документ.РеализацияТоваровУслуг КАК РеализацияТоваров

ГДЕ

РеализацияТоваров.Договор = ЗНАЧЕНИЕ(Справочник.ДоговорыКонтрагентов.ПустаяСсылка)

Этот запрос вернёт все реализации, у которых не заполнен договор. Обратный вариант — отобрать только заполненные — строится через неравенство:

ГДЕ

РеализацияТоваров.Договор <> ЗНАЧЕНИЕ(Справочник.ДоговорыКонтрагентов.ПустаяСсылка)

Важно: тип внутри ЗНАЧЕНИЕ() должен точно совпадать с типом проверяемого поля. Если реквизит имеет тип «СправочникСсылка.ДоговорыКонтрагентов», а вы сравниваете его с ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка), условие никогда не выполнится — пустые ссылки разных типов не равны между собой.

Проверка после соединения: оператор ЕСТЬ NULL

Если поле приходит из левого соединения, его «пустота» чаще всего означает NULL, а не пустую ссылку. Классический пример: список номенклатуры с остатками, где для части позиций остатков нет вовсе.

ВЫБРАТЬ

Номенклатура.Ссылка,

Остатки.КоличествоОстаток

ИЗ

Справочник.Номенклатура КАК Номенклатура

ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки КАК Остатки

ПО Номенклатура.Ссылка = Остатки.Номенклатура

ГДЕ

Остатки.Номенклатура ЕСТЬ NULL

Такой запрос вернёт позиции, по которым нет записей в таблице остатков. Здесь сравнение с ЗНАЧЕНИЕ(...ПустаяСсылка) не сработает, потому что отсутствующая строка — это NULL, а NULL не равен даже пустой ссылке.

На практике поле может оказаться и NULL, и пустой ссылкой одновременно в разных строках. Тогда условия комбинируют через ИЛИ:

ГДЕ

Остатки.Номенклатура ЕСТЬ NULL

ИЛИ Остатки.Номенклатура = ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка)

Маршрут решения

Как выбрать способ проверки

Поле — обычный реквизит таблицы без соединенийСравнивайте с ЗНАЧЕНИЕ(Тип.ПустаяСсылка) через = или <>
Поле пришло из ЛЕВОГО или ПРАВОГО соединенияИспользуйте ЕСТЬ NULL, при необходимости добавьте проверку на пустую ссылку через ИЛИ
Реквизит составного типаПроверяйте на NULL и на пустые ссылки всех входящих в состав типов
Нужно заменить пустое значение в выборкеИспользуйте ЕСТЬNULL(Поле, ЗначениеПоУмолчанию) или ВЫБОР

Составные типы и вывод значения вместо пустой ссылки

Реквизиты составного типа (например, «Контрагент» может быть и справочником, и документом) хранят NULL для незадействованных типов. Если поле не заполнено вовсе, значение также может читаться как NULL, поэтому для составных реквизитов надёжнее начинать проверку с ЕСТЬ NULL, а затем добавлять сравнение с пустыми ссылками каждого типа.

Когда пустую ссылку нужно не отфильтровать, а заменить в результате на читаемое значение, используют конструкцию ВЫБОР или функцию ЕСТЬNULL():

ВЫБРАТЬ

ВЫБОР

КОГДА Заказ.Менеджер = ЗНАЧЕНИЕ(Справочник.Пользователи.ПустаяСсылка)

ТОГДА "Не назначен"

ИНАЧЕ Заказ.Менеджер.Наименование

КОНЕЦ КАК Ответственный

ИЗ

Документ.ЗаказКлиента КАК Заказ

Функция ЕСТЬNULL(Поле, Замена) работает только с NULL и не перехватывает пустую ссылку — это частая причина «непонятного» поведения отчётов. Если поле может содержать именно пустую ссылку, замену делайте через ВЫБОР, а не через ЕСТЬNULL.

Типичные ошибки
01
Сравнение Поле = NULL — условие никогда не выполняется, NULL проверяется только оператором ЕСТЬ NULL
02
ЕСТЬNULL(Поле, Замена) не заменяет пустую ссылку — функция обрабатывает только NULL
03
Проверка составного реквизита на пустую ссылку одного типа — значения других типов и NULL проходят мимо фильтра
04
Несовпадение типа в ЗНАЧЕНИЕ() с типом реквизита — пустые ссылки разных типов не равны, условие молча не срабатывает
05
Передача Неопределено параметром вместо пустой ссылки — сравнение в запросе не даст ожидаемого результата

Проверка через параметр запроса

Иногда тип пустой ссылки заранее неизвестен или определяется в коде — тогда значение передают параметром. В модуле пустую ссылку получают через менеджер объекта:

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| Реализация.Ссылка

|ИЗ

| Документ.РеализацияТоваровУслуг КАК Реализация

|ГДЕ

| Реализация.Договор = &ПустойДоговор";

Запрос.УстановитьПараметр("ПустойДоговор",

Справочники.ДоговорыКонтрагентов.ПустаяСсылка());

Результат = Запрос.Выполнить();

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

Порядок действий при отладке условия
  1. 1
    Определите точный тип проверяемого реквизита в конфигураторе (свойства реквизита, состав типа)
  2. 2
    Выясните, откуда приходит поле: прямая таблица или результат соединения
  3. 3
    Для прямой таблицы напишите условие с ЗНАЧЕНИЕ(Тип.ПустаяСсылка), для соединения — ЕСТЬ NULL
  4. 4
    Выполните запрос в консоли запросов и убедитесь, что строки с пустыми значениями отбираются
  5. 5
    Проверьте обратное условие (<> или НЕ ... ЕСТЬ NULL), чтобы исключить ложные срабатывания

Проверка результата и отладка условия

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

Если запрос с условием на пустую ссылку возвращает пустой результат, хотя вы точно видели незаполненные реквизиты, проверьте три вещи: совпадает ли тип в ЗНАЧЕНИЕ() с типом реквизита; не является ли значение на самом деле NULL из соединения; не составного ли типа реквизит.

Полезный приём — вывести в запросе само проверяемое поле и его представление рядом с результатом условия. Так сразу видно, какие строки попадают под фильтр и почему:

ВЫБРАТЬ

Заказ.Менеджер,

ВЫБОР

КОГДА Заказ.Менеджер = ЗНАЧЕНИЕ(Справочник.Пользователи.ПустаяСсылка)

ТОГДА ИСТИНА

ИНАЧЕ ЛОЖЬ

КОНЕЦ КАК МенеджерПустой

ИЗ

Документ.ЗаказКлиента КАК Заказ

Контрольные точки

Как проверить результат

Запрос с условием на пустую ссылку
Норма

Возвращает строки, где реквизит визуально не заполнен

Тревожный признак

Пустой результат при наличии незаполненных реквизитов — неверный тип в ЗНАЧЕНИЕ() или значение является NULL

Тип реквизита в конфигураторе
Норма

Тип в ЗНАЧЕНИЕ() совпадает с типом реквизита

Тревожный признак

Типы различаются — условие никогда не выполнится

Источник поля в запросе
Норма

Для полей из соединений используется ЕСТЬ NULL

Тревожный признак

NULL из левого соединения сравнивается с пустой ссылкой — строки теряются

Частые вопросы

Можно ли проверить пустую ссылку через ЕСТЬ NULL?

Нет. Пустая ссылка — хранимое значение, а не NULL. Условие «Поле ЕСТЬ NULL» для реквизита с пустой ссылкой вернёт Ложь. ЕСТЬ NULL применяйте только к полям, которые могут отсутствовать из-за соединения или иметь составной тип.

Как проверить на пустую ссылку поле составного типа?

Комбинируйте условия: сначала «Поле ЕСТЬ NULL», затем через ИЛИ сравнение с пустой ссылкой каждого типа из состава реквизита. Альтернатива — привести поле через ВЫРАЗИТЬ к конкретному типу и сравнить с его пустой ссылкой.

Чем отличается ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка) от параметра с пустой ссылкой?

Результат сравнения одинаков. Разница в гибкости: литерал ЗНАЧЕНИЕ() жёстко фиксирует тип в тексте запроса, а параметр позволяет подставлять ссылку любого типа из кода. Для универсальных механизмов удобнее параметр, для конкретных запросов — ЗНАЧЕНИЕ().

Почему ЕСТЬNULL не заменяет пустую ссылку на нужное значение?

Функция ЕСТЬNULL обрабатывает только значения NULL. Пустая ссылка для неё — обычное заполненное значение, поэтому она проходит без замены. Используйте конструкцию ВЫБОР с явным сравнением на пустую ссылку.

Как отобрать документы, где хотя бы один реквизит не заполнен?

Перечислите условия через ИЛИ: «Реквизит1 = ЗНАЧЕНИЕ(Тип1.ПустаяСсылка) ИЛИ Реквизит2 = ЗНАЧЕНИЕ(Тип2.ПустаяСсылка)». Для строковых реквизитов проверяйте равенство пустой строке "" , для числовых — равенство нулю, так как у них нет понятия пустой ссылки.

Работает ли проверка на пустую ссылку в СКД?

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

Итог

Что важно запомнить

Пустая ссылка проверяется сравнением с ЗНАЧЕНИЕ(Тип.ПустаяСсылка), NULL из соединений — оператором ЕСТЬ NULL, и эти способы не взаимозаменяемы. Тип в ЗНАЧЕНИЕ() должен точно совпадать с типом реквизита, а для составных полей условия комбинируются через ИЛИ.