К статье
Практический материал

Разработка и Конфигурация · 11 мин

Пустое значение в запросе 1С: проверка и обработка

Как проверить пустое значение в запросе 1С: ЗНАЧЕНИЕ, ЕСТЬ NULL, пустые ссылки, даты и строки. Примеры кода, типичные ошибки и способы обработки.

Пустое значение в запросе 1С — одна из самых частых причин «неожиданных» результатов выборки: строки пропадают из отчёта, отбор не срабатывает, а соединение таблиц возвращает меньше записей, чем ожидалось. Причина почти всегда в том, что «пустота» в языке запросов имеет несколько разных форм: NULL, пустая ссылка, пустая строка, пустая дата и неопределённое значение — и каждая проверяется по-своему.

Ошибка «сравнил с пустой строкой, а там NULL» встречается даже у опытных разработчиков, потому что NULL в запросах 1С не равен ничему, даже самому себе. Поэтому сравнение Поле = NULL всегда даёт ложь, и условие молча отбрасывает записи. Понимание различий между видами пустых значений и правильные конструкции проверки избавляют от большинства таких проблем.

Ниже разобраны все виды пустых значений в языке запросов 1С, способы их проверки, типовые сценарии с кодом, ограничения и ошибки, которые чаще всего допускают при работе с отборами и соединениями.

Какие виды пустых значений существуют в языке запросов 1С

Прежде чем писать условие, нужно понять, с каким именно «пустым» значением вы имеете дело. В языке запросов 1С их пять основных видов, и они не взаимозаменяемы.

  • NULL — отсутствие значения. Возникает при левом соединении, когда в присоединяемой таблице нет подходящей записи, а также в незаполненных полях составного типа в некоторых ситуациях.
  • Пустая ссылка — ссылка существует как значение, но не указывает ни на один объект: ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка).
  • Пустая строка — строка нулевой длины "". Для строк неограниченной длины в запросе сравнение с пустой строкой имеет ограничения.
  • Пустая дата — начало отсчёта ДАТАВРЕМЯ(1,1,1), то есть 1 января года 1.
  • Неопределено — значение по умолчанию для составных полей; в запросе передаётся параметром НЕОПРЕДЕЛЕНО.

Ключевое практическое следствие: одно и то же визуально «пустое» поле в карточке объекта может хранить пустую ссылку, пустую строку или NULL в зависимости от типа реквизита. Поэтому сначала определите тип поля в конфигураторе, а потом выбирайте способ проверки.

Проверка на NULL: операторы ЕСТЬ NULL и ЕСТЬ НЕ NULL

Проверка на NULL чаще всего нужна после левого соединения. Когда для записи основной таблицы не нашлось пары в присоединяемой, все поля второй таблицы получают значение NULL. Сравнивать такие поля через равенство бессмысленно — условие никогда не выполнится.

ВЫБРАТЬ

Товары.Ссылка КАК Номенклатура,

Остатки.КоличествоОстаток КАК Остаток

ИЗ

Справочник.Номенклатура КАК Товары

ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки КАК Остатки

ПО Товары.Ссылка = Остатки.Номенклатура

ГДЕ

Остатки.КоличествоОстаток ЕСТЬ NULL

Этот запрос вернёт всю номенклатуру, по которой нет остатков ни на одном складе. Обратная проверка — ЕСТЬ НЕ NULL — отберёт только позиции с остатками. Допустим и вариант с отрицанием: НЕ (Поле ЕСТЬ NULL), он эквивалентен.

Важный нюанс: NULL может «приехать» не только из соединения, но и из параметра запроса, если вы передали его из кода без инициализации. Поэтому параметры, участвующие в сравнениях, стоит явно инициализировать перед выполнением запроса.

Проверка пустой ссылки через ЗНАЧЕНИЕ()

Реквизиты ссылочного типа, которые пользователь не заполнил, хранят пустую ссылку соответствующего типа. Для проверки используется функция ЗНАЧЕНИЕ() с указанием пустой ссылки конкретного объекта метаданных.

ВЫБРАТЬ

Реализация.Ссылка,

Реализация.Контрагент

ИЗ

Документ.РеализацияТоваровУслуг КАК Реализация

ГДЕ

Реализация.Договор = ЗНАЧЕНИЕ(Справочник.ДоговорыКонтрагентов.ПустаяСсылка)

Здесь важно указать именно тот тип, который имеет реквизит. Если реквизит составного типа (например, договор может быть ссылкой на разные справочники), проверку строят через ИЛИ для каждого типа либо через параметр.

