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

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

При настройке правил обмена в конфигурации 1С:Конвертация данных 2.1 (КД2) нередко возникает задача: в базе-источнике реквизит (например, номер ГТД в табличной части документа) хранится в виде простого типа Строка, а в базе-приемнике этот же реквизит является ссылкой на справочник (СправочникСсылка.НомераГТД). При этом необходимо найти существующий элемент по коду или наименованию, а если такого элемента еще нет — создать новый.

Часто при первой настройке такого правила разработчики сталкиваются с тем, что в базе-приемнике при каждой загрузке создаются дублирующиеся элементы справочника с одинаковыми кодами или наименованиями. Разберем по шагам, почему это происходит и как правильно настроить конвертацию.

Причина возникновения дублей при переносе

Проанализируем типовую логику сопоставления объектов в КД2. По умолчанию механизм поиска сначала пытается сопоставить объект по его уникальному идентификатору (GUID). Так как в источнике передается простая строка, у нее нет реального GUID справочника приемника. Выгрузчик формирует новый идентификатор или пустой узел поиска. Если в настройках правила конвертации объекта (ПКО) выключена опция Продолжить поиск по полям поиска, если по идентификатору объект приемника не найден, платформа прекращает дальнейший поиск и сразу создает новый элемент при каждой загрузке данных.

Пошаговая настройка правил конвертации (ПКО и ПКС)

Разберем базовый и самый надежный алгоритм настройки через стандартные механизмы конвертации.

  1. Создание отдельного ПКО для справочника-приемника:

    Создадим новое правило конвертации объектов. В поле Источник оставляем пустое значение (так как прямого соответствия между объектами метаданных нет), а в поле Приемник указываем целевой справочник (например, НомераГТД).

  2. Настройка флагов поиска в ПКО:

    Откроем настройки созданного ПКО справочника и выполним следующие действия:

    Снимем флаг Искать объект приемника по внутреннему идентификатору (или включим флаг Продолжить поиск по полям поиска, если по идентификатору объект приемника не найден).

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

  3. Настройка свойств конвертации (ПКС) внутри ПКО справочника:

    Внутри созданного ПКО создадим правило конвертации свойства (ПКС) для поля сопоставления — Наименование или Код (в зависимости от того, по какому реквизиту ведется учет в целевой базе).

    В этом ПКС оставим Источник пустым, а Приемник укажем как Наименование (или Код).

    Обязательно установим флаг Поиск напротив этого свойства.

    В обработчике ПередВыгрузкой данного ПКС напишем:

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

    Так как в данное ПКО будет передаваться строковое значение, переменная Источник будет содержать исходный текст, который мы и передаем в реквизит поиска.

  4. Привязка правила в табличной части документа:

    Перейдем в ПКО документа, найдем строку табличной части и соответствующее ПКС реквизита.

    В поле Правило конвертации выберем созданное ранее ПКО справочника.

Предотвращение создания пустых элементов и нормализация данных

Рассмотрим тонкости, которые могут нарушить корректную работу сопоставления на реальных базах.

1. Защита от пустых строк: если в табличной части источника строка не заполнена, выгрузчик по умолчанию попытается передать пустое значение в ПКО и создаст пустой элемент в базе-приемнике. Чтобы этого избежать, в ПКС табличной части документа в обработчике ПередВыгрузкой добавим условие:


Если Не ЗначениеЗаполнено(Значение) Тогда
    Отказ = Истина;
КонецЕсли;

2. Очистка невидимых символов и пробелов: неразрывные пробелы и хвостовые пробелы в строках приводят к тому, что поиск по точному совпадению в приемнике не находит существующий элемент. Добавим нормализацию строки перед передачей:


Если ЗначениеЗаполнено(Значение) Тогда
    Значение = СокрЛП(СтрЗаменить(Значение, Символы.НПП, " "));
Иначе
    Отказ = Истина;
КонецЕсли;

Альтернативный вариант: явный вызов через «ВыгрузитьПоПравилу»

Если мы хотим жестко контролировать процесс выгрузки без автоматической привязки, в ПКС табличной части документа в обработчике ПередВыгрузкой можно применить функцию ВыгрузитьПоПравилу:


Если ЗначениеЗаполнено(Источник.НомерГТД) Тогда
    Значение = ВыгрузитьПоПравилу(СокрЛП(Источник.НомерГТД), , , , "НомерГТД_Справочник");
Иначе
    Значение = Неопределено;
КонецЕсли;

Программный поиск и создание в обработчике загрузки

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


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

Таким образом, для исключения дублирования справочников достаточно корректно управлять признаками поиска по полям и передавать нормализованные строковые данные в ПКО.

← На главную