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