Полезные процедуры по работе с СКД и динамическими списками (часть 3)

19.11.18

Разработка - СКД

Еще пара приемов в копилку разработчика.

1. Копирование настроек СКД и динамических списков

Приведенная ниже функция позволяет скопировать любой элемент коллекции СКД со всеми вложенными в него элементами. Умеет копировать все элементы, перечисленные в таблицах в другой моей публикации.

Варианты использования:

  • Вариант 1. На форме есть динамический список с отбором. Необходимо при открытии этой формы восстанавливать отборы, настроенные пользователем ранее.
  • Вариант 2. Необходимо полностью или частично перенести настройки между схемами компоновки, компоновщиками настроек, динамическими списками.

Пример сохранения отборов для динамического списка.
- Создадим на форме динамический список СписокКонтрагенты.
- Выведем отбор списка в виде поля
- Создадим реквизит формы СписокКонтрагентыОтборСохранение с типом Произвольный

 

- При изменении отбора будем записывать новый отбор в реквизит СписокКонтрагентыОтборСохранение
- При восстановлении настроек будем заполнять отбор из сохраненного реквизита

&НаКлиенте
Процедура СписокКонтрагентыОтборПриИзменении(Элемент)
	СписокКонтрагентыОтборСохранение = СписокКонтрагенты.Отбор;
КонецПроцедуры

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

 

Это демонстрация использования функции копирования на примере отборов динамических списков. Но она универсальна и применялась мною для программной работы с настройками СКД.

 

2. Предопределенные отборы динамических списков

Пусть на форме есть два динамических списка Контрагенты и Договоры. 
Необходимо при двойном щелчке по первому списку, устанавливать отбор во втором списке. 
При этом пользователь имеет возможность установить дополнительные условия в отборе второго списка и они должны сохраняться.
Например, пользователь может установить условие, чтобы отображались только договоры с покупателем. А при щелчке по контрагенту, необходимо, чтобы в отборе изменился контрагент, но не удалился отбор по типу договора. 
В нашем упрощенном примере предопределенное условие только одно. Но предопределенных условий может быть и несколько, например, еще по периоду, если это выборка по документам контрагента.

Пример решения.
- Все предопределенные условия помещаем в группу "И". 
- У этой группы задаем некое предопределенное представление
- Перед установкой отбора ищем предопределенную группу и удаляем ее
- Затем создааем ее снова и помещаем в нее все необходимые условия

&НаКлиенте
Процедура СписокКонтрагентыВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
	СтандартнаяОбработка = Ложь;
	СписокКонтрагентыВыборНаСервере(ВыбраннаяСтрока);
КонецПроцедуры

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

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

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

 

Применение метода рассматривается на примере отборов динамических списков, но этот же принцип можно использовать для работы с настройками СКД.

 

Заключение

Тестировалось на платформе 8.3.8+, режим совместимости 8.2.13+. Но описанные приемы должны работать и на более ранних версиях 1С 8.
 

процедуры процедура функции функция СКД отбор отборы Компоновка Схема универсальные универсальная компоновки библиотечные универсальная

См. также

SALE! 20%

Infostart Toolkit: Инструменты разработчика 1С 8.3 на управляемых формах

Инструментарий разработчика Роли и права Запросы СКД Платформа 1С v8.3 Управляемые формы Запросы Система компоновки данных Конфигурации 1cv8 Платные (руб)

Набор инструментов программиста и специалиста 1С для всех конфигураций на управляемых формах. В состав входят инструменты: Консоль запросов, Консоль СКД, Консоль кода, Редактор объекта, Анализ прав доступа, Метаданные, Поиск ссылок, Сравнение объектов, Все функции, Подписки на события и др. Редактор запросов и кода с раскраской и контекстной подсказкой. Доработанный конструктор запросов тонкого клиента. Продукт хорошо оптимизирован и обладает самым широким функционалом среди всех инструментов, представленных на рынке.

13000 10400 руб.

02.09.2020    121542    670    389    

709

Генератор схемы компоновки данных (СКД), написание кода схемы программно

Инструментарий разработчика СКД Платформа 1С v8.3 Конфигурации 1cv8 1С:Зарплата и Управление Персоналом 3.x Абонемент ($m)

По выбранной схеме компоновки данных генерирует программный код, который генерирует СКД, аналогичную исходной схеме. Есть дополнительные инструменты для просмотра дерева схемы, сравнение исходной схемы и полученной по коду, а также сравнение изменений в сгенерированном коде для исходной схемы и для измененной.

3 стартмани

05.02.2024    4022    25    obmailok    17    

63

Набор-объект для СКД по тексту или запросу

Запросы СКД Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Абонемент ($m)

Есть список полей в виде текста, или запрос - закидываем в набор СКД.

1 стартмани

