Регистрация изменений объектов для выгрузки (версионирование)
Стояла задача разработать выгрузку в базу на Oracle, в общем, не между 1С базами. Представляю, как реализовал регистрацию изменений с помощью подписок на события.
- Описание
- Подробнее
Описание
Принцип работы по выгрузке изменений следующий. Первая выгрузка идет для всех объектов в базе, без фильтров. Далее cнекоторой периодичностью запускается выгрузка объектов из базы. При этом выгружаются только объекты, для которых есть строка в регистре мИзмененныеОбъекты. Данный регистр выступает здесь в качестве фильтра. По окончании выгрузки регистр очищается.
Просчитаем все варианты действий над объектами конфигурации, и что мы будем записывать при этом в регистр. Могут быть три вида операций над объектами в базе: 1.добавлен 2.изменен 3.удален.
Теперь считаем, что мы будем записывать в регистр:
Объект существовал перед очисткой регистра? | Действия над объектом за прошедший период | Пишем в регистр по итогам |
1.Cуществовал | Изменен | Изменен |
2.Существовал | Удален | Удален |
3.Существовал | Изменен, Удален | Удален |
4.Не существовал | Добавлен | Добавлен |
5.Не существовал | Добавлен, Изменен | Добавлен |
6.Не существовал | Добавлен, Удален | Удаляем запись «Добавлен» |
7.Не существовал | Добавлен, Изменен,Удален | Удаляем запись «Изменен» |
В двух последних случаях 6. и 7. необходимо очистить регистр, т.к. в базе, куда мы собираемся выгружать данные, нет данных объектов. Соответственно, эта база и знать ничего о них не должна.
Создаем регистр, разреза «строкаУИД» нам достаточно, сделаем его измерением. Все остальное добавим в ресурсы.

Поле «Ссылка» в его 1с-овском представлении нам не нужно, я добавил его временно на этапе разработки.
Как ясно из назначения регистра, нам необходима запись об удаленных объектах конфигурации . Т. е. нам нужна ситуация, когда запись в регистре есть, хотя объекта уже нет. Поэтому ссылочные типы данных для измерений и ресурсов нам не подходят. Если сделать, например, поле «Ссылка» ссылочным(каламбур 🙂 ), при удалении объекта пользователем система запретит это сделать. Контроль ссылочной целостности никто не отменял. Поэтому, поступаем здесь единственно возможным образом — делаем все поля строковыми.

Далее добавляем подписки на события, у меня для справочников и документов получилось 4 подписки:

Процедура мСправочникиИзмененияПередЗаписью(Источник, Отказ) Экспорт
Источник.ДополнительныеСвойства.Вставить(«Новый», Источник.ЭтоНовый());
КонецПроцедуры
Процедура мДокументыИзмененияПередЗаписью(Источник, Отказ, РежимЗаписи, РежимПроведения) Экспорт
Источник.ДополнительныеСвойства.Вставить(«Новый», Источник.ЭтоНовый());
КонецПроцедуры
Процедура мПриЗаписи(Источник, Отказ) Экспорт
НазваниеОбъекта = СокрЛП(Источник.Метаданные().ПолноеИмя());
РегИзмененныеОбъекты=РегистрыСведений.мИзмененныеОбъекты.СоздатьМенеджерЗаписи();
РегИзмененныеОбъекты.Название=НазваниеОбъекта;
РегИзмененныеОбъекты.СтрокаУИД=Источник.Ссылка.УникальныйИдентификатор();
РегИзмененныеОбъекты.Ссылка=Источник.Ссылка;
Результат = ОбъектДобавлен(РегИзмененныеОбъекты.СтрокаУИД);
Если Результат.Количество() > 0 Тогда
Возврат;
КонецЕсли;
Если Источник.ДополнительныеСвойства.Новый = Истина Тогда
РегИзмененныеОбъекты.Статус = «Добавлен»;
ИначеЕсли Источник.ДополнительныеСвойства.Новый = Ложь Тогда
РегИзмененныеОбъекты.Статус = «Изменен»;
КонецЕсли;
РегИзмененныеОбъекты.Записать();
КонецПроцедуры
Процедура мПередУдалением(Источник, Отказ) Экспорт
НазваниеОбъекта = СокрЛП(Источник.Метаданные().ПолноеИмя());
РегИзмененныеОбъекты=РегистрыСведений.мИзмененныеОбъекты.СоздатьМенеджерЗаписи();
РегИзмененныеОбъекты.СтрокаУИД=Источник.Ссылка.УникальныйИдентификатор();
Результат = ОбъектДобавлен(РегИзмененныеОбъекты.СтрокаУИД);
Если Результат.Количество() > 0 Тогда
РегИзмененныеОбъекты.Прочитать();
РегИзмененныеОбъекты.Удалить();
Иначе
РегИзмененныеОбъекты.Название=НазваниеОбъекта;
РегИзмененныеОбъекты.СтрокаУИД=Источник.Ссылка.УникальныйИдентификатор();
РегИзмененныеОбъекты.Статус = «Удален»;
РегИзмененныеОбъекты.Ссылка=Источник.Ссылка;
РегИзмененныеОбъекты.Записать();
КонецЕсли;
КонецПроцедуры
Функция ОбъектДобавлен(УИД)
Запрос = Новый Запрос;
Запрос.Текст =
«ВЫБРАТЬ
| ЕСТЬNULL(мИзмененныеОбъекты.СтрокаУИД, 0) КАК СтрокаУИД
|ИЗ
| РегистрСведений.мИзмененныеОбъекты КАК мИзмененныеОбъекты
|ГДЕ
| мИзмененныеОбъекты.СтрокаУИД = &СтрокаУИД
| И мИзмененныеОбъекты.Статус = «»Добавлен»»»;
Запрос.УстановитьПараметр(«СтрокаУИД», УИД);
Результат = Запрос.Выполнить().Выбрать();
Возврат Результат;
КонецФункции
Получаем в пользовательском режиме подобное:

