При интенсивном документообороте в базах данных на платформе 1С:Предприятие 7.7 разработчики часто сталкиваются с неприятным эффектом: при автоматическом создании или массовой загрузке большого количества документов время каждого следующего документа сдвигается вперед ровно на 10 секунд. Если в течение дня создаются тысячи документов, время записи и точка актуальности (ТА) стремительно «убегают» в будущее относительно системных часов компьютера. Выясним причину такого поведения платформы, проанализируем возможные последствия и разберем способы решения данной проблемы.
Разберем, почему 1С 7.7 ведет себя подобным образом. По умолчанию при создании нового документа платформа включает режим автопозиционирования «в конец дня» (метод АвтоВремяКонецДня()). Алгоритм платформы находит самый последний по времени документ за указанную дату и прибавляет к нему ровно 10 секунд. Если документов за день еще не было, по умолчанию назначается условное время 12:00:00.
Такой шаг в 10 секунд был заложен разработчиками платформы для визуального удобства и возможности вставки документов вручную в журнале. Однако при массовой генерации документов этот интервал накапливается с огромной скоростью: каждые 1000 проведенных документов сдвигают точку актуальности вперед почти на 2 часа и 47 минут. В результате к середине рабочего дня ТА может переместиться на вечер или вовсе упереться в границу суток (23:59:59).
Проанализируем риски, возникающие при неконтролируемом сдвиге времени:
Важно помнить: хронологическая последовательность документов в 1С 7.7 определяется не только временем, но и так называемой позицией документа, включающей дату, время и внутренний 36-ричный идентификатор. Несколько документов могут иметь абсолютно идентичное время вплоть до секунды — платформа все равно однозначно упорядочит их по системному ID.
Рассмотрим штатные программные методы управления временем документа. Вместо записи в конец дня мы можем явно указать платформе способ определения времени перед вызовом метода Записать().
Если нам необходимо, чтобы документ получал астрономическое системное время компьютера, применим метод АвтоВремяТекущее():
Док = СоздатьОбъект("Документ.РасходнаяНакладная");
Док.Новый();
// Заполнение реквизитов документа
Док.ДатаДок = ТекущаяДата();
Док.АвтоВремяТекущее();
Док.Записать();
Для документов, которые должны следовать строго за текущей точкой актуальности без искусственного растягивания 10-секундными интервалами, используется метод АвтоВремяПослеТА():
Док = СоздатьОбъект("Документ.РасходнаяНакладная");
Док.Новый();
// Заполнение реквизитов
Док.ДатаДок = ТекущаяДата();
Док.АвтоВремяПослеТА();
Док.Записать();
Разберем ручной способ контроля времени, когда требуется полностью исключить вмешательство платформы. Для этого вызываем метод АвтоВремяОтключить() и явно задаем нужное время с помощью УстановитьВремя().
Док = СоздатьОбъект("Документ.ПоступлениеТМЦ");
Док.Новый();
Док.ДатаДок = ТекущаяДата();
Док.АвтоВремяОтключить();
// Устанавливаем точное время (Часы, Минуты, Секунды)
Док.УстановитьВремя(10, 0, 0);
Док.Записать();
Посмотрим на интересную особенность работы метода УстановитьВремя(): платформа 1С 7.7 умеет самостоятельно пересчитывать значения часов, минут и секунд, превышающие стандартные границы. Например, вызов Док.УстановитьВремя(16, 120, 365) автоматически преобразуется во время 18:06:05. При массовой пакетной генерации документов в цикле можно использовать приращение счетчика секунд на единицу (а не на 10):
Сек = 0;
Пока ВыборкаДанных.ПолучитьСтроку() = 1 Цикл
Док = СоздатьОбъект("Документ.Чек");
Док.Новый();
Док.ДатаДок = РабочаяДата();
Док.АвтоВремяОтключить();
Сек = Сек + 1;
// Платформа корректно пересчитает даже Сек > 59
Док.УстановитьВремя(9, 0, Сек);
Док.Записать();
КонецЦикла;
Однако помните об ограничении: если передать в параметры значения, выходящие за рамки текущих суток (например, 23 часа и 120 минут), платформа установит предельное значение суток — 23:59:59.
Рассмотрим подход, который часто применяется для входящих первичных документов (например, накладных поставщиков). Такие документы не должны влиять на позицию точки актуальности в течение дня, поэтому их целесообразно помещать в самое начало суток:
ДокПоступление = СоздатьОбъект("Документ.ПоступлениеТМЦ");
ДокПоступление.Новый();
ДокПоступление.ДатаДок = ТекущаяДата();
ДокПоступление.АвтоВремяОтключить();
ДокПоступление.УстановитьВремя(0, 0, 1);
ДокПоступление.Записать();
В этом случае при последующем проведении таких документов они займут фиксированное начальное положение в журнале, не сдвигая ТА вперед и обеспечивая корректное наличие остатков к моменту начала дневных продаж.
Проанализируем параметры программы, которые влияют на поведение документов при проведении в интерактивном режиме. В главном меню перейдем в «Сервис» -> «Параметры»:
Если массовая загрузка документов уже завершена и точка актуальности оторвалась от реального времени на несколько часов, автоматические настройки не вернут ее назад. Выполним следующие шаги: