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

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

1С запрос: как проверить пустую дату через ВЫБОР и отборы

Как проверить пустую дату в запросе 1С: конструкция ВЫБОР с ДАТАВРЕМЯ(1,1,1), сравнение с NULL, типичные ошибки и готовые примеры кода для отборов.

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

Главная сложность в том, что «пустая дата» в 1С — это не NULL и не пустая строка, а конкретное значение ДАТАВРЕМЯ(1,1,1), то есть 1 января 0001 года 00:00:00. Поэтому привычные проверки вроде «равно NULL» или «равно пустой строке» не сработают и приведут к неверным результатам отбора.

Ниже разобраны рабочие способы: конструкция ВЫБОР для подстановки значения вместо пустой даты, условия в секции ГДЕ, сравнение с параметром, особенности составных типов и типичные ошибки, из-за которых запрос возвращает пустую выборку или лишние строки.

Что такое пустая дата в 1С и чем она отличается от NULL

В платформе 1С у каждого реквизита типа «Дата» всегда есть значение. Если пользователь не заполнил поле, там хранится дата 01.01.0001 0:00:00 — именно её возвращает литерал ДАТАВРЕМЯ(1,1,1). Это значение по умолчанию для типа, а не признак отсутствия данных.

NULL в запросах 1С появляется только в других ситуациях: при левом соединении, когда подходящей записи не нашлось, или при обращении к реквизиту через точку от NULL-ссылки. Если реквизит сам по себе имеет тип «Дата» и просто не заполнен, он содержит ДАТАВРЕМЯ(1,1,1), а не NULL. Проверка Реквизит ЕСТЬ NULL вернёт Ложь, и строка не попадёт в выборку — это самая частая причина «пустого» результата запроса.

Дополнительная тонкость — составной тип. Если реквизит может хранить и дату, и, например, строку, то незаполненное значение может интерпретироваться иначе. В таких случаях надёжнее приводить значение к типу через ВЫРАЗИТЬ(... КАК ДАТА) и уже потом сравнивать.

Конструкция ВЫБОР для подстановки значения вместо пустой даты

Конструкция ВЫБОР нужна, когда пустую дату требуется не отфильтровать, а заменить в результате запроса на понятное значение — например, на текущую дату, на дату документа или на строку-пояснение. Базовый шаблон выглядит так:

ВЫБРАТЬ

ВЫБОР

КОГДА Заказы.СрокОплаты = ДАТАВРЕМЯ(1, 1, 1)

ТОГДА Заказы.Дата

ИНАЧЕ Заказы.СрокОплаты

КОНЕЦ КАК ДатаОплаты

ИЗ

Документ.ЗаказПокупателя КАК Заказы

Здесь, если срок оплаты не заполнен, в поле «ДатаОплаты» подставляется дата самого документа. Обратите внимание: обе ветки — ТОГДА и ИНАЧЕ — должны возвращать значения одного типа, иначе при последующем сравнении или сортировке по этому полю возможны ошибки и неожиданный порядок строк.

Если нужно вывести текстовую пометку вместо даты, придётся выбирать: либо делать поле строковым целиком (например, через ПРЕДСТАВЛЕНИЕ), либо выносить текст в отдельное поле. Смешивать дату и строку в одном вычисляемом поле без приведения типов нельзя.

bsl
ВЫБОР
	КОГДА Поле.Дата = ДАТАВРЕМЯ(1, 1, 1)
		ТОГДА &ДатаПоУмолчанию
	ИНАЧЕ Поле.Дата
КОНЕЦ КАК ДатаРезультат

Отбор записей с пустой датой в секции ГДЕ

Когда задача — выбрать только документы или элементы справочника, где дата не заполнена, условие пишется в секции ГДЕ:

ВЫБРАТЬ

Контрагенты.Ссылка,

Контрагенты.ДатаРегистрации

ИЗ

Справочник.Контрагенты КАК Контрагенты

ГДЕ

Контрагенты.ДатаРегистрации = ДАТАВРЕМЯ(1, 1, 1)

Обратный отбор — только заполненные даты — делается оператором неравенства: ГДЕ Контрагенты.ДатаРегистрации <> ДАТАВРЕМЯ(1,1,1) либо ГДЕ Контрагенты.ДатаРегистрации > ДАТАВРЕМЯ(1,1,1). Оба варианта корректны, но сравнение «больше» иногда читается понятнее, поскольку любая реальная дата больше начальной.

