При настройке обмена между базами 1С с помощью конфигурации «Конвертация данных 2.1» разработчики часто сталкиваются с ситуацией, когда при каждой повторной загрузке одного и того же XML-файла в базе-приемнике создаются дублирующие документы. При этом в правилах конвертации объектов (ПКО) установлен флаг «Искать объект приемника по внутреннему идентификатору объекта источника», а сам файл обмена содержит корректный уникальный идентификатор (GUID).
Рассмотрим подробнее причины возникновения этой проблемы и разберем практические способы ее решения.
Если выгрузка объектов осуществляется из Правила выборки данных (ПВД) с произвольным алгоритмом, некорректная обработка результатов запроса может привести к тому, что в функцию выгрузки передаются пустые значения или данные нессылочного типа.
Распространенная ошибка — забытый вызов метода Следующий() при обходе выборки запроса. Если не позиционировать выборку перед обращением к полям, ссылка на объект не передается в обработку обмена, и система формирует новый случайный GUID.
Разберем правильный пример обхода выборки в событии ПВД:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ПоступлениеТоваровУслуг.Ссылка КАК Ссылка
|ИЗ
| Документ.ПоступлениеТоваровУслуг КАК ПоступлениеТоваровУслуг
|ГДЕ
| ПоступлениеТоваровУслуг.Дата МЕЖДУ &НачалоПериода И &ОкончаниеПериода";
Запрос.УстановитьПараметр("НачалоПериода", Параметры.НачалоПериода);
Запрос.УстановитьПараметр("ОкончаниеПериода", КонецДня(Параметры.ОкончаниеПериода));
ВыборкаДанных = Запрос.Выполнить().Выбрать();
Пока ВыборкаДанных.Следующий() Цикл
// Важно передавать именно ссылку на объект: ВыборкаДанных.Ссылка
ВыгрузитьПоПравилу(ВыборкаДанных.Ссылка, , Новый Структура, Новый Структура, "ПоступлениеТоваровУслуг_ПриемНаОтветХранение");
КонецЦикла;
Отказ = Истина;
Обязательно проверяйте, что в запросе выбирается реквизит Ссылка, а при вызове функции ВыгрузитьПоПравилу() в качестве первого параметра (Источник) передается именно ссылочный тип данных.
Более сложная ситуация возникает, когда один и тот же объект может выгружаться по нескольким разным ПКО (например, сначала как реквизит другого документа, а затем как самостоятельный документ по специальному правилу).
В «Конвертации данных 2.1» действует механизм глобального кэширования выгруженных объектов. По умолчанию ключ кэша формируется на основе ссылки и имени ПКО. Если объект был ранее занесен в кэш без сохранения полного идентификатора или с другими настройками поиска, повторный вызов ВыгрузитьПоПравилу() берет уже сформированный XML-узел из кэша.
Чтобы принудительно развести выгрузку объекта по разным правилам и исключить использование старого кэша, необходимо явно задавать Ключ выгружаемых данных.
Проанализируем применение ключа выгружаемых данных при вызове процедуры ВыгрузитьПоПравилу():
Пока ВыборкаДанных.Следующий() Цикл
// Формируем уникальный ключ на основе ссылки и имени ПКО
КлючДанных = Строка(ВыборкаДанных.Ссылка.УникальныйИдентификатор()) + "_ПоступлениеПрием";
ВыгрузитьПоПравилу(
ВыборкаДанных.Ссылка,
,
Новый Структура,
Новый Структура,
"ПоступлениеТоваровУслуг_ПриемНаОтветХранение",
КлючДанных
);
КонецЦикла;
Передача уникального ключа выгружаемых данных предотвращает коллизии в обработке обмена, благодаря чему уникальный идентификатор источника корректно записывается в XML-файл и используется базой-приемником для поиска существующего документа.
<Ссылка> должен присутствовать элемент {УникальныйИдентификатор} с заполненой строкой GUID.Источник передается ссылка на объект (ДокументСсылка), а не строка ТЗ или структура.КлючВыгружаемыхДанных при каждом вызове ВыгрузитьПоПравилу().