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

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

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

Как в 1С проверить реквизит с типом «Дата» на пустое значение: функция ЗначениеЗаполнено, сравнение с '00010101', проверка в запросе. Примеры кода и типичные ошибки.

В языке 1С пустая дата — это не NULL и не пустая строка, а вполне конкретное значение: 1 января 0001 года, 00:00:00. Из-за этого проверка «если дата = ""» не сработает, а сравнение с Неопределено даст ложный результат. Правильных способов проверки несколько, и выбор зависит от контекста: код модуля, запрос, СКД или условие в форме.

Ниже разобраны все рабочие варианты: функция ЗначениеЗаполнено(), прямое сравнение с литералом '00010101', проверка в тексте запроса и в выражениях СКД, а также типичные ошибки, которые приводят к тому, что пустая дата «проскакивает» в отчёты и документы.

Что такое пустая дата в 1С

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

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

Проверка через ЗначениеЗаполнено()

Самый универсальный и рекомендуемый способ — встроенная функция ЗначениеЗаполнено(). Она корректно работает не только с датами, но и с числами, строками, ссылками, поэтому её удобно использовать в общих проверках перед записью или проведением.

Если НЕ ЗначениеЗаполнено(Объект.ДатаОплаты) Тогда

Сообщить("Не указана дата оплаты!");

Отказ = Истина;

Возврат;

КонецЕсли;

Функция вернёт Ложь для даты 01.01.0001 и Истину для любой заполненной даты. Дополнительный плюс — если реквизит составного типа и содержит Неопределено или пустую ссылку, ЗначениеЗаполнено() тоже корректно отработает, то есть одна проверка закрывает несколько сценариев.

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

Прямое сравнение с пустой датой

Второй способ — сравнить значение с литералом пустой даты. В коде литерал записывается в одинарных кавычках в формате ГГГГММДД:

Если Объект.ДатаОплаты = '00010101' Тогда

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

КонецЕсли;

// эквивалентный вариант через конструктор

Если Объект.ДатаОплаты = Дата(1, 1, 1) Тогда

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

КонецЕсли;

Оба варианта идентичны по результату. Литерал '00010101' короче и работает быстрее — это самый производительный способ проверки, его часто используют внутри циклов обработки больших выборок. Конструктор Дата(1,1,1) нагляднее для тех, кто не привык к литералам.

Проверка пустой даты в запросе

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

ВЫБРАТЬ

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

Заказ.ДатаОтгрузки

ИЗ

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

ГДЕ

Заказ.ДатаОтгрузки = ДАТАВРЕМЯ(1,1,1)

Обратная задача — отобрать только заполненные даты:

ГДЕ

Заказ.ДатаОтгрузки <> ДАТАВРЕМЯ(1,1,1)

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

ГДЕ

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

Проверка в СКД, форме и других контекстах

СКД и отборы отчётов

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

Проверка в форме

В модуле формы работают те же два способа: ЗначениеЗаполнено(Объект.ДатаОплаты) или сравнение с '00010101'. Для валидации при записи удобно размещать проверку в обработчике ПередЗаписью или ОбработкаПроверкиЗаполнения — во втором случае платформа сама подсветит незаполненное поле, если добавить его в массив проверяемых реквизитов.

Выражение на языке выражений СКД и в печатных формах

При выводе пустой даты в печатную форму она часто отображается как «01.01.0001», что выглядит как дефект. Решение — форматная строка: Формат(ДатаОплаты, "ДЛФ=D; ДП=''") — параметр ДП задаёт представление пустой даты, и вместо 01.01.0001 выведется пустая строка.

Сравнение способов проверки

ЗначениеЗаполнено()

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

Дата = '00010101'

Максимально быстро, читаемо. Не подходит для составных типов с возможным Неопределено.

ДАТАВРЕМЯ(1,1,1) в запросе

Единственный вариант внутри запроса. Требует ЕСТЬNULL при соединениях.

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

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

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

Третья ошибка — проверка даты в составном реквизите только сравнением с '00010101', когда значение вообще не присвоено (Неопределено). Сравнение Неопределено = '00010101' вернёт Ложь, и пустое значение пройдёт проверку. Для составных типов всегда используйте ЗначениеЗаполнено().

Типичные ошибки
01
Сравнение с "" или Неопределено — проверка никогда не срабатывает, пустые даты проходят контроль
02
Игнорирование NULL в запросах с левым соединением — часть строк теряется из выборки
03
Сравнение с '00010101' для составного реквизита — значение Неопределено не отлавливается
04
Вывод пустой даты в печатную форму без форматной строки — на печати появляется 01.01.0001

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

Чтобы убедиться, что проверка работает, выведите значение через Сообщить(Объект.ДатаОплаты) — для пустой даты будет показано «01.01.0001 0:00:00». В отладчике значение пустой даты также видно в табло переменных.

Для запроса проверьте результат в консоли запросов: отберите заведомо пустой реквизит условием = ДАТАВРЕМЯ(1,1,1) и убедитесь, что строки находятся. Затем проверьте обратное условие с <> — сумма обеих выборок должна давать общее число записей (если нет NULL из соединений).

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

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

Вывод значения через Сообщить()
Норма

Пустая дата показывается как 01.01.0001 0:00:00

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

Выводится пустая строка или Неопределено — значит, тип реквизита составной или не дата

Запрос с условием = ДАТАВРЕМЯ(1,1,1)
Норма

Находятся все документы без даты

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

Выборка пуста, хотя пустые даты точно есть — проверьте соединения и NULL

Печатная форма
Норма

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

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

На печати видно 01.01.0001 — нужна форматная строка с параметром ДП

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

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

Значению 01.01.0001 0:00:00. Это значение по умолчанию для типа «Дата», а не NULL и не пустая строка. В коде его можно записать литералом '00010101' или конструктором Дата(1,1,1).

Почему условие «Если Дата = Неопределено» не работает?

Потому что реквизит с типом «Дата» хранит 01.01.0001, а не Неопределено. Неопределено возможно только у составного реквизита, когда тип значения вообще не присвоен. Используйте ЗначениеЗаполнено() или сравнение с '00010101'.

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

Через ЕСТЬNULL: ЕСТЬNULL(Таблица.Дата, ДАТАВРЕМЯ(1,1,1)) = ДАТАВРЕМЯ(1,1,1). Такое условие отберёт и строки с пустой датой, и строки, где соединение не нашло пару (NULL).

Что быстрее: ЗначениеЗаполнено() или сравнение с '00010101'?

Прямое сравнение с литералом '00010101' быстрее, что заметно при обработке больших объёмов в цикле. В обычной прикладной логике разницы нет, поэтому предпочтительнее универсальное ЗначениеЗаполнено().

Как не выводить 01.01.0001 в печатной форме?

Используйте функцию Формат с параметром ДП: Формат(Дата, "ДЛФ=D; ДП=''"). Вместо пустой даты будет выведено значение из параметра ДП — пустая строка, прочерк или любой другой текст.

Работает ли ЗначениеЗаполнено() с датой в составном реквизите?

Да, и это её главное преимущество. Функция вернёт Ложь и для пустой даты 01.01.0001, и для Неопределено, и для пустой ссылки, поэтому для составных типов рекомендуется именно она.

Итог

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

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