Альтернатива — передать пустую ссылку параметром из кода: Запрос.УстановитьПараметр("ПустойДоговор", Справочники.ДоговорыКонтрагентов.ПустаяСсылка()). Это удобно, когда тип реквизита может меняться или запрос строится динамически.

bsl
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ Т.Ссылка ИЗ Документ.Заказ КАК Т ГДЕ Т.Склад = &ПустойСклад";
Запрос.УстановитьПараметр("ПустойСклад", Справочники.Склады.ПустаяСсылка());
Результат = Запрос.Выполнить();

Пустая строка, пустая дата и число ноль

Примитивные типы проверяются прямым сравнением, но у каждого есть свои тонкости.

Пустая строка

Для строк фиксированной длины достаточно сравнения: ГДЕ Контрагент.ИНН = "". Для строк неограниченной длины прямое сравнение в запросе недоступно — потребуется функция ПОДСТРОКА или проверка через ВЫРАЗИТЬ(... КАК СТРОКА(1)), что усложняет запрос и замедляет его. Практичный приём — привести поле к строке ограниченной длины и сравнить с пустой строкой.

Пустая дата

Незаполненная дата хранится как ДАТАВРЕМЯ(1,1,1). Условие выглядит так:

ГДЕ Документ.ДатаОплаты = ДАТАВРЕМЯ(1,1,1)

Не сравнивайте дату с пустой строкой или нулём — запрос либо вернёт пустой результат, либо завершится ошибкой несоответствия типов в зависимости от контекста.

Число ноль

Для чисел «пустым» значением фактически является 0: ГДЕ Строка.Количество = 0. Отдельного «пустого числа» в платформе нет, поэтому логику «не заполнено» для числовых реквизитов при необходимости реализуют через дополнительный признак.

Замена пустых значений: ЕСТЬNULL и ВЫБОР

Часто пустое значение нужно не отфильтровать, а заменить на осмысленное — например, показать 0 вместо NULL в отчёте по остаткам. Для этого служит функция ЕСТЬNULL.

ВЫБРАТЬ

Товары.Ссылка КАК Номенклатура,

ЕСТЬNULL(Остатки.КоличествоОстаток, 0) КАК Остаток

ИЗ

Справочник.Номенклатура КАК Товары

ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки КАК Остатки

ПО Товары.Ссылка = Остатки.Номенклатура

ЕСТЬNULL принимает два аргумента: проверяемое выражение и значение, которое подставится вместо NULL. Типы обоих аргументов должны быть совместимы — нельзя заменить числовой NULL строкой.

Для более сложной логики подходит конструкция ВЫБОР, позволяющая обработать сразу несколько видов пустоты:

ВЫБОР

КОГДА Остатки.КоличествоОстаток ЕСТЬ NULL

ТОГДА 0

КОГДА Товары.СтавкаНДС = ЗНАЧЕНИЕ(Перечисление.СтавкиНДС.ПустаяСсылка)

ТОГДА -1

ИНАЧЕ Остатки.КоличествоОстаток

КОНЕЦ КАК Остаток

Способы обработки пустых значений

ЕСТЬNULL

Быстро и коротко, но только для NULL и одного значения замены

ВЫБОР ... КОГДА

Гибко: обрабатывает NULL, пустые ссылки, строки и даты в одной конструкции, но запрос длиннее

Отбор в ГДЕ

Когда пустые значения нужно исключить из выборки, а не заменить

Пошаговый порядок диагностики проблемы с пустыми значениями

Если запрос возвращает не те строки, и вы подозреваете проблему с пустыми значениями, действуйте последовательно — это быстрее, чем перебирать варианты наугад.

Порядок действий
  1. 1
    Откройте конфигуратор и определите точный тип реквизита, который участвует в условии
  2. 2
    Выполните запрос без проблемного условия и посмотрите фактические значения поля — NULL, пустая ссылка или пустая строка
  3. 3
    Для NULL добавьте проверку ЕСТЬ NULL, для ссылки — сравнение с ЗНАЧЕНИЕ(...ПустаяСсылка), для строки — с "", для даты — с ДАТАВРЕМЯ(1,1,1)
  4. 4
    Проверьте, не появляется ли NULL из-за левого соединения — при необходимости оберните поле в ЕСТЬNULL
  5. 5
    Выполните запрос в консоли запросов на копии базы и сверьте количество строк с ожидаемым

Работайте с отладкой на копии базы или в тестовом контуре. Сам запрос данных не меняет, но если результат используется дальше в коде для записи или проведения документов, ошибка в условии может привести к некорректным изменениям данных.

