Разработка и Конфигурация · 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.01.0001, чтобы отобрать записи с незаполненной датой.
В вычисляемых полях и ресурсах СКД используется выражение на языке выражений компоновки. Там тоже работает сравнение с пустой датой:
Выбор
Когда ДатаОплаты = ДатаВремя(1, 1, 1)
Тогда "Не оплачено"
Иначе "Оплачено"
Конец
Если поле приходит из левого соединения и может быть NULL, оберните его в ЕстьNull(ДатаОплаты, ДатаВремя(1,1,1)) прямо в выражении — тогда отбор и вывод будут работать предсказуемо.
Какой способ выбрать
Выбор зависит от контекста исполнения кода и от типа проверяемого значения. Сводная логика выбора приведена ниже.
| Контекст | Рекомендуемый способ | Особенности |
|---|---|---|
| Модуль объекта, общий модуль | ЗначениеЗаполнено() | Универсально, работает с составными типами |
| Модуль объекта, сравнение в условии | Дата = '00010101' | Короткая запись, привычна в типовых |
| Запрос | = ДАТАВРЕМЯ(1,1,1) или параметр | ЗначениеЗаполнено недоступна; помнить про NULL |
| Форма, клиент | ЗначениеЗаполнено() | Допустимы оба способа |
| СКД, отборы и выражения | Сравнение с ДатаВремя(1,1,1) | Для соединений — ЕстьNull |
| Составной реквизит | ЗначениеЗаполнено() | Ловит и Неопределено, и пустую дату |
Как выбрать действие
Проверка результата и отладка
Убедиться, что проверка работает, проще всего через отладчик: поставьте точку останова на условии и посмотрите фактическое значение переменной. Пустая дата отображается как 01.01.0001 0:00:00 — если вы видите именно её, значит реквизит не заполнен.
Быстрая проверка без отладчика — вывести значение через Сообщить() или выполнить тестовый запрос в консоли запросов с условием = ДАТАВРЕМЯ(1,1,1). Если запрос вернул записи, которые вы считали заполненными, значит дата в них действительно пустая, а проблема — в логике заполнения, а не в проверке.
При подозрении на NULL в запросе временно уберите условие по дате и добавьте поле в выборку: значения NULL в результате видны сразу, и станет понятно, почему отбор «не находит» записи.
Как проверить результат
Пустая дата отображается как 01.01.0001 0:00:00, условие срабатывает ожидаемо
Значение Неопределено или NULL — проверка сравнением с датой не сработает
Возвращаются только записи с незаполненной датой
Записей меньше, чем ожидалось — вероятно, часть полей имеет 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(). В обычном отчёте на запросе тот же признак формируется конструкцией ВЫБОР в тексте запроса.