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