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