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

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

Как в запросе 1С проверить поле на пустую дату

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

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

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

Ниже разобраны рабочие варианты проверки, их отличия, поведение в разных СУБД и типичные ошибки, которые приводят к неверным выборкам.

Что такое пустая дата в 1С и почему ЕСТЬ NULL не работает

В платформе 1С у каждого примитивного типа есть значение по умолчанию. Для типа «Дата» это начало отсчёта — 01.01.0001 00:00:00. Когда реквизит документа или справочника с типом «Дата» не заполнен, в базе физически хранится именно это значение, а не NULL.

Конструкция ЕСТЬ NULL в языке запросов проверяет именно NULL-значение, которое возникает в других ситуациях: при левом соединении без совпадения, в необязательных полях виртуальных таблиц, при обращении к реквизиту через точку от NULL-ссылки. Обычный незаполненный реквизит типа «Дата» такой проверкой не поймать — условие просто никогда не сработает.

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

Базовая проверка через ДАТАВРЕМЯ(1,1,1)

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

ВЫБРАТЬ

РеализацияТоваров.Ссылка,

РеализацияТоваров.ДатаОтгрузки

ИЗ

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

ГДЕ

РеализацияТоваров.ДатаОтгрузки = ДАТАВРЕМЯ(1, 1, 1)

Такой запрос вернёт все документы, где реквизит «ДатаОтгрузки» не заполнен. Обратная проверка — «дата заполнена» — записывается через неравенство:

ГДЕ

РеализацияТоваров.ДатаОтгрузки <> ДАТАВРЕМЯ(1, 1, 1)

Важно не перепутать направление условия. Если в отчёте нужно показать только документы с проставленной датой отгрузки, используйте <>. Если нужно найти «проблемные» документы без даты для дозаполнения — используйте =.

bsl
ГДЕ Поле.Дата = ДАТАВРЕМЯ(1,1,1)   // дата пустая
ГДЕ Поле.Дата <> ДАТАВРЕМЯ(1,1,1)  // дата заполнена

Проверка через параметр запроса

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

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| Док.Ссылка

|ИЗ

| Документ.ЗаказКлиента КАК Док

|ГДЕ

| Док.ДатаОтгрузки = &ПустаяДата";

Запрос.УстановитьПараметр("ПустаяДата", Дата(1, 1, 1));

Функция Дата(1,1,1) во встроенном языке возвращает то же значение пустой даты, что и литерал ДАТАВРЕМЯ(1,1,1) в запросе. Можно также передать переменную типа «Дата», которой не присваивали значение, — она по умолчанию равна пустой дате.

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

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

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

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

Надёжный шаблон для таких случаев:

ГДЕ

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

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

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

Если реквизит имеет составной тип (например, «Дата или Строка» или «Дата или СправочникСсылка»), то незаполненным он считается, когда значение вообще не установлено. На уровне запроса такое поле чаще всего содержит NULL либо значение одного из допустимых типов.

Для составного поля корректная проверка «дата не задана» выглядит так:

ГДЕ

ЕСТЬNULL(Док.СрокИсполнения, ДАТАВРЕМЯ(1,1,1)) = ДАТАВРЕМЯ(1,1,1)

ИЛИ НЕ Док.СрокИсполнения ССЫЛКА Справочник.Контрагенты

Точное условие зависит от бизнес-смысла: иногда нужно отобрать только строки, где тип значения — именно «Дата» и она пустая. Тогда добавляют проверку типа через ВЫРАЗИТЬ или сравнение результата приведения:

ВЫБОР

КОГДА ВЫРАЗИТЬ(Док.СрокИсполнения КАК ДАТА) = ДАТАВРЕМЯ(1,1,1)

ТОГДА "Дата не задана"

ИНАЧЕ "Дата задана"

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

Учтите, что ВЫРАЗИТЬ для значения другого типа вернёт пустую дату, поэтому такая проверка «схлопнет» в один результат и строковые, и ссылочные значения. Если нужно отличать их, добавьте явную проверку типа.

Сравнение вариантов проверки

Поле = ДАТАВРЕМЯ(1,1,1)

Подходит для обычных реквизитов таблиц с типом «Дата». Не ловит NULL после соединений.

ЕСТЬNULL(Поле, ДАТАВРЕМЯ(1,1,1)) = ДАТАВРЕМЯ(1,1,1)

Универсальный вариант для соединений и виртуальных таблиц. Чуть тяжелее по производительности на больших выборках.

Поле ЕСТЬ NULL

Только для NULL из соединений и необязательных полей. Для обычного незаполненного реквизита не работает.

Параметр &ПустаяДата

Когда условие формируется из кода или переиспользуется. Требует установки параметра перед выполнением.

Проверка результата и типичные ошибки

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

Частые ошибки, которые встречаются на практике:

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

Ещё одна тонкость — сравнение дат с временем. Если реквизит хранит дату со временем, а вы сравниваете с границей без времени, документы за граничный день могут не попасть в выборку. Для проверки на пустоту это не критично, но при комбинации условий «пустая или раньше границы» задавайте границу с концом дня: ДАТАВРЕМЯ(2026,12,31,23,59,59).

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

Альтернативы: проверка в коде и в СКД

Не всегда проверку нужно выполнять именно в запросе. Если вы обходите выборку в коде, пустая дата проверяется встроенной функцией:

Если Не ЗначениеЗаполнено(Строка.ДатаОтгрузки) Тогда

// дата не заполнена

КонецЕсли;

Функция ЗначениеЗаполнено() универсальна: для даты она возвращает «ложь» при значении 01.01.0001, для ссылок — при пустой ссылке, для строк — при пустой строке. Прямое сравнение Строка.ДатаОтгрузки = Дата(1,1,1) даёт тот же результат, но работает только для типа «Дата».

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

Порядок действий при написании проверки
  1. 1
    Определите, где находится поле: обычный реквизит таблицы, виртуальная таблица или результат соединения.
  2. 2
    Для обычного реквизита напишите условие Поле = ДАТАВРЕМЯ(1,1,1) или Поле <> ДАТАВРЕМЯ(1,1,1).
  3. 3
    Для поля из соединения оберните его в ЕСТЬNULL(Поле, ДАТАВРЕМЯ(1,1,1)).
  4. 4
    Для составного типа добавьте проверку типа значения, если нужно отличать дату от строки или ссылки.
  5. 5
    Выполните запрос в консоли и сверьте результат с документами, где дата визуально пустая.

FAQ

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

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

Чем ДАТАВРЕМЯ(1,1,1) отличается от Дата(1,1,1)?

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

Как проверить, что дата заполнена, а не пустая?

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

Почему после левого соединения проверка на пустую дату «теряет» строки?

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

Можно ли проверить пустую дату в отборе динамического списка?

Да. В настройках отбора динамического списка выберите поле даты, вид сравнения «Равно» и укажите значение 01.01.0001, либо оставьте значение даты незаполненным — для типа «Дата» это эквивалентно пустой дате.

Работает ли проверка одинаково на разных СУБД?

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

Итог

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

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