Как предотвратить создание лишних версий в механизме «История данных» 1С, если данные объекта не изменились?

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

Механизм ИсторияДанных, появившийся в платформе 1С:Предприятие 8.3, значительно упростил задачу логирования изменений в системе. Однако разработчики часто сталкиваются с проблемой: при каждой записи объекта (даже если пользователь просто нажал «Записать», ничего не меняя) платформа создает новую запись в истории. Это приводит к неоправданному росту объема базы данных и затрудняет анализ реальных изменений. Разберем подробно, как решить эту задачу и оптимизировать работу механизма.

Проблема «пустых» записей и эволюция платформы

В ранних версиях платформы (до 8.3.15) механизм ИсторияДанных был довольно жестким: он фиксировал сам факт записи объекта. Даже если данные внутри документа или справочника оставались идентичными предыдущей версии, платформа все равно создавала техническую запись о версии. Хотя 1С заявляет, что хранит только «дельту» (разницу), наличие сотен идентичных записей все равно создает нагрузку на индексы и таблицы истории.

Проанализируем ситуацию: начиная с версии платформы 8.3.15, разработчикам дали в руки мощный инструмент — специальные обработчики в модуле менеджера объекта. Теперь мы можем программно управлять процессом сохранения истории.

Решение через программные обработчики событий

Для того чтобы внедрить выборочную запись версий, нам необходимо обратиться к модулю менеджера интересующего нас объекта (например, справочника или документа). Рассмотрим подробнее ключевой обработчик ПередЗаписьюИсторииДанных. Он вызывается перед тем, как данные будут помещены в очередь (стек) истории данных.

Рассмотрим алгоритм действий в этом обработчике:

  1. Получаем текущие данные объекта, которые платформа собирается записать.
  2. Извлекаем последнюю существующую версию объекта из истории данных.
  3. Сравниваем значимые реквизиты и табличные части.
  4. Если изменений не обнаружено, устанавливаем параметр Отказ в значение Истина.

Посмотрим на пример реализации такого кода в модуле менеджера:


Процедура ПередЗаписьюИсторииДанных(МетаданныеОбъекта, ПараметрыЗаписи, Отказ)
	
	// Проверяем, включено ли вообще версионирование для этого вызова
	Если ПараметрыЗаписи.ДополнительныеСвойства.Свойство("ТолькоТехническаяЗапись") Тогда
		Возврат;
	КонецЕсли;

	// Логика сравнения данных
	Если ДанныеОбъектаНеИзменились(ПараметрыЗаписи) Тогда
		// Отменяем запись версии, если значимых изменений нет
		Отказ = Истина;
	КонецЕсли;

КонецПроцедуры

Использование свойства ПараметрыЗаписиИсторииДанных.Отказ позволяет гибко управлять хранилищем. Выясним причину, почему это важно: это не только экономит место, но и делает отчет по истории данных (стандартную форму сравнения версий) более «чистым» для конечного пользователя, убирая из него бессмысленные записи «Записан без изменений».

Сравнение данных: как сделать это эффективно

Для сравнения текущего объекта с предыдущей версией можно использовать разные подходы. Самый простой, но трудоемкий — перебор всех реквизитов. Более продвинутый метод — вычисление хеш-суммы (MD5 или SHA) от данных объекта. Мы можем собрать значимые данные в структуру, преобразовать её в JSON или XML, и сравнить хеши новой и старой версии.

Проанализируем работу с предыдущими версиями через встроенный язык:


// Пример получения последней версии для сравнения
Версии = ИсторияДанных.ВыбратьПоследнюю(СсылкаНаОбъект);
Если Версии.Следующий() Тогда
    ПоследниеДанные = Версии.Данные;
    // Здесь выполняем сравнение с текущим объектом
КонецЕсли;

Важно помнить, что ИсторияДанных.ВыбратьПоследнюю() возвращает данные в том виде, в котором они сохранены в истории. При сравнении учитывайте, что некоторые технические поля (например, ВерсияДанных самого объекта) могут меняться при каждой записи, даже если бизнес-данные остались прежними. Исключайте их из алгоритма сравнения.

Интеграция с БСП (Библиотека стандартных подсистем)

Если ваша конфигурация построена на базе БСП (версии 3.1.5 и выше), разберем приятную новость: разработчики БСП уже интегрировали платформенный механизм ИсторияДанных в подсистему «Версионирование объектов». Теперь БСП умеет:

Если вы используете современную БСП, вам достаточно включить флаг «Версионировать при записи» в настройках программы, и система сама позаботится о том, чтобы лишние версии не создавались. Это избавляет от необходимости писать код в каждом модуле менеджера вручную.

Особенности фоновой обработки и «стека» истории

Разберем важный технический нюанс, который часто вызывает путаницу — так называемый «интервал 20 дней». В документации 1С упоминается, что данные в истории могут обрабатываться с задержкой. Проанализируем, как это работает:

Запись в историю происходит асинхронно. Когда объект записывается, данные сначала попадают в специальную служебную таблицу (стек). Затем регламентное задание Обновление истории данных (платформенное) обрабатывает этот стек, вычисляет разницу (дельту) и переносит данные в постоянное хранилище. 20 дней — это рекомендуемый максимальный срок нахождения данных в этом промежуточном стеке. Сами же версии после обработки хранятся столько, сколько нужно разработчику.

Если вы заметили, что история данных «тормозит» или версии появляются не сразу, проверьте работу регламентных заданий в консоли администрирования. Без работающего задания Обновление истории данных механизм не будет функционировать полноценно.

Преимущества платформенного механизма перед «самописным» логированием

Выясним, почему стоит переходить на ИсторияДанных, несмотря на описанные сложности с лишними записями:

  1. Поддержка Регистров Сведений: В отличие от старых методов БСП, платформа позволяет версионировать независимые регистры сведений. Это критично для истории цен, настроек или кадровых данных.
  2. Скорость работы: Основная транзакция записи объекта не блокируется процессом формирования версии, так как расчет «дельты» вынесен в фоновое задание.
  3. Безопасность (RLS): Механизм автоматически учитывает права доступа. Пользователь не увидит в истории изменения полей, к которым у него нет доступа в текущем сеансе.
  4. Экономия места: Хранение бинарных разниц (deltas) гораздо эффективнее, чем хранение полных копий объектов в формате XML в регистрах сведений (как это делалось раньше).

Подводя итог, можно сказать: чтобы эффективно использовать ИсторияДанных и экономить место в базе, обязательно используйте платформу версии 8.3.15 и выше. Используйте обработчик ПередЗаписьюИсторииДанных для программной отсечки пустых изменений или доверьте эту работу современным механизмам БСП. Это позволит вам сохранить только действительно важную информацию об изменениях в системе.

← На главную