В типовых конфигурациях есть замечательный механизм обмена по правилам через COM-соединение. Объекты по одному передаются из базы-источника в базу-приемник, подключенную через COM. В результате не требуется промежуточный файл обмена, иногда большой и процесс обмена более контролируемый. Тем не менее, типовой механизм можно улучшить и добиться, чтобы, как только объект передавался в базу-получатель, сразу же бы удалялась и регистрация изменений для базы-получателя. Несколько строк кода приносят волшебный эффект!
Улучшение позволяет принести много положительных эффектов в обмены через COM:
Сначала я беспокоился, что обмен по COM-соединению реализован через выгрузку во временный файл обмена. Но, к счастью, передача идет по одному объекту.
Изменения нужно вносить в обработку ОбменДаннымиXML: в процедуру ВыполнитьВыгрузкуИзмененныхДанныхДляУзлаОбмена в цикл по перебору изменений. Добавляемый код выделен жирным курсивом:
ВыборкаИзменений = ПланыОбмена.ВыбратьИзменения(ЗаписьСообщения.Получатель, ЗаписьСообщения.НомерСообщения, МассивВыгружаемыхМетаданных);
Пока ВыборкаИзменений.Следующий() Цикл
//Осипов - сразу удаляем регистрацию измений, отмечаем что передали...
Если НепосредственноеЧтениеВИБПриемнике Тогда //Типовой флаг. Обозначает обмен через COM
ПланыОбмена.УдалитьРегистрациюИзменений(ЗаписьСообщения.Получатель, Данные);
КонецЕсли;
Если ИспользоватьТранзакцииПриВыгрузкеДляПлановОбмена
И (КоличествоЭлементовВТранзакцииПриВыгрузкеДляПлановОбмена > 0)
И (КоличествоНайденныхДляЗаписиОбъектов = КоличествоЭлементовВТранзакцииПриВыгрузкеДляПлановОбмена) Тогда
// промежуточную транзакцию закрываем и открываем новую
ЗафиксироватьТранзакцию();
НачатьТранзакцию();
КоличествоНайденныхДляЗаписиОбъектов = 0;
КонецЕсли;
КонецЦикла;
Важно! Изменения нужно добавить в код обработок обеих базах. Почему? Обычно обмен двухсторонний.
Обмен происходит в процедуре ПроцедурыОбменаДанными. ВыполнитьОбменДаннымиЧерезComСоединение.
Сначала происходит загрузка из базы-приемника, при этом вызывается экземпляр обработки обмена из базы-приемника ОбработкаОбменаПриемника.ВыполнитьВыгрузку. Поэтому важно, чтобы в базе-приемнике обработка тоже была пропатчена аналогичным образом.
Затем идет выгрузка из базы-отправителя, используется уже обработка из базы-отправителя
ВыполнитьВыгрузку.
В журнале регистрации базы-получателя видим, что пришел документ РОТ 3006:
В мониторе обмена в базе-отправителе видим, что объект зарегистрирован:
Теперь выполним код по удалению, посмотрим монитор обмена, однако вместо ожидаемого удаления документа РОТ из зарегистрированных изменений увидим ошибку:
Дело в том, что в настройке обмена указан размер транзакции – 200 объектов:
Поэтому нужно подождать буквально несколько секунд, транзакция завершится и мы увидим, что документ исчез из зарегистрированных изменений.
Еще одно свидетельство, до обмена количество зарегистрированных изменений было большим:
После обмена добавились только свежие изменения (в тестовой базе активно работают пользователи):
Эта статья замечательно показывает, как минимальное, точечное вмешательство, может привести к потрясающему эффекту. Как тут не вспомнить анекдот про сантехника, который приходит, тыкает пальцем и берет за это 1000 рублей, объясняя – сам тык стоит 1 рубль, но время, в течении которого я изучал этот тык стоит 999 рублей.
Сначала я обсуждал эту проблему на инфостарте в контексте:
1С:Предприятие
8.1 (8.1.15.14)
"Управление торговлей", редакция 10.3 (10.3.7.9)
В УТ настроен обмен с Розницей по правилам обмена через COM-соединение.
Хочу, чтобы при выгузке из УТ в Розницу (из базы-отправителя в
базу-получатель), когда документ передан в базу-получатель и зарегистрирован в
отложенных движениях, чтобы он удалялся из плана-обмена базы-отправителя (УТ).
Т.к. иногда выгрузка не доходит до конца, или же не получает подтверждения,
чтобы данные повторно не гонялись.
К сожалению, никто мне там не подсказал этого замечательного решения, пришлось до всего додумываться самому.