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