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

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

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

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

Проверка ссылки на пустоту — одна из самых частых операций в клиентском коде 1С. Она нужна, когда форма содержит необязательный реквизит, когда пользователь мог очистить поле ввода, или когда значение пришло из параметра, который мог быть не передан. Ошибка в этой проверке приводит либо к падению кода с сообщением «Значение не является значением объектного типа», либо к тихой записи некорректных данных.

На клиенте действуют ограничения: нельзя напрямую обращаться к запросам, нельзя вызывать многие серверные методы, а в тонком и веб-клиенте недоступна часть объектной модели. Поэтому проверку пустой ссылки нужно делать теми средствами, которые гарантированно работают в клиентском контексте.

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

Что такое пустая ссылка и когда она появляется

Пустая ссылка — это заранее существующее значение каждого ссылочного типа (справочника, документа, плана счетов и т.д.), которое обозначает «значение не выбрано». У неё есть уникальный идентификатор, состоящий из нулей, и она не соответствует ни одному реальному объекту базы данных.

Пустая ссылка появляется в типичных ситуациях: пользователь открыл форму, но не заполнил реквизит; поле было очищено кнопкой очистки; новый объект создан, но ссылочные реквизиты ещё не заполнены; параметр процедуры объявлен, но не передан при вызове. Каждый из этих случаев нужно корректно обработать до того, как код попытается обратиться к свойствам объекта через точку.

Универсальный способ: функция ЗначениеЗаполнено

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

&НаКлиенте

Процедура ПередЗаписьюПродолжение()

Если НЕ ЗначениеЗаполнено(Объект.Контрагент) Тогда

ПоказатьПредупреждение(, "Укажите контрагента перед записью");

Возврат;

КонецЕсли;

// дальнейшая логика

КонецПроцедуры

У функции есть особенность, о которой нужно помнить: она возвращает Ложь и для числа 0, и для пустой строки. Если вы проверяете именно ссылку и хотите отличить «пустая ссылка» от «значение вообще не задано», одной этой функции недостаточно — понадобится комбинация с проверкой типа или на Неопределено.

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

Если тип реквизита известен заранее, можно сравнить значение напрямую с пустой ссылкой нужного вида. Этот способ чуть быстрее и точнее, потому что не «схлопывает» разные пустые значения в одно.

&НаКлиенте

Процедура ПроверитьСклад()

Если Объект.Склад = ПредопределенноеЗначение("Справочник.Склады.ПустаяСсылка") Тогда

Сообщить("Склад не выбран");

КонецЕсли;

КонецПроцедуры

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

Этот способ не подходит для составных реквизитов (например, «Контрагент» может быть и справочником «Контрагенты», и «Организации»): для каждого типа пустая ссылка своя, и сравнение с одной из них не покроет остальные. В таких случаях возвращайтесь к ЗначениеЗаполнено().

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

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

Универсально, работает с любым типом и составными реквизитами. Минус: считает пустыми также 0 и пустую строку.

ПредопределенноеЗначение + ПустаяСсылка

Точная проверка конкретного типа, работает в тонком клиенте. Минус: нужно знать тип заранее, не подходит для составных полей.

Сравнение с Неопределено

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

Проверка на Неопределено и NULL

Значение Неопределено встречается, когда параметр процедуры не передан, поле структуры отсутствует или реквизит формы ещё не инициализирован. Это не то же самое, что пустая ссылка, и сравнение Значение = ПустаяСсылка() для Неопределено вернёт Ложь, хотя фактически значения нет.

Значение NULL приходит на клиент в основном из результатов запросов, переданных с сервера, — например, при левом соединении, когда связанной записи не нашлось. Проверяйте его явно:

&НаКлиенте

Процедура ОбработатьРезультат(Данные)

Если Данные = Неопределено Тогда

Возврат; // параметр не передан

КонецЕсли;

Если Данные.Партнер = NULL Тогда

Возврат; // связь в запросе не найдена

КонецЕсли;

Если НЕ ЗначениеЗаполнено(Данные.Партнер) Тогда

Возврат; // ссылка пустая

КонецЕсли;

КонецПроцедуры

