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

Программирование - Практика программирования

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

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

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

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

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

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

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

 

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

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

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

 

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

 

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

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

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

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

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

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

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

 

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

 

Заключение

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

36

См. также

Специальные предложения

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Спасибо за комментарий. Возможно действительно велосипед, но я ее писал полтора года назад, когда ещё не было новых БСП
22. triviumfan 7 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 1927 21.11.18 11:23 Сейчас в теме
(22) выглядит солидно.
Спасибо большое, чуть позже поразбираюсь.
Возможно вы правы, и велосипед имеет место быть))
Оставьте свое сообщение