Разработчики, часто работающие с механизмом «Конвертации данных 2.1», нередко сталкиваются со следующей крайне неприятной ситуацией. Написанные правила обмена проходят успешное тестирование в ручном режиме: при использовании стандартной обработки УниверсальныйОбменДаннымиXML все документы и связанные справочники (например, Номенклатура, Контрагенты, Склады) переносятся полностью, со всеми реквизитами и табличными частями. Однако, стоит только внедрить эти же самые правила в типовую синхронизацию данных на базе Библиотеки стандартных подсистем (БСП) — например, настроить регулярный обмен между конфигурациями Управление торговлей 10.3 и Бухгалтерия предприятия 3.0, — как обмен начинает вести себя некорректно.
В базу-приемник переносятся только те реквизиты справочников, которые отмечены в правилах как «поля поиска» (чаще всего это только Код или Наименование). Все остальные свойства (например, ставки НДС, группы, производители) остаются незаполненными. Более того, полностью игнорируются обработчики событий загрузки, такие как ПриЗагрузке и ПослеЗагрузки, а также теряются переданные параметры объектов. Давайте подробно разберем, почему так происходит, проанализируем внутреннее поведение механизмов платформы 1С и БСП и рассмотрим несколько эффективных способов решения этой проблемы.
Чтобы понять суть проблемы, нам необходимо сопоставить логику работы ручной выгрузки через обработку УниверсальныйОбменДаннымиXML и автоматической онлайн-синхронизации БСП.
При использовании Универсального обмена: когда система выгружает документ (например, ПоступлениеТоваровУслуг), она последовательно обходит все его реквизиты. Натыкаясь на ссылку справочника Номенклатура, система обращается к соответствующему Правилу конвертации объектов (ПКО) для этого справочника. По умолчанию этот справочник выгружается полностью как самостоятельный <Объект> со всеми реквизитами, которые сопоставлены в Правилах конвертации свойств (ПКС). В файл выгрузки XML записывается вся структура элемента.
При использовании Синхронизации данных (БСП): здесь вступает в силу жесткая оптимизация трафика и производительности. Главный постулат БСП — передавать в транзакции только то, что действительно изменилось с момента последнего обмена. Для отслеживания изменений используется механизм планов обмена. Если изменен и зарегистрирован к выгрузке только сам документ, но связанные с ним элементы справочников (номенклатура, контрагенты) не изменялись и не были зарегистрированы на узле плана обмена, БСП принимает решение сэкономить трафик.
Вместо полноценного блока <Объект> для справочника в файл выгрузки помещается усеченный узел <Ссылка>. Этот узел содержит исключительно уникальный идентификатор (GUID) объекта и его ключевые поля поиска (например, код или артикул), необходимые для сопоставления в базе-приемнике. Предполагается, что раз элемент справочника не менялся, значит, он уже существует в приемнике, и передавать его повторно полностью нет никакого смысла.
Такой оптимизированный подход БСП отлично работает на полностью синхронизированных базах, но ломает логику кастомных или нетиповых правил обмена. Проанализируем основные проблемы:
ПриЗагрузке, ПослеЗагрузки и другие аналогичные события на стороне базы-приемника выполняются платформой 1С только при парсинге полноценного XML-блока <Объект>. Для блоков формата <Ссылка> эти обработчики попросту не вызываются.ПараметрыОбъекта, они не попадут в базу-приемник. Блок <Ссылка> физически не предусматривает хранение и передачу параметров.Код, а все остальные важные поля останутся пустыми.Это самый быстрый и прямолинейный способ заставить систему выгрузить объект полностью, даже если он не зарегистрирован в плане обмена. Мы можем явно указать платформе, что данный реквизит требует полной сериализации.
Рассмотрим по шагам, как это реализовать в «Конвертации данных 2.1»:
ПоступлениеТоваровУслуг) и перейдите на вкладку Конвертация свойств.Контрагент или Номенклатура) и откройте его свойства.
// Принудительно выгружаем объект полностью со всеми реквизитами и табличными частями
ВыгрузитьОбъект = Истина;
Как это работает: инициализация переменной ВыгрузитьОбъект значением Истина является для выгрузчика директивой обязательного формирования полноценного XML-узла <Объект>. В этом случае БСП проигнорирует отсутствие регистрации элемента справочника в плане обмена и запишет его структуру целиком. Это гарантирует вызов обработчиков ПослеЗагрузки на стороне приемника.
Минусы подхода: данный метод увеличивает размер файла обмена. Если в документе содержится табличная часть на 10 000 строк с уникальной номенклатурой, использование этого флага заставит систему выгружать все 10 000 карточек номенклатуры при каждой выгрузке документа, даже если они давно созданы в приемнике. Используйте этот способ точечно, только для критически важных реквизитов (например, реквизитов шапки документа — Договор, Контрагент, Склад).
Более правильным решением с точки зрения архитектуры БСП является настройка автоматической регистрации связанных справочников на узлах обмена при изменении или проведении основных документов. Выясним, как это реализовать.
Если справочник зарегистрирован к обмену, БСП увидит это и выгрузит его как полноценный <Объект> без использования принудительных флагов в ПКС. Добиться этого можно двумя путями:
Мы можем создать подписку на событие для документов, которая при записи будет программно регистрировать связанные реквизиты на узлах плана обмена. Рассмотрим пример кода, который можно разместить в обработчике подписки на событие ПередЗаписью или ПриЗаписи документа-источника:
Процедура ЗарегистрироватьСвязанныеСправочникиПередЗаписью(Источник, Отказ, РежимЗаписи, РежимПроведения) Экспорт
// Получаем узел обмена, для которого нужно зарегистрировать изменения
// В реальной задаче здесь должен быть обход активных узлов нужного плана обмена
УзлыДляРегистрации = ПланыОбмена.ОбменУправлениеТорговлейБухгалтерияПредприятия.Выбрать();
Пока УзлыДляРегистрации.Следующий() Цикл
// Регистрируем реквизиты шапки документа
Если ЗначениеЗаполнено(Источник.Контрагент) Тогда
ПланыОбмена.ЗарегистрироватьИзменения(УзлыДляРегистрации.Ссылка, Источник.Контрагент);
КонецЕсли;
Если ЗначениеЗаполнено(Источник.Склад) Тогда
ПланыОбмена.ЗарегистрироватьИзменения(УзлыДляРегистрации.Ссылка, Источник.Склад);
КонецЕсли;
// Регистрируем номенклатуру из табличной части Товары
Для Каждого СтрокаТовары Из Источник.Товары Цикл
Если ЗначениеЗаполнено(СтрокаТовары.Номенклатура) Тогда
ПланыОбмена.ЗарегистрироватьИзменения(УзлыДляРегистрации.Ссылка, СтрокаТовары.Номенклатура);
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецПроцедуры
Если вы не хотите вносить изменения в конфигурацию-источник и создавать новые подписки, настройте логику регистрации в самой «Конвертации данных 2.1» с помощью Правил регистрации объектов (ПРО). В ПРО можно гибко прописать скрипты, которые при регистрации документа будут автоматически ставить в очередь на выгрузку все связанные с ним справочники. Это сохранит конфигурацию типовой и решит проблему неполной выгрузки.
Если вам действительно не нужно переносить все реквизиты справочника заново (например, карточки справочников в приемнике гарантированно заполнены корректно), но вы хотите застраховать систему от создания пустых «битых» элементов при случайном отсутствии объекта в приемнике, настройте поведение ПКО:
Номенклатура).Проанализировав проблему, мы видим, что «срезание» реквизитов справочников при синхронизации — это не баг платформы 1С, а заложенное поведение оптимизации БСП. Для быстрого исправления «здесь и сейчас» используйте установку флага ВыгрузитьОбъект = Истина; в ПКС правил обмена. Для создания надежной, промышленной интеграции без раздувания xml-файлов всегда отдавайте предпочтение правильной настройке планов обмена и авторегистрации связанных данных.