Почему при обмене по плану обмена связанные справочники переносятся пустыми и как это исправить

Программист 1С v8.3 (Обычные формы) 1С:Зарплата и Управление Персоналом IT и автоматизация бизнеса
← На главную

При переносе данных между конфигурациями 1С (например, между базами ЗУП 2.5 или УПП) разработчики часто сталкиваются с ситуацией: при ручной выгрузке через обработку УниверсальныйОбменДаннымиXML все документы и связанные справочники переносятся корректно со всеми реквизитами. Однако при переходе на автообмен через планы обмена с использованием типовой обработки ОбменДаннымиXML поведение меняется: связанные элементы (сотрудники, должности, номенклатура) либо не создаются вовсе, либо создаются с заполненными полями поиска, но пустыми остальными реквизитами, а в документе может появиться представление <Объект не найден...>.

Разберем детально, почему так происходит, как устроена внутренняя оптимизация выгрузки в планах обмена и какими способами можно обеспечить корректный перенос данных.

Причины различий в поведении УниверсальныйОбменДаннымиXML и ОбменДаннымиXML

Проанализируем техническую сторону работы подсистемы обмена данными на базе правил «Конвертации данных 2.1»:

  1. Режим оптимизации ссылочных типов при обмене через планы обмена. В типовой обработке ОбменДаннымиXML при работе в контексте планов обмена по умолчанию активируется оптимизация трафика. Типовой механизм предполагает, что нормативно-справочная информация (НСИ) должна регистрироваться и передаваться отдельно, а при передаче документов выгружаются только ссылки на связанные объекты (узлы ссылок с уникальным идентификатором GUID и ключевыми полями поиска), но не их свойства.
  2. Поиск по внутреннему идентификатору (GUID). Если в правиле конвертации объекта (ПКО) для справочника включен поиск по уникальному идентификатору источника и флаг выгрузки свойств по ссылкам сброшен, база-приемник при отсутствии элемента создает пустую болванку с переданным GUID. Заполняются только те реквизиты, которые были явно переданы в ссылочном узле (поля поиска). Все остальные реквизиты остаются пустыми.
  3. Различие типа источника в обработчиках. В зависимости от режима выгрузки переменная Источник в обработчиках КД может содержать как непосредственный объект (СправочникОбъект, ДокументОбъект), так и ссылку (СправочникСсылка, ДокументСсылка). Если в алгоритмах правил конвертации свойств (ПКС) или ПКО не предусмотрена проверка типа, чтение реквизитов через точку от объекта или обращение к связанным регистрам может возвращать пустые значения.
  4. Очистка движений и отложенное проведение. В типовом коде ОбменДаннымиXML для документов может выполняться очистка существующих движений с последующей попыткой проведения, тогда как УниверсальныйОбменДаннымиXML переносит движения как самостоятельные наборы записей. Если зависимый объект не был полностью записан к моменту проведения документа, документ не проведется или запишет битую ссылку.

Способ 1. Управление флагом ТолькоПолучитьУзелСсылки в обработчиках правил

Для того чтобы заставить механизм выгрузки передавать связанные объекты полностью, а не только их ссылочные идентификаторы, необходимо программно отключить режим получения узла ссылки.

Рассмотрим, как скорректировать вызов функции ВыгрузитьПоПравилу. Четвертый параметр этой функции — ТолькоПолучитьУзелСсылки. Если передать туда значение Ложь, выгрузка сформирует полный XML-узел объекта:


// Пример вызова выгрузки зависимого объекта целиком
ВыгрузитьПоПравилу(ВыбЗапрос.Ссылка, , , Ложь, "ПриемНаРаботуВОрганизацию", , , );

Если требуется отключить режим выгрузки ссылок на уровне всего документа или конкретного правила, в обработчике Перед выгрузкой соответствующего ПКО можно явно установить служебную переменную:


ТолькоПолучитьУзелСсылки = Ложь;
НеВыгружатьОбъектыСвойствПоСсылкам = Ложь;

Благодаря этому объект будет выгружен в поток XML со всей иерархией реквизитов и табличных частей, а не в виде сокращенного описания ссылки.

Способ 2. Корректная обработка типа Источник в правилах

Выясним, как избежать ошибок при обращении к данным источника, если в одном режиме передается ссылка, а в другом — объект. В обработчиках событий КД (например, Перед выгрузкой или При выгрузке) следует использовать универсальную конструкцию проверки:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |    КонтактнаяИнформация.Тип,
    |    КонтактнаяИнформация.Вид,
    |    КонтактнаяИнформация.Представление
    |ИЗ
    |    РегистрСведений.КонтактнаяИнформация КАК КонтактнаяИнформация
    |ГДЕ
    |    КонтактнаяИнформация.Объект = &Объект";

// Универсальное получение ссылки независимо от того, передан объект или ссылка
Если Источник.Ссылка = Источник Тогда
    Запрос.УстановитьПараметр("Объект", Источник);
Иначе
    Запрос.УстановитьПараметр("Объект", Источник.Ссылка);
КонецЕсли;

Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
    ВыгрузитьПоПравилу(,, Выборка, Ложь, "КонтактнаяИнформация");
КонецЦикла;

Способ 3. Принудительная регистрация связанных данных на плане обмена

Если правила конвертации менять нежелательно, чтобы сохранить типовую архитектуру обмена, необходимо гарантировать, что все связанные со справочниками и документами объекты зарегистрированы к обмену на узле.

Разберем реализацию через подписку на событие при записи документа в базе-источнике:


// В обработчике подписки на событие ПриЗаписи документа
Для Каждого Стр Из Источник.РаботникиОрганизации Цикл
    Если ЗначениеЗаполнено(Стр.Сотрудник) Тогда
        ПланыОбмена.ЗарегистрироватьИзменения(УзелОбмена, Стр.Сотрудник);
    КонецЕсли;
    Если ЗначениеЗаполнено(Стр.Должность) Тогда
        ПланыОбмена.ЗарегистрироватьИзменения(УзелОбмена, Стр.Должность);
    КонецЕсли;
    Если ЗначениеЗаполнено(Стр.ПодразделениеОрганизации) Тогда
        ПланыОбмена.ЗарегистрироватьИзменения(УзелОбмена, Стр.ПодразделениеОрганизации);
    КонецЕсли;
КонецЦикла;

В этом случае при очередной сессии обмена типовая обработка ОбменДаннымиXML выгрузит зарегистрированные элементы справочников как самостоятельные полноценные объекты, и в базе-приемнике не возникнет пустых полей или отсутствующих ссылок.

← На главную