31.01.2024    1996    2    Yashazz    0    

29

СКД на JavaScript в 1С

СКД WEB-интеграция Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Долгое время поддерживаю web-портал, в котором появилась необходимость создавать отчеты. Просмотрев различные фреймворки на js, я решил сделать свое решение, которое позволяло бы быстро разрабатывать и добавлять новые отчеты на web-портал.

2 стартмани

11.12.2023    8149    20    John_d    25    

123

Использование менеджера временных таблиц в СКД

СКД Платформа 1С v8.3 Система компоновки данных Конфигурации 1cv8 Бесплатно (free)

Рассмотрим еще не получивший широкого распространения способ работы с внешними данным в СКД. В процессе обсуждения работы с СКД выяснилось, что многие не знакомы со способом помещения туда временной таблицы, полученной предварительно. Статья будет полезна разработчикам, знакомым с программным созданием СКД.

05.12.2023    4644    PROSTO-1C    13    

61

Модель СКД

Инструментарий разработчика СКД Платформа 1С v8.3 Система компоновки данных Абонемент ($m)

DSL для работы с СКД.

1 стартмани

15.11.2023    5800    15    kalyaka    5    

86

Пользовательские настройки отчетов 1С. Часть 1. Простые и расширенные настройки

СКД Инструкции пользователю Платформа 1С v8.3 Конфигурации 1cv8 1С:Бухгалтерия 3.0 Россия Бесплатно (free)

Простые приемы работы с отчетами на СКД. Что нужно знать пользователю про настройку отчетов, чтобы использовать их на полную катушку.

18.09.2023    6676    accounting_cons    5    

29

Разрыв страницы в СКД. Легко!

СКД Платформа 1С v8.3 Система компоновки данных Бесплатно (free)

Когда отчет надо разделить по страницам, это всегда проблема для разработчика. Поскольку в СКД нет стандартных вариантов, как это сделать. Нашел (на свой взгляд) самое простое и оптимальное решение.

01.09.2023    4510    KVIKS    15    

80
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. VmvLer 19.11.18 17:19 Сейчас в теме
Такая подача материала характеризуется очень просто - "в час по чайной ложе".
Если быть честным до конце, то это просто халтура.

мое мнение может не совпадать ...бла бла бла.
dooD1iez; oleg-x; +2 2 Ответить
2. json 3297 19.11.18 21:23 Сейчас в теме
(1) Тролли всегда найдут до чего докопаться. Их мнение меня слабо интересует
3. al_zzz 309 20.11.18 08:04 Сейчас в теме
(1) Сказал человек, имеющий нулевой вклад в сообщество...
denis_aka_wolf; +1 Ответить
4. oleg-x 26 20.11.18 18:56 Сейчас в теме
(1) Верну тебе один минус, но все же. Может и по чайной ложке, но из таких маленьких статей, потом можно собрать всю необходимую информации. Если сделать конкретный запрос, получишь ссылку на статью (если она есть) с конкретным ответом. И не придется листать огромную статью, в поисках нужного материала.
А если модераторы пропустили статью, значит какое то право на жизнь она имеет.
5. triviumfan 92 20.11.18 21:13 Сейчас в теме
Ребят, это же все есть в БСП...
КомпоновкаДанныхКлиентСервер.СкопироватьЭлементы();
КомпоновкаДанныхКлиентСервер.ДобавитьОтбор();
...
sapervodichka; rpgshnik; mitia.mackarevich; +3 Ответить
6. oleg-x 26 20.11.18 21:17 Сейчас в теме
(5) А если я не пользуюсь БСП и не хочу копаться в этом монстре? :-)
7. json 3297 20.11.18 21:19 Сейчас в теме
(5) в 2.4?
В 2.3.5 я такого не нашел
8. mitia.mackarevich 72 21.11.18 02:55 Сейчас в теме
(7) Плюсану, но "Не нашел как добавить отбор в элемент"????? что же такое творится то !!!
ОбщегоНазначенияКлиентСервер - живет там не первый год вместе со всем остальным
по поводу первого - сериализатором XDTО не проще воспользоваться для сохранения настроек и всего прочего - благо все сериализуется? Все равно если реквизит сохранятеся в хранилище настроек форм - там то он хранится в сериализованном виде
11. json 3297 21.11.18 07:09 Сейчас в теме
(8) настройки динамических списков не сохраняются. Нет там галочки Сохранение, посмотрите повнимательнее.
Если же их сериализовать, то чтобы потом вставить в динамический список, нужна функция копирования отборов. Я такой функции в типовых конфигурациях не встречал. Если встречали вы, то просьба скинуть в каком модуле она лежит и как называется

И кстати, предложенная мною функция копирует не только отборы, а любые элементы настроек. Отборы приведены в качестве примера
20. mitia.mackarevich 72 21.11.18 10:09 Сейчас в теме
(11)
) настройки динамических списков не сохраняются.

