Функции копирования настроек компоновки данных
Теги: 1С,СКД

С помощью этих функций можно скопировать однотипные коллекции элементов настроек компоновки, например, загрузить в компоновщик ранее сохраненные в XML настройки или, наоборот, выгрузить в XML  (см. примеры в комментариях). Функции рекомендуется разместить в клиент-серверном общем модуле.

# Код реализации

```1c
// СкопироватьЭлементыНастроекКомпоновкиДанных  —  копирует однотипные коллекции элементов настроек Компоновки Данных
//
// Параметры:
// КоллекцияПриемник —  — приемник,коллекция элементов Компоновки Данных, того же типа, что и источник
// КоллекцияИсточник —  — источник, любая коллекция элементов Компоновки Данных
// ОчищатьПриемник — Булево — при значении Истина (по умолчанию) предварительно очищается коллекция приемник
//
// Пример:
//А.
//	ЗаписьXML = Новый ЗаписьXML;
//	ЗаписьXML.УстановитьСтроку();
//	СериализаторXDTO.ЗаписатьXML(ЗаписьXML, НастройкиОтбора , "Filter", "http://v8.1c.ru/8.1/data-composition-system/settings");
//  УсловияСопоставленияДокументовXML = ЗаписьXML.Закрыть();
//  ......
//	ЧтениеXML = Новый ЧтениеXML;
//	ЧтениеXML.УстановитьСтроку(УсловияСопоставленияДокументовXML);
//	НастройкиОтбораДокументов = СериализаторXDTO.ПрочитатьXML(ЧтениеXML, Тип("ОтборКомпоновкиДанных"));
//      СкопироватьЭлементыНастроекКомпоновкиДанных(КомпоновщикНастроек.Настройки.Отбор, НастройкиОтбораДокументов, Истина);
//
//Б.
//	СкопироватьЭлементыНастроекКомпоновкиДанных(ОтчетОбъект.КомпоновщикНастроек.Настройки.Порядок, Настройки.Порядок, Истина);
Процедура СкопироватьЭлементыНастроекКомпоновкиДанных(Знач КоллекцияПриемник, Знач КоллекцияИсточник, Знач ОчищатьПриемник = Истина) Экспорт

    Если ТипЗнч(КоллекцияИсточник) = Тип("УсловноеОформлениеКомпоновкиДанных")
        ИЛИ ТипЗнч(КоллекцияИсточник) = Тип("ВариантыПользовательскогоПоляВыборКомпоновкиДанных")
        ИЛИ ТипЗнч(КоллекцияИсточник) = Тип("ОформляемыеПоляКомпоновкиДанных")
        ИЛИ ТипЗнч(КоллекцияИсточник) = Тип("ЗначенияПараметровДанныхКомпоновкиДанных") Тогда
        СоздаватьПоТипу = Ложь;
    Иначе
        СоздаватьПоТипу = Истина;
    КонецЕсли;

    ПриемникЭлементов = КоллекцияПриемник.Элементы;
    Если ОчищатьПриемник Тогда
        ПриемникЭлементов.Очистить();
    КонецЕсли;
    ИсточникЭлементов = КоллекцияИсточник.Элементы;

    Для каждого ЭлементИсточник Из ИсточникЭлементов Цикл

        Если ТипЗнч(ЭлементИсточник) = Тип("ЭлементПорядкаКомпоновкиДанных") Тогда
            Индекс = ИсточникЭлементов.Индекс(ЭлементИсточник);                            // Элементы порядка добавляем в начало

            ЭлементПриемник = ПриемникЭлементов.Вставить(Индекс, ТипЗнч(ЭлементИсточник));
        Иначе
            Если СоздаватьПоТипу Тогда
                ЭлементПриемник = ПриемникЭлементов.Добавить(ТипЗнч(ЭлементИсточник));
            Иначе
                ЭлементПриемник = ПриемникЭлементов.Добавить();
            КонецЕсли;
        КонецЕсли;

        ЗаполнитьЗначенияСвойств(ЭлементПриемник, ЭлементИсточник);

        // скопируем вложенные коллекции
        Если ТипЗнч(ИсточникЭлементов) = Тип("КоллекцияЭлементовУсловногоОформленияКомпоновкиДанных") Тогда
            СкопироватьЭлементыНастроекКомпоновкиДанных(ЭлементПриемник.Поля, ЭлементИсточник.Поля);
            СкопироватьЭлементыНастроекКомпоновкиДанных(ЭлементПриемник.Отбор, ЭлементИсточник.Отбор);
            ЗаполнитьЭлементыНастроекКомпоновкиДанных(ЭлементПриемник.Оформление, ЭлементИсточник.Оформление);
        ИначеЕсли ТипЗнч(ИсточникЭлементов) = Тип("КоллекцияВариантовПользовательскогоПоляВыборКомпоновкиДанных") Тогда
            СкопироватьЭлементыНастроекКомпоновкиДанных(ЭлементПриемник.Отбор, ЭлементИсточник.Отбор);
        КонецЕсли;

        // скопируем подчиненные коллекции
        Если ТипЗнч(ЭлементИсточник) = Тип("ГруппаЭлементовОтбораКомпоновкиДанных") Тогда
            СкопироватьЭлементыНастроекКомпоновкиДанных(ЭлементПриемник, ЭлементИсточник);
        ИначеЕсли ТипЗнч(ЭлементИсточник) = Тип("ГруппаВыбранныхПолейКомпоновкиДанных") Тогда
            СкопироватьЭлементыНастроекКомпоновкиДанных(ЭлементПриемник, ЭлементИсточник);
        ИначеЕсли ТипЗнч(ЭлементИсточник) = Тип("ПользовательскоеПолеВыборКомпоновкиДанных") Тогда
            СкопироватьЭлементыНастроекКомпоновкиДанных(ЭлементПриемник.Варианты, ЭлементИсточник.Варианты);
        ИначеЕсли ТипЗнч(ЭлементИсточник) = Тип("ПользовательскоеПолеВыражениеКомпоновкиДанных") Тогда
            ЭлементПриемник.УстановитьВыражениеДетальныхЗаписей (ЭлементИсточник.ПолучитьВыражениеДетальныхЗаписей());
            ЭлементПриемник.УстановитьВыражениеИтоговыхЗаписей(ЭлементИсточник.ПолучитьВыражениеИтоговыхЗаписей());
            ЭлементПриемник.УстановитьПредставлениеВыраженияДетальныхЗаписей(ЭлементИсточник.ПолучитьПредставлениеВыраженияДетальныхЗаписей ());
            ЭлементПриемник.УстановитьПредставлениеВыраженияИтоговыхЗаписей(ЭлементИсточник.ПолучитьПредставлениеВыраженияИтоговыхЗаписей ());
        КонецЕсли;

    КонецЦикла;

КонецПроцедуры

// ЗаполнитьЭлементыНастроекКомпоновкиДанных  —  копирует однотипные коллекции значений параметров настроек Компоновки Данных
//
// Параметры:
// ПриемникЗначения —  — приемник, коллекция однотипная с источником
// ИсточникЗначения —  — источник, любая коллекция значений параметров настроек Компоновки Данных
// ПредыдущийУровень —  — предыдущий уровень в иерархии приемника
//
Процедура ЗаполнитьЭлементыНастроекКомпоновкиДанных(Знач ПриемникЗначения, Знач ИсточникЗначения, Знач ПредыдущийУровень = Неопределено) Экспорт

    Если ТипЗнч(ПриемникЗначения) = Тип("КоллекцияЗначенийПараметровКомпоновкиДанных") Тогда
        КоллекцияЗначений = ИсточникЗначения;
    Иначе
        КоллекцияЗначений = ИсточникЗначения.Элементы;
    КонецЕсли;

    Для каждого ЭлементИсточник Из КоллекцияЗначений Цикл
        Если ПредыдущийУровень = Неопределено Тогда
            ЭлементПриемник = ПриемникЗначения.НайтиЗначениеПараметра(ЭлементИсточник.Параметр);
        Иначе
            ЭлементПриемник = ПредыдущийУровень.НайтиЗначениеПараметра(ЭлементИсточник.Параметр);
        КонецЕсли;
        Если ЭлементПриемник = Неопределено Тогда
            Продолжить;
        КонецЕсли;
        ЗаполнитьЗначенияСвойств(ЭлементПриемник, ЭлементИсточник);
        Если ТипЗнч(ЭлементИсточник) = Тип("ЗначениеПараметраКомпоновкиДанных") Тогда
            Если ЭлементИсточник.ЗначенияВложенныхПараметров.Количество() <> 0 Тогда
                ЗаполнитьЭлементыНастроекКомпоновкиДанных(ЭлементПриемник.ЗначенияВложенныхПараметров, ЭлементИсточник.ЗначенияВложенныхПараметров, ПриемникЗначения);
            КонецЕсли;
        КонецЕсли;
    КонецЦикла;

КонецПроцедуры
```