Механизм "конвертация данных версии 2.x" с использованием обработки "Универсальный обмен данными в формате XML" не предоставляет "из коробки" возможность передавать в сообщениях информации о непосредственном удалении объектов или записей регистров, сообщения типа "Удаление объетка" и удаления из независимого регистра просто пропускаются. В случае ссылочных объектов, проблем обычно не возникает, так как информация о пометке на удаление чаще всего уже передается в другой узел, до того как объект будет удален. Но когда удаляется независимый регистр, в узел приемник информация об этом никак не попадает.
И если вдруг понадобилось "просто добавить в план обмена и правила обмена этот простенький регистр который есть в обеих конфигурациях" разработчик с удивлением обнаруживает что новые записи успешно переносятся а вот удаленные записи из регистрации узла успешо исчезают, но даже и не думают удалятся в базе узла приемника. Что требует от разработчика активно "шевелить мозгами" срочно придымувать "костыли" и всячески старатся не сорвать сроки сдачи, казалось такой простейшей задачи.
Делюсь со всеми знакомыми с механизмами КД своей реализацией решения этой задачи, надеюсь кому нибудь это сэкономит пару часов работы:
1. В правило конвертации объекта нашего регистра я добавил свойство передаваемое в параметр "ЭтоУдаление" :
И неболшой код проверяющий есть ли входящие данные и такое свойство в них.
2. В коде перед вызовом метода "ОбработкаОбмена.ВыполнитьВыгрузку()" я добавил строчку кода:
ОбработкаОбмена.Параметры.Вставить("УзелПолучатель",УзелПолучатель);
Без этот я никак не смог решить эту задачу .
Важно — чтобы параметра с таким именем не было в параметрах определенных в самих правилах в XML файле, иначе он будет затерт при инициализации обработки.
3. В правила обмена добавляется обработчик "Перед выгрузкой данных", который выбирает из узла регистрации с удалением интересующих нас записей:
МетаРег = Метаданные.РегистрыСведений.НАШ_РЕГИСТР;
Узел = Параметры.УзелПолучатель;
Выборка = ПланыОбмена.ВыбратьИзменения(Узел,Узел.НомерОтправленного,МетаРег);
УдаляемыеЗаписи = Новый ТаблицаЗначений;
УдаляемыеЗаписи.Колонки.Добавить("Активность");
УдаляемыеЗаписи.Колонки.Добавить("Период",Новый ОписаниеТипов("Дата"));
Для Каждого Рекв Из МетаРег.Измерения Цикл
УдаляемыеЗаписи.Колонки.Добавить(Рекв.Имя,Рекв.Тип);
КонецЦикла;
Для Каждого Рекв Из МетаРег.Ресурсы Цикл
УдаляемыеЗаписи.Колонки.Добавить(Рекв.Имя,Рекв.Тип);
КонецЦикла;
Для Каждого Рекв Из МетаРег.Реквизиты Цикл
УдаляемыеЗаписи.Колонки.Добавить(Рекв.Имя,Рекв.Тип);
КонецЦикла;
УдаляемаяЗапись = УдаляемыеЗаписи.Добавить();
УдаляемаяЗапись.Активность = Ложь;
Параметры = Новый СТруктура("Удаление",Истина);
Пока Выборка.Следующий() Цикл
Запись = Выборка.Получить();
Для Каждого ЭлОтб Из Запись.Отбор Цикл
Имя = ЭлОтб.Имя;
УдаляемаяЗапись[Имя] = ЭлОтб.Значение;
КОнецЦикла;
Запись.Прочитать();
Если Запись.Количество()=0 Тогда // Это удаление
ВыгрузитьПоПравилу(УдаляемаяЗапись,,Параметры,,"НАШ_РЕГИСТР");
КОнецЕсли;
КонецЦикла;
4. В ПКО нашего регистра добавил обработчик "После загрузки"
Если ПараметрыОбъекта <> Undefined Тогда
ЭтоУдаление = ПараметрыОбъекта.ПОлучить("ЭтоУдаление");
Если ЭтоУдаление=Истина Тогда
Отказ = Истина;
НЗ = РегистрыСведений.ТоварыВАкции.СоздатьМенеджерЗаписи();
ЗаполнитьЗначенияСвойств(НЗ,Объект);
НЗ.Прочитать();
Если НЗ.Выбран() Тогда
НЗ.Удалить();
КонецЕсли;
КонецЕсли;
КонецЕсли;
и НАШ_РЕГИСТР успешно начал удалятся в узле приемнике вместе с удалением в узле источнике.
Данный метод после небольшой доработки можно применить не только к независимым регистрам, но и к любым другим объектам конфигурации.
Странно конечно. Когда удаляется набор записей РС то в плане обмена эта запись все равно регистрируется. по полям основного отбора. и при выгрузке выгружается пустой набор записей с полями отбора. когда приходит в другую базу то там должен создаваться набор записей по этим полям и записываться. а все мы знаем, что если создать набор записей, установить отборы и записать его. то он затрет все записи в РС по этим отборам. почему у вас такое не происходило трудно сказать. Но в теории должно так работать.
(1)
Обработка «Универсальный обмен данными в формате XML» пропускает записи удаления и пустые записи регистров, и они не попадают в узел получатель ( в другую базу).
Можно конечно изменить алгоритмы в обработке, но это уже другое решение этой же проблемы.
(2)Ясно. Эта обработка на мой взгляд вообще предназначена для одноразового переноса данных, а не для постоянных обменов между базами. Обмены написаны с помощью этой обработки имеют большой недостаток, так как не ходят номера сообщений и нету подтверждения, что отправленные данные все приняты и обмен прошел удачно.
Я имел горький опыт когда программист сделал такой обмен между 2мя базами, даже придумал какой то самописный механизм с номерами сообщений (правда он норм не работа). В итоге он уволился, а обмен так норм и не работал. Пришлось все переделывать. А причина всего этого была в том, что ему было лень разобраться как сделать онлайн обмен с помощью БСП.
(3) Номера сообщений отправляются и принимаются через другие «костыли» — а за «переписывать всё» клиент совсем не готов платить если всё вдруг работает стабильно и без БСП. Я же не «Робин гуд» от 1С )).
Подскажите, вот я пытаюсь реализовать Вашу разработку для обмена между ЗУП-СУМД. У меня проблема с пунктом 2 (скрины приложила). Я уже писала по-разному:
но увы ошибка не исчезает. Что я не так делаю?? Вот полный код этого пункта:
Показать
(5) так же попробовала так:
(6)
Извините что так долго, не заходил на сайт всё это время.
1. Можете ли вы проверить в XML файле есть ли соответствующие записи ?
2. Реализован в правилах обработчик «После загрузки» ? — Именно он и удаляет эти записи.
А что за зверь typesIsStructure? никак не могу найти описание. 🙁 А то ошибка выскакивает, а я не могу понять в чем дело.