В процессе разработки и сопровождения конфигураций на платформе 1С:Предприятие (особенно на обычных формах, таких как в УПП 1.3 или УТ 10.3) программисты часто сталкиваются с неочевидным поведением системы. Один из классических вопросов: почему на последней строчке процедуры ПередОткрытием дата нового документа все еще пустая (01.01.0001 00:00:00), а на первой строчке процедуры ПриОткрытии она уже заполнена конкретным значением?
В этой статье мы подробно разберем внутренние механизмы платформы 1С, которые отрабатывают «между» этими двумя событиями, выясним, как на это влияет свойство «АвтоВремя», и решим практическую проблему, когда у конкретного пользователя новые документы создаются со странной или устаревшей датой.
---
Чтобы понять, в какой момент документу присваивается дата, давайте пошагово проанализируем всю цепочку событий при создании нового документа (в том числе при вводе на основании):
ОбработкаЗаполнения в модуле объекта. В этой процедуре определяются реквизиты заполнения по умолчанию. В типовых конфигурациях дата документа здесь обычно не заполняется и остается пустой.ПередОткрытием формы. Этот обработчик выполняется самым первым в модуле формы. Здесь мы еще можем отказаться от открытия формы, установив параметр Отказ = Истина. Обратите внимание: на протяжении всей этой процедуры дата нашего нового документа все еще равна 01.01.0001 00:00:00 (если только мы не заполнили её принудительно в коде ранее).ПередОткрытием дата документа остается пустой, система берет инициативу в свои руки и автоматически заполняет её.ПриОткрытии формы. На первой же строчке этого обработчика мы видим уже заполненную дату. Форма полностью готова к показу пользователю.---
Когда выполнение процедуры ПередОткрытием завершается без ошибок и отказов, платформа 1С выполняет автоматическую настройку и инициализацию расширения формы документа. Система проверяет значение реквизита Дата. Если дата пустая, то платформа:
Рассмотрим подробнее, как свойство АвтоВремя влияет на результат, который мы увидим в процедуре ПриОткрытии:
ПриОткрытии вы увидите актуальное время (например, 29.08.2012 14:35:12).00:00:00. Окончательное реальное время документа будет рассчитано и записано только в момент непосредственной записи документа в базу данных. В процедуре ПриОткрытии вы увидите только дату и нулевое время.---
Иногда возникает ситуация, когда у десятков пользователей новые документы создаются с текущей датой, а у одного конкретного сотрудника дата нового документа всегда устанавливается фиксированным прошлым или будущим числом (например, началом какого-то месяца). При этом никаких ошибок в коде нет, и у остальных всё работает корректно.
Причина проблемы: У данного пользователя в персональных настройках системы жестко задан параметр Рабочая дата.
Разберем по шагам, как исправить эту ситуацию без изменения кода конфигурации:
После выполнения этих простых действий новые документы у пользователя снова будут создаваться с текущей датой компьютера.
---
Если вы работаете в современных конфигурациях (например, ERP, Комплексная автоматизация 2 или Бухгалтерия предприятия 3.0), концепция обычных форм уже не используется, и события ПередОткрытием там нет. Однако логика инициализации даты осталась похожей, просто она сместилась на сервер.
Последовательность событий в управляемом приложении выглядит следующим образом:
Модуль объекта: ОбработкаЗаполнения()
↓
Модуль формы: ПриСозданииНаСервере()
↓
Модуль формы: ПриОткрытии() (выполняется на клиенте)
Если вам необходимо программно перехватить и изменить дату нового документа до того, как форма откроется на экране пользователя, это следует делать в процедуре ПриСозданииНаСервере модуля формы или в ОбработкаЗаполнения модуля объекта. Проверить, является ли документ новым, в управляемой форме можно следующим образом:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Проверяем, что документ новый и еще не записан в базу
Если Объект.Ссылка.Пустая() Тогда
// Если дата еще не заполнена платформой, можем установить её вручную
Если Не ЗначениеЗаполнено(Объект.Date) Тогда
Объект.Дата = ТекущаяДатаСеанса();
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Использование свойства ТекущаяДатаСеанса() является наиболее правильным и надежным способом получения актуального времени в управляемом приложении, так как оно возвращает время сервера с учетом часового пояса клиента, исключая проблемы разницы времени на локальных компьютерах пользователей.