Часто условие передают параметром, чтобы один и тот же запрос работал в двух режимах. Тогда используют конструкцию с проверкой параметра: ГДЕ (&ТолькоПустые = ЛОЖЬ ИЛИ Поле.Дата = ДАТАВРЕМЯ(1,1,1)). При значении параметра Ложь условие фактически отключается.

Как добавить проверку пустой даты в запрос
  1. 1
    Определите, какой реквизит проверяете, и убедитесь, что его тип — Дата (а не составной)
  2. 2
    Для подстановки значения используйте ВЫБОР КОГДА Поле = ДАТАВРЕМЯ(1,1,1) ТОГДА ... ИНАЧЕ Поле КОНЕЦ
  3. 3
    Для отбора добавьте в ГДЕ условие Поле = ДАТАВРЕМЯ(1,1,1) или обратное неравенство
  4. 4
    Выполните запрос в консоли запросов на тестовой базе и проверьте, что строки с пустой датой попали (или не попали) в результат
  5. 5
    Проверьте граничный случай: записи, где дата заполнена реальным значением, не должны задваиваться или теряться

Пустая дата в соединениях и виртуальных таблицах

При левом соединении ситуация меняется: если в правой таблице не нашлось пары, все её поля, включая дату, будут равны NULL. Здесь уже корректна проверка Поле ЕСТЬ NULL, а сравнение с ДАТАВРЕМЯ(1,1,1) ничего не найдёт. Поэтому в одном запросе могут понадобиться оба типа проверок — для разных источников.

Универсальный приём для соединений — функция ЕСТЬNULL(Поле, ДАТАВРЕМЯ(1,1,1)). Она заменяет NULL на пустую дату, после чего дальнейшая логика работает единообразно:

ВЫБРАТЬ

Заказы.Ссылка,

ВЫБОР

КОГДА ЕСТЬNULL(Оплаты.ДатаОплаты, ДАТАВРЕМЯ(1, 1, 1)) = ДАТАВРЕМЯ(1, 1, 1)

ТОГДА "Не оплачен"

ИНАЧЕ "Оплачен"

КОНЕЦ КАК Статус

ИЗ

Документ.ЗаказПокупателя КАК Заказы

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

ПО Заказы.Ссылка = Оплаты.Заказ

В виртуальных таблицах регистров (Остатки, Обороты, СрезПоследних) пустая дата в параметрах имеет особый смысл: незаполненный параметр периода обычно означает «без ограничения по дате». Это не ошибка, но важно не передавать туда ДАТАВРЕМЯ(1,1,1) случайно — отбор по такой дате может вернуть данные на начало времён, чего вы не ожидали.

Сравнение способов проверки пустой даты

Разные подходы решают разные задачи, и выбирать их стоит осознанно. Ниже — сопоставление основных вариантов.

СпособКогда применятьОграничение
Поле = ДАТАВРЕМЯ(1,1,1)Реквизит типа «Дата», прямой отбор или ВЫБОРНе ловит NULL из соединений
Поле ЕСТЬ NULLПоля из левых соединений, разыменованияНе ловит незаполненную дату реквизита
ЕСТЬNULL(Поле, ДАТАВРЕМЯ(1,1,1))Универсальная обработка полей из соединенийЛишняя обёртка там, где NULL невозможен
ВЫРАЗИТЬ(Поле КАК ДАТА) + сравнениеСоставные типы реквизитовТребует аккуратности с прочими типами значения
Параметр запроса с датойПереиспользуемые запросы, отборы из кодаНужно контролировать, что передаётся в параметр

ВЫБОР или отбор в ГДЕ

ВЫБОР в списке полей

Подходит, когда нужно показать все записи, но заменить пустую дату на другое значение или текст. Не сокращает выборку.

Условие в ГДЕ

Подходит, когда нужны только записи с пустой (или только заполненной) датой. Сокращает результат, остальные строки теряются.

ЕСТЬNULL + ВЫБОР

Подходит для запросов с левыми соединениями, где пустая дата и NULL должны обрабатываться одинаково.

Типичные ошибки и как их избежать

Самая распространённая ошибка — проверять пустую дату через ЕСТЬ NULL. Запрос выполнится без ошибок, но ни одна строка не попадёт в результат, и поиск причины может занять много времени, потому что синтаксически всё корректно. Запомните правило: NULL — это про соединения, ДАТАВРЕМЯ(1,1,1) — про незаполненные реквизиты.

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

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