Порядок проверок важен: сначала Неопределено, затем NULL, затем пустая ссылка. Если проверить пустую ссылку первой, обращение Данные.Партнер при Данные = Неопределено вызовет ошибку выполнения.

Порядок проверки значения на клиенте
  1. 1
    Проверьте значение на Неопределено — отсекает неинициализированные параметры
  2. 2
    Проверьте на NULL — отсекает пустые поля из запросов и соединений
  3. 3
    Проверьте ЗначениеЗаполнено() или сравните с ПустаяСсылка() — отсекает незаполненные ссылочные реквизиты
  4. 4
    Только после всех проверок обращайтесь к свойствам объекта через точку

Особенности для управляемых и обычных форм

В управляемых формах клиентский код работает с данными формы, а не с объектом напрямую. Реквизит типа «ДанныеФормыСтруктура» содержит ссылку как есть, и проверка ЗначениеЗаполнено(Объект.Ссылка) корректна. Но для нового, ещё не записанного объекта Объект.Ссылка будет пустой — это нормальное состояние, а не ошибка данных.

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

Для полей ввода на форме удобно выполнять проверку в обработчиках ПриИзменении или ОбработкаВыбора, чтобы среагировать сразу после действия пользователя, а не в момент записи, когда исправлять уже поздно.

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

Типичные ошибки при проверке

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

Вторая ошибка — сравнение строкового представления: Если Строка(Ссылка) = "" Тогда. Пустая ссылка может иметь непустое строковое представление вида «<Объект не найден>» или GUID, и такая проверка ненадёжна. Сравнивать нужно сами значения, а не их строки.

Третья ошибка — использование Если Ссылка Тогда с расчётом на автоматическое приведение типа. Встроенный язык 1С не приводит ссылку к булеву, такая конструкция вызовет ошибку преобразования. Всегда используйте явное сравнение или ЗначениеЗаполнено().

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

Проверка результата и отладка

Убедиться, что проверка работает, можно через вывод значения в отладчике или через Сообщить() с типом значения: Сообщить(ТипЗнч(Объект.Склад)). Для пустой ссылки тип будет соответствовать объекту (например, «СправочникСсылка.Склады»), а для непереданного параметра тип будет «Неопределено» — это позволяет быстро понять, какая именно ситуация сложилась.

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

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

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

Поведение при очищенном поле
Норма

Код выводит сообщение и не обращается к свойствам объекта

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

Ошибка «Значение не является значением объектного типа»

Тип значения в отладчике
Норма

СправочникСсылка.Имя или Неопределено — как ожидалось

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

Неожиданный тип, например Строка вместо ссылки

Количество серверных вызовов
Норма

Проверка выполняется локально, вызовов нет

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

Каждая проверка тянет серверный вызов

Итог

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

На клиенте используйте ЗначениеЗаполнено() как универсальную проверку или ПредопределенноеЗначение с ПустаяСсылка для известного типа. Проверяйте в порядке: Неопределено → NULL → пустая ссылка. Никогда не разыменовывайте ссылку до проверки и не сравнивайте строковые представления.

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

Работает ли ЗначениеЗаполнено в тонком и веб-клиенте?

Да, функция доступна во всех видах клиентов и на сервере. Это делает её основным выбором для общих модулей, которые компилируются в разных контекстах без директив препроцессора.

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

Пустая ссылка — это типизированное значение конкретного вида объекта, означающее «не выбрано». Неопределено — отсутствие значения как такового: параметр не передан, поле структуры не существует. Сравнение пустой ссылки с Неопределено даёт Ложь, поэтому проверять нужно оба случая.

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

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

Почему сравнение с Справочники.Имя.ПустаяСсылка() не работает в тонком клиенте?

Менеджеры прикладных объектов (Справочники, Документы и т.д.) недоступны в тонком и веб-клиенте. Используйте ПредопределенноеЗначение("Справочник.Имя.ПустаяСсылка") — этот метод работает везде.

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

У нового объекта ссылка всегда пустая до первой записи — это норма. Проверять нужно реквизиты объекта, а не его собственную ссылку. Если логика зависит от наличия ссылки, используйте ЭтоНовый() на сервере или проверку пустой ссылки как признак незаписанного объекта.