Очистка даты и обнуление реквизита типа Дата

· 7 мин

Содержание

Пустая дата в 1С — это не Неопределено и не ноль, а конкретное значение '00010101' (1 января 0001 года). Чтобы очистить реквизит типа «Дата», ему присваивают именно это значение: литералом '00010101' или функцией Дата(1, 1, 1). Через Неопределено обнуляют только реквизиты составного типа — у обычной даты это вызовет ошибку преобразования.

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

Что такое пустая дата и почему это не ноль

Тип «Дата» в 1С хранит момент времени: и календарную дату, и время с точностью до секунды. Литерал записывается в одинарных кавычках в формате 'ГГГГММДДЧЧММСС', например '20240115093000' — 15 января 2024 года, 09:30:00.

Пустое (незаполненное) значение даты — это '00010101000000', которое можно сократить до '00010101'. В форме такое поле выглядит пустым, но внутри это полноценная дата, а не отсутствие значения.

Диапазон допустимых дат — от '00010101' до '39991231235959'. Пустая дата — это нижняя граница диапазона, поэтому любая реальная дата всегда строго больше неё. Это свойство пригодится дальше, в отборах.

Отсюда три вывода, которые экономят время:

  • 🔸 Пустая дата не равна пустой строке "" и не равна числу 0. Сравнение с ними даёт ошибку типов или всегда ложь.
  • 🔸 Реквизит с единственным типом «Дата» не может хранить Неопределено. Это значение доступно только реквизитам составного типа.
  • 🔸 У даты всегда есть время. Если сравниваете «по дню», обрезайте время функцией НачалоДня().

Путаница с «пустотой» — главный источник ошибок: один и тот же реквизит в разных ситуациях называют и «нулевой датой», и «неопределённой», и «пустой строкой», хотя в 1С это три разных вещи.

Проверить, заполнена ли дата, проще всего функцией ЗначениеЗаполнено(): для '00010101' она вернёт Ложь, для любой реальной даты — Истина.

Как обнулить реквизит датой в коде модуля

Самый частый случай — сбросить дату у реквизита объекта или у переменной. Работают два равнозначных способа.

Способ 1. Литерал пустой даты. Короче и нагляднее:

Объект.ДатаОтгрузки = '00010101';

Способ 2. Функция Дата(). Удобна, когда пустую дату формируете динамически или хотите подчеркнуть смысл:

Объект.ДатаОтгрузки = Дата(1, 1, 1);

Оба варианта дают одно и то же значение. Выбор — дело стиля: литерал компактнее, функция читается однозначнее для тех, кто видит код впервые.

Если нужно получить пустое значение по типу реквизита, не зная заранее, дата это или что-то другое, пригодится приведение через Новый:

ПустоеЗначение = Новый(Тип("Дата")); // вернёт '00010101'

Для реквизита составного типа (например, «Дата» + «Число») обнуление делают через Неопределено — так поле становится по-настоящему незаполненным, без привязки к какому-либо из типов:

Объект.СрокИлиДата = Неопределено;

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

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

Для Каждого Строка Из Объект.Товары Цикл
    Строка.ДатаПоставки = Дата(1, 1, 1);
КонецЦикл;

Иногда дату нужно очищать не всегда, а по условию — например, сбрасывать плановую дату при смене статуса. Тогда обнуление ставят внутрь проверки:

Если Объект.Статус = Перечисления.СтатусыЗаказов.Отменён Тогда
    Объект.ДатаОтгрузки = Дата(1, 1, 1);
КонецЕсли;

Очистка даты в форме и интерфейсе

В пользовательском режиме дату из поля убирают так:

  1. 🖱 Навести курсор на поле — справа появится кнопка-крестик очистки. Нажать её.
  2. ⌨ Либо выделить содержимое поля и нажать Del или Backspace.

После очистки поле становится пустым, а в данных сохраняется та самая пустая дата '00010101'.

Программно на управляемой форме обнуляют реквизит объекта или реквизит самой формы — так же, как в модуле:

&НаКлиенте
Процедура ОчиститьДату(Команда)
    Объект.ДатаНачала = Дата(1, 1, 1);
КонецПроцедуры

Если дата лежит в реквизите формы, а не в объекте, обращайтесь к нему напрямую по имени:

