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