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