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

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

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

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

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

Главная особенность типа «Дата» в 1С: он не может быть «пустым» в привычном смысле. Если реквизит даты не заполнен, его значение равно началу календаря — 1 января 1 года (01.01.0001 00:00:00). Именно с этим значением и идёт сравнение при любой проверке. Понимание этого факта избавляет от большинства ошибок, которые допускают начинающие разработчики.

Ниже разобраны рабочие способы проверки: через функцию ЗначениеЗаполнено(), прямое сравнение с пустой датой, проверку в запросах и на управляемой форме, а также типичные ошибки и граничные случаи с составными типами.

Что означает «пустая дата» в 1С

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

Из этого правила есть важное следствие: проверка вида «Дата = Неопределено» или «Дата = NULL» для реквизита типа «Дата» никогда не сработает. Такие проверки уместны только для переменных, которым значение не присваивалось, или для полей запроса, где NULL появляется в результате левого соединения таблиц.

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

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

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

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

// Дата заполнена — выполняем расчёт срока

Иначе

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

КонецЕсли;

Преимущество этого подхода — читаемость и универсальность. Код легко адаптируется, если тип реквизита изменится, а сама проверка одинаково работает для реквизитов объектов, переменных и параметров процедур.

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

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

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

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

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

КонецЕсли;

// Эквивалентный вариант

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

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

КонецЕсли;

При сравнении учитывайте состав даты. Тип «Дата» может включать время: если реквизит заполнен как 01.01.0001 00:00:00, сравнение сработает, но если в значении вдруг присутствует время (что для «пустой» даты практически невозможно, но встречается при программном заполнении), лучше использовать ЗначениеЗаполнено(), которая учитывает и дату, и время.

Прямое сравнение удобно, когда нужно одновременно проверить несколько условий или когда код пишется в стиле, принятом в конкретной конфигурации. Функционально оба варианта равнозначны для стандартного реквизита типа «Дата».

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

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

ВЫБРАТЬ

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

Реализация.ДатаОплаты

ИЗ

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

ГДЕ

Реализация.ДатаОплаты = ДАТАВРЕМЯ(1, 1, 1)

Альтернатива — передать пустую дату параметром: Запрос.УстановитьПараметр("ПустаяДата", '00010101') и в условии написать ДатаОплаты = &ПустаяДата. Оба варианта дают одинаковый результат; параметризованный удобнее, если значение используется в запросе несколько раз.

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

bsl
ВЫБРАТЬ
	Заказ.Ссылка,
	ЕСТЬNULL(Оплата.ДатаОплаты, ДАТАВРЕМЯ(1,1,1)) КАК ДатаОплаты
ИЗ
	Документ.ЗаказКлиента КАК Заказ
		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.Оплаты КАК Оплата
		ПО Заказ.Ссылка = Оплата.Заказ
ГДЕ
	ЕСТЬNULL(Оплата.ДатаОплаты, ДАТАВРЕМЯ(1,1,1)) = ДАТАВРЕМЯ(1,1,1)

Проверка на форме и валидация ввода пользователя

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

Если стандартной проверки недостаточно (например, дата обязательна только при определённом статусе документа), логику размещают в обработчике ОбработкаПроверкиЗаполнения модуля объекта:

Процедура ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)

Если Статус = Перечисления.Статусы.Оплачен

И Не ЗначениеЗаполнено(ДатаОплаты) Тогда

ОбщегоНазначения.СообщитьПользователю(

"Укажите дату оплаты", , "ДатаОплаты", "Объект", Отказ);

КонецЕсли;

КонецПроцедуры

На управляемой форме для интерактивной реакции используют обработчик ПриИзменении поля даты: в нём можно сразу проверить значение, вывести предупреждение или заблокировать связанные элементы. Учтите, что обработчики формы срабатывают только при интерактивном вводе — при программной записи объекта они не вызываются, поэтому контроль в модуле объекта обязателен.

Проверка в СКД, динамических списках и при обмене

В схеме компоновки данных условие на пустую дату задаётся в отборе: поле сравнивается со значением 01.01.0001, которое можно ввести как дату в параметре отбора. В вычисляемых полях СКД доступна функция ЗначениеЗаполнено() языка выражений — удобно для вывода признака «Дата указана / не указана» прямо в отчёте.

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

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

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

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

Универсально и читаемо; подходит для любых типов; не работает в тексте запроса

Сравнение с '00010101'

Просто и наглядно для типа «Дата»; требует аккуратности со временем и составными типами

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

Стандарт для запросов; не ловит NULL из левых соединений

ЕСТЬNULL + ДАТАВРЕМЯ

Единственный надёжный вариант для полей из соединений в запросах

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

Самая распространённая ошибка — проверка «Дата = Неопределено» или «Дата = NULL» во встроенном коде. Такое условие молча не срабатывает, и дефект обнаруживается только когда отчёт строится неправильно. Вторая частая ошибка — сравнение строки с датой без приведения типов, что приводит к ошибке исполнения или всегда ложному условию.

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

Типичные ошибки
01
Проверка «Дата = Неопределено» для реквизита типа «Дата» — условие никогда не выполнится, пустая дата останется незамеченной
02
Игнорирование NULL в левых соединениях запроса — строки без связанных записей выпадают из выборки
03
Валидация только на форме — при обмене и программной записи пустая дата сохраняется в базе
04
Сравнение даты со строкой без преобразования типов — ошибка исполнения или всегда ложное условие

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

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

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

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

Условие срабатывает, выводится сообщение или строка отбирается

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

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

Поведение на заполненной дате
Норма

Условие не срабатывает, логика продолжается

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

Ложное срабатывание — проверьте типы и время в значении

Запрос с левым соединением
Норма

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

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

Строки теряются — нужен ЕСТЬNULL вместо прямого сравнения

Запись через обмен или обработку
Норма

Пустая дата блокируется проверкой в модуле объекта

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

Объект записывается без даты — проверка есть только на форме

Итог

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

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

Частые вопросы о проверке дат в 1С

Чем ЗначениеЗаполнено() лучше сравнения с '00010101'?

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

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

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

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

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

Как запретить сохранение документа без даты?

Установите у реквизита свойство «Проверка заполнения» в значение «Выдавать ошибку» — платформа сама заблокирует запись. Если обязательность зависит от условий (статуса, вида операции), реализуйте проверку в обработчике ОбработкаПроверкиЗаполнения модуля объекта с установкой параметра Отказ = Истина.

Как отобрать документы с незаполненной датой в отчёте на СКД?

Добавьте в отбор отчёта условие «Поле Равно 01.01.0001», указав значение как дату. Если поле берётся из соединения таблиц, надёжнее вынести его в вычисляемое поле с ЕСТЬNULL и накладывать отбор уже на него — так отчёт корректно обработает и NULL, и пустую дату.

Что делать, если пустая дата приходит из обмена как пустая строка?

Перед присвоением проверяйте входящее значение: если строка пустая, либо пропустите заполнение реквизита (он останется 01.01.0001), либо зафиксируйте ошибку в журнале обмена. Прямое присвоение пустой строки реквизиту типа «Дата» без контроля может вызвать ошибку преобразования или неявные значения, которые потом сложно найти.