Разработка и Конфигурация · 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.
Проверка через параметр запроса
Иногда тип пустой ссылки заранее неизвестен или определяется в коде — тогда значение передают параметром. В модуле пустую ссылку получают через менеджер объекта:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Реализация.Ссылка
|ИЗ
| Документ.РеализацияТоваровУслуг КАК Реализация
|ГДЕ
| Реализация.Договор = &ПустойДоговор";
Запрос.УстановитьПараметр("ПустойДоговор",
Справочники.ДоговорыКонтрагентов.ПустаяСсылка());
Результат = Запрос.Выполнить();
Такой подход удобен в универсальных процедурах, где тип реквизита определяется метаданными в момент выполнения. Проверить, что параметр действительно содержит пустую ссылку нужного типа, можно в коде через ЗначениеЗаполнено() или сравнение Параметр = Справочники.ДоговорыКонтрагентов.ПустаяСсылка().
- 1Определите точный тип проверяемого реквизита в конфигураторе (свойства реквизита, состав типа)
- 2Выясните, откуда приходит поле: прямая таблица или результат соединения
- 3Для прямой таблицы напишите условие с ЗНАЧЕНИЕ(Тип.ПустаяСсылка), для соединения — ЕСТЬ NULL
- 4Выполните запрос в консоли запросов и убедитесь, что строки с пустыми значениями отбираются
- 5Проверьте обратное условие (<> или НЕ ... ЕСТЬ NULL), чтобы исключить ложные срабатывания
Проверка результата и отладка условия
Самый быстрый способ убедиться, что условие работает, — консоль запросов (в типовых конфигурациях есть встроенная, для разработки используют внешние консоли). Выполните запрос без условия, посмотрите, какие значения реально хранятся в поле, затем добавьте фильтр и сравните количество строк.
Если запрос с условием на пустую ссылку возвращает пустой результат, хотя вы точно видели незаполненные реквизиты, проверьте три вещи: совпадает ли тип в ЗНАЧЕНИЕ() с типом реквизита; не является ли значение на самом деле NULL из соединения; не составного ли типа реквизит.
Полезный приём — вывести в запросе само проверяемое поле и его представление рядом с результатом условия. Так сразу видно, какие строки попадают под фильтр и почему:
ВЫБРАТЬ
Заказ.Менеджер,
ВЫБОР
КОГДА Заказ.Менеджер = ЗНАЧЕНИЕ(Справочник.Пользователи.ПустаяСсылка)
ТОГДА ИСТИНА
ИНАЧЕ ЛОЖЬ
КОНЕЦ КАК МенеджерПустой
ИЗ
Документ.ЗаказКлиента КАК Заказ
Как проверить результат
Возвращает строки, где реквизит визуально не заполнен
Пустой результат при наличии незаполненных реквизитов — неверный тип в ЗНАЧЕНИЕ() или значение является NULL
Тип в ЗНАЧЕНИЕ() совпадает с типом реквизита
Типы различаются — условие никогда не выполнится
Для полей из соединений используется ЕСТЬ NULL
NULL из левого соединения сравнивается с пустой ссылкой — строки теряются
Частые вопросы
Можно ли проверить пустую ссылку через ЕСТЬ NULL?
Нет. Пустая ссылка — хранимое значение, а не NULL. Условие «Поле ЕСТЬ NULL» для реквизита с пустой ссылкой вернёт Ложь. ЕСТЬ NULL применяйте только к полям, которые могут отсутствовать из-за соединения или иметь составной тип.
Как проверить на пустую ссылку поле составного типа?
Комбинируйте условия: сначала «Поле ЕСТЬ NULL», затем через ИЛИ сравнение с пустой ссылкой каждого типа из состава реквизита. Альтернатива — привести поле через ВЫРАЗИТЬ к конкретному типу и сравнить с его пустой ссылкой.
Чем отличается ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка) от параметра с пустой ссылкой?
Результат сравнения одинаков. Разница в гибкости: литерал ЗНАЧЕНИЕ() жёстко фиксирует тип в тексте запроса, а параметр позволяет подставлять ссылку любого типа из кода. Для универсальных механизмов удобнее параметр, для конкретных запросов — ЗНАЧЕНИЕ().
Почему ЕСТЬNULL не заменяет пустую ссылку на нужное значение?
Функция ЕСТЬNULL обрабатывает только значения NULL. Пустая ссылка для неё — обычное заполненное значение, поэтому она проходит без замены. Используйте конструкцию ВЫБОР с явным сравнением на пустую ссылку.
Как отобрать документы, где хотя бы один реквизит не заполнен?
Перечислите условия через ИЛИ: «Реквизит1 = ЗНАЧЕНИЕ(Тип1.ПустаяСсылка) ИЛИ Реквизит2 = ЗНАЧЕНИЕ(Тип2.ПустаяСсылка)». Для строковых реквизитов проверяйте равенство пустой строке "" , для числовых — равенство нулю, так как у них нет понятия пустой ссылки.
Работает ли проверка на пустую ссылку в СКД?
Да, в схеме компоновки данных действуют те же правила языка запросов. В отборах СКД дополнительно доступно сравнение «Не заполнено», которое построитель отбора сам преобразует в корректное условие с учётом типа поля.
Что важно запомнить
Пустая ссылка проверяется сравнением с ЗНАЧЕНИЕ(Тип.ПустаяСсылка), NULL из соединений — оператором ЕСТЬ NULL, и эти способы не взаимозаменяемы. Тип в ЗНАЧЕНИЕ() должен точно совпадать с типом реквизита, а для составных полей условия комбинируются через ИЛИ.