Типичные ошибки
01
Проверка пустой даты через ЕСТЬ NULL — запрос работает, но возвращает пустой результат
02
Сравнение даты с пустой строкой или нулём — условие всегда ложно, ошибки не возникает
03
Разные типы в ветках ТОГДА и ИНАЧЕ — сбои при сортировке, группировке и в СКД
04
Передача ДАТАВРЕМЯ(1,1,1) в параметр периода виртуальной таблицы вместо незаполненного параметра
05
Игнорирование составного типа реквизита — пустое значение не совпадает с ДАТАВРЕМЯ(1,1,1)

Проверка результата и отладка запроса

После изменения запроса проверьте его в консоли запросов на копии базы или на тестовых данных. Убедитесь, что в выборку попали именно те записи, где дата не заполнена, и что записи с реальными датами обработаны правильно. Полезно временно вывести само проверяемое поле рядом с вычисляемым, чтобы видеть исходное значение.

Если запрос используется в отчёте СКД, дополнительно проверьте отборы на форме: пользовательские отборы по вычисляемому полю с ВЫБОР могут вести себя не так, как ожидается, особенно при сравнении с датой, введённой вручную. В таких случаях надёжнее выносить признак «дата пустая» в отдельное булево поле запроса и ставить отбор по нему.

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

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

Строки с пустой датой в выборке
Норма

Присутствуют при отборе «= ДАТАВРЕМЯ(1,1,1)» и отсутствуют при обратном условии

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

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

Значение вычисляемого поля ВЫБОР
Норма

Для пустых дат подставлено значение по умолчанию, для заполненных — исходная дата

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

Везде одно и то же значение — условие КОГДА написано неверно

Тип результирующего поля
Норма

Обе ветки ВЫБОР возвращают дату

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

Смешаны дата и строка — возможны ошибки в отчётах и сортировке

Если проверка на пустую дату встречается в запросе несколько раз, удобно один раз вычислить поле-признак ВЫБОР КОГДА Поле = ДАТАВРЕМЯ(1,1,1) ТОГДА ИСТИНА ИНАЧЕ ЛОЖЬ КОНЕЦ во временную таблицу и дальше работать уже с ним — так запрос читается проще и меньше риск ошибиться в повторных условиях.
ПЗ
Практическое замечание

Частые вопросы

Чему равна пустая дата в запросе 1С?

Пустая дата равна 1 января 0001 года, 0 часов 0 минут 0 секунд. В языке запросов это значение записывается литералом ДАТАВРЕМЯ(1, 1, 1). Именно с ним нужно сравнивать реквизит типа «Дата», чтобы найти незаполненные значения.

Почему проверка «Поле ЕСТЬ NULL» не находит пустые даты?

Потому что незаполненный реквизит типа «Дата» хранит значение 01.01.0001, а не NULL. NULL появляется только при соединениях без совпадений или при разыменовании пустых ссылок. Для реквизита-даты используйте сравнение с ДАТАВРЕМЯ(1,1,1), а для полей из левых соединений — ЕСТЬ NULL или ЕСТЬNULL.

Как вывести текст вместо пустой даты в результате запроса?

Напрямую смешать дату и строку в одном поле нельзя. Либо выводите в отдельном поле признак через ВЫБОР («Не указана» / «Указана»), либо приводите дату к представлению: ВЫБОР КОГДА Поле = ДАТАВРЕМЯ(1,1,1) ТОГДА "Не указана" ИНАЧЕ ПРЕДСТАВЛЕНИЕ(Поле) КОНЕЦ — тогда всё поле становится строковым.

Как отобрать только записи с заполненной датой?

Добавьте в секцию ГДЕ условие Поле <> ДАТАВРЕМЯ(1,1,1) или Поле > ДАТАВРЕМЯ(1,1,1). Оба варианта эквивалентны для реквизита типа «Дата»: любая реально введённая дата больше 01.01.0001.

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

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

Можно ли передать пустую дату параметром запроса?

Да. В коде сформируйте значение как Дата(1,1,1) и передайте через УстановитьПараметр, затем сравнивайте поле с параметром: ГДЕ Поле = &ПустаяДата. Это удобно, когда один запрос должен работать с разными контрольными значениями без изменения текста.

Итог

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

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