Восстановление номенклатуры из версий. БСП. Облака
При загрузке картинок номенклатуры в обработке загрузке была допущена ошибка, в результате слетели категория и группа номенклатура у всех позиций, по которым была загружена картинка.
Слава богу, было включено версионирование. Решено было восстанавливать из версий.
Все ошибочные позиции можно было отобрать по категории. Группы пользователи уже пытались восстановить вручную, а про то, что слетели категории еще не знали.
Время правильных версий было до 4 марта 2023.
В итоге получился такой скрипт:
З = Новый Запрос( "ВЫБРАТЬ | Т.Ссылка КАК Ссылка |ИЗ | Справочник.Номенклатура КАК Т |ГДЕ | НЕ Т.ЭтоГруппа | И Т.КатегорияНоменклатуры.Наименование = ""Розетки"""); Выборка = З.Выполнить().Выбрать(); Пока Выборка.Следующий() Цикл ТекСсылка = Выборка.Ссылка; Сообщить(ТекСсылка); ТекРодитель = ТекСсылка.Родитель; ТекКатегорияНоменклатуры = ТекСсылка.КатегорияНоменклатуры; Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ ПЕРВЫЕ 1 | ВерсииОбъектов.НомерВерсии КАК НомерВерсии |ИЗ | РегистрСведений.ВерсииОбъектов КАК ВерсииОбъектов |ГДЕ | ВерсииОбъектов.ДатаВерсии < ДАТАВРЕМЯ(2024, 3, 4) | И ВерсииОбъектов.Объект = &Объект | |УПОРЯДОЧИТЬ ПО | ДатаВерсии УБЫВ"; Запрос.УстановитьПараметр("Объект", ТекСсылка); ВыборкаВерсий = Запрос.Выполнить().Выбрать(); Если НЕ ВыборкаВерсий.Следующий() Тогда Сообщить(" Не найдена версия: " + ТекСсылка + " !"); Продолжить; КонецЕсли; НачатьТранзакцию(); //Сообщить(ВыборкаВерсий.Количество()); //ТЗ = Запрос.Выполнить().Выгрузить(); //Для Каждого Колонка ИЗ ТЗ.Колонки Цикл // Сообщить(Колонка.имя); //КонецЦикла; НомерВерсии = ВыборкаВерсий.НомерВерсии; Попытка ВерсионированиеОбъектов.ПерейтиНаВерсиюСервер(ТекСсылка, НомерВерсии, Ложь); НовРодитель = ТекСсылка.Родитель; НовКатегорияНоменклатуры = ТекСсылка.КатегорияНоменклатуры; Исключение Сообщить(" Не удалось перейти на версию: " + НомерВерсии + ": " + ОписаниеОшибки()); ОтменитьТранзакцию(); Прервать; КонецПопытки; ОтменитьТранзакцию(); Сообщить(" Родитель: " + ТекРодитель + " -> " + НовРодитель + " Категория: " + ТекКатегорияНоменклатуры + " -> " + НовКатегорияНоменклатуры); ОбрабатываемыйОбъект = ТекСсылка.ПолучитьОбъект(); Если НовРодитель <> ТекРодитель Тогда ОбрабатываемыйОбъект.Родитель = НовРодитель; КонецЕсли; Если НовКатегорияНоменклатуры <> ТекКатегорияНоменклатуры Тогда ОбрабатываемыйОбъект.КатегорияНоменклатуры = НовКатегорияНоменклатуры; КонецЕсли; Если ОбрабатываемыйОбъект.Модифицированность() Тогда Сообщить(" восстановлено"); ОбрабатываемыйОбъект.Записать(); КонецЕсли; //Прервать; //Для отладки КонецЦикла;
Здесь используется транзакционное восстановление. Если полностью переходить на версию, потеряются добавленные картинки.
К сожалению, метод ВерсионированиеОбъектов.ВосстановитьОбъектПоXML не экспортирумый, вместо отмены транзакции можно было использовать его.
Протокол восстановления переда клиенту для ознакомления.
Я хотел было использовать обработку по восстановлению версий с инфостарта, даже скачал её, но, увы, вспомнил потому уже, что у меня облако и обработку надо передавать на аудит. Поэтому просто прогнал свой код в консоли кода, уже прошедшей аудит.
Среда: УНФ 3.0.5.145 Объем: 1 час.
«К сожалению, метод ВерсионированиеОбъектов.ВосстановитьОбъектПоXML не экспортирумый, вместо отмены транзакции можно было использовать его.»
а что мешает модуль ВерсионированиеОбъектов запихнуть в расширение и добавить в нём свою экспортную процедуру (функцию) и вызвать в ней типовую неэкспортируемую ВосстановитьОбъектПоXML()?
Процедура МояЭкспортируемая_ВосстановитьОбъектПоXML(…) Экспорт
ВосстановитьОбъектПоXML(…);
КонецПроцедуры
Я делал это на базе с разделителями, где у меня только безопасная консоль кода прошла аудит.
Так, конечно, можно, но через аудит расширения, на что не было времени.
Нужно было срочно. Поэтому как есть. Транзакционные операции на самом деле мне уже привычны — та же транзакционная печать накладных за поставщика у меня пользуется спросом, часто покупают.