Как в Конвертации данных перенести справочник в определенную папку с сохранением иерархии?

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

При переносе данных между базами 1С часто возникает задача выгрузить элементы и группы справочника не в корень базы-приемника, а поместить их внутрь заранее созданной целевой папки, полностью сохранив исходную структуру подчинения. Разберем, как правильно реализовать эту логику с помощью механизмов конфигурации «Конвертация данных 2.1» и какие подводные камни могут встретиться.

Типичные ошибки при ручной установке родителя

Проанализируем распространенную ошибку, возникающую при попытке назначить папку-приемник в обработчике «После загрузки» правила конвертации объектов (ПКО):


Если Объект.ЭтоГруппа Тогда
    Если Объект.Уровень() = 0 Тогда
        Объект.Родитель = Справочники.Номенклатура.НайтиПоКоду("00000000686");
        Объект.Записать();
    КонецЕсли;
КонецЕсли;

Такой подход часто дает сбой по следующим причинам:

  1. Некорректная работа метода Уровень(): во время выполнения обработчиков загрузки ссылка может быть еще не сформирована в информационной базе, из-за чего проверка уровня дает непредвиденный результат.
  2. Пропуск элементов: условие Объект.ЭтоГруппа оставляет без внимания элементы, которые в базе-источнике находились в корне справочника (без папки). Они так и останутся в корне приемника.
  3. Ошибки в полях поиска: если в ПКО установлен поиск по реквизитам, не заполняемым у групп (например, Артикул), алгоритм сопоставления связывает группу источника с первой попавшейся записью с пустым артикулом. В итоге вся иерархия нарушается и «схлопывается».
  4. Дублирование записи: явный вызов Объект.Записать() в обработчиках загрузки создает лишние транзакции и может конфликтовать со стандартным алгоритмом записи КД.

Способ 1. Переопределение родителя в ПКС «Родитель»

Рассмотрим наиболее надежный и типовой способ — управление значением реквизита Родитель в правиле конвертации свойств (ПКС).

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

Вариант А: Определение родителя на стороне приемника (обработчик «При загрузке» в ПКС)

Если в базе-приемнике уже известна конкретная группа (например, по коду или предопределенному значению), проверяем, передано ли значение родителя. Если значение пустое, значит элемент/группа находились в корне, и мы подставляем нужную папку:


Если Не ЗначениеЗаполнено(Значение) Тогда
    Значение = Справочники.Номенклатура.НайтиПоКоду("00000000686");
КонецЕсли;

Вариант Б: Формирование структуры поиска на стороне источника (обработчик «Перед выгрузкой» в ПКС)

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


Если Не ЗначениеЗаполнено(Источник.Родитель) Тогда
    Значение = Новый Структура("Наименование, ЭтоГруппа, ПометкаУдаления", "МояПапкаПриемник", Истина, Ложь);
КонецЕсли;

Способ 2. Разделение правил поиска для групп и элементов

Чтобы избежать ошибок слияния папок из-за незаполненных реквизитов (например, артикула), настроим обработчик ПКО «Поля поиска». Разберем по шагам, как задать различные критерии сопоставления:


Если СвойстваПоиска["ЭтоГруппа"] = Истина Тогда
    // Для групп выполняем поиск по наименованию и признаку группы
    СтрокаИменСвойствПоиска = "Наименование, ЭтоГруппа";
Иначе
    // Для элементов ищем по артикулу
    СтрокаИменСвойствПоиска = "Артикул, ЭтоГруппа";
КонецЕсли;

Благодаря этому группы не будут сопоставляться по пустым артикулам, а дерево иерархии сохранится в исходном виде.

Способ 3. Использование параметров конвертации

Чтобы не прописывать жестко коды и наименования папок в коде обработчиков, удобно использовать параметры обмена:

  1. Создаем параметр конвертации (например, ПапкаПриемник).
  2. В обработчике «Перед загрузкой данных» или через диалог параметров заполняем его ссылкой на целевую группу в базе-приемнике: Параметры.ПапкаПриемник = Справочники.Номенклатура.НайтиПоКоду("00000000686");
  3. В ПКС реквизита Родитель в обработчике «При загрузке» используем полученный параметр:
    
    Если Не ЗначениеЗаполнено(Значение) Тогда
        Значение = Параметры.ПапкаПриемник;
    КонецЕсли;
    

Таким образом, все корневые элементы и корневые группы попадают в заданную папку, а их подчиненные элементы сохраняют корректные ссылки на своих непосредственных родителей.

← На главную