Почему при оперативном проведении документа в 1С время устанавливается в будущее и как это исправить?

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

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

Как устроен механизм оперативной отметки времени (ООВ)

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

Для реализации этого правила платформа использует специальный внутренний счетчик — Оперативную отметку времени (ООВ). Расчет времени для нового проводимого документа выполняется по следующему алгоритму:

Новая отметка времени = Максимум (Текущее время сервера/сеанса, Предыдущая отметка времени + 1 секунда)

Проанализируем эту формулу: если в текущем дне уже существует хотя бы один документ с некорректно установленным будущим временем (например, 18:59:39 вместо 14:35:00), то платформенная функция ПолучитьОперативнуюОтметкуВремени() при проведении каждого нового документа начнет отсчитывать время от этой ошибочной точки, добавляя по одной секунде к последнему зафиксированному значению.

Критически важная особенность данного механизма заключаются в том, что текущее значение оперативной отметки времени кэшируется в оперативной памяти рабочего процесса сервера 1С (rphost) и действует глобально для всей информационной базы.

Причины, почему время «улетает» в будущее

Выясним основные источники возникновения подобного сбоя в практической работе:

  1. Наличие в базе документов с будущей датой. Пользователь мог вручную ввести документ, указав время «наперед», или изменить время уже проведенного документа на более поздний час текущих суток и провести его оперативно. Платформа моментально запоминает эту точку как последнюю оперативную отметку.
  2. Программные вызовы встроенных функций в цикле. Если в кастомном коде конфигурации, обработках или фоновых заданиях выполняется регулярный вызов метода ПолучитьОперативнуюОтметкуВремени() без создания документа, каждое обращение увеличивает счетчик в памяти на 1 секунду. При массовой обработке данных счетчик за считанные минуты может уйти вперед на несколько часов.
  3. Сбой системных часов и NTP-синхронизации. При временном рассинхроне часов между сервером приложений 1С и сервером СУБД (например, скачок времени вперед с последующим откатом назад) платформа успевает зафиксировать оперативную отметку по ошибочному опережающему времени.
  4. Разница часовых поясов сеансов. В распределенных системах или при работе пользователей из разрозненных регионов некорректная настройка свойства ЧасовойПояс сеанса может приводить к тому, что документ, проведенный пользователем из «старшего» часового пояса, смещает оперативную отметку для всей базы.

Опасность блокировки: ошибка «Оперативное проведение документов в данном дне более невозможно»

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

Оперативное проведение документов в данном дне более невозможно

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

Пошаговый алгоритм исправления проблемы

Рассмотрим порядок действий для полного восстановления корректной работы проведения документов.

Шаг 1. Поиск документов с «будущим» временем

Сформируем список всех документов за текущие сутки и отсортируем их по убыванию времени. Задача — найти документы, время которых превышает реальное текущее время. Важно понимать: простое изменение даты у этих документов в пользовательском режиме не сбросит уже зафиксированное значение в оперативной памяти сервера!

Шаг 2. Очистка кэша оперативной отметки времени

Чтобы стереть запомненное значение из оперативной памяти процесса rphost, необходимо полностью завершить все активности с информационной базой. Выполним следующие действия:

  1. Завершим работу всех активных пользователей.
  2. Закроем все сеансы режимов Конфигуратор и внешних соединений (COM/HTTP/REST).
  3. Завершим все фоновые и регламентные задания в информационной базе.
  4. Перезапустим службу сервера 1С:Предприятия (или выполним принудительное завершение всех сеансов информационной базы через консоль администрирования серверов 1С / утилиту rac).

После перезапуска службы или полного завершения сеансов кэш в процессе rphost очищается, и очередная оперативная отметка будет получена заново от текущего времени сервера.

Шаг 3. Корректировка существующих документов

После сброса кэша новые документы начнут проводиться с нормальным временем. Однако если в базе останутся старые документы с опережающим временем, при их повторном перепроведении оперативная отметка снова сдвинется в будущее. Поэтому у ранее созданных «кривых» документов необходимо скорректировать время на реальное (например, перевести их в неоперативный режим проведения или вручную установить правильные часы и минуты).

Примеры кода и программная профилактика

Проанализируем способы проверки и предотвращения сдвига времени на уровне конфигуратора.

Для проверки текущей оперативной отметки времени во встроенном языке используется функция ПолучитьОперативнуюОтметкуВремени():


// Проверка текущей оперативной отметки времени
ОтметкаВремени = ПолучитьОперативнуюОтметкуВремени();
Сообщить("Текущая оперативная отметка времени базы: " + Строка(ОтметкаВремени));

Для предотвращения случайной записи и проведения документов с датой из будущего рекомендуется внедрить проверку в подписку на событие ПередЗаписью для всех документов системы:


Процедура ПроверитьДатуДокументаПередЗаписью(Источник, Отказ, РежимЗаписи, РежимПроведения) Экспорт
	
	// Проверяем только при оперативном проведении
	Если РежимПроведения = РежимПроведенияДокумента.Оперативный Тогда
		
		ТекущееВремяСеанса = ТекущаяДатаСеанса();
		МаксимальноДопустимоеВремя = ТекущееВремяСеанса + 300; // Допускаем люфт в 5 минут
		
		Если Источник.Дата > МаксимальноДопустимоеВремя Тогда
			Отказ = Истина;
			ВызватьИсключение "Ошибка проведения: дата документа (" + Строка(Источник.Дата) 
				+ ") существенно превышает текущее время сервера (" + Строка(ТекущееВремяСеанса) + ")!";
		КонецЕсли;
		
	КонецЕсли;
	
КонецПроцедуры

Для документов, которые не требуют строгого хронологического контроля остатков и партий в реальном времени (например, БухгалтерскаяСправка, ИнвентаризацияТоваров, АктСверкиВзаиморасчетов), рекомендуется устанавливать свойство метаданных Оперативное проведение в значение Запретить. Это снизит нагрузку на механизм ООВ и полностью исключит влияние таких документов на общую временную линию базы данных.

← На главную