Как в Конвертации данных создать подчиненный справочник в базе-приемнике, если его нет в источнике?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При переносе данных между неидентичными конфигурациями 1С часто возникает ситуация, когда в базе-источнике учет ведется в плоской структуре (например, в справочнике ОбъектыРасчета), а в базе-приемнике данные нормализованы и разделены на два справочника — справочник-владелец ОбъектыРасчета и подчиненный ему справочник Показатели. Разберем основные способы реализации такого переноса в конфигурации «Конвертация данных 2.0», выясним причину распространенных ошибок и рассмотрим правильные варианты настройки правил обмена.

Способ 1. Программное создание подчиненного элемента на стороне приемника (в обработчике «После загрузки»)

Проанализируем самый надежный и производительный вариант. В этом случае мы не создаем лишних XML-узлов в выгрузке, а формируем подчиненные элементы средствами встроенного языка непосредственно в базе-приемнике сразу после записи основного объекта.

Разберем по шагам порядок настройки:

  1. Создаем одно Правило конвертации объектов (ПКО) для справочника-владельца ОбъектыРасчета (Источник — ОбъектыРасчета, Приемник — ОбъектыРасчета).
  2. В созданном ПКО открываем обработчик «После загрузки». В этом обработчике доступна переменная Объект, содержащая ссылку и реквизиты только что записанного объекта-владельца.
  3. Добавляем программный код для поиска и создания подчиненного элемента:

// Объект - загруженный объект-владелец
НайденныйПоказатель = Справочники.Показатели.НайтиПоНаименованию(Объект.Наименование, Истина, , Объект.Ссылка);
Если НайденныйПоказатель.Пустая() Тогда
    НовыйПоказатель = Справочники.Показатели.СоздатьЭлемент();
    НовыйПоказатель.Владелец = Объект.Ссылка;
    НовыйПоказатель.Наименование = Объект.Наименование;
    НовыйПоказатель.Записать();
КонецЕсли;

Этот подход гарантирует, что у подчиненного элемента всегда будет корректно установлен реквизит Владелец, а файл обмена не будет перегружен дублирующимися данными.

Способ 2. Настройка выгрузки через входящие данные и метод ВыгрузитьПоПравилу

Если подчиненный объект должен обязательно присутствовать в потоке данных XML и регистрироваться правилами конвертации, настроим генерацию через механизм входящих данных.

Разберем этот вариант по шагам:

  1. Создаем ПКО для подчиненного справочника Показатели:
    1. Поле Источник оставляем пустым (Не указывать), поле Приемник — Показатели.
    2. Для свойств Наименование и Владелец в Правилах конвертации свойств (ПКС) включаем флаг «Получить из входящих данных».
    3. Для ПКС Владелец в качестве правила конвертации выбираем ПКО ОбъектыРасчета.
    4. На вкладке настроек поиска включаем флаги поиска по полям Владелец и Наименование, а флаг поиска по внутреннему идентификатору снимаем.
  2. В ПКО основного справочника ОбъектыРасчета переходим в обработчик «После выгрузки» и передаем структуру с данными через метод ВыгрузитьПоПравилу:

Входящие = Новый Структура;
Входящие.Вставить("Наименование", Источник.Наименование);
Входящие.Вставить("Владелец", Источник);

ВыгрузитьПоПравилу( , , Входящие, , "Показатели");

При таком подходе подчиненный объект выгружается строго в контексте выгрузки владельца, что исключает рассинхронизацию связей.

Способ 3. Прямая привязка источника через Значение = Источник

Посмотрим на упрощенный способ передачи владельца, когда создаются 2 ПКО, где в обоих источником выступает справочник ОбъектыРасчета. В ПКО Показатели для ПКС Владелец поле «Источник» оставляется пустым, а в обработчике «Перед выгрузкой» данного свойства прописывается:

Значение = Источник;

В качестве правила конвертации для реквизита Владелец выбирается ПКО ОбъектыРасчета. Важно: этот способ работает, но при сложной структуре связей между справочниками может приводить к ошибкам рекурсии.

Причина ошибки «Значение индекса выходит за границы диапазона» и способы её устранения

При использовании конструкции Значение = Источник или при выгрузке зависимых объектов нередко возникает исключение: Ошибка при выгрузке данных: ошибка при вызове метода контекста (Удалить): Значение индекса выходит за границы диапазона. Выясним причину ее появления.

Эта ошибка платформы возникает во внутренней таблице стека выгрузки (мСтекВызововВыгрузкиДанных) обработки «Универсальный обмен данными XML» из-за циклической или бесконечной рекурсивной выгрузки. Объект начинает выгружать связанный объект, а тот, ссылаясь обратно на владельца через ПКО по умолчанию, повторно инициирует выгрузку родителя, ломая внутренний стек.

Чтобы устранить эту проблему, применим проверку коллекции уже выгруженных объектов перед вызовом конвертации:


Если Правила.ОбъектыРасчета.Выгруженные[Источник.Владелец] = Неопределено Тогда
    ВыгрузитьПоПравилу(Источник.Владелец);
КонецЕсли;

Особенности настройки поиска для подчиненных справочников

Рассмотрим важное правило сопоставления: для любых подчиненных справочников в КД 2.0 реквизит Владелец обязательно должен быть отмечен флагом «Использовать при поиске». Если этого не сделать, сопоставление по коду или наименованию будет выполняться глобально по всей таблице приемника, что приведет к ошибочной перезаписи элементов, принадлежащих другим владельцам.

← На главную