При организации переноса данных между двумя информационными базами 1С через COM-соединение (COMConnector) часто возникает задача синхронизации не только самих элементов справочника, но и структуры папок (родительских групп), в которых они расположены. Рассмотрим подробнее, с какими трудностями можно столкнуться при решении этой задачи и как правильно реализовать поиск и создание групп в целевой базе.
Начинающие разработчики иногда пытаются получить цепочку родителей с помощью запроса с текстом вроде Контрагенты.Родитель.Родитель.Наименование. Проанализируем, почему такой подход приводит к ошибкам:
Родитель не сможет обработать вложенность, превышающую количество написанных полей. Если глубина иерархии изменится, логика сломается.И для проверки наименований всех вышестоящих родителей одной переменной (например, Контрагенты.Родитель.Наименование = &Наименование И Контрагенты.Родитель.Родитель.Наименование = &Наименование) некорректно, так как родитель каждого уровня имеет свое наименование. Такой запрос всегда будет возвращать пустой результат.Разберем по шагам рабочий подход к назначению родительской группы для элемента в целевой базе через COM-соединение. Если в целевой базе группы с таким наименованием еще нет, её необходимо предварительно создать и записать, после чего привязать переносимый элемент к созданной группе.
Рассмотрим пример кода, выполняющего проверку наличия родительской группы в приемнике и её создание при отсутствии:
Если ЗначениеЗаполнено(ТекСтрока.Ссылка.Родитель) Тогда
// Ищем группу в базе-приемнике по наименованию
СсылкаГруппы = Соединение.Справочники.Контрагенты.НайтиПоНаименованию(ТекСтрока.Ссылка.Родитель.Наименование);
Если НЕ СсылкаГруппы.Пустая() И СсылкаГруппы.ЭтоГруппа Тогда
// Группа найдена в целевой базе
Контрагент.Родитель = СсылкаГруппы;
Иначе
// Группа не найдена, создаем новую
Группа = Соединение.Справочники.Контрагенты.СоздатьГруппу();
Группа.Наименование = ТекСтрока.Ссылка.Родитель.Наименование;
Группа.Записать();
Сообщить("Записана новая группа: " + Группа.Наименование);
Контрагент.Родитель = Группа.Ссылка;
КонецЕсли;
КонецЕсли;
В этом примере мы сначала проверяем, заполнен ли родитель у переносимого элемента в источнике. Затем через объект COM-соединения Соединение выполняем метод НайтиПоНаименованию в целевой базе. Если группа найдена и является именно группой (проверка СсылкаГруппы.ЭтоГруппа), присваиваем её полю Родитель создаваемого контрагента. Если группа отсутствует, вызываем метод СоздатьГруппу(), заполняем наименование, записываем её и подставляем полученную ссылку Группа.Ссылка в реквизит Родитель.
Для создания устойчивого механизма синхронизации иерархических справочников важно учитывать следующие архитектурные особенности:
УникальныйИдентификатор(), либо явно передавать GUID при создании группы в приемнике.