Контрольные точки

Как проверить результат

Количество строк в выборке
Норма

Совпадает с числом объектов, видимых в списке с тем же отбором вручную

Тревожный признак

Строк меньше — вероятно, условие отсекает NULL или пустые ссылки

Поля из присоединённой таблицы
Норма

Вместо отсутствующих данных подставлено значение ЕСТЬNULL

Тревожный признак

В полях NULL, а дальше по коду идёт сравнение или арифметика

Отбор по ссылочному реквизиту
Норма

Находятся документы с явно незаполненным реквизитом

Тревожный признак

Пустой результат — тип пустой ссылки в ЗНАЧЕНИЕ() не совпадает с типом реквизита

Типичные ошибки и ограничения

Типичные ошибки
01
Сравнение с NULL через равенство: Поле = NULL всегда ложно, записи теряются без сообщения об ошибке
02
Проверка пустой ссылки одного типа для реквизита другого типа — условие не сработает, хотя синтаксически запрос корректен
03
Сравнение строки неограниченной длины с пустой строкой напрямую — ошибка выполнения запроса
04
Забытый ЕСТЬNULL в арифметике: NULL + число даёт NULL, и итог по группировке оказывается пустым
05
Отбор по пустой дате через сравнение со строкой или числом вместо ДАТАВРЕМЯ(1,1,1)

Ещё одно ограничение касается параметров виртуальных таблиц. Если вы передаёте пустую ссылку или пустой список в параметр отбора виртуальной таблицы (например, остатков), поведение может отличаться от ожидаемого: пустой отбор иногда означает «без отбора», а иногда — «ничего не найдено». Проверяйте результат на тестовых данных.

При работе с СКД учитывайте, что проверки на пустые значения в выражениях полей и в отборах имеют свои особенности синтаксиса. То, что работает в тексте запроса, не всегда одинаково ведёт себя в выражении компоновки — тестируйте отчёт целиком, а не только запрос в консоли.

FAQ

Итог

Что важно запомнить

Пустое значение в запросе 1С бывает нескольких видов, и для каждого своя проверка: NULL — через ЕСТЬ NULL, пустая ссылка — через ЗНАЧЕНИЕ(...ПустаяСсылка), строка — через "", дата — через ДАТАВРЕМЯ(1,1,1). Для замены NULL в выборке используйте ЕСТЬNULL или ВЫБОР. Никогда не сравнивайте поле с NULL через равенство.

Чем NULL отличается от пустой ссылки в запросе 1С?

NULL означает отсутствие значения и появляется, например, при левом соединении без найденной пары. Пустая ссылка — это вполне определённое значение: реквизит заполнен, но ссылается «ни на что». NULL проверяется оператором ЕСТЬ NULL, пустая ссылка — сравнением с ЗНАЧЕНИЕ(Тип.ПустаяСсылка). Взаимозаменять эти проверки нельзя.

Почему условие «Поле = NULL» не находит записи?

По правилам логики NULL не равен ничему, включая другой NULL. Поэтому сравнение через равенство всегда даёт ложь, и все строки отбрасываются. Правильная проверка — Поле ЕСТЬ NULL или Поле ЕСТЬ НЕ NULL.

Как проверить, что строковый реквизит не заполнен?

Для строки фиксированной длины используйте условие Поле = "". Для строки неограниченной длины прямое сравнение недоступно — приведите поле через ВЫРАЗИТЬ к строке ограниченной длины и сравните с пустой строкой, либо проверяйте первый символ через ПОДСТРОКА.

Как вывести ноль вместо NULL в отчёте по остаткам?

Оберните поле остатка в функцию ЕСТЬNULL: ЕСТЬNULL(Остатки.КоличествоОстаток, 0). Тогда для номенклатуры без движений вместо NULL выведется 0. Учтите, что тип значения замены должен совпадать с типом поля.

Как проверить пустую дату в запросе?

Незаполненная дата равна началу отсчёта: ДАТАВРЕМЯ(1,1,1). Условие записывается как ГДЕ Документ.ДатаОплаты = ДАТАВРЕМЯ(1,1,1). Сравнение с пустой строкой или нулём для дат не работает.

Что делать, если реквизит составного типа и нужно найти незаполненные?

Проверьте значение НЕОПРЕДЕЛЕНО через параметр запроса (передайте Неопределено из кода) либо постройте комбинированное условие: поле равно пустой ссылке каждого возможного типа, объединённое через ИЛИ. Предварительно уточните в конфигураторе, какие типы входят в составной тип реквизита.