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