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