Я про реквизиты формы в целом писал - предварительная сериализация проходит, как еще они иначе храняться=)
21. json 3297 21.11.18 10:11 Сейчас в теме
(20)
да, прошу прощения, неправильно понял. С телефона читал.
9. json 3297 21.11.18 06:41 Сейчас в теме
(5)
(8)
Коллеги, позвольте уточнить, что во второй части публикации основная мысль не "как добавить отбор", а "как установить служебный отбор в списке, в котором уже могут присутствовать ручные и служебные отборы". Я этот служебный отбор назвал Предопределенным. Моя идея в том, чтобы собрать их в группу, а группу узнавать по представлению. Тогда служебные отборы будут жить вместе с ручными и мы не удалим лишнего при переключении служебного отбора.
Подумаю, как лучше сформулировать эту мысль в публикации, чтобы не возникало таких двусмысленностей.
12. VmvLer 21.11.18 09:07 Сейчас в теме
(9) эта идея - велик, причем устаревшей модели

а вопящите тут, мол, "чайная ложка" это класс - просто лентяи.

Конечно, можно отдать свой мозг во власть поисковых гагантов и по малейшему поводу
вяло шептать "ок, гугл найди на инфостар ченить по отборам"

А можно использовать мозг по назначению - изучить общие модули и всегда быть на коне
полученных знаний.
13. json 3297 21.11.18 09:19 Сейчас в теме
(12)
эта идея - велик, причем устаревшей модели

это вы как обычно троллите?
Или сможете привести доказательство, что вы это уже где-нибудь встречали?

А можно использовать мозг по назначению - изучить общие модули и всегда быть на коне
полученных знаний.

Слова человека, который прикипел к одной конфигурации и не представляет себе ситуации, когда разработчик может поддерживать десять и более конфигураций одновременно, с разными версиями БСП, с разными режимами совместимости.
14. VmvLer 21.11.18 09:30 Сейчас в теме
(13) могу, но зачем я буду тратить время на очевидное, пролистайте общие модули современных конфигураций и вам станет ясно насколько банальна эта тема.
15. json 3297 21.11.18 09:36 Сейчас в теме
(14) если бы могли, то сделали.
А если не хотите тратить свое время - то что вы тут комментируете тогда.
Дело не во времени, а в том, что вы сначала написали, а потом не можете подтвердить свои слова. Так делают обычные балаболы
Dmitri93; ixijixi; +2 Ответить
16. VmvLer 21.11.18 09:47 Сейчас в теме
(15) "лечить" наивность труд неблагодарный, вы должны сами все найти и усвоить, тогда будет толк. Лучший способ это сделать - балаболить.

"хотите про это поговорить?"
17. json 3297 21.11.18 09:50 Сейчас в теме
(16) спасибо за ваши советы, о великий разработчик, зарегестрированный 1,5 года назад даже без аватара.
Буду счастлив, если вы избавите меня от своих комментариев
18. VmvLer 21.11.18 09:58 Сейчас в теме
(17) это ж хорошо, если мои слова делают вас счастливее, а ум пытливым

будет отлично - если вы избавитесь от привычки уходить от темы на личности.
19. json 3297 21.11.18 10:00 Сейчас в теме
(18)
а дело не в личности, а в вашей компетенции.
Сколько я ни пытаюсь, не могу понять, почему ваши слова достойны внимания. Что вы из себя представляете как специалист. Чем вы отличаетесь от тролля

С любого конкретного вопроса вы съезжаете. Типа нет времени или еще какая причина.
Но зато грязь подливаете вы охотно, причем не только в мою публикацию
10. json 3297 21.11.18 06:50 Сейчас в теме
(5)
Немного неточно сформулировал мой вопрос.
Я не могу найти модуль КомпоновкаДанныхКлиентСервер и метод СкопироватьЭлементы().

Установил ещё БСП 3, но не оказалось на компе платформы 12. Чуть позже поковыряюсь. Интересно что там нового появилось.

Спасибо за комментарий. Возможно действительно велосипед, но я ее писал полтора года назад, когда ещё не было новых БСП
22. triviumfan 92 21.11.18 11:19 Сейчас в теме
(10) У меня УТ11, я эти модули видел ещё пару лет назад.
УТ11.3.4.228 используетверсию 2.3.6.196 стандартной подсистемы, но этот модуль появился ещё хз когда... но очень давно.

КомпоновкаДанныхКлиентСервер
////////////////////////////////////////////////////////////­////////////////////
//МОДУЛЬ СОДЕРЖИТ ПРОЦЕДУРЫ И ФУНКЦИИ ДЛЯ РАБОТЫ С СКД
//
////////////////////////////////////////////////////////////­////////////////////

