Как установить фиксированное время документа при оперативном проведении в 1С

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

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

Почему платформа 1С «перетирает» установленное время?

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

  1. При оперативном проведении документа текущей датой платформа принудительно назначает ему актуальное системное время сервера.
  2. Это делается для обеспечения целостности данных: движения документа в регистрах должны гарантированно ложиться в «конец» временной шкалы текущего дня, чтобы исключить путаницу в остатках и не допустить появления записей «из будущего» относительно текущего момента.
  3. Любые программные манипуляции с датой в процедурах ПередЗаписью или ОбработкаПроведения будут проигнорированы, если выбран режим РежимПроведенияДокумента.Оперативный.

Разбор типичных ошибок реализации

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


Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
    // Попытка установить 8 утра
    Дата = НачалоДня(Дата) + 3600 * 8; 
КонецПроцедуры

Этот код успешно отработает при простой записи документа (без проведения) или при неоперативном проведении (например, задним числом). Однако, как только пользователь нажимает кнопку «Провести» в текущем периоде, платформа инициирует механизм оперативного проведения и замещает ваши «08:00:00» на текущие, скажем, «14:25:10».

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


Процедура ОбработкаПроведения(Отказ, РежимПроведения)
    Если РежимПроведения = РежимПроведенияДокумента.Оперативный Тогда
        Дата = НачалоДня(ТекущаяДата()) + 28800; // Пытаемся обмануть систему
    КонецЕсли;
КонецПроцедуры

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

Решение №1: Отказ от оперативного проведения

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

  1. Откройте Конфигуратор и найдите нужный документ.
  2. В свойствах документа на закладке «Основные» найдите параметр «Оперативное проведение».
  3. Установите его в значение «Запретить».

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


Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
    Если НЕ ЗначениеЗаполнено(Дата) Тогда
        Дата = ТекущаяДата();
    КонецЕсли;
    
    // Устанавливаем строго 08:00:00
    Дата = НачалоДня(Дата) + 28800; 
КонецПроцедуры

Важно: При таком подходе вы теряете возможность использовать механизм «Актуальных итогов» в его классическом виде, так как документ перестает считаться оперативным.

Решение №2: Программное переключение режима проведения

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

Для этого в форме документа или в процедуре ПередЗаписью можно применить условие:


Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
    // Если документ проводится и мы хотим зафиксировать время
    Если РежимЗаписи = РежимЗаписиДокумента.Проведение Тогда
        // Принудительно меняем режим на неоперативный
        РежимПроведения = РежимПроведенияДокумента.Неоперативный;
        // Устанавливаем нужное время
        Дата = НачалоДня(Дата) + 28800;
    КонецЕсли;
КонецПроцедуры

Нюанс: Этот метод «обманывает» стандартную логику кнопок формы. Однако стоит помнить, что неоперативное проведение не проверяет остатки на «сейчас», а берет остатки на момент времени самого документа. В нашем случае — на 08:00 утра.

Решение №3: Использование свойства «Автоматическая установка времени»

Выясним, как работает свойство документа «Автоматическая установка времени» в Конфигураторе. Оно может принимать значения:

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

Последствия для последовательностей и итогов

Проанализируем риски. Когда мы искусственно переносим время документа на 08:00, проводя его физически в 15:00, мы создаем ситуацию «заднего числа». Если в течение дня (с 08:00 до 15:00) уже были созданы другие документы, которые зависят от остатков, создаваемых вашим документом, возникнет нарушение последовательности.

Рекомендуем при использовании фиксированного времени всегда следовать правилам:

  1. Убедитесь, что проведение на 08:00 не нарушает логику партионного учета или расчета себестоимости.
  2. Если документ должен делать движения по регистрам остатков, лучше использовать реальное оперативное время, а фиксированное время оставить только для управленческих печатных форм.
  3. В случае необходимости жесткой фиксации используйте РежимПроведенияДокумента.Неоперативный, но помните о необходимости последующего пересчета итогов или восстановления последовательностей.

Резюме

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

← На главную