При работе в связке нескольких конфигураций (например, Управление торговлей 11 и Бухгалтерия предприятия 3.0) пользователи часто сталкиваются с неприятной ситуацией: документ в одной базе изменяется в результате обмена, но в Истории изменений (версионировании) эта правка не отображается. Это создает огромные сложности при расследовании инцидентов, когда данные «неожиданно» меняются, а ответственного найти невозможно. Если подобные искажения приводят к расхождениям в учете, для их быстрого выявления можно запустить автоматическое сравнение проводок между базами 1С через прямое подключение.
В этой статье мы подробно разберем, почему стандартный механизм версионирования игнорирует загрузку данных, и как настроить систему так, чтобы каждое изменение фиксировалось в истории, даже если оно пришло через синхронизацию.
Разберем внутреннюю логику работы Библиотеки стандартных подсистем (БСП), которая отвечает за версионирование в большинстве современных конфигураций. Основная причина отсутствия записей кроется в оптимизации производительности. Проанализируем типичный сценарий: при обмене данными программный код устанавливает признак ОбменДанными.Загрузка = Истина. Это дает платформе сигнал не выполнять лишние проверки и обработчики, чтобы загрузка тысяч документов прошла быстрее.
Подписки на события, которые отвечают за запись версии объекта, в первую очередь проверяют этот флаг. Если он установлен, процедура просто прекращает выполнение (Возврат), и версия не создается. С точки зрения системы это оправдано: если в базе-источнике версия уже создана, зачем дублировать ее в базе-приемнике при каждом обмене, нагружая сервер? Однако для аудита данных это становится «слепой зоной». Для прямой передачи уже сформированной истории между базами можно использовать обработку для переноса версий объектов БСП.
Прежде чем приступать к написанию кода, рассмотрим возможность перехода на штатный механизм платформы 1С:Предприятие 8.3.11 и выше — История данных. В отличие от БСП-шного версионирования, этот механизм встроен на уровне ядра платформы.
Посмотрим на настройки метаданных любого объекта (например, документа РеализацияТоваровУслуг). В свойствах есть параметр Обновлять историю данных при загрузке. Рассмотрим его значения:
ОбменДанными.Загрузка = Истина.Важный нюанс: Платформенная история данных и версионирование БСП — это разные подсистемы. Если вы включите платформенную историю, записи не появятся в привычном отчете «История изменений» БСП. Вам придется использовать стандартную форму платформы для просмотра истории. Для переноса накопленных данных между этими подсистемами можно использовать инструмент для перехода с платформенного механизма истории данных на версионирование БСП.
Если нам необходимо, чтобы версии продолжали записываться именно в стандартный журнал БСП, проанализируем, как можно «обмануть» систему. В БСП предусмотрено специальное дополнительное свойство объекта, которое управляет записью версии.
Рассмотрим по шагам, как реализовать это через расширение:
1. Создадим расширение и добавим в него документ, историю которого нужно сохранять при обмене.
2. Нам необходимо перехватить событие ПередЗаписью. Проанализируем ситуацию: нам нужно программно установить свойство ПропуститьЗаписьВерсииОбъекта в значение Ложь, чтобы подписки БСП проигнорировали факт загрузки.
Пример кода в расширении для модуля объекта или через подписку на событие:
Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
// Проверяем, идет ли загрузка данных через обмен
Если ЭтотОбъект.ОбменДанными.Загрузка Тогда
// Принудительно разрешаем версионирование для этого объекта
ЭтотОбъект.ДополнительныеСвойства.Вставить("ПропуститьЗаписьВерсииОбъекта", Ложь);
// Дополнительно можно пометить в комментарии, что изменение пришло из обмена
// Это поможет потом быстро фильтровать версии
КонецЕсли;
КонецПроцедуры
3. Этот код заставит стандартную подписку БСП ВерсионированиеОбъектовСобытия.ЗаписатьВерсиюОбъекта отработать в штатном режиме, несмотря на установленный флаг загрузки.
Если задача стоит шире и нужно включить версионирование для всех объектов обмена, проанализируем общий модуль ОбменДаннымиXDTO. В нем происходит разбор входящих данных и установка свойств объектов.
Найдем место, где устанавливается свойство ПропуститьЗаписьВерсииОбъекта. Обычно система принудительно ставит его в Истина при инициализации обмена. Если через расширение переопределить этот момент, мы получим историю по всем документам сразу. Однако будьте осторожны: это может значительно замедлить процесс синхронизации.
Прежде чем внедрять эти изменения, разберем, к чему это может привести в высоконагруженных системах:
IndexData и регистр сведений ВерсииОбъектов начнут расти очень быстро. Каждая синхронизация будет создавать новую «порцию» данных.Чтобы не «положить» сервер, рекомендуем внедрять версионирование при обмене избирательно:
— Включайте запись версий только для критически важных документов (например, ЗаказКлиента или РеализацияТоваровУслуг). Для справочников или мелких корректировок это чаще всего не требуется.
— Настройте регламентное задание Очистка устаревших версий объектов. В БСП это делается в разделе Администрирование — Общие настройки — История изменений. Установите срок хранения, например, не более 3 месяцев для документов, участвующих в частом обмене.
— Рассмотрите возможность использования Журнала регистрации как альтернативы. Хотя он не показывает «что именно» изменилось (состав полей), он четко фиксирует событие записи от имени пользователя «Обмен», что уже является серьезным аргументом в спорах с пользователями.
Таким образом, мы выяснили, что отсутствие истории при обмене — это не ошибка, а заложенное поведение системы для экономии ресурсов. Использование дополнительных свойств ДополнительныеСвойства.Вставить("ПропуститьЗаписьВерсииОбъекта", Ложь) является самым корректным и безопасным способом вернуть прозрачность изменений в вашу базу 1С.