#Область ПрограммныйИнтерфейс

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

// Добавляет группировку в компоновщик настроек в самый нижний уровень структуры, если поле не указано - детальные поля
//
// Параметры:
//	КомпоновщикНастроек	- КомпоновщикНастроекКомпоновкиДанных, НастройкиКомпоновкиДанных - элемент структуры КД
//	Поле				- Строка, ПолеКомпоновкиДанных - имя или поле КД
//	Строки				- Булево - признак для получения последний группировки строк (Серий) или колонок (точек)
//	ПараметрыДГруппировки - Структура
//		* НачалоПериода  - Дата - начало периода группировки по полю периода
//		* КонецПериода   - Дата - конец периода группировки по полю периода
//		* ТипГруппировки - ТипГруппировкиКомпоновкиДанных
//		* ТипДополнения  - ТипДополненияПериодаКомпоновкиДанных
//
// Возвращаемое значение:
//	ГруппировкаТаблицыКомпоновкиДанных, ГруппировкаДиаграммыКомпоновкиДанных, 
//	ЭлементСтруктурыТаблицыКомпоновкиДанных, ЭлементСтруктурыДиаграммыКомпоновкиДанных
//	ГруппировкаКомпоновкиДанных - новая группировка
//
Функция ДобавитьГруппировку(КомпоновщикНастроек, Знач Поле = Неопределено, Строки = Истина, ПараметрыГруппировки = Неопределено) Экспорт
	
	Если ПараметрыГруппировки = Неопределено Тогда
		ПараметрыГруппировки = Новый Структура("НачалоПериода, КонецПериода, ТипГруппировки, ТипДополнения");
	КонецЕсли;
	
	ЭлементСтруктуры = ПолучитьПоследнийЭлементСтруктуры(КомпоновщикНастроек, Строки);
	Если ЭлементСтруктуры = Неопределено 
		ИЛИ ПолучитьЭлементСтруктурыДетальныеЗаписи(КомпоновщикНастроек) <> Неопределено 
		И Поле = Неопределено Тогда
		Возврат Неопределено;
	КонецЕсли;
	
	Если ТипЗнч(Поле) = Тип("Строка") Тогда
		Поле = Новый ПолеКомпоновкиДанных(Поле);
	КонецЕсли;
	
	Если ТипЗнч(ЭлементСтруктуры) = Тип("ГруппировкаТаблицыКомпоновкиДанных") 
	 ИЛИ ТипЗнч(ЭлементСтруктуры) = Тип("ГруппировкаДиаграммыКомпоновкиДанных") Тогда
		НоваяГруппировка = ЭлементСтруктуры.Структура.Добавить();
	ИначеЕсли ТипЗнч(ЭлементСтруктуры) = Тип("КоллекцияЭлементовСтруктурыТаблицыКомпоновкиДанных")
			ИЛИ ТипЗнч(ЭлементСтруктуры) = Тип("КоллекцияЭлементовСтруктурыДиаграммыКомпоновкиДанных") Тогда
		НоваяГруппировка = ЭлементСтруктуры.Добавить();
	Иначе
		НоваяГруппировка = ЭлементСтруктуры.Структура.Добавить(Тип("ГруппировкаКомпоновкиДанных"));
	КонецЕсли;
	
	НоваяГруппировка.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных"));
	НоваяГруппировка.Порядок.Элементы.Добавить(Тип("АвтоЭлементПорядкаКомпоновкиДанных"));
	Если Поле <> Неопределено Тогда
		ПолеГруппировки = НоваяГруппировка.ПоляГруппировки.Элементы.Добавить(Тип("ПолеГруппировкиКомпоновкиДанных"));
		ПолеГруппировки.Поле = Поле;
		
		Если ПараметрыГруппировки.НачалоПериода <> Неопределено 
			И ТипЗнч(ПараметрыГруппировки.НачалоПериода) = Тип("Дата") Тогда
			ПолеГруппировки.НачалоПериода = ПараметрыГруппировки.НачалоПериода;
		КонецЕсли;
		Если ПараметрыГруппировки.КонецПериода <> Неопределено 
			И ТипЗнч(ПараметрыГруппировки.КонецПериода) = Тип("Дата") Тогда
			ПолеГруппировки.КонецПериода = ПараметрыГруппировки.КонецПериода;
		КонецЕсли;
		Если ПараметрыГруппировки.ТипГруппировки <> Неопределено 
			И ТипЗнч(ПараметрыГруппировки.ТипГруппировки) = Тип("ТипГруппировкиКомпоновкиДанных") Тогда
			ПолеГруппировки.ТипГруппировки = ПараметрыГруппировки.ТипГруппировки;
		КонецЕсли;
		Если ПараметрыГруппировки.ТипДополнения <> Неопределено 
			И ТипЗнч(ПараметрыГруппировки.ТипДополнения) = Тип("ТипДополненияПериодаКомпоновкиДанных") Тогда
			ПолеГруппировки.ТипДополнения = ПараметрыГруппировки.ТипДополнения;
		КонецЕсли;
	КонецЕсли;
	Возврат НоваяГруппировка;
	
