Почему 1С устанавливает время документов 23:59:59 в последний день месяца и как это исправить?

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

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

Истинная причина проблемы: логика закрытия периода

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

Рассмотрим, как система распределяет время:

  1. Если документ создается "задним" числом (неоперативное проведение), платформа по умолчанию пытается поставить условное время, например, 12:00:00.
  2. Однако в свойствах формы документа чаще всего установлено АвтоВремя в значении ТекущимИлиПоследним.
  3. Это свойство заставляет систему искать последний проведенный документ за эту дату. Если регламентное закрытие месяца (с временем 23:59:59) уже создано в базе, алгоритмы попытаются приравнять время нового документа к последнему найденному. Именно поэтому документ "улетает" в самый конец дня.

Проблема кроется в порядке документов внутри одной секунды. У каждого документа есть уникальный МоментВремени. Если обычный документ встанет по моменту времени позже, чем регламентная операция в той же секунде (23:59:59), закрытие месяца просто не увидит этот документ, что приведет к искажению финансового результата и зависшим остаткам.

Решение 1: Программная корректировка в модуле формы

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


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

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

Решение 2: Обход проверок через подписки на события

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

Посмотрим на пример кода, который решает проблему в обработчике подписки:


Процедура ПодпискаПередЗаписьюДокумента(Источник, Отказ)
    // Устанавливаем флаг загрузки, чтобы отключить бизнес-логику при записи
    Источник.ОбменДанными.Загрузка = Истина;
    
    // Если используются последовательности
    Если Источник.ПринадлежностьПоследовательностям.Количество() > 0 Тогда
        Источник.ПринадлежностьПоследовательностям[0].ОбменДанными.Загрузка = Истина;
    КонецЕсли;
КонецПроцедуры

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

Более правильным подходом в рамках подписки будет простой сдвиг времени. Например, отнять один час от времени документа, чтобы создать безопасный "зазор" перед документами закрытия месяца:


Если КонецМесяца(Источник.Дата) = КонецДня(Источник.Дата) Тогда
    // Сдвигаем время на 23:00:00 (отнимаем 3600 секунд)
    Источник.Дата = КонецДня(Источник.Дата) - 3600;
КонецЕсли;

Решение 3: Использование типовых настроек (без кодирования)

Проанализируем ситуацию с точки зрения стандартного функционала. Во многих современных конфигурациях (таких как ERP, Комплексная автоматизация или Бухгалтерия КОРП) разработчики уже предусмотрели механизм для предотвращения таких коллизий. Посмотрим на настройки администрирования.

Перейдите в раздел Администрирование -> Проведение документов. Найдите опцию Время документов устанавливать автоматически (название может незначительно отличаться в зависимости от конфигурации).

Если включить эту настройку, система перестанет пытаться сдвигать документы на конец дня на основе свойства АвтоВремя. Вместо этого платформа начнет жестко разносить различные типы документов по предопределенному времени внутри дня. Например, документы поступления всегда будут записываться в 12:00:00, а документы реализации — в 14:00:00. Это полностью исключит скопление оперативных документов в последней секунде месяца (23:59:59) и решит проблему конфликтов с регламентными операциями.

← На главную