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