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

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

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

Способ 1: Получение даты из уникального идентификатора (GUID)

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

Посмотрим на пример функции, которая вычисляет дату из ссылки:


Функция ДатаСозданияСсылки(Ссылка)
    ГУИД = Ссылка.УникальныйИдентификатор();
    Строка16 = Сред(ГУИД, 16, 3) + Сред(ГУИД, 10, 4) + Сред(ГУИД, 1, 8);
    Разрядность = СтрДлина(Строка16);
    ЧислоСек = 0;
    
    Для Позиция = 1 По Разрядность Цикл
        ЧислоСек = ЧислоСек + Найти("123456789abcdef", Сред(Строка16, Позиция, 1)) * Pow(16, Разрядность - Позиция);
    КонецЦикла;
    
    ЧислоСек = ЧислоСек / 10000000;
    Возврат Дата(1582, 10, 15, 00, 00, 00) + ЧислоСек + СмещениеСтандартногоВремени + СмещениеЛетнегоВремени;
КонецФункции

Важные нюансы и ограничения данного метода:

  1. Этот способ может дать неверный результат. Если ссылка генерируется программно с помощью функции НовыйУникальныйИдентификатор до записи объекта в базу, время в GUID будет соответствовать моменту исполнения кода, а не реальной дате появления записи.
  2. При интеграциях и обменах могут генерироваться идентификаторы стандарта UUID версии 4. В них символы генерируются случайным образом, и отметка времени там отсутствует в принципе. В таких ситуациях для сопоставления объектов можно использовать перенос данных между похожими конфигурациями 1С с поиском по произвольным полям.
  3. В запросе штатно эту дату не получить. Придется сначала выбрать все ссылки, обработать их программно в цикле, и только потом накладывать отборы, что сильно бьет по производительности отчетов.

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

Дату создания объекта можно попробовать найти по записям в Журнале регистрации (ЖР). Проанализируем этот подход с помощью кода:


Фильтр = Новый Структура("Событие,Метаданные", "_$Data$_.New", Метаданные.Справочники.Номенклатура);
ТЗ = Новый ТаблицаЗначений;
ВыгрузитьЖурналРегистрации(ТЗ, Фильтр, "Данные, Дата", , 10000);

Минусы решения:

  1. Чтение большого Журнала регистрации может надолго "повесить" систему.
  2. Если база была восстановлена из копии с обрезкой журнала или ЖР регулярно очищается для экономии места, данные будут безвозвратно утеряны — вы просто не найдете момент создания старых элементов. Чтобы сохранить важные сведения перед регламентной очисткой, можно настроить автоматическое архивирование и тестирование баз 1С по расписанию.

Способ 3: Подсистема "Версионирование объектов" (из БСП)

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


ВЫБРАТЬ ПЕРВЫЕ 1 
    ВерсииОбъектов.ВерсияОбъекта КАК ВерсияОбъекта, 
    ВерсииОбъектов.ДатаВерсии КАК ДатаВерсии 
ИЗ 
    РегистрСведений.ВерсииОбъектов КАК ВерсииОбъектов 
ГДЕ
    ВерсииОбъектов.Объект = &СсылкаНаОбъект
УПОРЯДОЧИТЬ ПО 
    ДатаВерсии ВОЗРАСТАНИЕ

Для СКД можно составить более сложный запрос, соединив целевой справочник с регистром сведений по условию НомерВерсии = 1, что позволит делать полноценные отборы прямо в отчете (например, получать товары-новинки за последние 30 дней).

Способ 4: Механизм "История данных" (рекомендуемое решение)

Платформа 1С:Предприятие (начиная с версии 8.3.11) предоставляет встроенный механизм История данных. Это более современный и надежный подход по сравнению с самописными регистрами или выгрузками из ЖР.

Выясним причины, почему этот вариант считается лучшим:

  1. Отсутствие изменений конфигурации: Включать сохранение истории можно программно средствами встроенного языка в пользовательском режиме, не снимая конфигурацию с поддержки.
  2. Точность данных: При записи нового объекта платформа автоматически создает первую версию в скрытых системных таблицах (с пометкой "Добавление (+)"). Система железно фиксирует реальную дату, время и автора транзакции.
  3. К данным истории можно обращаться программно и строить на их основе логику.

Ограничения механизма: Важно учитывать, что стандартный механизм истории данных не переносится при обменах через узлы распределенной информационной базы (РИБ). Если элемент был создан в главном узле базы, в подчиненном узле история (и системная дата его создания) может быть недоступна или будет отображать дату первого обмена.

Альтернативный вариант: Свой Регистр сведений

Если задача не разовая, а ни один из типовых механизмов (версионирование или история данных) использовать нельзя, разработчики часто применяют следующий паттерн. Создается отдельный независимый Регистр сведений, куда через подписку на событие ПриЗаписи (проверяя Объект.ЭтоНовый() или отсутствие записи в регистре) пишется дата. Для уже существующих объектов этот регистр заполняется единоразовой обработкой, которая извлекает приблизительные даты создания из их GUID (описано в Способе 1). Для автоматизации подобного подхода можно использовать готовый механизм для хронологического хранения данных справочников в регистрах сведений.

← На главную