КонецФункции

// Добавляет группировку в компоновщик настроек в корневой уровень структуры настроек, если поле не указано - детальные поля
//
// Параметры:
//	КомпоновщикНастроек	- КомпоновщикНастроекКомпоновкиДанных, НастройкиКомпоновкиДанных - элемент структуры КД
//	Поле				- Строка, ПолеКомпоновкиДанных - имя или поле КД
//	ПараметрыДГруппировки - Структура
//		* НачалоПериода  - Дата - начало периода группировки по полю периода
//		* КонецПериода   - Дата - конец периода группировки по полю периода
//		* ТипГруппировки - ТипГруппировкиКомпоновкиДанных
//		* ТипДополнения  - ТипДополненияПериодаКомпоновкиДанных
//
// Возвращаемое значение:
//	ГруппировкаТаблицыКомпоновкиДанных, ГруппировкаДиаграммыКомпоновкиДанных, 
//	ЭлементСтруктурыТаблицыКомпоновкиДанных, ЭлементСтруктурыДиаграммыКомпоновкиДанных
//	ГруппировкаКомпоновкиДанных - новая группировка в корне структуры
//
Функция ДобавитьГруппировкуВКореньСтруктуры(КомпоновщикНастроек, Знач Поле = Неопределено, ПараметрыГруппировки = Неопределено) Экспорт
	
	Если ПараметрыГруппировки = Неопределено Тогда
		ПараметрыГруппировки = Новый Структура("НачалоПериода, КонецПериода, ТипГруппировки, ТипДополнения");
	КонецЕсли;
	
	Если Поле = Неопределено Тогда
		Возврат Неопределено;
	КонецЕсли;
	
	ЭлементСтруктуры = КомпоновщикНастроек.Настройки;
	
	Если ТипЗнч(Поле) = Тип("Строка") Тогда
		Поле = Новый ПолеКомпоновкиДанных(Поле);
	КонецЕсли;
	
	НоваяГруппировка = ЭлементСтруктуры.Структура.Добавить(Тип("ГруппировкаКомпоновкиДанных"));
	
	НоваяГруппировка.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных"));
	НоваяГруппировка.Порядок.Элементы.Добавить(Тип("АвтоЭлементПорядкаКомпоновкиДанных"));
	Если Поле <> Неопределено Тогда
		ПолеГруппировки = НоваяГруппировка.ПоляГруппировки.Элементы.Добавить(Тип("ПолеГруппировкиКомпоновкиДанных"));
		ПолеГруппировки.Поле = Поле;
		
		Если ПараметрыГруппировки.НачалоПериода <> Неопределено 
			И ТипЗнч(ПараметрыГруппировки.НачалоПериода) = Тип("Дата") Тогда
			ПолеГруппировки.НачалоПериода = ПараметрыГруппировки.НачалоПериода;
		КонецЕсли;
		Если ПараметрыГруппировки.КонецПериода <> Неопределено 
			И ТипЗнч(ПараметрыГруппировки.КонецПериода) = Тип("Дата") Тогда
			ПолеГруппировки.КонецПериода = ПараметрыГруппировки.КонецПериода;
		КонецЕсли;
		Если ПараметрыГруппировки.ТипГруппировки <> Неопределено 
			И ТипЗнч(ПараметрыГруппировки.ТипГруппировки) = Тип("ТипГруппировкиКомпоновкиДанных") Тогда
			ПолеГруппировки.ТипГруппировки = ПараметрыГруппировки.ТипГруппировки;
		КонецЕсли;
		Если ПараметрыГруппировки.ТипДополнения <> Неопределено 
			И ТипЗнч(ПараметрыГруппировки.ТипДополнения) = Тип("ТипДополненияПериодаКомпоновкиДанных") Тогда
			ПолеГруппировки.ТипДополнения = ПараметрыГруппировки.ТипДополнения;
		КонецЕсли;
	КонецЕсли;
	Возврат НоваяГруппировка;
	
КонецФункции

