Как получить рабочую дату сеанса в 1С вместо системной даты?

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

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

Использование свойства глобального контекста РабочаяДата

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

Проанализируем описание данного свойства из синтакс-помощника:

  1. Тип: Дата.
  2. Использование: Чтение и запись (запись доступна, если свойство ИспользованиеРабочейДаты имеет значение Назначать).
  3. Доступность: Только Толстый клиент (обычное приложение).

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


// Получение текущей установленной рабочей даты
ТекущаяРабочаяДата = РабочаяДата;

// Установка новой рабочей даты (если разрешено изменение)
Если ИспользованиеРабочейДаты = ИспользованиеРабочейДаты.Назначать Тогда
    РабочаяДата = '20231231';
КонецЕсли;

Важное ограничение: Свойство РабочаяДата отсутствует в тонком клиенте, веб-клиенте и на стороне сервера. Попытка обратиться к нему в серверном модуле или в контексте управляемой формы приведет к ошибке компиляции «Переменная не определена».

Разница между ТекущаяДата() и ТекущаяДатаСеанса()

Выясним причину, почему функция ТекущаяДата() часто приводит к расхождениям во времени, особенно в клиент-серверном варианте работы базы:

  1. ТекущаяДата() возвращает время операционной системы того физического устройства, на котором выполняется код. Вызов на клиенте возвращает системные часы клиентского ПК, а вызов на сервере — системные часы сервера. Если между ними есть рассинхронизация или они находятся в разных часовых поясах, значения будут отличаться.
  2. ТекущаяДатаСеанса() возвращает платформенное время с учетом часового пояса сеанса пользователя независимо от того, где выполняется код — на клиенте или на сервере.

Посмотрим на пример безопасного получения актуального системного времени сеанса:


// Корректное получение времени сеанса в управляемом приложении
АктуальнаяДата = ТекущаяДатаСеанса();

Реализация рабочей даты в управляемом приложении и БСП

В управляемом приложении концепция встроенной платформенной рабочей даты была упразднена. В типовых конфигурациях на базе Библиотеки стандартных подсистем (БСП) этот механизм перенесен на прикладной уровень.

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

  1. Пользователь задает дату в персональных настройках программы.
  2. Значение сохраняется в ХранилищеОбщихНастроек или в специальном служебном регистре.
  3. При создании нового объекта (в событии ОбработкаЗаполнения модуля менеджера или объекта) дата документа инициализируется сохраненным значением.

Варианты реализации рабочей даты для собственных разработок

Если требуется реализовать механизм рабочей даты, независимый от системных часов и доступный во всех программных контекстах (включая серверный код), разберем два основных подхода.

Способ 1. Использование параметров сеанса

Создадим параметр сеанса РабочаяДатаСеанса с типом Дата. Инициализируем его при старте программы в модуле сеанса в обработчике УстановкаПараметровСеанса:


Процедура УстановкаПараметровСеанса(ТребуемыеПараметры)
    
    Если ТребуемыеПараметры = Неопределено 
       Или ТребуемыеПараметры.Найти("РабочаяДатаСеанса") <> Неопределено Тогда
        
        // Считываем сохраненное значение из настроек пользователя
        СохраненнаяДата = ХранилищеОбщихНастроек.Загрузить("НастройкиПользователя", "РабочаяДата");
        
        Если ЗначениеЗаполнено(СохраненнаяДата) Тогда
            ПараметрыСеанса.РабочаяДатаСеанса = СохраненнаяДата;
        Иначе
            ПараметрыСеанса.РабочаяДатаСеанса = ТекущаяДатаСеанса();
        КонецЕсли;
        
    КонецЕсли;
    
КонецПроцедуры

Теперь значение параметра ПараметрыСеанса.РабочаяДатаСеанса доступно на сервере для быстрой подстановки в документы без повторных обращений к базе данных.

Способ 2. Чтение и запись через ХранилищеОбщихНастроек

Рассмотрим пример сохранения и чтения даты непосредственно через хранилище настроек:


// Сохранение рабочей даты пользователя
ХранилищеОбщихНастроек.Сохранить("ПараметрыРаботы", "РабочаяДата", ВыбраннаяПользователемДата);

// Чтение рабочей даты при создании документа
ДатаДляЗаполнения = ХранилищеОбщихНастроек.Загрузить("ПараметрыРаботы", "РабочаяДата");
Если Не ЗначениеЗаполнено(ДатаДляЗаполнения) Тогда
    ДатаДляЗаполнения = ТекущаяДатаСеанса();
КонецЕсли;

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

← На главную