В типовых конфигурациях 1С для справочников (например, «Контрагенты» или «Номенклатура») по умолчанию не предусмотрен стандартный реквизит «Дата создания». Это часто становится проблемой, когда возникает необходимость отобрать объекты, созданные за определенный период, или, как в нашем случае, перенести старые элементы в архивную группу. Рассмотрим подробно все доступные способы решения этой задачи: от программного извлечения данных из идентификатора ссылки до анализа системных логов.
Разберем самый технологичный метод. Каждый объект в 1С имеет уникальный идентификатор (GUID/UUID). Платформа 1С версии 8 при генерации нового идентификатора обычно использует алгоритм UUID версии 1, который основан на времени (time-based). Это означает, что в самом коде ссылки зашифрован момент её создания.
Проанализируем структуру такого идентификатора. Он состоит из набора шестнадцатеричных цифр, где первые группы символов отвечают за временные метки. Однако важно учитывать ограничение: этот метод сработает только в том случае, если ссылка была создана «естественным» путем в базе, а не была назначена программно или загружена из внешней системы с идентификатором версии 4 (рандомным).
Посмотрим на пример функции, которая позволяет преобразовать УникальныйИдентификатор ссылки в полноценную дату:
Функция ПолучитьДатуИзUUID(Ссылка) Экспорт
Идентификатор = Ссылка.УникальныйИдентификатор();
СтрокаUUID = СтрЗаменить(Строка(Идентификатор), "-", "");
// UUID v1 хранит время в 60-битном числе (интервалы по 100 нс с 15 октября 1582 года)
// Извлекаем части времени из соответствующих позиций строки
TimeLow = Сред(СтрокаUUID, 1, 8);
TimeMid = Сред(СтрокаUUID, 9, 4);
TimeHigh = Сред(СтрокаUUID, 13, 3); // Последние 3 цифры, так как первая (4-я) - версия UUID
// Собираем шестнадцатеричное число
HexTime = "0" + TimeHigh + TimeMid + TimeLow;
// Переводим в десятичное число (количество 100-наносекундных интервалов)
// Для этого можно использовать сторонние компоненты или написать свой конвертер HexToDec
// Ниже приведен упрощенный алгоритм для понимания логики
ЧислоИнтервалов = HexToDec(HexTime);
// Константа смещения между 1582 и 1970 годом
Смещение = 122192928000000000;
ДатаUnix = (ЧислоИнтервалов - Смещение) / 10000000;
Возврат '19700101' + ДатаUnix;
КонецФункции
Этот метод работает мгновенно и не требует дополнительных настроек базы данных. Однако помните, что если в вашей базе используется УстановитьСсылкуНового() с произвольным GUID, результат может быть неверным.
Выясним ситуацию, когда извлечь дату из UUID невозможно. В этом случае на помощь приходит Журнал регистрации. Платформа фиксирует событие «Добавление» для каждого нового объекта. Если журнал не очищался с момента начала работы базы, это самый надежный источник информации.
Проанализируем, как программно обратиться к этим данным. Мы можем использовать метод ВыгрузитьЖурналРегистрации() с фильтром по конкретной ссылке и событию. Разберем пример кода для получения даты создания одного контрагента:
Функция ПолучитьДатуСозданияИзЖР(ОбъектСсылка)
ТаблицаСобытий = Новый ТаблицаЗначений;
Отбор = Новый Структура;
Отбор.Вставить("Данные", ОбъектСсылка);
Отбор.Вставить("Событие", "_$Data$_.New"); // Событие создания нового элемента
ВыгрузитьЖурналРегистрации(ТаблицаСобытий, Отбор, "Дата", , 1);
Если ТаблицаСобытий.Количество() > 0 Тогда
Возврат ТаблицаСобытий[0].Дата;
Иначе
Возврат Неопределено;
КонецЕсли;
КонецФункции
Важный нюанс: поиск по журналу регистрации может выполняться долго, если объем логов составляет несколько гигабайт. Если вам нужно обработать тысячи контрагентов, лучше выгрузить все события создания справочника в общую таблицу один раз, а затем сопоставлять их со ссылками в памяти.
Если журнал регистрации был обрезан, а UUID не информативен, рассмотрим косвенный метод. Можно предположить, что контрагент был создан примерно в то же время, когда с ним был оформлен первый документ. Это может быть «Договор», «Заказ покупателя» или «Поступление товаров».
Разберем алгоритм поиска:
СправочникСсылка.Контрагенты.Хотя этот метод не дает 100% точности (контрагент мог быть создан за месяц до первой сделки), он часто является единственным доступным способом для старых баз.
Проверим, включена ли в вашей конфигурации подсистема «Версионирование объектов» из состава Библиотеки стандартных подсистем (БСП). Если для справочника «Контрагенты» включено хранение версий, то информация о самом первом изменении (создании) хранится в регистре сведений СведенияОВерсияхОбъектов.
Для получения даты нам достаточно найти запись с минимальным номером версии для данного объекта. Обычно версия №1 соответствует моменту создания. Дата этой версии и будет искомой датой создания элемента.
Если ваша база работает в клиент-серверном варианте под управлением Microsoft SQL Server или PostgreSQL, можно задействовать инструменты СУБД. Рассмотрим ситуацию: даже если в 1С записи в журнале регистрации удалены, в логах транзакций SQL (Transaction Log) информация о вставке строки в таблицу справочника (например, _Reference45) может сохраняться дольше.
Специалисты по базам данных могут использовать системные функции для анализа лога, такие как fn_dblog в MS SQL Server, чтобы найти момент выполнения команды INSERT для конкретной записи. Это сложный метод, требующий прав администратора сервера, но он позволяет восстановить данные даже в критических случаях.
Чтобы в будущем не прибегать к сложным вычислениям, проанализируем лучший архитектурный подход. Мы рекомендуем добавить в справочник реквизит ДатаСоздания с типом Дата.
Для автоматического заполнения этого поля выполним следующие шаги в модуле объекта:
Процедура ПередЗаписью(Отказ)
Если ЭтоНовый() Тогда
ДатаСоздания = ТекущаяДатаСеанса();
КонецЕсли;
КонецПроцедуры
Такой подход обеспечит мгновенный доступ к данным через обычные запросы, позволит легко строить отчеты и выполнять регламентные операции, такие как перенос старых контрагентов в другую группу, без нагрузки на систему.
Мы рассмотрели пять различных подходов к определению даты создания элемента. В большинстве случаев сочетание анализа UUID и Журнала регистрации дает исчерпывающий результат. Если же вы только проектируете систему, обязательно закладывайте реквизит даты создания в структуру справочников заранее.