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

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

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

Как проверить пустую ссылку в 1С: функция ЗначениеЗаполнено, ПустаяСсылка, сравнение с Неопределено. Примеры кода, типичные ошибки и FAQ.

Пустая ссылка в 1С — это ссылочное значение, которое указывает на объект определённого типа, но не связано ни с одной реальной записью базы данных. Такое значение возникает, когда реквизит не заполнен, переменной присвоено значение по умолчанию или запрос вернул NULL для необязательного соединения. Если не проверить ссылку на пустоту, программа может обратиться к несуществующему объекту, выдать ошибку или записать в документ некорректные данные.

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

Ниже разобраны рабочие способы проверки с примерами кода, отличия для запросов и СКД, типичные ошибки и правила выбора подходящего варианта.

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

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

Значение Неопределено — это отсутствие значения как такового. Оно появляется, когда переменной вообще не присвоено значение, когда функция ничего не вернула или когда реквизит составного типа не заполнен и не имеет ограничения по типу. Сравнение пустой ссылки с Неопределено даст Ложь — это разные состояния.

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

Проверка через функцию ЗначениеЗаполнено()

Самый универсальный способ — встроенная функция ЗначениеЗаполнено(). Она возвращает Истина, если значение отличается от значения по умолчанию для своего типа, и Ложь для пустых ссылок, Неопределено, пустых строк, нулевых дат и числа 0.

Если НЕ ЗначениеЗаполнено(КонтрагентСсылка) Тогда

Сообщить("Контрагент не указан");

Возврат;

КонецЕсли;

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

Используйте ЗначениеЗаполнено() как проверку первого уровня перед дальнейшей обработкой. Если логика требует отличать пустую ссылку от Неопределено, дополняйте проверку сравнением с конкретной пустой ссылкой.

Сравнение с пустой ссылкой конкретного типа

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

Если ЗаказСсылка = Документы.ЗаказКлиента.ПустаяСсылка() Тогда

// ссылка пустая

КонецЕсли;

Для переменной, тип которой неизвестен, можно вызвать метод Пустая() у самой ссылки — он вернёт Истина для пустой ссылки:

Если ТипЗнч(ЗначениеРеквизита) = Тип("СправочникСсылка.Номенклатура")

И ЗначениеРеквизита.Пустая() Тогда

// пустая ссылка на номенклатуру

КонецЕсли;

Важный нюанс: сравнение ссылок разных типов не вызывает ошибку, а просто возвращает Ложь. Поэтому сравнение ДокументСсылка = Справочники.Контрагенты.ПустаяСсылка() всегда будет ложным — такая проверка бесполезна и указывает на ошибку в логике.

bsl
Если СсылкаНаОбъект = Справочники.Контрагенты.ПустаяСсылка() Тогда
    Возврат; // ссылка не заполнена
КонецЕсли;

// альтернатива без указания типа:
Если НЕ ЗначениеЗаполнено(СсылкаНаОбъект) Тогда
    Возврат;
КонецЕсли;

Проверка пустой ссылки в запросах

В языке запросов 1С проверка выполняется сравнением поля с параметром-ссылкой или с литералом пустой ссылки через функцию ЗНАЧЕНИЕ():

ВЫБРАТЬ

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

ИЗ

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

ГДЕ

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

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

Для полей, полученных левым соединением, проверяйте NULL: условие ГДЕ Таблица.Поле ЕСТЬ NULL. Сравнение NULL с пустой ссылкой не даст Истина, потому что NULL не равен ничему, включая сам себя.

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

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

В запросах и СКД используйте только средства языка запросов: ЗНАЧЕНИЕ(...), параметры и ЕСТЬ NULL. Функции встроенного языка в тексте запроса недоступны — попытка написать ЗначениеЗаполнено в запросе приведёт к ошибке.

Сравнение способов проверки

ЗначениеЗаполнено()

Универсально, не требует знания типа. Не различает пустую ссылку, Неопределено и пустую строку.

= ПустаяСсылка() конкретного типа

Строгая и читаемая проверка, когда тип известен. Требует указания менеджера объекта.

Метод Пустая() у ссылки

