База знаний Одина — Одинэсника › Форумы › ODIN — Форум по 1С Предприятию › Как написать процедуру копирования иерархических справочников в 1С с сохранением › Ответ в теме: Как написать процедуру копирования иерархических справочников в 1С с сохранением
Navigator, привет!
Вот пример процедуры на 1С (язык встроенный), которая копирует иерархический справочник СтатьиДвиженияДенежныхСредств в другой справочник с такой же структурой — СтатьиДДС, в одной базе. При этом сохраняется иерархия, реквизиты копируются по именам.
Основная идея — сначала собрать все элементы исходного справочника в массив, потом пройтись по ним в порядке от корня к листьям, создавая элементы в целевом справочнике и устанавливая ссылки на родителей.
Процедура КопироватьИерархическийСправочник()
// Словарь для сопоставления ссылок исходного справочника и нового
СоответствиеСсылок = Новый Соответствие;
// Массив для хранения элементов исходного справочника
МассивЭлементов = Новый Массив;
// Получаем все элементы исходного справочника с сортировкой по уровню иерархии
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Стр.Ссылка КАК Ссылка,
| Стр.Родитель КАК Родитель,
| Стр.Код КАК Код,
| Стр.Наименование КАК Наименование,
| Стр.УровеньИерархии КАК УровеньИерархии
|ИЗ
| Справочник.СтатьиДвиженияДенежныхСредств КАК Стр
|УПОРЯДОЧИТЬ ПО
| Стр.УровеньИерархии";
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();
Пока Выборка.Следующий() Цикл
МассивЭлементов.Добавить(Выборка.ПолучитьОбъект());
КонецЦикла;
// Проходим по элементам в порядке иерархии
Для Каждого Элемент Из МассивЭлементов Цикл
// Создаем новый элемент целевого справочника
НовыйЭлемент = Справочники.СтатьиДДС.СоздатьЭлемент();
// Копируем реквизиты по именам (пример для типовых реквизитов)
НовыйЭлемент.Код = Элемент.Код;
НовыйЭлемент.Наименование = Элемент.Наименование;
// Устанавливаем родителя, если он есть
Если ЗначениеЗаполнено(Элемент.Родитель) Тогда
Если СоответствиеСсылок.СодержитКлюч(Элемент.Родитель) Тогда
НовыйЭлемент.Родитель = СоответствиеСсылок.Получить(Элемент.Родитель);
КонецЕсли;
КонецЕсли;
// Если есть дополнительные реквизиты, их тоже нужно скопировать здесь
// Записываем новый элемент
НовыйЭлемент.Записать();
// Запоминаем соответствие ссылок
СоответствиеСсылок.Вставить(Элемент.Ссылка, НовыйЭлемент.Ссылка);
КонецЦикла;
Сообщить("Копирование справочника завершено.");
КонецПроцедуры
Объяснения:
— Запрос выбирает все элементы с уровнем иерархии, чтобы гарантировать, что родители будут созданы раньше детей.
— В цикле создаются новые элементы, копируются основные реквизиты (код, наименование).
— Родитель устанавливается по сопоставлению ссылок.
— Если в справочниках есть дополнительные реквизиты — их нужно добавить в копирование.
— В конце выводится сообщение об успешном завершении.
Если справочники имеют одинаковую структуру реквизитов, то можно расширить копирование, перебирая реквизиты динамически через Метаданные.
Если нужно — могу помочь с этим.