При разработке и кастомизации конфигураций на платформе 1С:Предприятие 8.3 часто возникает задача управления хронологией документов. По умолчанию система пытается автоматически распределить документы по оси времени, чтобы избежать коллизий при проведении и расчете остатков. Однако в некоторых бизнес-сценариях требуется жестко зафиксировать время создания определенных документов — например, установить его строго на начало дня (00:00:01).
В этой статье мы подробно разберем, как устроены механизмы работы со временем документов в платформе 1С и типовых конфигурациях (таких как 1С:Бухгалтерия 3.0), выясним причины системного поведения и рассмотрим оптимальные программные решения для реализации этой задачи.
Прежде чем переходить к написанию кода, давайте проанализируем, как сама платформа регулирует время при записи нового документа в зависимости от настроек его свойств в Конфигураторе и действий пользователя:
12:00:00. Это предотвращает случайное попадание документа на самую границу суток.АвтоВремя установлено в значение «Не использовать», платформа берет текущее время сеанса при записи текущей датой. В остальных случаях (например, при неоперативном проведении, если время документа было «нулевым» — 00:00:00), платформа может автоматически скорректировать его на начало или конец дня в зависимости от настроек этого свойства.В конфигурациях на базе библиотеки стандартных подсистем (БСП) присутствует пользовательская настройка «Время документов устанавливать автоматически» (ее можно найти в разделе Администрирование — Проведение документов).
Рассмотрим, как ведет себя система при разных состояниях этого флага:
12:00:00 — для документов за другие даты).Например, в типовом решении распределение выглядит так:
Для реализации этого в модуле менеджера каждого документа прописана экспортная функция:
Функция ВремяДокументаПоУмолчанию() Экспорт
Она возвращает структуру с часами и минутами. Если вам необходимо скорректировать поведение глобально для системы с включенным авто-временем, то переопределение этой функции в расширении — правильный «архитектурный» путь. Однако этот метод возвращает только часы и минуты, поэтому настроить точные секунды (например, именно 00:00:01) через него напрямую не всегда удается.
Начало дня (00:00:00) часто воспринимается платформой 1С и некоторыми механизмами как «пустое» или «неустановленное» время. Если записать документ со временем 00:00:00, платформа при определенных сценариях проведения или изменения даты может решить, что время не задано, и автоматически перезаписать его на текущее или на 12:00:00.
Установка времени в 00:00:01 (ровно одна секунда первого часа) гарантирует платформе, что время заполнено осознанно. Такой документ гарантированно встанет в самое начало дня (после документов с «пустым» временем, если такие есть) и не будет случайно изменен автоматическими алгоритмами платформы при перезаписи.
Перейдем к практической реализации. Нам необходимо переопределить время документа непосредственно перед тем, как данные будут физически сохранены в базу данных SQL.
Важное правило: Изменение времени нужно делать строго в событии ПередЗаписью, а не ПриЗаписи!
ПриЗаписи документ уже физически записан в базу данных. Если менять дату/время на этом этапе, системе придется повторно перезаписывать объект, что приведет к двойной нагрузке на СУБД, лишним транзакциям и возможным блокировкам.ПередЗаписью (в модуле объекта или через подписку на событие) данные еще находятся в оперативной памяти и не сохранены в СУБД. Изменяя реквизит Дата здесь, мы записываем его корректно с первого раза.Рассмотрим два основных способа реализации.
Этот способ является наиболее предпочтительным, так как позволяет избежать изменения типовой конфигурации и не требует создания расширения для каждого отдельного документа. Мы создаем одну подписку, которая будет обслуживать нужные типы документов.
Разберем по шагам, как это сделать:
РаботаСДокументамиСобытия) с установленными флажками Сервер, Внешнее соединение.УстановитьВремяДокументаПередЗаписью).ПередЗаписью.Напишем код обработчика события в общем модуле:
Процедура УстановитьВремяДокументаПередЗаписью(Источник, Отказ, РежимЗаписи, РежимПроведения) Экспорт
// Проверяем, что документ не помечен на удаление и это не обмен данными
Если Источник.ОбменДанными.Загрузка Тогда
Возврат;
КонецЕсли;
// Устанавливаем время 00:00:01.
// Функция НачалоДня(Дата) сбрасывает время в 00:00:00.
// В 1С прибавление числа к дате увеличивает ее на это количество секунд.
// Прибавляя 1, мы получаем ровно 1 секунду первого часа суток.
Источник.Дата = НачалоДня(Источник.Дата) + 1;
КонецПроцедуры
Если вам требуется изменить поведение только одного конкретного документа, который уже снят с поддержки или находится в вашей собственной конфигурации, вы можете прописать код непосредственно в его модуле объекта.
Рассмотрим пример кода в модуле объекта документа:
Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
// Вызываем стандартную обработку, если это необходимо
Если ОбменДанными.Загрузка Тогда
Возврат;
КонецЕсли;
// Корректируем время документа на первую секунду дня
Дата = НачалоДня(Дата) + 1;
КонецПроцедуры
Мы проанализировали системные механизмы платформы «1С:Предприятие 8.3» по управлению временем документов. Использование обработчика ПередЗаписью в связке с подпиской на событие — это наиболее чистый, надежный и производительный способ переопределить стандартное поведение платформы без изменения типовой конфигурации.