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

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

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

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

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

В языке 1С пустая дата — это не отсутствие значения и не NULL, а вполне конкретная величина: '00010101000000', то есть 1 января 0001 года 0 часов 0 минут 0 секунд. Именно с этим значением и ведётся сравнение в большинстве случаев.

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

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

Тип «Дата» в 1С всегда содержит какое-либо значение: он не может быть равен Неопределено или NULL сам по себе. Когда реквизит типа «Дата» не заполнен, платформа хранит в нём начало отсчёта — '00010101000000'. Это значение и считается «пустой датой».

Важный нюанс: дата в 1С всегда содержит и время. Если пользователь ввёл только день, месяц и год, время будет равно 00:00:00. Поэтому сравнение Дата = '00010101' корректно, но при работе с датами, полученными из разных источников, стоит помнить о составляющей времени.

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

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

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

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

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

Иначе

Сообщить("Не указана дата окончания");

КонецЕсли;

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

Единственное ограничение — функция недоступна в некоторых контекстах, например в выражениях языка запросов и в формулах СКД. Там применяются другие приёмы, описанные ниже.

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

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

Если Объект.ДатаРождения = '00010101' Тогда

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

КонецЕсли;

// эквивалентная запись через конструктор

Если Объект.ДатаРождения = Дата(1, 1, 1) Тогда

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

КонецЕсли;

Обе записи эквивалентны: Дата(1, 1, 1) создаёт ту же самую дату 01.01.0001 0:00:00. Какой вариант выбрать — вопрос стиля команды; в типовых конфигурациях чаще встречается литерал '00010101'.

Для проверки на заполненность используется обратное условие: Если Дата <> '00010101' Тогда. Будьте внимательны с оператором: распространённая опечатка — написать = вместо <>, и логика модуля переворачивается.

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

В языке запросов функции ЗначениеЗаполнено() нет, поэтому пустую дату сравнивают напрямую с конструктором ДАТАВРЕМЯ(1, 1, 1) или передают пустую дату параметром.

ВЫБРАТЬ

Сотрудники.Ссылка,

Сотрудники.ДатаУвольнения

ИЗ

Справочник.Сотрудники КАК Сотрудники

ГДЕ

Сотрудники.ДатаУвольнения = ДАТАВРЕМЯ(1, 1, 1)

Такой запрос выберет всех сотрудников, у которых дата увольнения не заполнена. Обратное условие — <> ДАТАВРЕМЯ(1, 1, 1) — отберёт только заполненные даты.

Второй вариант — передать пустую дату параметром. Это удобно, когда значение формируется в коде и может меняться:

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

// в тексте запроса: ГДЕ ДатаУвольнения = &ПустаяДата

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

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

Проверка даты на форме и перед записью

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

&НаКлиенте

Процедура ПередЗаписью(Отказ, ПараметрыЗаписи)

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

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

ПоказатьПредупреждение(, "Укажите дату поставки");

КонецЕсли;

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

Для полей ввода на форме есть и декларативный вариант без кода: свойство «АвтоотметкаНезаполненного» и проверка заполнения в свойствах реквизита («Выдавать ошибку» / «Выдавать предупреждение»). Платформа сама подчеркнёт незаполненное поле и не даст записать объект, если настроена проверка с ошибкой.

Учтите, что стандартная проверка заполнения срабатывает только при интерактивной записи. Если объект записывается программно из обработки или обмена, проверку нужно выполнять явно в коде — иначе пустая дата попадёт в базу.

Проверка даты в СКД и отчётах

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

В вычисляемых полях и ресурсах СКД используется выражение на языке выражений компоновки. Там тоже работает сравнение с пустой датой:

Выбор

Когда ДатаОплаты = ДатаВремя(1, 1, 1)

Тогда "Не оплачено"

Иначе "Оплачено"

Конец

Если поле приходит из левого соединения и может быть NULL, оберните его в ЕстьNull(ДатаОплаты, ДатаВремя(1,1,1)) прямо в выражении — тогда отбор и вывод будут работать предсказуемо.

Какой способ выбрать

Выбор зависит от контекста исполнения кода и от типа проверяемого значения. Сводная логика выбора приведена ниже.

КонтекстРекомендуемый способОсобенности
Модуль объекта, общий модульЗначениеЗаполнено()Универсально, работает с составными типами
Модуль объекта, сравнение в условииДата = '00010101'Короткая запись, привычна в типовых
Запрос= ДАТАВРЕМЯ(1,1,1) или параметрЗначениеЗаполнено недоступна; помнить про NULL
Форма, клиентЗначениеЗаполнено()Допустимы оба способа
СКД, отборы и выраженияСравнение с ДатаВремя(1,1,1)Для соединений — ЕстьNull
Составной реквизитЗначениеЗаполнено()Ловит и Неопределено, и пустую дату
Маршрут решения

Как выбрать действие

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

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

Убедиться, что проверка работает, проще всего через отладчик: поставьте точку останова на условии и посмотрите фактическое значение переменной. Пустая дата отображается как 01.01.0001 0:00:00 — если вы видите именно её, значит реквизит не заполнен.

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

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

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

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

Значение переменной в отладчике
Норма

Пустая дата отображается как 01.01.0001 0:00:00, условие срабатывает ожидаемо

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

Значение Неопределено или NULL — проверка сравнением с датой не сработает

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

Возвращаются только записи с незаполненной датой

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

Записей меньше, чем ожидалось — вероятно, часть полей имеет NULL

Поведение формы при записи
Норма

При пустой дате выводится сообщение и запись блокируется

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

Объект записывается с пустой датой — проверка не подключена или стоит не в том обработчике

Итог

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

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

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

Чем отличается пустая дата от Неопределено?

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

Почему ЗначениеЗаполнено() не работает в запросе?

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

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

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

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

Да, если речь о дате в реквизите объекта: в свойствах реквизита в конфигураторе установите «Проверка заполнения» в значение «Выдавать ошибку». Платформа сама не даст записать объект интерактивно. Но программная запись из обработок и обменов эту проверку обходит, если не вызывать ПроверитьЗаполнение() явно.

Что вернёт сравнение пустой даты с пустой строкой?

Сравнение значений разных типов в 1С не вызывает ошибку, но результат определяется правилами упорядочивания типов и не означает «пусто». Такая проверка — ошибка: для даты всегда сравнивайте с датой ('00010101') или используйте ЗначениеЗаполнено().

Как вывести в отчёте признак «дата не заполнена»?

В СКД добавьте вычисляемое поле с выражением вида: Выбор Когда Дата = ДатаВремя(1,1,1) Тогда "Не указана" Иначе "" Конец. Если поле может быть NULL, предварительно оберните его в ЕстьNull(). В обычном отчёте на запросе тот же признак формируется конструкцией ВЫБОР в тексте запроса.