Разработка и Конфигурация · 12 мин
Как проверить на пустое значение в запросе 1С
Проверка на пустые значения в запросах 1С: NULL, пустые ссылки, пустые строки и даты. Примеры кода, функции ЕСТЬNULL, типичные ошибки и FAQ.
Проверка на пустое значение — одна из самых частых задач при написании запросов в 1С. Ошибка здесь приводит к потере строк в выборке, некорректным итогам в отчётах и трудноуловимым дефектам, которые проявляются только на реальных данных. Причина в том, что «пустое значение» в 1С — не одно понятие, а несколько разных сущностей: NULL, пустая ссылка, пустая строка, пустая дата, незаполненный реквизит составного типа.
Универсального оператора «пусто / не пусто» в языке запросов нет. Для каждого типа данных применяется своя конструкция: сравнение с NULL, с пустой ссылкой через ЗНАЧЕНИЕ(), с пустой строкой или датой. Кроме того, есть встроенная функция проверки заполненности значения — о ней часто забывают, хотя она закрывает большинство сценариев.
Материал разбирает все способы проверки: от простейшего сравнения с NULL до обработки составных типов и левых соединений. Примеры приведены на языке запросов 1С и подходят для платформы 8.3.
Что считается пустым значением в запросе 1С
Перед выбором конструкции важно понять, с каким именно «пустым» значением вы работаете. В языке запросов 1С существует несколько разных состояний отсутствия данных, и они не равны друг другу при сравнении.
NULL — специальное значение, означающее отсутствие данных. Оно появляется при левом соединении, когда в присоединяемой таблице не нашлось подходящей строки, при обращении к реквизиту через точку от NULL-ссылки и в агрегатных функциях без данных. NULL не равен ничему, даже самому себе: условие Поле = NULL всегда ложно, поэтому для проверки используется только ЕСТЬ NULL или НЕ ЕСТЬ NULL.
Пустая ссылка — реальное значение ссылочного типа, которое хранится в базе и означает «объект не указан». Это не NULL: реквизит заполнен, но ссылается на пустую ссылку конкретного типа. Пустые ссылки разных справочников не равны между собой.
Пустая строка и пустая дата — значения примитивных типов. Пустая строка — это "", пустая дата — ДАТАВРЕМЯ(1,1,1), то есть 01.01.0001 00:00:00. Число нулевого значения — обычный 0, он сравнивается стандартно.
Возникает при соединениях и обращениях через точку; проверяется только через ЕСТЬ NULL
Сравнивается со ЗНАЧЕНИЕ(Справочник.Имя.ПустаяСсылка)
Сравнивается с пустым строковым литералом
Сравнивается с ДАТАВРЕМЯ(1,1,1)
Проверка на NULL: оператор ЕСТЬ NULL
Основная конструкция для проверки отсутствия данных — оператор ЕСТЬ NULL (в английском синтаксисе — IS NULL). Он возвращает Истина, если выражение равно NULL, и Ложь в противном случае. Обратная проверка записывается как НЕ ... ЕСТЬ NULL.
ВЫБРАТЬ
Заказы.Номер,
Оплаты.Сумма
ИЗ
Документ.ЗаказПокупателя КАК Заказы
ЛЕВОЕ СОЕДИНЕНИЕ Документ.Оплата КАК Оплаты
ПО Заказы.Ссылка = Оплаты.Заказ
ГДЕ
Оплаты.Сумма ЕСТЬ NULL
Этот запрос вернёт все заказы, по которым нет оплаты: при левом соединении поля правой таблицы для несопоставленных строк будут NULL. Обратите внимание: проверять нужно поле, которое гарантированно заполнено в правой таблице (обычно ссылку или ключевой реквизит), иначе условие сработает и на строки, где поле просто не заполнено.
Частая ошибка — написать ГДЕ Оплаты.Сумма = NULL. Такое условие никогда не выполнится, потому что любое сравнение с NULL даёт NULL (неопределённость), а не Истину. Запрос отработает без ошибки синтаксиса, но вернёт пустой результат, и найти причину бывает непросто.
Проверка на пустую ссылку через ЗНАЧЕНИЕ()
Для ссылочных реквизитов пустое значение проверяется сравнением с пустой ссылкой конкретного типа. Она задаётся оператором ЗНАЧЕНИЕ() с указанием объекта метаданных.
ВЫБРАТЬ
Товары.Номенклатура
ИЗ
Документ.Реализация.Товары КАК Товары
ГДЕ
Товары.Склад = ЗНАЧЕНИЕ(Справочник.Склады.ПустаяСсылка)
Здесь важно указать правильный тип объекта: Справочник.Склады.ПустаяСсылка, Документ.ЗаказПокупателя.ПустаяСсылка, Перечисление.ВидыОпераций.ПустаяСсылка. Если реквизит составного типа (например, может хранить ссылку на разные документы), одной проверки недостаточно — нужно перечислить пустые ссылки всех возможных типов через ИЛИ либо использовать другой подход, описанный ниже.
Для перечислений пустая ссылка записывается аналогично: ЗНАЧЕНИЕ(Перечисление.СтавкиНДС.ПустаяСсылка). Не путайте её с предопределённым значением перечисления — это разные вещи.
Составные типы и обращение через точку
Если реквизит имеет составной тип, обращение к его свойству через точку (например, Товары.ДокументОснование.Номер) для строк, где хранится ссылка другого типа или пустая ссылка, даст NULL. Поэтому проверка «заполнен ли реквизит» и «заполнено ли поле связанного объекта» — разные условия, и их часто приходится комбинировать.
Проверка пустых строк, дат и чисел
Примитивные типы проверяются обычным сравнением с литералом пустого значения. Для строки это пустой литерал, для даты — начало отсчёта, для числа — ноль.
ВЫБРАТЬ
Контрагенты.Наименование
ИЗ
Справочник.Контрагенты КАК Контрагенты
ГДЕ
Контрагенты.ИНН = ""
ИЛИ Контрагенты.ДатаРегистрации = ДАТАВРЕМЯ(1, 1, 1)
ИЛИ Контрагенты.Лимит = 0
У строк есть тонкость: реквизит может содержать строку из пробелов, которая визуально пуста, но сравнению с "" не равна. Если данные вводились вручную и такое возможно, имеет смысл подчищать данные при записи, а в запросе при необходимости использовать дополнительные условия. Функции сокращения пробелов в языке запросов нет, поэтому полноценная обработка таких случаев выполняется уже в коде встроенного языка.
Для дат помните, что ДАТАВРЕМЯ(1,1,1) — это именно 01.01.0001 00:00:00. Дата 01.01.0002 или любая другая пустым значением не считается. Если пользователи вместо очистки поля вводят «условно пустую» дату вроде 01.01.1900, запрос её не отловит.
Функция ЕСТЬNULL: замена пустых значений
Функция ЕСТЬNULL(Выражение, ЗначениеПоУмолчанию) не проверяет, а заменяет: если первый аргумент равен NULL, возвращается второй аргумент, иначе — само выражение. Это стандартный приём для отчётов, где вместо пустоты нужно показать ноль, прочерк или текст.
ВЫБРАТЬ
Заказы.Номер,
ЕСТЬNULL(Оплаты.Сумма, 0) КАК СуммаОплаты,
ВЫБОР
КОГДА Оплаты.Ссылка ЕСТЬ NULL
ТОГДА "Не оплачен"
ИНАЧЕ "Оплачен"
КОНЕЦ КАК Статус
ИЗ
Документ.ЗаказПокупателя КАК Заказы
ЛЕВОЕ СОЕДИНЕНИЕ Документ.Оплата КАК Оплаты
ПО Заказы.Ссылка = Оплаты.Заказ
Ограничение функции: оба аргумента должны быть совместимы по типу. Нельзя написать ЕСТЬNULL(Сумма, "нет данных") для числового поля — получите ошибку либо неожиданное приведение. Если нужен текст вместо числа, сначала приведите значение к строке или используйте конструкцию ВЫБОР.
ЕСТЬNULL работает только с NULL. Если реквизит содержит пустую ссылку или пустую строку, функция вернёт их как есть — для таких случаев нужен ВЫБОР с явным сравнением.
Чем проверять пустое значение
Только для NULL после соединений и обращений через точку; не работает с пустыми ссылками
Для ссылочных реквизитов; при составном типе нужно перечислять все типы
Заменяет NULL на значение по умолчанию; не проверяет пустые ссылки и строки
Универсальный вариант для сложных условий и нескольких видов пустоты одновременно
Проверка заполненности в коде и в запросе: где граница
Не всю проверку нужно тащить в запрос. Если результат запроса всё равно обходится в коде, часть логики проще реализовать там: метод ЗначениеЗаполнено() встроенного языка корректно определяет пустые ссылки, пустые строки, нулевые даты и NULL одним вызовом.
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
Если Не ЗначениеЗаполнено(Выборка.Склад) Тогда
Продолжить;
КонецЕсли;
КонецЦикла;
Правило простое: фильтрацию, которая уменьшает объём выборки, выгоднее делать в запросе — это снижает нагрузку на сервер и сеть. А проверки для принятия решения по отдельной строке можно оставить в коде, где они читаются проще и не требуют знания типа реквизита.
При работе с параметрами запроса учитывайте: если параметр не установлен, при выполнении возникнет ошибка. Пустая ссылка как параметр передаётся явно, например через Запрос.УстановитьПараметр("Склад", Справочники.Склады.ПустаяСсылка()), и в тексте запроса сравнивается обычным равенством.
- 1Определите тип проверяемого поля: ссылка, строка, дата, число или результат соединения
- 2Для NULL (соединения, обращения через точку) используйте ЕСТЬ NULL или НЕ ЕСТЬ NULL
- 3Для ссылочного реквизита сравните со ЗНАЧЕНИЕ(Тип.ПустаяСсылка)
- 4Для строки, даты, числа сравните с "", ДАТАВРЕМЯ(1,1,1) или 0
- 5Если нужно вывести замену вместо пустоты — оберните поле в ЕСТЬNULL() или ВЫБОР
- 6Выполните запрос в консоли на копии базы и проверьте, что отобрались именно ожидаемые строки
Типичные ошибки и как их проверить
Самая распространённая ошибка — сравнение с NULL через равенство, о ней уже сказано выше. Вторая по частоте — проверка ссылочного реквизита составного типа на одну пустую ссылку: строки с пустыми ссылками других типов останутся в выборке. Третья — использование ЕСТЬNULL там, где значение на самом деле пустая ссылка, а не NULL.
Ещё одна ловушка — соединение с виртуальными таблицами. При левом соединении с таблицей остатков NULL появляется для всей номенклатуры без остатков, и если забыть обернуть количество в ЕСТЬNULL, итоги по группировкам могут посчитаться неверно или не посчитаться вовсе.
Проверять поведение запроса удобно в консоли запросов на копии рабочей базы: подставьте реальные данные, где точно есть и пустые, и заполненные значения, и убедитесь, что условие отбирает обе категории так, как задумано.
Как проверить результат
Возвращает строки, где в присоединённой таблице нет соответствий
Пустой результат при заведомо существующих несопоставленных строках — возможно, сравнение через «=»
Находятся все документы с незаполненным реквизитом
Часть документов не отобрана — реквизит составного типа, проверены не все типы
Вместо пустых ячеек выводится значение по умолчанию, суммы считаются
В итогах остаются пустые значения — поле не обёрнуто в функцию
FAQ
Чем NULL отличается от пустой ссылки в запросе 1С?
NULL означает отсутствие данных и появляется при соединениях таблиц или обращении к реквизиту через точку, когда исходного значения нет. Пустая ссылка — конкретное хранимое значение ссылочного типа. NULL проверяется оператором ЕСТЬ NULL, пустая ссылка — сравнением со ЗНАЧЕНИЕ(Тип.ПустаяСсылка). Взаимозаменяемыми эти проверки не являются.
Можно ли проверить заполненность реквизита составного типа одним условием?
Единой конструкции для всех типов сразу нет. Обычно перечисляют пустые ссылки всех возможных типов через ИЛИ. Альтернатива — выразить реквизит строкой или проверять в коде после выборки через ЗначениеЗаполнено(), что проще, но не фильтрует данные на уровне запроса.
Почему условие «Поле = NULL» не возвращает ни одной строки?
Потому что любая операция сравнения с NULL даёт неопределённый результат, а не Истину или Ложь. Строки с неопределённым результатом условия в выборку не попадают. Для проверки на NULL существуют только операторы ЕСТЬ NULL и НЕ ЕСТЬ NULL.
Как вывести в отчёте 0 вместо пустого значения суммы?
Оберните поле в функцию ЕСТЬNULL: ЕСТЬNULL(Остатки.Сумма, 0). Это сработает, если пустота возникает из-за левого соединения. Если же в поле хранится просто незаполненное значение другого вида, используйте конструкцию ВЫБОР с явной проверкой.
Как проверить, что строковый реквизит заполнен, без учёта пробелов?
В языке запросов нет функции сокращения пробелов, поэтому сравнение с "" не отловит строку из пробелов. Надёжное решение — очищать значение при записи объекта методом СокрЛП() либо выполнять проверку в коде после выполнения запроса через ЗначениеЗаполнено().
Работает ли ЗначениеЗаполнено() внутри текста запроса?
Нет, это метод встроенного языка, а не языка запросов. В тексте запроса используются ЕСТЬ NULL, сравнения с пустыми значениями и ЕСТЬNULL. ЗначениеЗаполнено() применяется к результатам выборки уже в коде модуля.
Что важно запомнить
NULL проверяется только через ЕСТЬ NULL, пустая ссылка — через ЗНАЧЕНИЕ(...ПустаяСсылка), строка и дата — сравнением с "" и ДАТАВРЕМЯ(1,1,1). Для замены NULL на значение по умолчанию используйте ЕСТЬNULL, для сложных условий — ВЫБОР. Перед применением в рабочем коде проверяйте запрос на копии базы с реальными данными.