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

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

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

Способы проверки пустой ссылки документа в запросе 1С: ЗНАЧЕНИЕ с пустой ссылкой, ЕСТЬ NULL, сравнение в условиях ГДЕ и ВЫБОР. Примеры кода и типичные ошибки.

Проверка на пустую ссылку — одна из самых частых задач при написании запросов в 1С. Документы могут ссылаться на другие документы (основание, заказ, счёт), и если поле не заполнено, в нём хранится не NULL, а именно пустая ссылка соответствующего типа. Неправильная проверка приводит к тому, что записи либо теряются из выборки, либо, наоборот, попадают в неё лишние строки.

Главная сложность в том, что пустая ссылка документа — это не NULL и не пустая строка. Это вполне конкретное значение: ссылка с нулевым внутренним идентификатором, типизированная конкретным видом документа. Поэтому сравнение с NULL или с пустой строкой не сработает — нужен специальный синтаксис языка запросов.

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

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

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

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

Практический вывод: если вы фильтруете реквизит самой таблицы документа, проверяйте на пустую ссылку. Если проверяете поле, полученное соединением таблиц, проверяйте на NULL через ЕСТЬ NULL. Часто нужны обе проверки одновременно.

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

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

Типичный запрос, выбирающий реализации без указанного документа-основания:

ВЫБРАТЬ

Реализация.Ссылка КАК Документ,

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

ИЗ

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

ГДЕ

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

Обратная проверка — отобрать документы, у которых основание заполнено:

ГДЕ

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

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

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

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

Когда вид документа заранее неизвестен или запрос строится универсально, пустую ссылку передают параметром. Во встроенном языке её получают методом ПустаяСсылка() менеджера документа:

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

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

"ВЫБРАТЬ

| Т.Ссылка

|ИЗ

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

|ГДЕ

| Т.ДокументОснование = &ПустоеОснование";

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

Документы.ЗаказКлиента.ПустаяСсылка());

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

Минус подхода — необходимость не забыть установить параметр перед выполнением. Если параметр не установлен, запрос завершится с ошибкой «Параметр не найден», что на рабочей базе проявится только в момент выполнения кода.

Сравнение вариантов

ЗНАЧЕНИЕ(...ПустаяСсылка)

Просто и читаемо, работает везде, включая СКД и динамические списки. Ограничение: вид документа жёстко зашит в текст запроса.

Параметр запроса

Гибко, подходит для универсальных процедур. Ограничение: нужно помнить об установке параметра, иначе ошибка в момент выполнения.

ЕСТЬ NULL

Единственный вариант для полей из левых соединений и составных типов с NULL. Не подходит для реквизитов самой таблицы документа.

Составные поля и проверка нескольких типов

Реквизит документа часто имеет составной тип: например, основание может быть заказом клиента или счётом на оплату. В этом случае сравнение с пустой ссылкой одного вида документа не покроет все варианты — пустые ссылки разных типов не равны между собой.

Решение — перечислить все допустимые пустые ссылки через ИЛИ:

ГДЕ

(Т.Основание = ЗНАЧЕНИЕ(Документ.ЗаказКлиента.ПустаяСсылка)

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

ИЛИ Т.Основание = НЕОПРЕДЕЛЕНО)

Значение НЕОПРЕДЕЛЕНО добавлено не случайно: в составном поле платформа может хранить именно его, если реквизит ни разу не заполнялся и тип не был зафиксирован. Поведение зависит от истории заполнения данных, поэтому надёжнее учесть и этот вариант.

Альтернатива — проверка через оператор ССЫЛКА: условие НЕ Т.Основание ССЫЛКА Документ.ЗаказКлиента отберёт строки, где основание либо пустое, либо другого типа. Это полезно, когда нужно найти «неправильно» заполненные поля, но для точной проверки на пустоту перечисление пустых ссылок надёжнее.

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

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

ВЫБРАТЬ

Реализация.Ссылка КАК Документ

ИЗ

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

ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.СтатусыДокументов КАК Статусы

ПО Статусы.Документ = Реализация.Ссылка

ГДЕ

Статусы.Документ ЕСТЬ NULL

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

Если одно и то же поле в запросе может оказаться и пустой ссылкой, и NULL (например, после объединения ОБЪЕДИНИТЬ нескольких источников с соединениями), комбинируйте обе проверки: Поле ЕСТЬ NULL ИЛИ Поле = ЗНАЧЕНИЕ(...). Порядок условий на результат не влияет, но оборачивайте их в скобки при сочетании с другими условиями.

Проверка в ВЫБОР и при работе с результатом

