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