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