С выходом платформы 1С:Предприятие 8.3.12 разработчики получили мощный встроенный инструмент — «История данных». Этот механизм позволяет отслеживать изменения объектов (кто, когда и что изменил) на уровне платформы, не прибегая к использованию сложных подсистем вроде БСП (Библиотека стандартных подсистем). Однако многие программисты сталкиваются с тем, что после включения опции в метаданных список изменений остается пустым. Проанализируем, почему это происходит и как правильно настроить систему.
Для того чтобы понять, почему история не появляется мгновенно, нам необходимо рассмотреть внутреннюю архитектуру этого механизма. Разработчики платформы спроектировали его асинхронным, чтобы минимизировать влияние на производительность при записи объектов. Процесс формирования версии состоит из двух четко разделенных этапов:
DataHistoryQueue). Этот этап выполняется платформой незаметно и очень быстро, не нагружая основную транзакцию записи.DataHistoryVersions). Только после завершения этого этапа данные становятся доступны для просмотра через стандартную команду «История изменений».Выясним причину отсутствия данных: если вы включили историю в метаданных, но не инициировали второй этап, очередь будет копиться, но отчет об изменениях останется пустым. Второй этап всегда инициируется разработчиком программно.
Для того чтобы данные переместились из очереди в хранилище, в языке 1С предусмотрен специальный менеджер МенеджерИсторииДанных. Рассмотрим основной метод, который решает проблему пустой таблицы истории:
// Пример простого вызова обновления истории
ИсторияДанных.ОбновитьИсторию();
Рассмотрим подробнее, как и где следует вызывать этот код. В реальных информационных системах нецелесообразно запускать это обновление вручную. Правильным подходом является создание регламентного задания, которое будет выполнять этот метод с определенной периодичностью (например, раз в 10–15 минут или раз в сутки, в зависимости от интенсивности работы пользователей).
Проанализируем пример кода для серверного модуля, который можно назначить обработчиком регламентного задания:
Процедура ОбновитьИсториюДанныхНаСервере() Экспорт
// Метод обрабатывает накопившуюся очередь сообщений
// Рекомендуется запускать вне транзакции
Попытка
ИсторияДанных.ОбновитьИсторию();
Исключение
ЗаписьЖурналаРегистрации("ИсторияДанных", УровеньЖурналаРегистрации.Ошибка, , ,
"Ошибка при обновлении истории: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Важно помнить: метод ОбновитьИсторию() обрабатывает данные порциями. Если в базе данных накопилось огромное количество изменений (например, после массовой обработки документов), может потребоваться несколько вызовов метода или определенное время для полной очистки очереди.
Прежде чем программный код начнет приносить пользу, проверим настройки в конфигураторе. Разберем по шагам, что должно быть включено:
Полезный совет: начиная с версии платформы 8.3.14, разработчики добавили стандартную обработку «Управление историей данных» (доступна через «Все функции» или «Функции для технического специалиста»). Она позволяет увидеть размер очереди и запустить обновление без написания кода, что очень удобно для администраторов.
Часто возникает задача вывести информацию о последнем авторе или дате изменения прямо в форму списка документов. Рассмотрим ситуацию: напрямую обращаться к таблицам истории данных в динамическом списке — плохая идея с точки зрения производительности. Платформе придется выполнять сложные соединения с системными таблицами истории при каждой прокрутке списка.
Проанализируем два способа решения этой задачи:
&НаСервере
Процедура СписокПриПолученииДанныхНаСервере(ИмяЭлемента, Настройки, Строки)
Для Каждого СтрокаСписок Из Строки Цикл
// Получаем последнюю версию объекта
ПоследняяВерсия = ИсторияДанных.ПолучитьПоследнююВерсию(СтрокаСписок.Ключ);
Если ПоследняяВерсия <> Неопределено Тогда
СтрокаСписок.Данные["АвторИзменения"] = ПоследняяВерсия.Пользователь;
СтрокаСписок.Данные["ДатаИзменения"] = ПоследняяВерсия.Дата;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
ПоследнийАвтор и ДатаПоследнегоИзменения. Тогда в списке эти данные будут отображаться мгновенно без обращения к механизму истории.Механизм «История данных» может существенно увеличить размер базы данных, если не ограничивать срок хранения версий. По умолчанию данные хранятся вечно. Посмотрим, как можно ограничить аппетиты системы программно, используя метод УстановитьНастройкиСрокаХранения():
// Установим срок хранения истории для документа "РеализацияТоваровУслуг" в 365 дней
НастройкиХранения = ИсторияДанных.ПолучитьНастройкиСрокаХранения(Метаданные.Документы.РеализацияТоваровУслуг);
НастройкиХранения.Вариант = ВариантСрокаХраненияИсторииДанных.СрокВ Днях;
НастройкиХранения.СрокВ Днях = 365;
ИсторияДанных.УстановитьНастройкиСрокаХранения(Метаданные.Документы.РеализацияТоваровУслуг, НастройкиХранения);
Таким образом, мы выяснили, что для полноценной эксплуатации «Истории данных» недостаточно просто переключить флаг в конфигураторе. Требуется комплексный подход: настройка метаданных, внедрение регламентного задания для обновления очереди и установка политик хранения данных. Следуя этим правилам, вы получите надежный инструмент аудита изменений без потери производительности системы.