Как через подписки на события изменить дату документа при проведении

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

При разработке бизнес-логики в 1С часто возникает необходимость автоматически приводить дату документа к началу дня (00:00:00) или к определенному времени при проведении. Программисты подписываются на событие ПередЗаписью и пишут стандартную проверку, однако при записи и оперативном проведении новых документов сталкиваются с проблемой: платформа 1С все равно подставляет текущее время или сдвигает отметку времени.

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

Выясним причину: почему время сбрасывается при оперативном проведении

Проанализируем работу платформы 1С при записи и проведении документов. Если для документа разрешено оперативное проведение и он записывается в режиме РежимЗаписиДокумента.Проведение с параметром РежимПроведенияДокумента.Оперативный, вступает в действие механизм оперативной отметки времени.

Посмотрим, что происходит на уровне платформы:

  1. В обработчике события ПередЗаписью код подписки успешно меняет время на начало дня. Посмотрим на этот код:

Если Источник.Дата <> НачалоДня(Источник.Дата) Тогда 
    Источник.Дата = НачалоДня(Источник.Дата); 
КонецЕсли;
  1. Отладчик подтверждает, что значение Источник.Дата изменилось (например, стало 08.02.2018 00:00:00).
  2. Однако далее платформа перед фиксацией транзакции проверяет режим проведения. В случае оперативного проведения платформа принудительно заменяет время документа на оперативную отметку времени (получаемую с помощью ПолучитьОперативнуюОтметкуВремени()). Если в этой секунде уже есть документы, платформа может добавить +1 секунду или поставить время 23:59:59.

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

Способ 1. Программное изменение режима проведения в подписке ПередЗаписью

Разберем наиболее эффективный способ решения проблемы через подписку на событие без изменения свойств метаданных документа.

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

Рассмотрим пример кода в подписке на событие ПередЗаписью:


Процедура ИмяПодпискиПередЗаписью(Источник, Отказ, РежимЗаписи, РежимПроведения) Экспорт

    Если Отказ Тогда
        Возврат;
    КонецЕсли;

    // Приводим дату к началу дня
    Источник.Дата = НачалоДня(Источник.Дата);

    // Если документ проводится, переводим режим в неоперативный
    Если РежимЗаписи = РежимЗаписиДокумента.Проведение Тогда
        РежимПроведения = РежимПроведенияДокумента.Неоперативный;
    КонецЕсли;

КонецПроцедуры

Важно: этот способ отключает оперативную отметку времени для документа, благодаря чему переданная дата Источник.Дата сохраняется в базе данных в исходном виде.

Способ 2. Отключение оперативного проведения в метаданных документа

Если бизнес-логика документа в целом не требует оперативного контроля остатков на текущую секунду, правильным решением будет отключение оперативного проведения на уровне конфигуратора.

Разберем шаги по настройке метаданных:

  1. Откроем дерево метаданных конфигурации и найдем нужный документ.
  2. Перейдем на вкладку Движения.
  3. В поле Использовать режим проведения установим значение Запретить.

После этого документ всегда будет проводиться в неоперативном режиме, и код смены даты в подписке ПередЗаписью будет отрабатывать без вмешательства алгоритмов платформы.

Способ 3. Отключение автовремени при записи

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

Для явного отключения сдвига времени в документе используется свойство ЗаполнениеДокументов.ЗаполнитьВремяДокумента или настройка РежимАвтоВремя.НеИспользовать при программной записи объекта.

Способ 4. Корректировка формы документа в расширении

Если проведение выполняется пользователем из формы документа, мы можем изменить режим проведения на сервере до запуска транзакции записи.

Рассмотрим пример кода в расширении формы документа в событии ПередЗаписьюНаСервере:


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

КонецПроцедуры

Подведем итоги

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

← На главную