Как расположить документ последним внутри секунды в 1С и почему не работают доли секунды?

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

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

Ограничения типа данных Дата и устройство Момента времени

Выясним причину такого поведения платформы. В «1С:Предприятии» тип данных Дата хранит значение с дискретностью строго до одной секунды (в формате ГГГГММДДччммсс). Никаких долей секунды, миллисекунд или микросекунд во встроенном языке и СУБД для этого типа не существует.

Когда мы сравниваем два документа или упорядочиваем их на временной оси, платформа использует объект МоментВремени. Он состоит из двух частей:

  1. Значения даты и времени с точностью до секунды.
  2. Уникального идентификатора ссылки на документ (UUID).

Если дата и секунда у двух документов совпадают (например, оба имеют время 31.01.2024 23:59:59), их взаимное расположение определяется исключительно двоичным сравнением их ссылок. Так как UUID генерируется платформой с использованием сетевых параметров и случайных значений, документ, созданный позже реального времени, вполне может получить идентификатор, который при сравнении окажется «меньше». Полагаться на порядок ввода документов внутри одной и той же секунды категорически нельзя.

Решение 1. Искусственное разнесение регламентных документов по секундам

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

Например, в типовых конфигурациях регламентные документы выстраиваются по фиксированной секундной сетке:

  1. Промежуточные документы учета (например, формирование вычетов) записываются на 23:59:58.
  2. Итоговые регламентные документы и закрытие периода записываются на 23:59:59.

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


Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
    
    // Устанавливаем время на предпоследнюю секунду месяца
    КонецТекущегоДня = КонецДня(ЭтотОбъект.Дата);
    ЭтотОбъект.Дата = КонецТекущегоДня - 1; // 23:59:58
    
КонецПроцедуры

Если требуется управлять позицией документа относительно других документов дня при интерактивной или программной записи, можно использовать метод УстановитьВремя():


// Установка времени документа последним в пределах указанной даты
ДокументОбъект.УстановитьВремя(РежимАвтоВремя.Последним, Истина);
ДокументОбъект.Записать(РежимЗаписиДокумента.Проведение);

Решение 2. Использование объекта Граница для выборки итогов в запросах

Часто задача поставить документ «в самую последнюю долю секунды» возникает из-за необходимости собрать остатки или обороты регистра строго со всеми движениями текущего месяца. Если передать в параметры виртуальной таблицы МоментВремени() документа на 23:59:59, часть движений других документов этой же секунды может выпасть из-за меньшего значения их UUID.

Чтобы гарантированно включить все движения за весь месяц, сформируем объект Граница на начало следующего месяца с видом Исключая:


// Получаем первую секунду следующего месяца
НачалоСледующегоМесяца = НачалоМесяца(ДобавитьМесяц(ДатаДокумента, 1));

// Создаем границу, исключающую первую секунду следующего месяца
ПараметрПериод = Новый Граница(НачалоСледующегоМесяца, ВидГраницы.Исключая);

Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	Остатки.Счет,
    |	Остатки.СуммаОстаток
    |ИЗ
    |	РегистрБухгалтерии.Хозрасчетный.Остатки(&Период, , , ) КАК Остатки";

Запрос.УстановитьПараметр("Период", ПараметрПериод);

В этом случае запрос учтет абсолютно все движения, совершенные вплоть до 23:59:59 включительно, независимо от внутренних идентификаторов документов.

Решение 3. Контроль порядка проведения через механизм Последовательности

Когда требуется обеспечить строгий логический порядок проведения разнородных документов без привязки к секундам, используют объект метаданных Последовательность.

  1. В дереве метаданных настраивается состав последовательности (включаются необходимые документы и регистры).
  2. При проведении документов платформа контролирует границу последовательности.
  3. При изменении документов задним числом граница сдвигается, сигнализируя о необходимости регламентного перепроведения по цепочке.

Использование последовательностей полностью исключает зависимость логики учета от случайного совпадения времени документов.

← На главную