При организации периодического обмена данными между 1С и внешними системами (например, PLM-системами или другими базами) часто возникает необходимость протоколировать изменения: фиксировать, какие именно объекты загружаются, создаются или меняют свои реквизиты. Рассмотрим, как правильно отслеживать моменты перед записью и после записи объектов при загрузке через план обмена.
Разберем частую ошибку: попытку использовать подписку на событие ОбработкаЗаполнения. Данное событие срабатывает только при интерактивном вводе на основании или при вызове метода Заполнить(). При стандартном обмене данными платформа создает объект программы и напрямую записывает в него считываемые из потока данных значения, огибая процедуру заполнения. По этой причине событие ОбработкаЗаполнения при обмене не вызывается.
Основным и наиболее корректным инструментом для отслеживания изменения данных является создание конфигурационной подписки на события ПередЗаписью или ПриЗаписи для нужных метаданных (например, СправочникОбъект.Номенклатура).
Когда платформа 1С записывает объект в рамках процедуры обмена данными, она автоматически устанавливает свойство объекта Источник.ОбменДанными.Загрузка = Истина. Это позволяет чётко отделить записи, выполняемые фоновым обменом, от ручных действий пользователей.
Разберем по шагам порядок настройки подписки:
СправочникОбъект.Номенклатура).ПередЗаписью.Проанализируем пример кода для сопоставления изменяемых реквизитов:
Процедура ПодпискаПередЗаписьюПриОбменеПередЗаписью(Источник, Отказ) Экспорт
// Проверяем, выполняется ли запись в процессе обмена данными
Если НЕ Источник.ОбменДанными.Загрузка Тогда
Возврат;
КонецЕсли;
// Если объект новый, фиксируем создание
Если Источник.ЭтоНовый() Тогда
// Логика обработки создания нового объекта
Возврат;
КонецЕсли;
// Для существующего объекта считываем его состояние из базы данных до записи
СтарыеДанные = Источник.Ссылка.ПолучитьОбъект();
Если СтарыеДанные <> Неопределено Тогда
// Сравниваем значения реквизитов
Если Источник.Наименование <> СтарыеДанные.Наименование Тогда
// Фиксируем изменение реквизита "Наименование"
КонецЕсли;
КонецЕсли;
КонецПроцедуры
В приведенном примере мы запрашиваем из базы данных исходную версию объекта с помощью Источник.Ссылка.ПолучитьОбъект(). Так как метод выполняются в процедуре ПередЗаписью, в базе данных еще сохранена предыдущая версия данных, что позволяет сравнить значения любых полей и табличных частей.
Если обмен данными происходит автоматически по расписанию под специальной служебной учетной записью (например, «Пользователь Обмена PLM»), мы можем определять факт обмена по текущему авторизованному пользователю информационной базы. Это удобно, если требуется привязать протоколирование к конкретной подсистеме или автору изменений.
В подписке на событие ПриЗаписи проверяется логин текущего пользователя (ПользователиИнформационнойБазы.ТекущийПользователь()) или значение реквизита Ответственный/Автор, если он заполняется службой обмена.
Если задача заключается исключительно в сохранении истории изменений реквизитов и сравнении версий, целесообразно рассмотреть использование штатного механизма Версионирование объектов, встроенного в типовые решения (включая УПП, ERP, КА, УТ). При включении версионирования платформа автоматически сохраняет копии объектов при каждой записи, предоставляя удобные отчеты по истории изменений без необходимости написания собственного кода.
Посмотрим на практические аспекты, с которыми сталкиваются разработчики при написании собственных логов:
E:\отчеты\ приведет к ошибке, если у службы сервера 1С (пользователя ОС usr1cv8) нет прав на создание файлов в этом каталоге.