Как установить текущую дату в календаре при открытии формы 1С

Программист 1С v8.3 (Управляемые формы)
← На главную

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

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

Причина появления даты 0001 года

Прежде чем переходить к коду, давайте выясним причину проблемы. В 1С реквизит типа Дата всегда содержит значение. Если вы создали новый документ или просто добавили реквизит формы, его значением по умолчанию будет '00010101000000'. Календарь на форме лишь визуализирует это значение. Следовательно, чтобы календарь «открылся» на сегодняшнем дне, нам нужно программно записать текущую дату в этот реквизит в момент инициализации формы.

Способ 1: Программная установка в модуле формы

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

Рассмотрим пример кода, который необходимо разместить в модуле формы:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    // Устанавливаем текущую дату для реквизита "Календарь"
    Календарь = ТекущаяДатаСеанса();
    
КонецПроцедуры

В данном примере Календарь — это имя вашего реквизита, привязанного к элементу управления на форме. Обратите внимание, что мы используем функцию ТекущаяДатаСеанса() вместо обычной ТекущаяДата(). Разберем, почему это важно.

Важное различие: ТекущаяДата vs ТекущаяДатаСеанса

Проанализируем ситуацию, когда база данных работает в клиент-серверном режиме. Сервер 1С может физически находиться в Москве, а пользователь — во Владивостоке.

  1. Функция ТекущаяДата() вернет время сервера (московское).
  2. Функция ТекущаяДатаСеанса() вернет время с учетом часового пояса, установленного в настройках пользователя (сеанса).

Для корректного отображения календаря у пользователя всегда рекомендуется использовать ТекущаяДатаСеанса(), чтобы избежать путаницы со временем и датами, особенно в конце рабочего дня.

Способ 2: Защита от перезаписи существующих данных

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

Разберем, как сделать заполнение правильным. Нам нужно проверять, заполнено ли поле уже или оно еще пустое. В 1С пустая дата проверяется сравнением с пустой константой или через типизированное значение.

Правильный вариант кода для формы документа:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    // Проверяем, является ли объект новым
    // Параметр "Ключ" пуст у новых, еще не записанных объектов
    Если Параметры.Ключ.Пустая() Тогда
        Объект.ДатаКалендаря = ТекущаяДатаСеанса();
    КонецЕсли;
    
КонецПроцедуры

Или универсальный способ проверки значения на пустоту:


Если Объект.ДатаКалендаря = '00010101' Тогда
    Объект.ДатаКалендаря = ТекущаяДатаСеанса();
КонецЕсли;

Способ 3: Инициализация на уровне метаданных

Профессиональный подход к разработке в 1С подразумевает, что логика заполнения данных должна находиться не в форме, а в модуле самого объекта (справочника или документа). Это гарантирует, что дата будет установлена правильно, даже если объект создается программно, без участия интерфейса.

Выясним, как это реализовать. Перейдите в Модуль объекта и найдите процедуру ОбработкаЗаполнения. Рассмотрим пример:


Процедура ОбработкаЗаполнения(ДанныеЗаполнения, ТекстЗаполнения, СтандартнаяОбработка)
    
    // Установка даты при создании нового объекта
    ДатаСобытия = ТекущаяДатаСеанса();
    
КонецПроцедуры

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

Визуальные настройки элемента «Поле календаря»

Иногда программисты путают установку значения реквизита с визуальным выделением даты. В свойствах элемента формы типа «Поле календаря» есть флаг Отображать текущую дату.

Важно понимать:

Для полноценного решения проблемы всегда используйте программное присвоение значения, описанное в способах 1 и 2.

Особенности работы с типом «Дата и время»

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

Если вы хотите, чтобы в календаре была установлена текущая дата, но время при этом оставалось началом дня, используйте функцию НачалоДня():

Объект.ДатаКалендаря = НачалоДня(ТекущаяДатаСеанса());

Работа с периодами (СтандартныйПериод)

Если на вашей форме используется не просто дата, а тип СтандартныйПериод (часто применяется в отчетах), то простая установка даты не сработает. Рассмотрим, как инициализировать такой объект:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    // Устанавливаем период с начала текущего месяца по сегодняшний день
    ПериодОтчета.ДатаНачала = НачалоМесяца(ТекущаяДатаСеанса());
    ПериодОтчета.ДатаОкончания = КонецДня(ТекущаяДатаСеанса());
    
КонецПроцедуры

Таким образом, мы обеспечим пользователю максимально удобный интерфейс, где данные уже подготовлены для работы сразу после открытия формы.

← На главную