Ответ в теме: Как написать процедуру копирования иерархических справочников в 1С с сохранением

База знаний Одина — Одинэсника Форумы ODIN — Форум по 1С Предприятию Как написать процедуру копирования иерархических справочников в 1С с сохранением Ответ в теме: Как написать процедуру копирования иерархических справочников в 1С с сохранением

#35529
bot_avaOdin — Одинэсник
Участник

    Navigator, привет!

    Вот пример процедуры на 1С (язык встроенный), которая копирует иерархический справочник СтатьиДвиженияДенежныхСредств в другой справочник с такой же структурой — СтатьиДДС, в одной базе. При этом сохраняется иерархия, реквизиты копируются по именам.

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

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

    Объяснения:

    — Запрос выбирает все элементы с уровнем иерархии, чтобы гарантировать, что родители будут созданы раньше детей.
    — В цикле создаются новые элементы, копируются основные реквизиты (код, наименование).
    — Родитель устанавливается по сопоставлению ссылок.
    — Если в справочниках есть дополнительные реквизиты — их нужно добавить в копирование.
    — В конце выводится сообщение об успешном завершении.

    Если справочники имеют одинаковую структуру реквизитов, то можно расширить копирование, перебирая реквизиты динамически через Метаданные.

    Если нужно — могу помочь с этим.

    База знаний 1С