Проверка на пустую ссылку нужна не только в отборе, но и в вычисляемых полях. Конструкция ВЫБОР позволяет вывести признак заполненности прямо в результат запроса:

ВЫБРАТЬ

Т.Ссылка КАК Документ,

ВЫБОР

КОГДА Т.ДокументОснование = ЗНАЧЕНИЕ(Документ.ЗаказКлиента.ПустаяСсылка)

ТОГДА ИСТИНА

ИНАЧЕ ЛОЖЬ

КОНЕЦ КАК ОснованиеНеЗаполнено

ИЗ

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

Если дальше результат обходится во встроенном языке, помните: поле выборки с пустой ссылкой вернёт объект типа ДокументСсылка, а не NULL и не Неопределено. Проверять его в коде нужно методом Пустая() или функцией ЗначениеЗаполнено() — а не сравнением с Неопределено.

Отдельный случай — разыменование. Выражение вида Т.Основание.Номер для пустой ссылки вернёт NULL, а для «битой» ссылки (удалённого объекта) — тоже NULL. Поэтому NULL в разыменованном поле не означает, что само поле-ссылка пустое: возможно, объект был удалён. Для поиска битых ссылок используют проверку Т.Основание.Ссылка ЕСТЬ NULL при условии, что само поле Основание не пустое.

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

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

Количество строк в выборке
Норма

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

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

Ноль строк при заведомо существующих пустых полях — вероятно, проверка идёт не по тому типу

Реакция на тестовый документ
Норма

Документ с очищенным основанием появляется в выборке после перезаписи

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

Документ не попадает в выборку — возможно, в поле хранится НЕОПРЕДЕЛЕНО, а не пустая ссылка

Поведение при соединениях
Норма

Строки без связанных записей отбираются через ЕСТЬ NULL

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

Отбор по пустой ссылке после левого соединения ничего не находит

Типичные ошибки и как их избежать

Самая распространённая ошибка — сравнение ссылки со строкой: ГДЕ Т.Основание = "". Запрос при этом может даже выполниться, но условие всегда ложно, потому что типы несравнимы. Вторая по частоте — проверка Т.Основание ЕСТЬ NULL для реквизита самой таблицы, где NULL не бывает в принципе.

Третья группа ошибок связана с составными типами: разработчик проверяет только одну пустую ссылку и теряет документы, где в поле лежит НЕОПРЕДЕЛЕНО или пустая ссылка другого вида. Перед написанием условия откройте свойства реквизита в конфигураторе и посмотрите его состав типов — это займёт меньше минуты и избавит от скрытых пропусков данных.

Наконец, не забывайте про виртуальные таблицы и СКД: в параметрах виртуальных таблиц конструкция ЗНАЧЕНИЕ работает так же, но в схеме компоновки условия лучше выносить в отборы с параметрами, чтобы пользователь мог управлять ими без правки текста запроса.

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

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

Пустая ссылка документа проверяется через ЗНАЧЕНИЕ(Документ.Имя.ПустаяСсылка) или параметр запроса. NULL возникает только после соединений и разыменований и проверяется через ЕСТЬ NULL. Для составных полей учитывайте все типы и значение НЕОПРЕДЕЛЕНО. Всегда проверяйте запрос на тестовых данных с заведомо пустыми полями.

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

Можно ли проверить пустую ссылку сравнением с НЕОПРЕДЕЛЕНО?

Нет, это разные значения. НЕОПРЕДЕЛЕНО встречается в составных полях, которым ни разу не присваивали типизированное значение. Пустая ссылка — типизированное значение. Надёжная проверка для составного поля включает оба варианта через ИЛИ.

Как проверить на пустую ссылку в СКД, если вид документа задаёт пользователь?

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

Почему условие ГДЕ Основание ЕСТЬ NULL не находит документы без основания?

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

Как найти документы с «битыми» ссылками на удалённые объекты?

Используйте обращение через точку: условие вида ГДЕ НЕ Т.Основание = ЗНАЧЕНИЕ(Документ.ЗаказКлиента.ПустаяСсылка) И Т.Основание.Ссылка ЕСТЬ NULL. Поле заполнено, но объекта в базе нет — значит, ссылка битая.

Работает ли ЗНАЧЕНИЕ с пустой ссылкой в параметрах виртуальных таблиц?

Да, конструкция ЗНАЧЕНИЕ допустима в параметрах виртуальных таблиц регистров, в условиях соединений и в секции ИМЕЮЩИЕ. Ограничений по месту использования в тексте запроса у неё нет.