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