Как узнать дату создания документа по УИД или служебным данным в 1С

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

В типовых конфигурациях 1С, таких как Бухгалтерия предприятия 3.0, дата самого документа отражает хозяйственную операцию, а не момент фактической записи объекта в информационную базу. Часто возникает задача выяснить, когда именно документ был создан физически. Разберем основные способы решения этой проблемы с помощью служебных механизмов платформы и конфигурации.

Способ 1. Извлечение метки времени из уникального идентификатора (UUID)

Платформа 1С использует стандарт UUID Version 1 (time-based). В таком идентификаторе заложено количество интервалов по 100 наносекунд, прошедших с момента перехода на григорианский календарь (15 октября 1582 года). Переставив шестнадцатеричные блоки строки идентификатора, мы можем вычислить исходную метку времени.

Рассмотрим программный алгоритм получения даты создания ссылки:


Функция ДатаСозданияСсылки(Ссылка) Экспорт
    ГУИД = Строка(Ссылка.УникальныйИдентификатор());
    
    // Проверим, что это UUID версии 1 (в третьей группе первым символом идет "1")
    Если Сред(ГУИД, 15, 1) <> "1" Тогда
        Возврат Неопределено;
    КонецЕсли;
    
    // Собираем шестнадцатеричное число времени из блоков идентификатора
    Строка16 = Сред(ГУИД, 16, 3) + Сред(ГУИД, 10, 4) + Сред(ГУИД, 1, 8);
    Разрядность = СтрДлина(Строка16);
    ЧислоСек = 0;
    
    Для Позиция = 1 По Разрядность Цикл
        Символ = НРег(Сред(Строка16, Позиция, 1));
        ЧислоСек = ЧислоСек + (Найти("123456789abcdef", Символ)) * Pow(16, Разрядность - Позиция);
    КонецЦикла;
    
    ЧислоСек = ЧислоСек / 10000000;
    
    // Начало отсчета UUID v1 — 15 октября 1582 года в формате UTC
    ДатаUTC = Дата(1582, 10, 15, 00, 00, 00) + ЧислоСек;
    
    // Для получения локального времени добавляем смещение часового пояса сеанса
    Возврат ДатаUTC + МестноеВремя(ТекущаяДатаСеанса()) - ТекущаяДатаСеанса();
КонецФункции

Проанализируем технические нюансы и ограничения данного метода:

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

Способ 2. Использование журнала регистрации

Самым надежным источником информации о первом появлении объекта является системный журнал регистрации платформы. Каждая первая запись документа фиксируется событием добавления данных.

Посмотрим на пример программной выборки первого события записи объекта:


Функция ПолучитьДатуСозданияИзЖР(Ссылка) Экспорт
    Фильтр = Новый Структура;
    Фильтр.Вставить("Данные", Ссылка);
    Фильтр.Вставить("Событие", "_$Data$_.New"); // Событие создания нового объекта
    
    ТаблицаЖР = Новый ТаблицаЗначений;
    ВыгрузитьЖурналРегистрации(ТаблицаЖР, Фильтр, "Дата, Пользователь, ИмяПользователя",, 1);
    
    Если ТаблицаЖР.Количество() > 0 Тогда
        Возврат ТаблицаЖР[0].Дата;
    КонецЕсли;
    
    Возврат Неопределено;
КонецФункции

Важно учитывать: Журнал регистрации может регулярно сокращаться регламентными процедурами обслуживания для экономии дискового пространства. Если документ создан давно, записей о его создании в журнале может уже не остаться. Кроме того, выборка из больших файлов ЖР создает существенную нагрузку на сервер.

Способ 3. Механизм версионирования объектов БСП

В конфигурации Бухгалтерия предприятия 3.0 присутствует встроенная подсистема версионирования. Если в разделе Администрирование — Общие настройки — История изменений включено версионирование для нужного вида документов, точные данные сохраняются в регистре сведений ВерсииОбъектов.

Разберем, как получить дату первой версии документа с помощью запроса:


Функция ПолучитьДатуПервойВерсии(Ссылка) Экспорт
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ ПЕРВЫЕ 1
        |    ВерсииОбъектов.ДатаВерсии КАК ДатаСоздания,
        |    ВерсииОбъектов.АвторВерсии КАК Автор
        |ИЗ
        |    РегистрСведений.ВерсииОбъектов КАК ВерсииОбъектов
        |ГДЕ
        |    ВерсииОбъектов.Объект = &Ссылка
        |УПОРЯДОЧИТЬ ПО
        |    ВерсииОбъектов.НомерВерсии ВОЗР";
    
    Запрос.УстановитьПараметр("Ссылка", Ссылка);
    Выборка = Запрос.Выполнить().Выбрать();
    
    Если Выборка.Следующий() Тогда
        Возврат Выборка.ДатаСоздания;
    КонецЕсли;
    
    Возврат Неопределено;
КонецФункции

Способ 4. Платформенный механизм «История данных»

В платформе 1С, начиная с версии 8.3.11, появился встроенный механизм ИсторияДанных. Если для метаданных документа включено свойство ИсторияДанных, сведения о создании и модификации хранятся на уровне СУБД независимо от БСП.

Выясним дату создания через менеджер истории данных:


Функция ДатаСозданияПоИсторииДанных(Ссылка) Экспорт
    История = ИсторияДанных.ПолучитьИсторию(Ссылка);
    Если История.Количество() > 0 Тогда
        // Самая ранняя версия находится в начале массива
        Возврат История[0].Дата;
    КонецЕсли;
    Возврат Неопределено;
КонецФункции

Превентивное решение для новых документов

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


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

Таким образом, для существующих документов в первую очередь следует проверить регистр ВерсииОбъектов и журнал регистрации. Если эти механизмы были отключены или очищены, вычисление даты из УИД остается единственным способом узнать приблизительное время создания объекта.

← На главную