// Добавляет отбор в коллекцию отборов компоновщика или группы отборов
//
// Параметры:
//	ЭлементСтруктуры        - КомпоновщикНастроекКомпоновкиДанных, НастройкиКомпоновкиДанных - элемент структуры КД
//	Поле                    - Строка - имя поля, по которому добавляется отбор
//	Значение                - Произвольный - значение отбора КД
//	ВидСравнения            - ВидСравненияКомпоновкиДанных - вид сравнений КД (по умолчанию: Неопределено)
//	Использование           - Булево - признак использования отбора (по умолчанию: Истина)
//	ДополнительныеПараметры - Структура
//		* ВПользовательскиеНастройки - Булево - признак добавления в пользовательсие настройки КД (по умолчанию: ложь)
//		* ЗаменятьСуществующий       - Булево - признак полной замены существующего отбора по полю (по умолчанию: истина)
//
// Возвращаемое значение:
//	ЭлементОтбораКомпоновкиДанных - добавленный отбор
//
Функция ДобавитьОтбор(ЭлементСтруктуры, Знач Поле, Значение = Неопределено, ВидСравнения = Неопределено, Использование = Истина, ДополнительныеПараметры = Неопределено) Экспорт
		
	Если ДополнительныеПараметры = Неопределено Тогда
		ДополнительныеПараметры = Новый Структура("ВПользовательскиеНастройки, ЗаменятьСуществующий", Ложь, Истина); 
	Иначе
		Если Не ДополнительныеПараметры.Свойство("ВПользовательскиеНастройки") Тогда
			ДополнительныеПараметры.Вставить("ВПользовательскиеНастройки", Ложь);
		КонецЕсли;
		Если Не ДополнительныеПараметры.Свойство("ЗаменятьСуществующий") Тогда
			ДополнительныеПараметры.Вставить("ЗаменятьСуществующий", Истина);
		КонецЕсли;
	КонецЕсли;
	
	Если ТипЗнч(Поле) = Тип("Строка") Тогда
		Поле = Новый ПолеКомпоновкиДанных(Поле);
	КонецЕсли;
	
	Если ТипЗнч(ЭлементСтруктуры) = Тип("КомпоновщикНастроекКомпоновкиДанных") Тогда
		Отбор = ЭлементСтруктуры.Настройки.Отбор;
		
		Если ДополнительныеПараметры.ВПользовательскиеНастройки Тогда
			Для Каждого ЭлементНастройки Из ЭлементСтруктуры.ПользовательскиеНастройки.Элементы Цикл
				Если ЭлементНастройки.ИдентификаторПользовательскойНастройки = ЭлементСтруктуры.Настройки.Отбор.ИдентификаторПользовательскойНастройки Тогда
					Отбор = ЭлементНастройки;
				КонецЕсли;
			КонецЦикла;
		КонецЕсли;
		
	ИначеЕсли ТипЗнч(ЭлементСтруктуры) = Тип("НастройкиКомпоновкиДанных") Тогда
		Отбор = ЭлементСтруктуры.Отбор;
	Иначе
		Отбор = ЭлементСтруктуры;
	КонецЕсли;
	
	Если ВидСравнения = Неопределено Тогда
		ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
	КонецЕсли;
	
	ЭлементОтбора = Неопределено;
	Если ДополнительныеПараметры.ЗаменятьСуществующий Тогда
		Для каждого Элемент Из Отбор.Элементы Цикл
			
			Если ТипЗнч(Элемент) = Тип("ГруппаЭлементовОтбораКомпоновкиДанных") Тогда
				Продолжить;
			КонецЕсли;
			
			Если Элемент.ЛевоеЗначение = Поле Тогда
				ЭлементОтбора = Элемент;
			КонецЕсли;
			
		КонецЦикла;
	КонецЕсли;
	
	Если ЭлементОтбора = Неопределено Тогда
		ЭлементОтбора = Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	КонецЕсли;
	ЭлементОтбора.Использование		= Использование;
	ЭлементОтбора.ЛевоеЗначение		= Поле;
	ЭлементОтбора.ВидСравнения		= ВидСравнения;
	ЭлементОтбора.ПравоеЗначение	= Значение;
	
	Возврат ЭлементОтбора;
	
КонецФункции

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

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

// Отключает в корневом элементе вывод общих итогов по вертикали и горизонтали
// Параметры:
//  Настройки - НастройкиКомпоновкиДанных - изменяемые настройки
//
Процедура ОтключитьВыводОбщихИтогов(Настройки) Экспорт
	
	УстановитьПараметрВывода(Настройки, "ГоризонтальноеРасположениеОбщихИтогов", РасположениеИтоговКомпоновкиДанных.Нет);
	УстановитьПараметрВывода(Настройки, "ВертикальноеРасположениеОбщихИтогов", РасположениеИтоговКомпоновкиДанных.Нет);
		
КонецПроцедуры

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

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

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

