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