Удобен в паре с ТипЗнч() для составных типов. Не работает с Неопределено — будет ошибка обращения к методу.

ЕСТЬ NULL в запросе

Единственный способ проверить NULL после левого соединения. Не применим к обычному коду.

Типичные ошибки и их последствия

Самая распространённая ошибка — обращение к реквизитам пустой ссылки. Выражение КонтрагентСсылка.Наименование для пустой ссылки вернёт пустую строку без ошибки, а вот КонтрагентСсылка.ПолучитьОбъект() вернёт Неопределено, и следующее обращение к его свойству вызовет исключение.

Вторая ошибка — сравнение с Неопределено там, где лежит пустая ссылка. Условие Если Реквизит = Неопределено не сработает для незаполненного реквизита ссылочного типа, и проверка «проскочит», пропустив проблемное значение дальше по алгоритму.

Третья ошибка — проверка ссылки на существование объекта через ПолучитьОбъект() ради самой проверки. Это лишнее обращение к базе. Если нужно убедиться, что ссылка не «битая» (объект удалён), используйте именно этот метод, но для проверки на пустоту он избыточен.

Типичные ошибки
01
Сравнение пустой ссылки с Неопределено — условие никогда не выполнится, значение пройдёт дальше без проверки.
02
Проверка NULL в запросе через равенство — NULL не равен ничему, записи не отберутся.
03
Вызов метода Пустая() у значения Неопределено — ошибка исполнения, так как у Неопределено нет методов.
04
Сравнение с пустой ссылкой другого типа — всегда Ложь, проверка бесполезна.
05
Использование ПолучитьОбъект() для проверки на пустоту — лишнее обращение к базе и риск получить Неопределено.

Проверка результата и границы безопасной работы

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

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

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

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

Тип значения через ТипЗнч()
Норма

Возвращает ожидаемый ссылочный тип или Неопределено

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

Тип не совпадает с ожидаемым — значит, проверка сравнивает не то

ЗначениеЗаполнено() для пустого реквизита
Норма

Возвращает Ложь

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

Возвращает Истина — реквизит заполнен, ищите причину в данных

Сравнение с ПустаяСсылка()
Норма

Истина для незаполненного реквизита

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

Ложь при пустом реквизите — возможно, там Неопределено или другой тип

Запрос с левым соединением
Норма

Пустые поля отбираются через ЕСТЬ NULL

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

Условие через равенство не возвращает строки — это норма для NULL, меняйте условие

Изменения кода выполняйте на копии базы или в тестовом окружении. Проверки, влияющие на проведение документов и запись данных, после отладки прогоняйте на типовых сценариях: создание, изменение, перепроведение, отмена.

Порядок добавления проверки
  1. 1
    Определите тип проверяемого значения через ТипЗнч() в отладчике
  2. 2
    Выберите способ: ЗначениеЗаполнено() для универсальной проверки или сравнение с ПустаяСсылка() для строгой
  3. 3
    Вставьте проверку до первого обращения к реквизитам или объекту ссылки
  4. 4
    Протестируйте на записи с пустым и заполненным значением
  5. 5
    Проверьте, что существующие данные не блокируются новой проверкой
Итог

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

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

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

Чем пустая ссылка отличается от битой ссылки?

Пустая ссылка никогда не указывала на объект — это штатное незаполненное состояние реквизита. Битая ссылка указывала на объект, который потом удалили: у неё есть непустой уникальный идентификатор, но ПолучитьОбъект() вернёт Неопределено. Проверка на пустоту битую ссылку не выявит — для неё нужна отдельная проверка через ПолучитьОбъект() или запрос.

Можно ли проверить пустую ссылку без указания типа?

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

Почему условие «= Неопределено» не находит пустую ссылку?

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

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

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

Что вернёт функция ЗначениеЗаполнено() для числа 0 и пустой строки?

Ложь. Функция считает незаполненными значения по умолчанию для типа: число 0, пустую строку, пустую дату, Неопределено, NULL и пустые ссылки. Поэтому её нельзя использовать, когда ноль или пустая строка — осмысленные данные, например количество 0 в строке табличной части.

Нужно ли проверять ссылку перед вызовом ПолучитьОбъект()?

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