// Возвращает последний элемент структуры - группировку
//
// Параметры:
//	ЭлементСтруктурыНастроек - КомпоновщикНастроекКомпоновкиДанных, НастройкиКомпоновкиДанных - элемент структуры КД
//	Строки - Булево - признак для получения последний группировки строк (серий) или колонок (точек)
//
// Возвращаемое значение:
//	КоллекцияЭлементовСтруктурыДиаграммыКомпоновкиДанных, КоллекцияЭлементовСтруктурыТаблицыКомпоновкиДанных, КоллекцияЭлементовСтруктурыНастроекКомпоновкиДанных - Неопределено, если ничего не найдено
//
Функция ПолучитьПоследнийЭлементСтруктуры(ЭлементСтруктурыНастроек, Строки = Истина) Экспорт
	
	Если ТипЗнч(ЭлементСтруктурыНастроек) = Тип("КомпоновщикНастроекКомпоновкиДанных") Тогда
		Настройки = ЭлементСтруктурыНастроек.Настройки;
	ИначеЕсли ТипЗнч(ЭлементСтруктурыНастроек) = Тип("НастройкиКомпоновкиДанных") Тогда
		Настройки = ЭлементСтруктурыНастроек;
	Иначе
		Возврат Неопределено;
	КонецЕсли;
	
	Структура = Настройки.Структура;
	Если Структура.Количество() = 0 Тогда
		Возврат Настройки;
	КонецЕсли;
	
	Если Строки Тогда
		ИмяСтруктурыТаблицы = "Строки";
		ИмяСтруктурыДиаграммы = "Серии";
	Иначе
		ИмяСтруктурыТаблицы = "Колонки";
		ИмяСтруктурыДиаграммы = "Точки";
	КонецЕсли;
	
	Пока Истина Цикл
		ЭлементСтруктуры = Структура[0];
		Если ТипЗнч(ЭлементСтруктуры) = Тип("ТаблицаКомпоновкиДанных") И ЭлементСтруктуры[ИмяСтруктурыТаблицы].Количество() > 0 Тогда
			Если ЭлементСтруктуры[ИмяСтруктурыТаблицы][0].Структура.Количество() = 0 Тогда
				Структура = ЭлементСтруктуры[ИмяСтруктурыТаблицы];
				Прервать;
			КонецЕсли;
			Структура = ЭлементСтруктуры[ИмяСтруктурыТаблицы][0].Структура;
		ИначеЕсли ТипЗнч(ЭлементСтруктуры) = Тип("ДиаграммаКомпоновкиДанных") И ЭлементСтруктуры[ИмяСтруктурыДиаграммы].Количество() > 0 Тогда
			Если ЭлементСтруктуры[ИмяСтруктурыДиаграммы][0].Структура.Количество() = 0 Тогда
				Структура = ЭлементСтруктуры[ИмяСтруктурыДиаграммы];
				Прервать;
			КонецЕсли;
			Структура = ЭлементСтруктуры[ИмяСтруктурыДиаграммы][0].Структура;
		ИначеЕсли ТипЗнч(ЭлементСтруктуры) = Тип("ГруппировкаКомпоновкиДанных")
			  ИЛИ ТипЗнч(ЭлементСтруктуры) = Тип("ГруппировкаТаблицыКомпоновкиДанных")
			  ИЛИ ТипЗнч(ЭлементСтруктуры) = Тип("ГруппировкаДиаграммыКомпоновкиДанных") Тогда
			Если ЭлементСтруктуры.Структура.Количество() = 0 Тогда
				Прервать;
			КонецЕсли;
			Структура = ЭлементСтруктуры.Структура;
		ИначеЕсли ТипЗнч(ЭлементСтруктуры) = Тип("ТаблицаКомпоновкиДанных") Тогда
			Возврат ЭлементСтруктуры[ИмяСтруктурыТаблицы];
		ИначеЕсли ТипЗнч(ЭлементСтруктуры) = Тип("ДиаграммаКомпоновкиДанных")	Тогда
			Возврат ЭлементСтруктуры[ИмяСтруктурыДиаграммы];
		Иначе
			Возврат ЭлементСтруктуры;
		КонецЕсли;
	КонецЦикла;
	
	Возврат Структура[0];
	
КонецФункции

// Возвращает группировку - детальные записи компоновщика настроек
//
// Параметры:
//	КомпоновщикНастроек - КомпоновщикНастроекКомпоновкиДанных, НастройкиКомпоновкиДанных - элемент структуры КД
//
// Возвращаемое значение:
//	СтруктураНастроекКомпоновкиДанных - последний элемент структуры. См. функцию КомпоновкаДанныхКлиентСервер.ПолучитьПоследнийЭлементСтруктуры
//
Функция ПолучитьЭлементСтруктурыДетальныеЗаписи(КомпоновщикНастроек) Экспорт
	
	ПоследнийЭлементСтруктуры = ПолучитьПоследнийЭлементСтруктуры(КомпоновщикНастроек, Истина);
	Если ТипЗнч(ПоследнийЭлементСтруктуры) = Тип("ГруппировкаКомпоновкиДанных")
	 ИЛИ ТипЗнч(ПоследнийЭлементСтруктуры) = Тип("ГруппировкаТаблицыКомпоновкиДанных")
	 ИЛИ ТипЗнч(ПоследнийЭлементСтруктуры) = Тип("ГруппировкаДиаграммыКомпоновкиДанных") Тогда
		Если ПоследнийЭлементСтруктуры.ПоляГруппировки.Элементы.Количество() = 0 Тогда
			Возврат ПоследнийЭлементСтруктуры;
		КонецЕсли;
	КонецЕсли;
	
