Часто в практике программиста 1С возникает хитрая задача: необходимо сделать отчет с отбором по дате создания элемента справочника. Однако, добавить новый реквизит для хранения даты в сам справочник не представляется возможным (например, запрещено менять структуру типовой конфигурации). Разберем по шагам, как можно типовыми средствами платформы вычислить дату создания элемента в справочнике. Рассмотрим несколько практических подходов, проанализируем ситуацию и выберем наиболее оптимальный вариант.
В платформе 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) + ЧислоСек + СмещениеСтандартногоВремени + СмещениеЛетнегоВремени;
КонецФункции
Важные нюансы и ограничения данного метода:
НовыйУникальныйИдентификатор до записи объекта в базу, время в GUID будет соответствовать моменту исполнения кода, а не реальной дате появления записи.Дату создания объекта можно попробовать найти по записям в Журнале регистрации (ЖР). Проанализируем этот подход с помощью кода:
Фильтр = Новый Структура("Событие,Метаданные", "_$Data$_.New", Метаданные.Справочники.Номенклатура);
ТЗ = Новый ТаблицаЗначений;
ВыгрузитьЖурналРегистрации(ТЗ, Фильтр, "Данные, Дата", , 10000);
Минусы решения:
Если в конфигурации внедрена Библиотека стандартных подсистем и включено версионирование нужного справочника, мы можем получить дату первой версии элемента прямо в запросе. Разберем небольшой пример:
ВЫБРАТЬ ПЕРВЫЕ 1
ВерсииОбъектов.ВерсияОбъекта КАК ВерсияОбъекта,
ВерсииОбъектов.ДатаВерсии КАК ДатаВерсии
ИЗ
РегистрСведений.ВерсииОбъектов КАК ВерсииОбъектов
ГДЕ
ВерсииОбъектов.Объект = &СсылкаНаОбъект
УПОРЯДОЧИТЬ ПО
ДатаВерсии ВОЗРАСТАНИЕ
Для СКД можно составить более сложный запрос, соединив целевой справочник с регистром сведений по условию НомерВерсии = 1, что позволит делать полноценные отборы прямо в отчете (например, получать товары-новинки за последние 30 дней).
Платформа 1С:Предприятие (начиная с версии 8.3.11) предоставляет встроенный механизм История данных. Это более современный и надежный подход по сравнению с самописными регистрами или выгрузками из ЖР.
Выясним причины, почему этот вариант считается лучшим:
Ограничения механизма: Важно учитывать, что стандартный механизм истории данных не переносится при обменах через узлы распределенной информационной базы (РИБ). Если элемент был создан в главном узле базы, в подчиненном узле история (и системная дата его создания) может быть недоступна или будет отображать дату первого обмена.
Если задача не разовая, а ни один из типовых механизмов (версионирование или история данных) использовать нельзя, разработчики часто применяют следующий паттерн. Создается отдельный независимый Регистр сведений, куда через подписку на событие ПриЗаписи (проверяя Объект.ЭтоНовый() или отсутствие записи в регистре) пишется дата. Для уже существующих объектов этот регистр заполняется единоразовой обработкой, которая извлекает приблизительные даты создания из их GUID (описано в Способе 1). Для автоматизации подобного подхода можно использовать готовый механизм для хронологического хранения данных справочников в регистрах сведений.