Разработка и Конфигурация · 10 мин
Как в 1С 8 проверить ссылку на пустую
Как в 1С 8 проверить ссылку на пустую: функция ЗначениеЗаполнено, сравнение с ПустаяСсылка(), проверка в запросе и на форме. Примеры кода и типичные ошибки.
Пустая ссылка в 1С 8 — это значение ссылочного типа, которое не указывает ни на один объект базы данных. Она возникает, когда реквизит не заполнен, переменная объявлена, но не инициализирована, или объект был удалён без контроля целостности. Проверка на пустую ссылку — одна из самых частых операций во встроенном языке, и ошибки здесь приводят к падению кода с сообщением «Поле объекта не обнаружено» или к некорректным данным в отчётах.
Существует несколько способов проверки: функция ЗначениеЗаполнено(), метод Пустая(), сравнение с ПустаяСсылка() конкретного типа, а также операторы языка запросов. Выбор зависит от контекста: где выполняется код (модуль, запрос, СКД), какого типа значение и нужна ли универсальность. Ниже разобраны все рабочие варианты с примерами кода, их ограничения и типичные ошибки.
Что такое пустая ссылка и чем она отличается от Неопределено
Пустая ссылка — это вполне определённое значение: у него есть конкретный тип (например, «СправочникСсылка.Номенклатура»), но внутренний идентификатор равен нулевому GUID. Платформа создаёт такое значение автоматически для каждого ссылочного реквизита, пока пользователь не выбрал реальный объект. Поэтому пустая ссылка не равна Неопределено и не равна NULL — это три разных состояния.
Значение Неопределено означает, что переменной вообще не присваивали значение или тип реквизита составной и значение не установлено. NULL появляется только в результатах запросов, чаще всего при левом соединении, когда в связанной таблице не нашлось записи. Сравнение пустой ссылки с Неопределено вернёт Ложь, поэтому проверка «на всё сразу» требует либо составного условия, либо функции ЗначениеЗаполнено(), которая корректно обрабатывает все три случая.
Проверка функцией ЗначениеЗаполнено — универсальный способ
Функция ЗначениеЗаполнено(Значение) — встроенная функция глобального контекста, которая возвращает Истина, если значение заполнено, и Ложь для пустых ссылок, Неопределено, NULL, пустых строк, нулевых дат и нулевых чисел. Для проверки на пустую ссылку её обычно используют с отрицанием:
Если НЕ ЗначениеЗаполнено(Документ.Контрагент) Тогда
Сообщить("Не указан контрагент");
КонецЕсли;
Главное достоинство подхода — универсальность: код не ломается, если тип реквизита изменится или переменная окажется составного типа. Расплата — избыточность: функция считает пустыми и число 0, и пустую строку, поэтому для строгой проверки именно ссылки она не всегда подходит. Например, если переменная может содержать либо ссылку, либо число, ЗначениеЗаполнено не отличит пустую ссылку от нуля.
В производительном коде, выполняемом в цикле над тысячами записей, ЗначениеЗаполнено работает чуть медленнее прямого сравнения с пустой ссылкой конкретного типа. На прикладном уровне разница незаметна, но в массовых обработках предпочтительнее точечные проверки.
Сравнение с ПустаяСсылка() и метод Пустая()
Когда тип значения известен заранее, используется прямое сравнение с пустой ссылкой нужного вида объекта. Менеджер каждого ссылочного типа предоставляет метод ПустаяСсылка():
Если Контрагент = Справочники.Контрагенты.ПустаяСсылка() Тогда
Возврат;
КонецЕсли;
Если ДокументОснование = Документы.РеализацияТоваровУслуг.ПустаяСсылка() Тогда
// основание не указано
КонецЕсли;
Альтернатива — метод Пустая() самого значения ссылки. Он возвращает Истина, если ссылка пустая:
Если Контрагент.Пустая() Тогда
Возврат;
КонецЕсли;
У метода Пустая() есть важное ограничение: его нельзя вызвать, если переменная содержит Неопределено или значение нессылочного типа — будет ошибка выполнения. Поэтому его применяют только там, где тип гарантирован. Прямое сравнение с ПустаяСсылка() безопаснее: если типы не совпадают, результат будет просто Ложь, без исключения.
Проверка пустой ссылки в запросе
В языке запросов сравнение с пустой ссылкой выполняется через литерал ЗНАЧЕНИЕ с указанием типа или через параметр. Оба варианта рабочие, выбор — вопрос читаемости и гибкости:
ВЫБРАТЬ
Реализация.Ссылка
ИЗ
Документ.РеализацияТоваровУслуг КАК Реализация
ГДЕ
Реализация.Контрагент = ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка)
Передача пустой ссылки параметром удобнее, когда тип реквизита может меняться или запрос строится динамически:
Запрос.УстановитьПараметр("ПустойКонтрагент", Справочники.Контрагенты.ПустаяСсылка());
// в тексте запроса: ГДЕ Реализация.Контрагент = &ПустойКонтрагент
Отдельная ситуация — левые соединения. Если реквизит получен из присоединённой таблицы и записи не нашлось, значение будет NULL, а не пустая ссылка. Проверка = ЗНАЧЕНИЕ(..ПустаяСсылка) такие строки не отберёт. Нужно либо ЕСТЬ NULL, либо комбинированное условие:
ГДЕ
Остатки.Склад ЕСТЬ NULL
ИЛИ Остатки.Склад = ЗНАЧЕНИЕ(Справочник.Склады.ПустаяСсылка)
Проверка на форме и в реквизитах объекта
В модулях форм проверка обычно выполняется при записи или при изменении поля ввода. Для реквизитов объекта доступны те же методы, но Контрагенты.ПустаяСсылка() на тонком клиенте вызвать нельзя. Здесь выручает ЗначениеЗаполнено(), работающая и на клиенте, и на сервере.
&НаКлиенте
Процедура КонтрагентПриИзменении(Элемент)
Если НЕ ЗначениеЗаполнено(Объект.Контрагент) Тогда
Объект.Договор = Неопределено;
КонецЕсли;
КонецПроцедуры
Если на клиенте требуется именно пустая ссылка конкретного типа (например, чтобы очистить поле программно), её получают один раз на сервере и кэшируют в реквизите формы, либо используют ПредопределенноеЗначение("Справочник.Контрагенты.ПустаяСсылка") — эта функция доступна на клиенте и возвращает пустую ссылку по строковому имени.
Функция ПредопределенноеЗначение() работает быстрее обращения к менеджеру объекта и доступна везде, включая тонкий клиент и СКД. Для проверок в выражениях компоновки это часто единственный способ получить пустую ссылку.
Выбор способа проверки под задачу
Единого «правильного» варианта нет — у каждого способа своя область применения. Ориентируйтесь на контекст выполнения кода и на то, гарантирован ли тип значения.
| Способ | Когда применять | Ограничения |
|---|---|---|
ЗначениеЗаполнено() | Универсальная проверка, клиент и сервер, составные типы | Не отличает пустую ссылку от 0 и пустой строки |
= Менеджер.ПустаяСсылка() | Сервер, тип известен заранее | Недоступно на тонком клиенте |
Ссылка.Пустая() | Тип гарантированно ссылочный | Ошибка при Неопределено |
ПредопределенноеЗначение() | Клиент, СКД, динамический тип | Требует строкового имени типа |
ЗНАЧЕНИЕ(..ПустаяСсылка) | Язык запросов | Не ловит NULL при соединениях |
Как выбрать действие
Как убедиться, что проверка работает правильно
После внедрения проверки протестируйте три сценария: реквизит не заполнен, реквизит заполнен реальным объектом, реквизит содержит «битую» ссылку на удалённый объект. Третий случай часто упускают: пустая ссылка и ссылка на несуществующий объект — разные вещи. Проверка на пустоту битую ссылку не отловит, для этого нужен запрос к базе или проверка Ссылка.ПолучитьОбъект() на Неопределено.
Как проверить результат
Условие срабатывает, выводится сообщение или ветка обработки
Код проходит мимо условия или падает с ошибкой
Условие на пустоту возвращает Ложь, логика продолжается
Заполненное значение ошибочно считается пустым
Отрабатывает условие ЕСТЬ NULL
Строка теряется из выборки без предупреждения
Полезный приём при отладке — вывести значение и его тип: Сообщить(ТипЗнч(Переменная));. Если ожидалась ссылка, а выводится «Неопределено» или «Число», причина неработающей проверки найдена — проблема не в самом сравнении, а в источнике данных.
Что важно запомнить
Для универсальной проверки используйте ЗначениеЗаполнено(), для строгой — сравнение с ПустаяСсылка() конкретного типа, в запросах — ЗНАЧЕНИЕ(..ПустаяСсылка) с учётом NULL. Метод Пустая() вызывайте только у гарантированно ссылочных значений.
Частые вопросы
Чем пустая ссылка отличается от битой ссылки?
Пустая ссылка не указывает ни на какой объект и имеет нулевой идентификатор. Битая ссылка содержит идентификатор реально существовавшего, но удалённого объекта. Проверка на пустоту битую ссылку не выявит — нужна проверка существования объекта в базе.
Почему сравнение с Неопределено не находит пустой реквизит?
Незаполненный ссылочный реквизит хранит пустую ссылку своего типа, а не Неопределено. Это разные значения, и сравнение между ними даёт Ложь. Используйте ЗначениеЗаполнено() или сравнение с ПустаяСсылка().
Как проверить на пустую ссылку в СКД?
В выражениях компоновки и отборах используйте функцию ПредопределенноеЗначение("Справочник.Имя.ПустаяСсылка") или параметр, в который пустая ссылка передаётся из кода. Прямой вызов менеджеров в СКД недоступен.
Работает ли ЗначениеЗаполнено на тонком клиенте?
Да, функция доступна во всех режимах выполнения, включая тонкий и веб-клиент. Это делает её основным инструментом проверки заполненности в клиентских процедурах форм.
Что вернёт сравнение пустых ссылок разных типов?
Пустая ссылка справочника не равна пустой ссылке документа — сравнение учитывает тип. Поэтому проверять нужно именно на пустую ссылку того вида объекта, который хранится в реквизите.
Как найти в базе все документы с незаполненным реквизитом?
Выполните запрос с условием Реквизит = ЗНАЧЕНИЕ(Тип.ПустаяСсылка). Для составных реквизитов добавьте проверку на все возможные типы или используйте условие на Неопределено через параметр.