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