Порой при обмене данных получается ситуация когда из удаленного узла необходимо удалить определенные объекты и сделать это непосредственно очень проблематично. Возможные варианты решения такой проблемы рассматриваются в данной статье. Необходимо заметить, что в целом рассматривается ситуация с распределенными информационными базами (РИБ).
Конкретная ситуация: по некоторым причинам необходимо по обмену (а если бы был прямой или удаленный доступ к удаленной базе, то вопрос бы просто отсутствовал) удалить некоторый объект из удаленной базы данных (БД).
Вариант 1. Использование объекта УдалениеОбъекта. Суть – находим ссылку на объект и по обмену посылаем в удаленную базу. Что-то вроде этого:
Узел = ПланыОбмена.ИмяНужногоПланОбмена.НайтиПоКоду(«02»);
Ссылка=Справочники.Номенклатура.НайтиПоКоду(«000000026»);
Удаление = Новый УдалениеОбъекта(Ссылка);
Удаление.Записать();
ПланыОбмена.ЗарегистрироватьИзменения(Узел, Удаление);
Но с данным кодом возникнет следующая проблема – при наличии строки Удаление.Записать(); будет удален объект в текущей базе (а это не нужно). При отсутствии строки Удаление.Записать(); в удаленной базе данные останутся, то есть задача не будет решена.
Вот если в текущей БД нет такого объекта, то можно использовать следующее:
Узел = ПланыОбмена.ИмяНужногоПланОбмена.НайтиПоКоду(«02»);
Ссылка=Справочники.Номенклатура.ПолучитьСсылку(Новый УникальныйИдентификатор(«de18c53b-c3a7-11e2-acf9-001966ee0859»));
Удаление = Новый УдалениеОбъекта(Ссылка);
Удаление.Записать();
ПланыОбмена.ЗарегистрироватьИзменения(Узел, Удаление);
Примечание: в 1С8 следует различать УникальныйИдентификатор (UUID) и глобальный уникальный идентификатор (GUID). При необходимости в сети можно найти код преобразования UUID в GUID и обратно.
В итоге получаем, что данный вариант подходит для случаев когда в удаленном узле необходимо удалить объекты, которые отсутсвуют в текущем узле.
Необходимо учесть ситуацию, что в удаленном узле объект присутствует в других объектах (то есть, удалили номенклатуру «Валенки», а этот элемент присутствует в документах удаленного узла). Тут уже надо думать либо о восстановлении элемента в текущей базе либо предусмотреть замену удаляемого элемента на другой элемент.
Под задачу удаления объектов, которые отсутствуют в текущей БД весьма подходит //infostart.ru/public/173851/ (Регистрация на узлах обмена или перерегистрация Ссылок.)
Но зачастую требуется удалить объект в удаленной БД, но в текущей БД он должен остаться.
Вариант 2. Муторный и не правильный.
Использовать вариант 1, отправить по обмену, получить подтверждение, восстановить элементы и предотвратить отправку восстановленных элементов в удаленный узел.
Вариант 3. Требуется вносить изменения в конфигуратор.
В модуле плана обмена в обработчике ПриОтправкеДанныхПодчиненному и/или ПриОтправкеДанныхГлавному отлавливаем нужные объекты и для них передаём Удаление.
Например:
Процедура ПриОтправкеДанныхПодчиненному(ЭлементДанных, ОтправкаЭлемента, СозданиеНачальногоОбраза)
Если ЭтоНужныйОбъект Тогда
ОтправкаЭлемента = ОтправкаЭлементаДанных.Удалить;
КонецЕсли;
КонецПроцедуры
Примечание: для универсальности возможен такой вариант. В план обмена вводим реквизит ВыполняемыйКод, тип строка неограниченной длины. В этот реквизит оперативно вставляется неоходимый программный код. Опять же следует учесть что процедура ПриОтправкеДанныхПодчиненному и ПриОтправкеДанныхГлавному срабатывает для КАЖДОГО отправляемого элемента.
Процедура ПриОтправкеДанныхПодчиненному(ЭлементДанных, ОтправкаЭлемента, СозданиеНачальногоОбраза)
Попытка
Выполнить(ВыполняемыйКод);
Исключение
КонецПопытки;
КонецПроцедуры
Вариант 4. Самостоятельно формировать файл XML.
Источник http://www.cyberforum.ru/1c/thread396358-page4.html
План обмена использую только для регистрации изменений, затем своей обработкой выгружаю выборку в XML по алгоритму из книги Радченко «Практическое пособие разработчика» (довольно просто и гибко получается).
Для передачи удаления объекта не требуется его регистрировать — достаточно выгрузить соответствющую «команду» в XML.
Если Не ВыгружаемыйОбъект.ОтражатьВБухгалтерскомУчете Тогда
ВыгружаемыйОбъект = Новый УдалениеОбъекта(ВыгружаемыйОбъект.Ссылка);
КонецЕсли;
… и затем собственно сама выгрузка
ЗаписатьXML(ЗаписьXML, ВыгружаемыйОбъект);
А теперь подводные камни.
Если вы желаете удалить некоторый объект, то помните, что на этот объект могут быть завязаны и другие объекты в базе данных. Например – подчиненные справочники, движения документа, независимые регистры сведений и т.д., то есть те объекты которые не имеют смысла при отсутствии удаляемого объекта. Часть объектов можно найти достаточно просто (подчиненные справочники, движения документа, регистры сведений где объект является ведущим измерением), а вот некоторые достаточно проблематично, так как необходимо просматривать каждый объект и смотреть в коде какие изменения он вносит в БД при записи и/или проведении.
И последний совет. Если расхождения в удаленной БД достаточно велики по сравнению с текущей БД, то гораздо быстрее и проще заново создать БД удаленного узла.
Причины купить
Достоинства
Сравнение версий
В БП 3.0 добавил следующий код в правила обмена для удаления объета (обработчик события — перед обработкой). Объект остается в центральной и удаляется в перефирийной базе.
1. Для удаления объектов:
2. Для удаления записей регистров: