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