При работе с обменом данными в 1С 8.3, особенно когда мы используем конфигурацию «Конвертация Данных 2.1» (КД 2.1) и обработку УниверсальныйОбменДаннымиXML, может возникнуть ситуация, когда вместо нескольких зарегистрированных для обмена объектов выгружается весь справочник целиком. Эта проблема является достаточно распространенной и часто связана с некорректной настройкой параметров вызова обработки обмена или самих правил конвертации. Давайте вместе разберем эту ситуацию и найдем решение.
Предположим, у нас есть свой план обмена, подписка на события, которая регистрирует изменения объектов, и мы ожидаем, что при выгрузке будут переданы только те данные, которые были зарегистрированы. Однако на практике обнаруживается, что выгружается гораздо больше данных, чем предполагалось.
В платформе 1С 8.3 для обмена данными между различными информационными базами по правилам, созданным в КД 2.1, обычно используется обработка УниверсальныйОбменДаннымиXML. Эта обработка, несмотря на свое название, вполне способна работать с зарегистрированными изменениями в Планах обмена, но для этого ей необходимо явно указать, с каким узлом обмена она должна взаимодействовать и какие данные выгружать.
В более старых конфигурациях, таких как ЗУП 2.5, могла использоваться обработка ОбменДаннымиXML. Однако в современных конфигурациях, например, в ЗУП 3.1, ее уже нет, и основной инструмент для обмена по правилам КД 2.1 — это именно УниверсальныйОбменДаннымиXML.
Давайте посмотрим на типичный пример кода, который может вызывать такую проблему (аналогичный приведенному в сообщении 4 темы):
// ... код получения правил обмена ...
ОбрО = Обработки.УниверсальныйОбменДаннымиXML.Создать();
ОбрО.ИмяФайлаПравилОбмена = ИмяФайлаПравилОбмена;
ОбрО.ИмяФайлаОбмена = ИмяФайлаСообщения;
ОбрО.ЭтоИнтерактивныйРежим = Ложь;
ОбрО.НеВыводитьНикакихИнформационныхСообщенийПользователю = Ложь;
ОбрО.ЗагрузитьПравилаОбмена();
ОбрО.ИнициализироватьПервоначальныеЗначенияПараметров();
ОбрО.ВыполнитьВыгрузку(); // Здесь происходит выгрузка
// ... далее код с ПланыОбмена.ВыбратьИзменения и ручное добавление в файл ...
В этом коде мы видим, что мы создаем экземпляр обработки УниверсальныйОбменДаннымиXML, задаем ей правила и файл выгрузки, а затем вызываем метод ВыполнитьВыгрузку(). Проблема заключается в том, что в данном фрагменте кода мы не указываем обработке УниверсальныйОбменДаннымиXML, для какого узла плана обмена ей следует выгружать данные.
Без явного указания узла обмена, обработка может:
Кроме того, в приведенном коде присутствует дублирующая логика: после вызова ОбрО.ВыполнитьВыгрузку(), вы пытаетесь самостоятельно с помощью ПланыОбмена.ВыбратьИзменения() получить зарегистрированные данные и добавить их в уже сформированный файл. Это избыточно и указывает на непонимание того, как УниверсальныйОбменДаннымиXML взаимодействует с планами обмена.
Прежде чем перейти к решению, давайте кратко вспомним, как работает механизм регистрации изменений, поскольку это основа нашего обмена:
ПланыОбмена.УдалитьРегистрациюИзменений().Чтобы УниверсальныйОбменДаннымиXML выгружала только зарегистрированные изменения для конкретного узла обмена, необходимо передать ей информацию об этом узле. Обычно это делается через свойство УзелОбмена или аналогичные параметры.
Прежде всего, убедимся, что у нас есть ссылка на узел-получатель, для которого мы хотим выгрузить изменения. Этот узел обычно передается в процедуру выгрузки плана обмена.
// Пример получения узла-получателя, если его нет в текущем контексте
// (в процедуре выгрузки плана обмена он обычно приходит как параметр Получатель)
Если Получатель = Неопределено Тогда
УзелОбмена = ПланыОбмена.СТ_ЗиУП_3х_БП_КОРП.НайтиПоКоду("КодУзлаПриемника"); // Замените на фактический код узла
Иначе
УзелОбмена = Получатель;
КонецЕсли;
Если УзелОбмена = Неопределено Тогда
ЗаписьЖурналаРегистрации("Ошибка", УровеньЖурналаРегистрации.Ошибка,,, "Не найден узел обмена для выгрузки!");
Возврат;
КонецЕсли;
Ключевым изменением будет установка свойства УзелОбмена у экземпляра обработки. Это свойство указывает обработке, для какого узла ей нужно получить зарегистрированные изменения.
//ИмяСобытияЖурналаРегистрации
СтандартнаяОбработка = Ложь;
// Получаем макет правил обмена
МакетПравилОбмена = ПланыОбмена.СТ_ЗиУП_3х_БП_КОРП.ПолучитьМакет("ПравилаОбмена");
ИмяФайлаПравилОбмена = ПолучитьИмяВременногоФайла(".xml");
МакетПравилОбмена.Записать(ИмяФайлаПравилОбмена);
// Создаем и настраиваем обработку УниверсальныйОбменДаннымиXML
ОбрО = Обработки.УниверсальныйОбменДаннымиXML.Создать();
ОбрО.ИмяФайлаПравилОбмена = ИмяФайлаПравилОбмена;
ОбрО.ИмяФайлаОбмена = ИмяФайлаСообщения;
ОбрО.ЭтоИнтерактивныйРежим = Ложь;
ОбрО.НеВыводитьНикакихИнформационныхСообщенийПользователю = Ложь;
// *** КРИТИЧЕСКИ ВАЖНОЕ ИЗМЕНЕНИЕ ***
// Указываем обработке узел обмена, для которого нужно выгрузить данные.
// Это заставит ее работать только с зарегистрированными изменениями для данного узла.
ОбрО.УзелОбмена = УзелОбмена; // Передаем найденный ранее узел обмена
// Загружаем правила обмена
ОбрО.ЗагрузитьПравилаОбмена();
// Инициализируем первоначальные значения параметров
// Если в правилах обмена есть параметры, они будут установлены
// с учетом контекста узла обмена.
ОбрО.ИнициализироватьПервоначальныеЗначенияПараметров();
// Выполняем выгрузку. Теперь обработка должна выгрузить только зарегистрированные изменения
// для указанного узла обмена согласно правилам конвертации.
ОбрО.ВыполнитьВыгрузку();
Если ОбрО.ФлагОшибки Тогда
ЗаписьЖурналаРегистрации("Ошибка",УровеньЖурналаРегистрации.Ошибка,,,"Ошибка обработки УниверсальныйОбменДаннымиXML: " + ОбрО.ТекстОшибки);
КонецЕсли;
// После успешной выгрузки, необходимо снять регистрацию изменений
// Это гарантирует, что те же объекты не будут выгружены повторно в следующем сеансе.
ПланыОбмена.УдалитьРегистрациюИзменений(УзелОбмена, ОбрО.НомерСообщенияВыгрузки);
// Очищаем временные файлы
УдалитьФайлы(ИмяФайлаПравилОбмена);
// Дополнительная логика из вашего кода по удалению XML файла
// Удалять ИмяФайлаОбмена после выгрузки обычно не нужно,
// так как это результат работы выгрузки.
// УдалитьФайлы(ИмяФайлаXML); // ИмяФайлаXML использовалось для ручного формирования, что теперь не нужно
Хотя передача узла обмена в обработку УниверсальныйОбменДаннымиXML является ключевым шагом, не менее важно убедиться, что сами правила выгрузки данных (ПВД) в КД 2.1 настроены корректно. Рассмотрим несколько аспектов:
УниверсальныйОбменДаннымиXML будет их учитывать. Если вы используете "Произвольный алгоритм", то внутри этого алгоритма вы должны самостоятельно обеспечить фильтрацию по зарегистрированным данным.Отказ = Истина;, чтобы предотвратить его выгрузку.В оригинальной теме форума прозвучала мысль, что УниверсальныйОбменДаннымиXML является "ошибкой". Это не совсем так. Эта обработка является стандартным и мощным инструментом для обмена данными по правилам КД 2.1 в 1С 8.3. Однако она требует правильного подхода и понимания ее параметров.
Распространенные ошибки:
УниверсальныйОбменДаннымиXML с ручным вызовом ПланыОбмена.ВыбратьИзменения() и последующим склеиванием XML-файлов — это излишний и часто ошибочный подход. Доверьте формирование XML-файла и работу с зарегистрированными изменениями самой обработке, если она правильно настроена.Проблема выгрузки всего справочника вместо нескольких зарегистрированных объектов при использовании КД 2.1 и УниверсальныйОбменДаннымиXML в 1С 8.3 (особенно в ЗУП 3.1) чаще всего решается путем корректной передачи узла обмена в параметры обработки УниверсальныйОбменДаннымиXML, а также проверкой и при необходимости корректировкой правил выгрузки данных в КД 2.1. Мы должны убедиться, что обработка УниверсальныйОбменДаннымиXML "знает", для какого узла плана обмена ей нужно выгружать зарегистрированные изменения. После внесения этих изменений, система должна начать выгружать только те объекты, которые были зарегистрированы для обмена, что значительно повысит эффективность и корректность ваших процессов интеграции.