Как правильно проверить реквизит ссылочного типа на заполненность в 1С

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

Вариант 1. Использование функции ЗначениеЗаполнено()

Глобальный метод ЗначениеЗаполнено() является основным, каноничным и универсальным способом проверки любых данных на заполненность согласно стандартам разработки фирмы «1С».

Посмотрим на пример использования функции:


Если ЗначениеЗаполнено(пАктСверкиВзаиморасчетов) Тогда
    // Обработка заполненного значения
КонецЕсли;

Проанализируем ключевые преимущества данного метода:

  1. Универсальность для составных типов. Если реквизит имеет составной тип данных (например, документ может быть как актом сверки, так и платежным поручением), в реквизите на момент проверки может храниться значение типа Неопределено или NULL. Функция ЗначениеЗаполнено() корректно обработает любое переданное значение и вернет Ложь без возникновения критических исключений.
  2. Устойчивость к изменению метаданных. Если в процессе развития конфигурации реквизит из однозначного ссылочного типа станет составным, код не потребует рефакторинга.
  3. Читаемость и лаконичность. Нет необходимости обращаться к свойствам объекта через точку или передавать дополнительные параметры.

Вариант 2. Использование метода ссылки Пустая()

У объектов ссылочного типа в платформе 1С существует встроенный метод Пустая(), который возвращает булево значение Истина, если ссылка не указывает на существующий объект и ее уникальный идентификатор (GUID) состоит из нулей.

Разберем пример с использованием метода .Пустая():


Если НЕ пАктСверкиВзаиморасчетов.Ссылка.Пустая() Тогда
    // Действия с заполненным документом
КонецЕсли;

Однако у такого подхода есть важные ограничения, которые необходимо учитывать:

  1. Ошибка при обращении через точку к пустому значению составного типа. Если переменная или реквизит содержит значение Неопределено или NULL, попытка вызвать метод через точку (например, Реквизит.Пустая()) вызовет критическую ошибку времени выполнения: «Поле объекта не обнаружено».
  2. Избыточность конструкции. Если переменная уже содержит ссылку, обращение пАктСверкиВзаиморасчетов.Ссылка является лишней операцией получения того же самого значения.

Вариант 3. Сравнение с предопределенной пустой ссылкой типа

В некоторых случаях разработчики сравнивают значение реквизита с пустой ссылкой менеджера конкретного объекта метаданных.

Посмотрим на пример такого кода:


МояПустаяСсылка = Документы.АктСверкиВзаиморасчетов.ПустаяСсылка();
Если пАктСверкиВзаиморасчетов <> МояПустаяСсылка Тогда
    // Обработка непустого значения
КонецЕсли;

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

Нюанс с «битыми» ссылками (Объект не найден)

Важно помнить, что и ЗначениеЗаполнено(), и .Пустая() проверяют исключительно заполненность идентификатора ссылки (не равен ли он нулям). Они не проверяют физическое наличие записи в базе данных.

Если объект был удален непосредственно из базы данных, но ссылка на него осталась в реквизите (так называемая «битая ссылка» или «Объект не найден»):

  1. Метод .Пустая() вернет Ложь.
  2. Функция ЗначениеЗаполнено() вернет Истина, так как идентификатор ссылки заполнен.

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

Проверка заполненности ссылок в текстах запросов

В языке запросов 1С функция ЗначениеЗаполнено() недоступна. Для проверки ссылочного реквизита в запросе применяются следующие конструкции:

1. Сравнение с пустой ссылкой через литерал ЗНАЧЕНИЕ:


ВЫБРАТЬ
    ДокументПродажи.Ссылка КАК Ссылка
ИЗ
    Документ.РеализацияТоваровУслуг КАК ДокументПродажи
ГДЕ
    ДокументПродажи.ДоговорКонтрагента <> ЗНАЧЕНИЕ(Справочник.ДоговорыКонтрагентов.ПустаяСсылка)

2. Проверка на отсутствие значения при соединениях (NULL):


ГДЕ
    НЕ ДокументПродажи.ДоговорКонтрагента ЕСТЬ NULL
    И ДокументПродажи.ДоговорКонтрагента <> ЗНАЧЕНИЕ(Справочник.ДоговорыКонтрагентов.ПустаяСсылка)

Платформенные механизмы проверки заполнения

Вместо ручного написания условий проверки в коде рекомендуется использовать декларативные возможности платформы:

  1. Свойство реквизита «Проверка заполнения». Установка значения Выдавать ошибку в свойствах реквизита объекта автоматически валидирует его заполнение платформой при записи и проведении.
  2. Событие «ОбработкаПроверкиЗаполнения». Позволяет программно настраивать список проверяемых реквизитов в модуле объекта или формы.
  3. Метод «ПроверитьЗаполнение()». Вызывает проверку всех обязательных реквизитов объекта или формы и автоматически информирует пользователя о незаполненных полях.

Итог и рекомендации

Для проверки ссылочных реквизитов во встроенном языке 1С всегда используем стандартную функцию ЗначениеЗаполнено(Реквизит). Это защищает код от исключений при появлении Неопределено или NULL, обеспечивает совместимость с составными типами данных и полностью соответствует официальным стандартам разработки 1С.

← На главную