КонецФункции

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

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

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

// Удаляет отбор из компоновщика настроек, если поле не указано, очищает отбор
//
// Параметры:
//	ЭлементСтруктуры - КомпоновщикНастроекКомпоновкиДанных, ОтборКомпоновкиДанных - элемент структуры компоновки
//	Поле             - Строка, ПолеКомпоновкиДанных - имя или поле компоновки
//
// Возвращаемое значение:
//	Булево - признак успешного удаления/очистки
//
Функция УдалитьОтбор(ЭлементСтруктуры, Знач Поле = Неопределено) Экспорт
	
	Если ТипЗнч(ЭлементСтруктуры) = Тип("КомпоновщикНастроекКомпоновкиДанных") Тогда
		Отбор = ЭлементСтруктуры.Настройки.Отбор;
	Иначе
		Отбор = ЭлементСтруктуры;
	КонецЕсли;
		
	Если Поле = Неопределено Тогда
		Отбор.Элементы.Очистить();
		Возврат Истина;
	КонецЕсли;
	Если ТипЗнч(Поле) = Тип("Строка") Тогда
		Поле = Новый ПолеКомпоновкиДанных(Поле);
	КонецЕсли;
	
	ПолеУдалено = Ложь;
	Элементы = ПолучитьЭлементыОтбора(Отбор);
	МассивУдаляемыхЭлементов = Новый Массив;
	Для Каждого Элемент Из Элементы Цикл
		Если Элемент.ЛевоеЗначение = Поле Тогда
			МассивУдаляемыхЭлементов.Добавить(Элемент);
		КонецЕсли;
	КонецЦикла;
	
	Если МассивУдаляемыхЭлементов.Количество() = 0 Тогда
		Возврат Ложь;
	Иначе
		Для Каждого Элемент Из МассивУдаляемыхЭлементов Цикл
			Отбор.Элементы.Удалить(Элемент);
		КонецЦикла;
		
		Возврат Истина;
		
	КонецЕсли;
	
КонецФункции

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

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

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

// Добавляет в коллекцию оформляемых полей компоновки данных новое поле
//
// Параметры:
//  КоллекцияОформляемыхПолей 	- Массив - коллекция оформляемых полей КД
//  ИмяПоля						- Строка - имя поля
//
// Возвращаемое значение:
//  ОформляемоеПолеКомпоновкиДанных - созданное поле
//
// Пример:
//  Форма.УсловноеОформление.Элементы[0].Поля
//
Функция ДобавитьОформляемоеПоле(КоллекцияОформляемыхПолей, ИмяПоля) Экспорт
	
	ПолеЭлемента 		= КоллекцияОформляемыхПолей.Элементы.Добавить();
	ПолеЭлемента.Поле 	= Новый ПолеКомпоновкиДанных(ИмяПоля);

	Возврат ПолеЭлемента;
	
КонецФункции

// Добавляет в коллекцию отбора новую группу указанного типа.
//
// Параметры:
//	КоллекцияЭлементовОтбора - КоллекцияЭлементовОтбораКомпоновкиДанных - элементы отбора
//	ТипГруппы - ГруппаЭлементовОтбораКомпоновкиДанных - ГруппаИ или ГруппаИли
//
// Возвращаемое значение:
//	ГруппаЭлементовОтбораКомпоновкиДанных - добавленная группа
//
Функция ДобавитьГруппуОтбора(КоллекцияЭлементовОтбора, ТипГруппы) Экспорт

	ГруппаЭлементовОтбора			 = КоллекцияЭлементовОтбора.Добавить(Тип("ГруппаЭлементовОтбораКомпоновкиДанных"));
	ГруппаЭлементовОтбора.ТипГруппы  = ТипГруппы;
	
	Возврат ГруппаЭлементовОтбора;

КонецФункции

#КонецОбласти

#Область СлужебныеПроцедурыИФункции

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

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

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

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

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

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

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

	КонецЦикла;
	
	Возврат ЕстьПоле;
	
КонецФункции //НайтиПоле()

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

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

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

#КонецОбласти

Показать
23. json 3297 21.11.18 11:23 Сейчас в теме
(22) выглядит солидно.
Спасибо большое, чуть позже поразбираюсь.
Возможно вы правы, и велосипед имеет место быть))
Оставьте свое сообщение