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