ДатаФильтра = Дата(1, 1, 1);

Для поля составного типа кнопка очистки сбрасывает значение в Неопределено — и в коде формы такому полю тоже присваивают Неопределено.

Частый сценарий — очистить одну дату, когда пользователь меняет другое поле. Это делают в обработчике события ПриИзменении того поля, от которого зависит дата:

&НаКлиенте
Процедура ВидОперацииПриИзменении(Элемент)
    Объект.ДатаЗакрытия = Дата(1, 1, 1);
КонецПроцедуры

Чтобы при создании нового документа дата не подставлялась автоматически, снимать её вручную не нужно: достаточно не заполнять реквизит значением по умолчанию в обработчике ПриСозданииНаСервере или в заполнении по умолчанию.

Сравнение способов: что выбрать под задачу

Все перечисленные приёмы дают пустую дату, но применяются в разных местах. Сводная таблица:

СпособГде применяютРезультатНюанс
'00010101'код модуля, реквизит типа «Дата»'00010101'самый короткий, виден как есть
Дата(1, 1, 1)код модуля, та же задача'00010101'читается однозначнее, можно собрать динамически
Новый(Тип("Дата"))когда тип определяется в рантайме'00010101'универсально по типу значения
Неопределенореквизит составного типанезаполненодля чистой даты даёт ошибку типа
ДАТАВРЕМЯ(1, 1, 1)язык запросовпустая дататолько в запросе, не в коде

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

Пустая дата в запросах и отборах

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

Отобрать документы с незаполненной датой:

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

Либо через параметр — тогда значение готовит код и передаёт в запрос:

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

В тексте запроса на этот параметр ссылаются как &ПустаяДата.

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

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

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

В отборах динамических списков и компоновки данных пустую дату тоже задают значением Дата(1, 1, 1), а не оставляют поле отбора пустым: пустое поле отбора означает «условие не задано», а не «дата не заполнена».

Как пустая дата выводится в отчётах и на печать

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

Строка = Формат(Дата(1, 1, 1), "ДЛФ=D"); // вернёт пустую строку ""

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

Если вместо пустоты нужен прочерк, подставьте его явно:

Представление = ?(ЗначениеЗаполнено(Дата), Формат(Дата, "ДЛФ=D"), "—");

В системе компоновки данных поле с датой тоже форматируют через оформление поля (формат ДЛФ=D), и пустые значения не выводятся — отдельное условие в макете обычно не требуется.

Типичные ошибки и как их диагностировать

Большинство проблем с очисткой даты сводится к путанице между пустой датой, Неопределено и пустой строкой. Разберём по симптому:

Диагностика: выберите симптом

Отдельно про время: если вы очищаете не весь реквизит, а «обнуляете» время в заполненной дате, используйте НачалоДня():

ДатаБезВремени = НачалоДня(Объект.ДатаДокумента);

Это оставит календарный день и выставит время 00:00:00 — удобно для сравнения дат «по дню», когда само значение даты очищать не нужно.

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

Чем пустая дата отличается от `Неопределено`?
Пустая дата '00010101' — это значение типа «Дата». Неопределено — отдельный тип, означающий «значения нет вовсе». Реквизит с единственным типом «Дата» хранит пустую дату, а реквизит составного типа может хранить Неопределено.
Можно ли присвоить дате пустую строку, чтобы очистить её?
Нет. Присваивание "" реквизиту типа «Дата» вызовет ошибку преобразования. Используйте Дата(1, 1, 1) или '00010101'.
Как проверить, что дата не заполнена?
Надёжнее всего ЗначениеЗаполнено(Дата) — для пустой даты вернёт Ложь. Можно и прямым сравнением: Дата = Дата(1, 1, 1).
Почему в запросе не работает литерал `'00010101'`?
В языке запросов дата задаётся функцией ДАТАВРЕМЯ(год, месяц, день). Для пустой даты это ДАТАВРЕМЯ(1, 1, 1). Литералы в кавычках — это синтаксис встроенного языка, а не запросов.
Как очистить дату прямо в поле на форме без кода?
Навести курсор на поле и нажать появившийся крестик очистки либо выделить значение и нажать Del. Поле станет пустым, в данных сохранится пустая дата.