///////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2024, ООО 1С-Софт
// Все права защищены. Эта программа и сопроводительные материалы предоставляются 
// в соответствии с условиями лицензии Attribution 4.0 International (CC BY 4.0)
// Текст лицензии доступен по ссылке:
// https://creativecommons.org/licenses/by/4.0/legalcode
///////////////////////////////////////////////////////////////////////////////////////////////////////

#Область ОписаниеПеременных
&НаКлиенте
Перем Замер;
#КонецОбласти

#Область ОбработчикиСобытийФормы

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

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

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

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

&НаКлиенте
Процедура ПриПовторномОткрытии()
	Если РежимНастройки Или ЗначениеЗаполнено(СтрокаПоиска) Тогда
		РежимНастройки = Ложь;
		СтрокаПоиска = "";
		ОбновитьПанельОтчетовНаКлиенте("ПриПовторномОткрытии");
	КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура ОбработкаОповещения(ИмяСобытия, Изменения, Источник)
	Если Источник = ЭтотОбъект Тогда
		Возврат;
	КонецЕсли;
	Если ПараметрыКлиента.Свойство("Обновлять") Тогда
		ОтключитьОбработчикОжидания("ОбновитьПанельОтчетовПоТаймеру");
	Иначе
		ПараметрыКлиента.Вставить("Обновлять", Ложь)
	КонецЕсли;
	Если ИмяСобытия = ВариантыОтчетовКлиент.ИмяСобытияИзменениеВарианта()
		Или ИмяСобытия = "Запись_НаборКонстант" Или ИмяСобытия = "Запись_ВариантыОтчетов" Тогда
		ПараметрыКлиента.Обновлять = Истина;
	ИначеЕсли ИмяСобытия = ВариантыОтчетовКлиент.ИмяСобытияИзменениеОбщихНастроек() Тогда
		Если Изменения.ПоказыватьПодсказки <> ПоказыватьПодсказки
			Или Изменения.ОтображатьВсеВариантыОтчетов <> ОтображатьВсеВариантыОтчетов
			Или Изменения.ИскатьВоВсехРазделах <> ИскатьВоВсехРазделах Тогда
			ПараметрыКлиента.Обновлять = Истина;
		КонецЕсли;
		ЗаполнитьЗначенияСвойств(ЭтотОбъект, Изменения, "ПоказыватьПодсказки,ИскатьВоВсехРазделах,ОтображатьВсеВариантыОтчетов");
	КонецЕсли;
	Если ПараметрыКлиента.Обновлять Тогда
		ПодключитьОбработчикОжидания("ОбновитьПанельОтчетовПоТаймеру", 1, Истина);
	КонецЕсли;
КонецПроцедуры

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

#Область ОбработчикиСобытийЭлементовШапкиФормы

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

// Параметры:
//  Элемент - ПолеФормы
//
&НаКлиенте
Процедура Подключаемый_ВидимостьВариантаПриИзменении(Элемент)
	Флажок = Элемент;
	Показать = ЭтотОбъект[Флажок.Имя];
	
	НадписьИмя = Сред(Флажок.Имя, СтрДлина("Флажок_")+1);
	Вариант = НайтиВариантПоИмениЭлемента(НадписьИмя);
	Элемент = Элементы.Найти(НадписьИмя);
	Если Вариант = Неопределено Или Элемент = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	ПоказатьСкрытьВариант(Вариант, Элемент, Показать);
КонецПроцедуры

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

&НаКлиенте
Функция ВведенаСлишкомКороткаяСтрокаПоиска(Текст)
	Текст = СокрЛП(Текст);
	Если СтрДлина(Текст) < 2 Тогда
		ПоказатьПредупреждение(, НСтр("ru = 'Введена слишком короткая строка поиска.'"));
		Возврат Истина;
	КонецЕсли;
	
	ЕстьНормальноеСлово = Ложь;
	МассивСлов = ВариантыОтчетовКлиентСервер.РазложитьСтрокуПоискаВМассивСлов(Текст);
	Для Каждого Слово Из МассивСлов Цикл
		Если СтрДлина(Слово) >= 2 Тогда
			ЕстьНормальноеСлово = Истина;
			Прервать;
		КонецЕсли;
	КонецЦикла;
	Если Не ЕстьНормальноеСлово Тогда
		ПоказатьПредупреждение(, НСтр("ru = 'Введены слишком короткие слова для поиска.'"));
		Возврат Истина;
	КонецЕсли;
	
	Возврат Ложь;
КонецФункции

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

// Параметры:
//  Элемент - ДекорацияФормы
// 
&НаКлиенте
Процедура Подключаемый_ЗаголовокРазделаНажатие(Элемент)
	ГруппаРазделаИмя = Элемент.Родитель.Имя;
	Подстроки = СтрРазделить(ГруппаРазделаИмя, "_");
	ПриоритетРаздела = Подстроки[1];
	Найденные = ПодсистемыПрограммы.НайтиСтроки(Новый Структура("Приоритет", ПриоритетРаздела));
	Если Найденные.Количество() = 0 Тогда
		Возврат;
	КонецЕсли;
	Раздел = Найденные[0];
	
	ПутьКПодсистеме = СтрЗаменить(Раздел.ПолноеИмя, "Подсистема.", "");

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

&НаКлиенте
Процедура ПоказыватьПодсказкиПриИзменении(Элемент)
	ОбновитьПанельОтчетовНаКлиенте("ПоказыватьПодсказкиПриИзменении");
	
	ОбщиеНастройки = Новый Структура;
	ОбщиеНастройки.Вставить("ПоказыватьПодсказки", ПоказыватьПодсказки);
	ОбщиеНастройки.Вставить("ИскатьВоВсехРазделах", ИскатьВоВсехРазделах);
	ОбщиеНастройки.Вставить("ОтображатьВсеВариантыОтчетов", ОтображатьВсеВариантыОтчетов);
	Оповестить(ВариантыОтчетовКлиент.ИмяСобытияИзменениеОбщихНастроек(), ОбщиеНастройки, ЭтотОбъект);
КонецПроцедуры

&НаКлиенте
Процедура ОтображатьВсеВариантыОтчетовПриИзменении(Элемент)
	ОбновитьПанельОтчетовНаКлиенте("ОтображатьВсеВариантыОтчетовПриИзменении");
	
	ОбщиеНастройки = Новый Структура;
	ОбщиеНастройки.Вставить("ПоказыватьПодсказки", ПоказыватьПодсказки);
	ОбщиеНастройки.Вставить("ИскатьВоВсехРазделах", ИскатьВоВсехРазделах);
	ОбщиеНастройки.Вставить("ОтображатьВсеВариантыОтчетов", ОтображатьВсеВариантыОтчетов);
	Оповестить(ВариантыОтчетовКлиент.ИмяСобытияИзменениеОбщихНастроек(), ОбщиеНастройки, ЭтотОбъект);
КонецПроцедуры

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

#Область ОбработчикиКомандФормы

&НаКлиенте
Процедура Настроить(Команда)
	РежимНастройки = Не РежимНастройки;
	ОбновитьПанельОтчетовНаКлиенте(?(РежимНастройки, "ВходВРежимНастройки", "ВыходИзРежимаНастройки"));
КонецПроцедуры

&НаКлиенте
Процедура ПереместитьВБыстрыйДоступ(Команда)
	
#Если ВебКлиент Тогда
	Элемент = Элементы.Найти(Сред(Команда.Имя, СтрНайти(Команда.Имя, "_")+1));
#Иначе
	Элемент = ТекущийЭлемент;
#КонецЕсли

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

&НаКлиенте
Процедура УбратьИзБыстрогоДоступа(Команда)
	
#Если ВебКлиент Тогда
	Элемент = Элементы.Найти(Сред(Команда.Имя, СтрНайти(Команда.Имя, "_")+1));
#Иначе
	Элемент = ТекущийЭлемент;
#КонецЕсли

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

&НаКлиенте
Процедура Изменить(Команда)
	
#Если ВебКлиент Тогда
	Элемент = Элементы.Найти(Сред(Команда.Имя, СтрНайти(Команда.Имя, "_")+1));
#Иначе
	Элемент = ТекущийЭлемент;
#КонецЕсли

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

&НаКлиенте
Процедура СброситьНастройки(Команда)
	ТекстВопроса = НСтр("ru = 'Сбросить настройки расположения отчетов?'");
	Обработчик = Новый ОписаниеОповещения("СброситьНастройкиЗавершение", ЭтотОбъект);
	ПоказатьВопрос(Обработчик, ТекстВопроса, РежимДиалогаВопрос.ДаНет, 60, КодВозвратаДиалога.Нет);
КонецПроцедуры

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

&НаКлиенте
Процедура Обновить(Команда)
	ОбновитьПанельОтчетовНаКлиенте("Обновить");
КонецПроцедуры

&НаКлиенте
Процедура ВыполнитьПоиск(Команда)
	ОбновитьПанельОтчетовНаКлиенте("ВыполнитьПоиск");
КонецПроцедуры

&НаКлиенте
Процедура СнимкиОтчетов(Команда)
	
	ОткрытьФорму("РегистрСведений.СнимкиОтчетов.ФормаСписка",
				Новый Структура("Пользователь",
							ПользователиКлиент.ТекущийПользователь()));
	
КонецПроцедуры

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

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

#Область Клиент

&НаКлиенте
Процедура ПоказатьСкрытьВариант(Вариант, Элемент, Показать)
	Вариант.Видимость = Показать;
	Элемент.ЦветТекста = ?(Показать, ?(Вариант.ВидимостьПоНазначению, ЦветВидимыхВариантов,
		ЦветСкрытыхПоНазначениюВариантов), ЦветСкрытыхВариантов);
	ЭтотОбъект["Флажок_"+ Вариант.НадписьИмя] = Показать;
	Если Вариант.Важный Тогда
		Если Показать Тогда
			Элемент.Шрифт = ШрифтВажнойНадписи;
		Иначе
			Элемент.Шрифт = Новый Шрифт;
		КонецЕсли;
	КонецЕсли;
	Подсистема = НайтиПодсистемуПоСсылке(ЭтотОбъект, Вариант.Подсистема);
	Подсистема.ВидимыхВариантов = Подсистема.ВидимыхВариантов + ?(Показать, 1, -1);
	Пока Подсистема.Ссылка <> Подсистема.РазделСсылка Цикл
		Подсистема = НайтиПодсистемуПоСсылке(ЭтотОбъект, Подсистема.РазделСсылка);
		Подсистема.ВидимыхВариантов = Подсистема.ВидимыхВариантов + ?(Показать, 1, -1);
	КонецЦикла;
	СохранитьПользовательскиеНастройки(Вариант.Ссылка, Вариант.Подсистема, Вариант.Видимость, Вариант.БыстрыйДоступ);
	Оповестить("ИзменениеВидимостиВариантаОтчетаВПанелиОтчетов", "Отчет." + Вариант.ИмяОтчета);
КонецПроцедуры

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

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

&НаКлиенте
Процедура ОбновитьПанельОтчетовПоТаймеру()
	Если ПараметрыКлиента.Обновлять Тогда
		ПараметрыКлиента.Обновлять = Ложь;
		ОбновитьПанельОтчетовНаКлиенте("");
	КонецЕсли;
КонецПроцедуры

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

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

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

&НаКлиенте
Процедура ЗакончитьЗамер(Замер)
	Если Замер <> Неопределено Тогда
		Замер.МодульОценкаПроизводительностиКлиент.ЗавершитьЗамерВремени(Замер.Идентификатор);
	КонецЕсли;
КонецПроцедуры

&НаКлиенте
Функция НайтиВариантПоИмениЭлемента(НадписьИмя)
	Идентификатор = ВариантОтчетаПоИмениЭлемента[НадписьИмя];
	Если Идентификатор <> Неопределено Тогда
		Возврат ДобавленныеВарианты.НайтиПоИдентификатору(Идентификатор);
	Иначе
		Найденные = ДобавленныеВарианты.НайтиСтроки(Новый Структура("НадписьИмя", НадписьИмя));
		Если Найденные.Количество() = 1 Тогда
			Возврат Найденные[0];
		КонецЕсли;
	КонецЕсли;
	Возврат Неопределено;
КонецФункции

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

#Область ВызовСервера

&НаКлиентеНаСервереБезКонтекста
Функция НайтиПодсистемуПоСсылке(Форма, Ссылка)
	Идентификатор = Форма.ПодсистемаПоСсылке[Ссылка];
	Если Идентификатор <> Неопределено Тогда
		Возврат Форма.ПодсистемыПрограммы.НайтиПоИдентификатору(Идентификатор);
	КонецЕсли;
	
	Найденные = Форма.ПодсистемыПрограммы.НайтиСтроки(Новый Структура("Ссылка", Ссылка));
	Если Найденные.Количество() = 1 Тогда
		Возврат Найденные[0];
	КонецЕсли;
	Возврат Неопределено;
КонецФункции

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

#Область ВызовСервера

&НаСервере
Процедура ПереместитьВариантБыстрогоДоступа(Знач ВариантИдентификатор, Знач БыстрыйДоступ)
	Вариант = ДобавленныеВарианты.НайтиПоИдентификатору(ВариантИдентификатор);
	Элемент = Элементы.Найти(Вариант.НадписьИмя);
	
	Если БыстрыйДоступ Тогда
		Элемент.Шрифт = Новый Шрифт;
		ГруппаДляПереноса = ПодгруппаСНаименьшимКоличествомЭлементов(Элементы.БыстрыйДоступ);
	ИначеЕсли Вариант.СмТакже Тогда
		Элемент.Шрифт = Новый Шрифт;
		ГруппаДляПереноса = ПодгруппаСНаименьшимКоличествомЭлементов(Элементы.СмТакже);
	ИначеЕсли Вариант.БезГруппы Тогда
		Элемент.Шрифт = ?(Вариант.Важный, ШрифтВажнойНадписи, Новый Шрифт);
		ГруппаДляПереноса = ПодгруппаСНаименьшимКоличествомЭлементов(Элементы.БезГруппы);
	Иначе
		Элемент.Шрифт = ?(Вариант.Важный, ШрифтВажнойНадписи, Новый Шрифт);
		Подсистема = НайтиПодсистемуПоСсылке(ЭтотОбъект, Вариант.Подсистема);
		
		ГруппаДляПереноса = Элементы.Найти(Подсистема.ИмяЭлемента + "_1");
		Если ГруппаДляПереноса = Неопределено Тогда
			Возврат;
		КонецЕсли;
	КонецЕсли;
	
	ПередКакимЭлементом = Неопределено;
	Если ГруппаДляПереноса.ПодчиненныеЭлементы.Количество() > 0 Тогда
		ПередКакимЭлементом = ГруппаДляПереноса.ПодчиненныеЭлементы.Получить(0);
	КонецЕсли;
	
	Элементы.Переместить(Элемент.Родитель, ГруппаДляПереноса, ПередКакимЭлементом);
	
	Если БыстрыйДоступ Тогда
		Элементы.БыстрыйДоступПодсказкаКогдаНеНастроен.Видимость = Ложь;
	Иначе
		ВариантыБыстрогоДоступа = ДобавленныеВарианты.НайтиСтроки(Новый Структура("БыстрыйДоступ", Истина));
		Если ВариантыБыстрогоДоступа.Количество() = 0 Тогда
			Элементы.БыстрыйДоступПодсказкаКогдаНеНастроен.Видимость = Истина;
		Иначе
			Элементы.БыстрыйДоступПодсказкаКогдаНеНастроен.Видимость = Ложь;
		КонецЕсли;
	КонецЕсли;
	
	ФлажокИмя = "Флажок_" + Вариант.НадписьИмя;
	Флажок = Элементы.Найти(ФлажокИмя);
	ФлажокВыведен = (Флажок.Видимость = Истина);
	Если ФлажокВыведен = БыстрыйДоступ Тогда
		Флажок.Видимость = Не БыстрыйДоступ;
	КонецЕсли;
	
	НадписьКонтекстноеМеню = Элемент.КонтекстноеМеню;
	Если НадписьКонтекстноеМеню <> Неопределено Тогда
		КнопкаУбрать = Элементы.Найти("УбратьИзБыстрогоДоступа_" + Вариант.НадписьИмя);
		КнопкаУбрать.Видимость = БыстрыйДоступ;
		КнопкаПереместить = Элементы.Найти("ПереместитьВБыстрыйДоступ_" + Вариант.НадписьИмя);
		КнопкаПереместить.Видимость = Не БыстрыйДоступ;
	КонецЕсли;
	
	СохранитьПользовательскиеНастройки(Вариант.Ссылка, Вариант.Подсистема, Вариант.Видимость, Вариант.БыстрыйДоступ);
КонецПроцедуры

&НаСервере
Функция ОбновитьПанельОтчетовНаСервере(Знач Событие = "")
	
	Если Событие = "СброситьНастройки" Тогда
		РегистрыСведений.НастройкиВариантовОтчетов.СброситьНастройкиПользователяВРазделе(ТекущийРазделСсылка);
	КонецЕсли;
	
	Если Событие = "" Или Событие = "СтрокаПоискаПриИзменении" Или Событие = "СброситьНастройки" Тогда
		Если ЗначениеЗаполнено(СтрокаПоиска) Тогда
			СписокВыбора = Элементы.СтрокаПоиска.СписокВыбора;
			ЭлементСписка = СписокВыбора.НайтиПоЗначению(СтрокаПоиска);
			Если ЭлементСписка = Неопределено Тогда
				СписокВыбора.Вставить(0, СтрокаПоиска);
				Если СписокВыбора.Количество() > 10 Тогда
					СписокВыбора.Удалить(10);
				КонецЕсли;
			Иначе
				Индекс = СписокВыбора.Индекс(ЭлементСписка);
				Если Индекс <> 0 Тогда
					СписокВыбора.Сдвинуть(Индекс, -Индекс);
				КонецЕсли;
			КонецЕсли;
			Если Событие = "СтрокаПоискаПриИзменении" Тогда
				СохранитьНастройкиЭтойПанелиОтчетов();
			КонецЕсли;
		КонецЕсли;
	ИначеЕсли Событие = "ПоказыватьПодсказкиПриИзменении"
		Или Событие = "ОтображатьВсеВариантыОтчетовПриИзменении"
		Или Событие = "ИскатьВоВсехРазделахПриИзменении" Тогда
		
		ОбщиеНастройки = Новый Структура;
		ОбщиеНастройки.Вставить("ПоказыватьПодсказки", ПоказыватьПодсказки);
		ОбщиеНастройки.Вставить("ИскатьВоВсехРазделах", ИскатьВоВсехРазделах);
		ОбщиеНастройки.Вставить("ОтображатьВсеВариантыОтчетов", ОтображатьВсеВариантыОтчетов);
		ВариантыОтчетов.СохранитьОбщиеНастройкиПанели(ОбщиеНастройки);
	КонецЕсли;
	
	Элементы.ПоказыватьПодсказки.Видимость = РежимНастройки;
	Элементы.ОтображатьВсеВариантыОтчетов.Видимость = РежимНастройки;
	Элементы.БыстрыйДоступШапкаНадпись.ОтображениеПодсказки = ?(РежимНастройки, ОтображениеПодсказки.Кнопка, ОтображениеПодсказки.Нет);
	Элементы.РезультатыПоискаИзДругихРазделовГруппа.Видимость = (ИскатьВоВсехРазделах = 1);
	Элементы.Настроить.Пометка = РежимНастройки;
	Элементы.ГруппаСнимкиОтчетов.Видимость = ПравоДоступа("Редактирование", Метаданные.РегистрыСведений.СнимкиОтчетов);
	
	// Заголовок.
	СуффиксРежимаНастройки = " (" + НСтр("ru = 'настройка'") + ")";
	СуффиксВыведен = (Прав(Заголовок, СтрДлина(СуффиксРежимаНастройки)) = СуффиксРежимаНастройки);
	Если СуффиксВыведен <> РежимНастройки Тогда
		Если РежимНастройки Тогда
			Заголовок = Заголовок + СуффиксРежимаНастройки;
		Иначе
			Заголовок = СтрЗаменить(Заголовок, СуффиксРежимаНастройки, "");
		КонецЕсли;
	КонецЕсли;
	
	// Удаление элементов.
	ОчиститьФормуОтДобавленныхЭлементов();
	
	// Удаление команд
	Если ОбщегоНазначения.ЭтоВебКлиент() Тогда
		УдаляемыеКоманды = Новый Массив;
		Для Каждого Команда Из Команды Цикл
			Если ПостоянныеКоманды.НайтиПоЗначению(Команда.Имя) = Неопределено Тогда
				УдаляемыеКоманды.Добавить(Команда);
			КонецЕсли;
		КонецЦикла;
		Для Каждого Команда Из УдаляемыеКоманды Цикл
			Команды.Удалить(Команда);
		КонецЦикла;
	КонецЕсли;
	
	// Сброс номера последнего добавленного элемента.
	Для Каждого СтрокаТаблицы Из ПодсистемыПрограммы Цикл
		СтрокаТаблицы.НомерЭлемента = 0;
		СтрокаТаблицы.ВидимыхВариантов = 0;
	КонецЦикла;
	
	Возврат ЗаполнитьПанельОтчетовВФоне();
	
КонецФункции

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

#Область Сервер

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

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

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

&НаСервере
Функция ПодгруппаСНаименьшимКоличествомЭлементов(Группа)
	ПодгруппаМин = Неопределено;
	ВложенныхЭлементовМин = 0;
	Для Каждого Подгруппа Из Группа.ПодчиненныеЭлементы Цикл
		ВложенныхЭлементов = Подгруппа.ПодчиненныеЭлементы.Количество();
		Если ВложенныхЭлементов < ВложенныхЭлементовМин Или ПодгруппаМин = Неопределено Тогда
			ПодгруппаМин          = Подгруппа;
			ВложенныхЭлементовМин = ВложенныхЭлементов;
		КонецЕсли;
	КонецЦикла;
	Возврат ПодгруппаМин;
КонецФункции

&НаСервере
Процедура ОпределитьПодсистемыИЗаголовок(Параметры)
	
	ЗаданЗаголовок = Не ПустаяСтрока(Параметры.Заголовок);
	ЗаголовокПанели = ?(ЗаданЗаголовок, Параметры.Заголовок, НСтр("ru = 'Отчеты'"));
	
	Если Параметры.ПутьКПодсистеме = ВариантыОтчетовКлиентСервер.ИдентификаторНачальнойСтраницы() Тогда
		ТекущийРазделПолноеИмя = Параметры.ПутьКПодсистеме;
	Иначе
		ТекущийРазделПолноеИмя = "Подсистема." + СтрЗаменить(Параметры.ПутьКПодсистеме, ".", ".Подсистема.");
	КонецЕсли;
	
	ПодсистемыПрограммы.Очистить();
	ВсеПодсистемы = ВариантыОтчетовПовтИсп.ПодсистемыТекущегоПользователя().Дерево;
	ВсеРазделы = ВсеПодсистемы.Строки[0].Строки;
	ПодсистемыПоСсылке = Новый Соответствие;
	Для Каждого СтрокаРаздел Из ВсеРазделы Цикл
		СтрокаТаблицы = ПодсистемыПрограммы.Добавить();
		ЗаполнитьЗначенияСвойств(СтрокаТаблицы, СтрокаРаздел);
		СтрокаТаблицы.ИмяЭлемента    = СтрЗаменить(СтрокаРаздел.ПолноеИмя, ".", "_");
		СтрокаТаблицы.НомерЭлемента  = 0;
		СтрокаТаблицы.РазделСсылка   = СтрокаРаздел.Ссылка;
		
		ПодсистемыПоСсылке[СтрокаТаблицы.Ссылка] = СтрокаТаблицы.ПолучитьИдентификатор();
		
		Если СтрокаРаздел.ПолноеИмя = ТекущийРазделПолноеИмя Тогда
			ТекущийРазделСсылка = СтрокаРаздел.Ссылка;
			Если ЗаданЗаголовок Тогда
				СтрокаРаздел.ПолноеПредставление = Параметры.Заголовок;
			Иначе
				ЗаголовокПанели = СтрокаРаздел.ПолноеПредставление;
			КонецЕсли;
		КонецЕсли;
		
		Найденные = СтрокаРаздел.Строки.НайтиСтроки(Новый Структура("РазделСсылка", СтрокаРаздел.Ссылка), Истина);
		Для Каждого СтрокаДерева Из Найденные Цикл
			СтрокаТаблицы = ПодсистемыПрограммы.Добавить();
			ЗаполнитьЗначенияСвойств(СтрокаТаблицы, СтрокаДерева);
			СтрокаТаблицы.ИмяЭлемента    = СтрЗаменить(СтрокаТаблицы.ПолноеИмя, ".", "_");
			СтрокаТаблицы.НомерЭлемента  = 0;
			СтрокаТаблицы.РодительСсылка = СтрокаДерева.Родитель.Ссылка;
			СтрокаТаблицы.РазделСсылка   = СтрокаРаздел.Ссылка;
			
			ПодсистемыПоСсылке[СтрокаТаблицы.Ссылка] = СтрокаТаблицы.ПолучитьИдентификатор();
			Если СтрокаДерева.ПолноеИмя = ТекущийРазделПолноеИмя Тогда
				ТекущийРазделСсылка = СтрокаДерева.Ссылка;
				Если ЗаданЗаголовок Тогда
					СтрокаДерева.ПолноеПредставление = Параметры.Заголовок;
				Иначе
					ЗаголовокПанели = СтрокаДерева.ПолноеПредставление;
				КонецЕсли;
			КонецЕсли;
		КонецЦикла;
	КонецЦикла;
	
	СтрокаТаблицы = ПодсистемыПрограммы.Добавить();
	СтрокаТаблицы.ИмяЭлемента    = "НеВключенныеВРазделы";
	СтрокаТаблицы.Имя            = "НеВключенныеВРазделы";
	СтрокаТаблицы.Представление  = НСтр("ru = 'Не включенные в разделы'");
	СтрокаТаблицы.НомерЭлемента  = 0;
	СтрокаТаблицы.РазделСсылка   = Справочники.ИдентификаторыОбъектовМетаданных.ПустаяСсылка();
	СтрокаТаблицы.РодительСсылка = Справочники.ИдентификаторыОбъектовМетаданных.ПустаяСсылка();
	СтрокаТаблицы.Ссылка   = Справочники.ИдентификаторыОбъектовМетаданных.ПустаяСсылка(); 
	СтрокаТаблицы.Приоритет = "999";
	ПодсистемыПоСсылке.Вставить(Справочники.ИдентификаторыОбъектовМетаданных.ПустаяСсылка(), СтрокаТаблицы.ПолучитьИдентификатор());
	
	Если Параметры.ПутьКПодсистеме = "НеВключенныеВРазделы" Тогда
		ТекущийРазделСсылка = Справочники.ИдентификаторыОбъектовМетаданных.ПустаяСсылка();
		ЗаголовокПанели = НСтр("ru = 'Отчеты, не включенные в разделы'");
	КонецЕсли;
	
	Если ТекущийРазделСсылка = Неопределено Тогда
		ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'Для панели отчетов указан несуществующий раздел ""%1"" (см. %2).'"),
			Параметры.ПутьКПодсистеме, "ВариантыОтчетовПереопределяемый.ОпределитьРазделыСВариантамиОтчетов");
	КонецЕсли;
	
	КлючНазначенияИспользования = "Раздел_" + Строка(ТекущийРазделСсылка.УникальныйИдентификатор());
	Заголовок = ЗаголовокПанели;
	ПодсистемаПоСсылке = Новый ФиксированноеСоответствие(ПодсистемыПоСсылке);
	
КонецПроцедуры

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

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

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

#Область СерверЗаполнениеПанелиОтчетов

&НаСервере
Функция ЗаполнитьПанельОтчетовВФоне()
	
	ОчиститьСведенияОбИзмененияхВПользовательскихНастройках();
	
	ПараметрыПоиска = Новый Структура;
	ПараметрыПоиска.Вставить("РежимНастройки", РежимНастройки);
	ПараметрыПоиска.Вставить("СтрокаПоиска", СтрокаПоиска);
	ПараметрыПоиска.Вставить("ИскатьВоВсехРазделах", ИскатьВоВсехРазделах);
	ПараметрыПоиска.Вставить("ТекущийРазделСсылка", ТекущийРазделСсылка);
	
	НазначенияВариантовОтчетов = Новый Массив;
	НазначенияВариантовОтчетов.Добавить(Перечисления.НазначенияВариантовОтчетов.ДляЛюбыхУстройств);
	НазначенияВариантовОтчетов.Добавить(?(ОбщегоНазначения.ЭтоМобильныйКлиент(),
									Перечисления.НазначенияВариантовОтчетов.ДляСмартфонов,
									Перечисления.НазначенияВариантовОтчетов.ДляКомпьютеровИПланшетов));
	ПараметрыПоиска.Вставить("НазначенияВариантовОтчетов", НазначенияВариантовОтчетов);
	ПараметрыПоиска.Вставить("ОтображатьВсеВариантыОтчетов", ОтображатьВсеВариантыОтчетов);
	
	ТолькоТекущийРаздел = РежимНастройки Или Не ЗначениеЗаполнено(СтрокаПоиска) Или ИскатьВоВсехРазделах = 0;
	Если ТолькоТекущийРаздел Тогда
		ТаблицаПодсистем = ПодсистемыПрограммы.Выгрузить(Новый Структура("РазделСсылка", ТекущийРазделСсылка));
	Иначе
		ТаблицаПодсистем = ПодсистемыПрограммы.Выгрузить();
	КонецЕсли;
	ПараметрыПоиска.Вставить("ПодсистемыПрограммы", ТаблицаПодсистем);
	
	Если ВариантыОтчетов.ПредставленияЗаполнены() = "Заполнены" Тогда
		АдресРезультата = ПоместитьВоВременноеХранилище(Неопределено, УникальныйИдентификатор);
		ВариантыОтчетов.НайтиВариантыОтчетовДляВывода(ПараметрыПоиска, АдресРезультата);
	Иначе
		ПараметрыВыполнения = ДлительныеОперации.ПараметрыВыполненияВФоне(УникальныйИдентификатор);
		Результат = ДлительныеОперации.ВыполнитьВФоне("ВариантыОтчетов.НайтиВариантыОтчетовДляВывода", ПараметрыПоиска, ПараметрыВыполнения);
		Если Результат.Статус <> "Выполнено" Тогда
			Возврат Результат;
		КонецЕсли;
		АдресРезультата = Результат.АдресРезультата;
	КонецЕсли;
	
	ЗаполнитьПанельОтчетов(АдресРезультата);
	Возврат Неопределено;
	
КонецФункции

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

&НаСервере
Процедура ЗаполнитьПанельОтчетов(АдресРезультата)
	
	ПараметрыЗаполнения = ПолучитьИзВременногоХранилища(АдресРезультата); // см. ВариантыОтчетов.ВариантыОтчетовДляВывода
	УдалитьИзВременногоХранилища(АдресРезультата);
	
	ИнициализироватьПараметрыЗаполнения(ПараметрыЗаполнения);
	Если РежимНастройки Тогда
		ПараметрыЗаполнения.КонтекстноеМеню.УбратьИзБыстрогоДоступа.Видимость = Истина;
		ПараметрыЗаполнения.КонтекстноеМеню.ПереместитьВБыстрыйДоступ.Видимость = Ложь;
	КонецЕсли;
	
	ВывестиВариантыРаздела(ПараметрыЗаполнения, ТекущийРазделСсылка);
	
	Если ПараметрыЗаполнения.ТолькоТекущийРаздел Тогда
		Элементы.РезультатыПоискаИзДругихРазделовГруппа.Видимость = Ложь;
	Иначе
		Элементы.РезультатыПоискаИзДругихРазделовГруппа.Видимость = Истина;
		Если ПараметрыЗаполнения.ДругиеРазделы.Количество() = 0 Тогда
			Надпись = Элементы.Вставить("ВДругихРазделах", Тип("ДекорацияФормы"), Элементы.РезультатыПоискаИзДругихРазделов);
			Надпись.Заголовок = НСтр("ru = 'Отчеты в других разделах не найдены.'") + Символы.ПС;
			Надпись.Высота = 2;
		КонецЕсли;
		Для Каждого РазделСсылка Из ПараметрыЗаполнения.ДругиеРазделы Цикл
			ВывестиВариантыРаздела(ПараметрыЗаполнения, РазделСсылка);
		КонецЦикла;
		Если ПараметрыЗаполнения.НеВыведено > 0 Тогда // Вывод информационной надписи.
			ЗаголовокНадписи = НСтр("ru = 'Выведены первые %1 отчетов из других разделов, уточните поисковый запрос.'");
			ЗаголовокНадписи = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ЗаголовокНадписи, ПараметрыЗаполнения.ПределВывода);
			Надпись = Элементы.Вставить("ПределВыводаПревышен", Тип("ДекорацияФормы"), Элементы.РезультатыПоискаИзДругихРазделов);
			Надпись.Заголовок = ЗаголовокНадписи;
			Надпись.Шрифт = ШрифтВажнойНадписи;
			Надпись.Высота = 2;
		КонецЕсли;
	КонецЕсли;
	
	Если ПараметрыЗаполнения.ДобавляемыеРеквизиты.Количество() > 0 Тогда
		// Регистрация старых реквизитов для удаления.
		УдаляемыеРеквизиты = Новый Массив;
		НаборРеквизитов = ПолучитьРеквизиты(); // Массив из РеквизитФормы
		Для Каждого Реквизит Из НаборРеквизитов Цикл
			Если ПостоянныеРеквизиты.НайтиПоЗначению(Реквизит.Имя) = Неопределено Тогда
				УдаляемыеРеквизиты.Добавить(Реквизит.Имя);
			КонецЕсли;
		КонецЦикла;
		// Удаление старых и добавление новых реквизитов.
		ИзменитьРеквизиты(ПараметрыЗаполнения.ДобавляемыеРеквизиты, УдаляемыеРеквизиты);
		// Связывание новых реквизитов с данными.
		Для Каждого Реквизит Из ПараметрыЗаполнения.ДобавляемыеРеквизиты Цикл
			Флажок = Элементы.Найти(Реквизит.Имя);
			Флажок.ПутьКДанным = Реквизит.Имя;
			НадписьИмя = Сред(Реквизит.Имя, СтрДлина("Флажок_")+1);
			Найденные = ДобавленныеВарианты.НайтиСтроки(Новый Структура("НадписьИмя", НадписьИмя));
			Если Найденные.Количество() > 0 Тогда
				Вариант = Найденные[0];
				ЭтотОбъект[Реквизит.Имя] = Вариант.Видимость;
			КонецЕсли;
		КонецЦикла;
	КонецЕсли;
	
	ВариантОтчетаПоИмениЭлемента = Новый ФиксированноеСоответствие(ПараметрыЗаполнения.ПоискВариантов);
	Элементы.Страницы.ТекущаяСтраница = Элементы.Основное;
	
КонецПроцедуры

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

// Параметры:
//  ПараметрыЗаполнения -  см. ВариантыОтчетов.ВариантыОтчетовДляВывода
//  РазделСсылка - СправочникСсылка.ИдентификаторыОбъектовМетаданных
//               - СправочникСсылка.ИдентификаторыОбъектовРасширений
//
&НаСервере
Процедура ВывестиВариантыРаздела(ПараметрыЗаполнения, РазделСсылка)
	ОтборПоРазделу = Новый Структура("РазделСсылка", РазделСсылка);
	ВариантыРаздела = ПараметрыЗаполнения.Варианты.Скопировать(ОтборПоРазделу);
	ПараметрыЗаполнения.Вставить("ВыводятсяВариантыТекущегоРаздела", РазделСсылка = ТекущийРазделСсылка);
	ПараметрыЗаполнения.Вставить("ВариантыРаздела",    ВариантыРаздела);
	ПараметрыЗаполнения.Вставить("ВариантыКоличество", ВариантыРаздела.Количество());
	Если ПараметрыЗаполнения.ВариантыКоличество = 0 Тогда
		// Вывод надписи, поясняющей почему нет вариантов (только для текущего раздела).
		Если ПараметрыЗаполнения.ВыводятсяВариантыТекущегоРаздела Тогда
			Надпись = Элементы.Вставить("СписокОтчетовПуст", Тип("ДекорацияФормы"), Элементы.БезГруппыКолонка1);
			Если ЗначениеЗаполнено(СтрокаПоиска) Тогда
				Если ПараметрыЗаполнения.ТолькоТекущийРаздел Тогда
					Надпись.Заголовок = НСтр("ru = 'Отчеты не найдены.'");
				Иначе
					Надпись.Заголовок = НСтр("ru = 'Отчеты в текущем разделе не найдены.'");
					Надпись.Высота = 2;
				КонецЕсли;
			Иначе
				Надпись.Заголовок = НСтр("ru = 'В этом разделе отчеты еще не размещены.'");
			КонецЕсли;
			Элементы["БыстрыйДоступШапка"].Видимость  = Ложь;
			Элементы["БыстрыйДоступПодвал"].Видимость = Ложь;
			Элементы["БезГруппыПодвал"].Видимость     = Ложь;
			Элементы["СГруппойПодвал"].Видимость      = Ложь;
			Элементы["СмТакжеЗаголовок"].Видимость    = Ложь;
			Элементы["СмТакжеПодвал"].Видимость       = Ложь;
			Элементы.БыстрыйДоступПодсказкаКогдаНеНастроен.Видимость = Ложь;
		КонецЕсли;
		Возврат;
	КонецЕсли;
	
	Если ПараметрыЗаполнения.ТолькоТекущийРаздел Тогда
		ПодсистемыРаздела = ПараметрыЗаполнения.ТаблицаПодсистем; // ТаблицаЗначений
	Иначе
		ПодсистемыРаздела = ПараметрыЗаполнения.ТаблицаПодсистем.Скопировать(ОтборПоРазделу);
	КонецЕсли;
	ПодсистемыРаздела.Сортировать("Приоритет ВОЗР"); // Сортировка по иерархии
	
	ПараметрыЗаполнения.Вставить("РазделСсылка",      РазделСсылка);
	ПараметрыЗаполнения.Вставить("ПодсистемыРаздела", ПодсистемыРаздела);
	
	ОпределитьГруппыИДекорацииДляВыводаВариантов(ПараметрыЗаполнения);
	
	Если Не ПараметрыЗаполнения.ВыводятсяВариантыТекущегоРаздела
		И ПараметрыЗаполнения.ОсталосьВывести = 0 Тогда
		ПараметрыЗаполнения.НеВыведено = ПараметрыЗаполнения.НеВыведено + ПараметрыЗаполнения.ВариантыКоличество;
		Возврат;
	КонецЕсли;
	
	Для Каждого ИмяГруппы Из ПараметрыЗаполнения.ГруппыВажности Цикл
		ПараметрыГруппы = ПараметрыЗаполнения[ИмяГруппы]; // см. ВариантыОтчетов.ВариантыОтчетовДляВывода
		Если ПараметрыЗаполнения.ОсталосьВывести <= 0 Тогда
			ПараметрыГруппы.Варианты   = Новый Массив;
			ПараметрыГруппы.Количество = 0;
		Иначе
			ПараметрыГруппы.Варианты   = ПараметрыЗаполнения.ВариантыРаздела.Скопировать(ПараметрыГруппы.Отбор);
			ПараметрыГруппы.Количество = ПараметрыГруппы.Варианты.Количество();
		КонецЕсли;
		
		Если ПараметрыГруппы.Количество = 0 И Не (РежимНастройки И ИмяГруппы = "СГруппой") Тогда
			Продолжить;
		КонецЕсли;
		
		Если Не ПараметрыЗаполнения.ВыводятсяВариантыТекущегоРаздела Тогда
			// Ограничение на вывод вариантов.
			ПараметрыЗаполнения.ОсталосьВывести = ПараметрыЗаполнения.ОсталосьВывести - ПараметрыГруппы.Количество;
			Если ПараметрыЗаполнения.ОсталосьВывести < 0 Тогда
				// Удаление строк, которые уже превышают предел.
				ЛишнихВариантов = -ПараметрыЗаполнения.ОсталосьВывести;
				Для Номер = 1 По ЛишнихВариантов Цикл
					ПараметрыГруппы.Варианты.Удалить(ПараметрыГруппы.Количество - Номер);
				КонецЦикла;
				ПараметрыЗаполнения.НеВыведено = ПараметрыЗаполнения.НеВыведено + ЛишнихВариантов;
				ПараметрыЗаполнения.ОсталосьВывести = 0;
			КонецЕсли;
		КонецЕсли;
		
		Если РежимНастройки Тогда
			ПараметрыЗаполнения.КонтекстноеМеню.УбратьИзБыстрогоДоступа.Видимость   = (ИмяГруппы = "БыстрыйДоступ");
			ПараметрыЗаполнения.КонтекстноеМеню.ПереместитьВБыстрыйДоступ.Видимость = (ИмяГруппы <> "БыстрыйДоступ");
		КонецЕсли;
		
		ПараметрыЗаполнения.ИмяГруппы = ИмяГруппы;
		ВывестиВариантыСГруппой(ПараметрыЗаполнения);
	КонецЦикла;
	
	ЕстьБыстрыйДоступ     = (ПараметрыЗаполнения.БыстрыйДоступ.Количество > 0);
	ЕстьВариантыБезГруппы = (ПараметрыЗаполнения.БезГруппы.Количество > 0);
	ЕстьВариантыСГруппой  = (ПараметрыЗаполнения.СГруппой.Количество > 0);
	ЕстьВариантыСмТакже   = (ПараметрыЗаполнения.СмТакже.Количество > 0);
	
	Элементы[ПараметрыЗаполнения.Префикс + "БыстрыйДоступШапка"].Видимость  = РежимНастройки Или ЕстьБыстрыйДоступ;
	Элементы[ПараметрыЗаполнения.Префикс + "БыстрыйДоступПодвал"].Видимость = (
		РежимНастройки
		Или (
			ЕстьБыстрыйДоступ
			И (
				ЕстьВариантыБезГруппы
				Или ЕстьВариантыСГруппой
				Или ЕстьВариантыСмТакже)));
	Элементы[ПараметрыЗаполнения.Префикс + "БезГруппыПодвал"].Видимость  = ЕстьВариантыБезГруппы;
	Элементы[ПараметрыЗаполнения.Префикс + "СГруппойПодвал"].Видимость   = ЕстьВариантыСГруппой;
	Элементы[ПараметрыЗаполнения.Префикс + "СмТакжеЗаголовок"].Видимость = ЕстьВариантыСмТакже;
	Элементы[ПараметрыЗаполнения.Префикс + "СмТакжеПодвал"].Видимость    = ЕстьВариантыСмТакже;
	
	Если ПараметрыЗаполнения.ВыводятсяВариантыТекущегоРаздела Тогда
		Элементы.БыстрыйДоступПодсказкаКогдаНеНастроен.Видимость = РежимНастройки И Не ЕстьБыстрыйДоступ;
	КонецЕсли;
	
КонецПроцедуры

&НаСервере
Процедура ОпределитьГруппыИДекорацииДляВыводаВариантов(ПараметрыЗаполнения)
	// В этой процедуре определяются подмены стандартных групп и элементов.
	ПараметрыЗаполнения.Вставить("Префикс", "");
	Если ПараметрыЗаполнения.ВыводятсяВариантыТекущегоРаздела Тогда
		Возврат;
	КонецЕсли;
	
	ИнформацияОРазделе = ПараметрыЗаполнения.ТаблицаПодсистем.Найти(ПараметрыЗаполнения.РазделСсылка, "Ссылка");
	ПараметрыЗаполнения.Префикс = "Раздел_" + ИнформацияОРазделе.Приоритет + "_";
	
	ГруппаРазделаИмя = ПараметрыЗаполнения.Префикс + ИнформацияОРазделе.Имя;
	ГруппаРаздела = Элементы.Вставить(ГруппаРазделаИмя, Тип("ГруппаФормы"), Элементы.РезультатыПоискаИзДругихРазделов);
	ГруппаРаздела.Вид         = ВидГруппыФормы.ОбычнаяГруппа;
	ГруппаРаздела.Отображение = ОтображениеОбычнойГруппы.Нет;
	ГруппаРаздела.ОтображатьЗаголовок      = Ложь;
	ГруппаРаздела.ОтображениеПодсказки     = ОтображениеПодсказки.ОтображатьСверху;
	ГруппаРаздела.РастягиватьПоГоризонтали = Истина;
	
	РазделСуффикс = " (" + Формат(ПараметрыЗаполнения.ВариантыКоличество, "ЧН=0; ЧГ=") + ")" + Символы.ПС;
	Если ПараметрыЗаполнения.ИспользоватьПодсветку Тогда
		ПараметрыПодсветки = ПараметрыЗаполнения.РезультатПоиска.ПодсветкаПодсистем.Получить(ПараметрыЗаполнения.РазделСсылка);
		Если ПараметрыПодсветки = Неопределено Тогда
			ПодсветкаПредставления = Новый Структура("Значение, КоличествоНайденныхСлов, ПодсветкаСлов", ИнформацияОРазделе.Представление, 0, Новый СписокЗначений);
			Для Каждого Слово Из ПараметрыЗаполнения.МассивСлов Цикл
				ВариантыОтчетов.ОтметитьСлово(ПодсветкаПредставления, Слово);
			КонецЦикла;
		Иначе
			ПодсветкаПредставления = ПараметрыПодсветки.НаименованиеПодсистемы;
		КонецЕсли;
		ПодсветкаПредставления.Значение = ПодсветкаПредставления.Значение + РазделСуффикс;
		Если ПодсветкаПредставления.КоличествоНайденныхСлов > 0 Тогда
			РазделЗаголовок = СформироватьСтрокуСПодсветкой(ПодсветкаПредставления);
		Иначе
			РазделЗаголовок = ПодсветкаПредставления.Значение;
		КонецЕсли;
	Иначе
		РазделЗаголовок = ИнформацияОРазделе.Представление + РазделСуффикс;
	КонецЕсли;
	
	ЗаголовокРаздела = ГруппаРаздела.РасширеннаяПодсказка; // ДекорацияФормы, РасширениеДекорацииФормыДляНадписи
	ЗаголовокРаздела.Заголовок   = РазделЗаголовок;
	ЗаголовокРаздела.Шрифт       = ШрифтРаздела;
	ЗаголовокРаздела.ЦветТекста  = ЦветРаздела;
	ЗаголовокРаздела.Высота      = 2;
	ЗаголовокРаздела.Гиперссылка = Истина;
	ЗаголовокРаздела.ВертикальноеПоложение = ВертикальноеПоложениеЭлемента.Верх;
	ЗаголовокРаздела.РастягиватьПоГоризонтали = Истина;
	ЗаголовокРаздела.УстановитьДействие("Нажатие", "Подключаемый_ЗаголовокРазделаНажатие");
	
	ГруппаРаздела.Группировка = ГруппировкаПодчиненныхЭлементовФормы.ГоризонтальнаяВсегда;
	
	ДекорацияОтступаИмя = ПараметрыЗаполнения.Префикс + "ДекорацияОтступа";
	ДекорацияОтступа = Элементы.Вставить(ДекорацияОтступаИмя, Тип("ДекорацияФормы"), ГруппаРаздела);
	ДекорацияОтступа.Вид = ВидДекорацииФормы.Надпись;
	ДекорацияОтступа.Заголовок = " ";
	
	// Ранее в других группах достигнут предел вывода - не нужно создавать подчиненные.
	Если ПараметрыЗаполнения.ОсталосьВывести = 0 Тогда
		ЗаголовокРаздела.Высота = 1; // Сам заголовок раздела больше не нужно отделять от вариантов.
		Возврат;
	КонецЕсли;
	
	СкопироватьЭлемент(ПараметрыЗаполнения.Префикс, ГруппаРаздела, "Колонки", 2);
	
	Элементы.Удалить(Элементы[ПараметрыЗаполнения.Префикс + "БыстрыйДоступПодсказкаКогдаНеНастроен"]);
	
	НайденнаяГруппа = Элементы[ПараметрыЗаполнения.Префикс + "БыстрыйДоступШапка"]; // ГруппаФормы
	НайденнаяГруппа.РасширеннаяПодсказка.Заголовок = "";
КонецПроцедуры

&НаСервере
Функция СкопироватьЭлемент(ПрефиксНового, ГруппаНового, ИмяКопируемого, УровеньВложенности)
	КопируемыйЭлемент = Элементы.Найти(ИмяКопируемого);
	ИмяНового = ПрефиксНового + ИмяКопируемого;
	НовыйЭлемент = Элементы.Найти(ИмяНового);
	ТипЭлемента = ТипЗнч(КопируемыйЭлемент);
	ЭтоГруппа = (ТипЭлемента = Тип("ГруппаФормы"));
	Если НовыйЭлемент = Неопределено Тогда
		НовыйЭлемент = Элементы.Вставить(ИмяНового, ТипЭлемента, ГруппаНового);
	КонецЕсли;
	Если ЭтоГруппа Тогда
		НеЗаполняемыеСвойства = "Имя, Родитель, Видимость, СочетаниеКлавиш, ПодчиненныеЭлементы, ПутьКДаннымЗаголовка";
	Иначе
		НеЗаполняемыеСвойства = "Имя, Родитель, Видимость, СочетаниеКлавиш, РасширеннаяПодсказка";
	КонецЕсли;
	ЗаполнитьЗначенияСвойств(НовыйЭлемент, КопируемыйЭлемент, , НеЗаполняемыеСвойства);
	Если ЭтоГруппа И УровеньВложенности > 0 Тогда
		Для Каждого ПодчиненныйЭлемент Из КопируемыйЭлемент.ПодчиненныеЭлементы Цикл
			СкопироватьЭлемент(ПрефиксНового, НовыйЭлемент, ПодчиненныйЭлемент.Имя, УровеньВложенности - 1);
		КонецЦикла;
	КонецЕсли;
	Возврат НовыйЭлемент;
КонецФункции

// Параметры:
//  ПараметрыЗаполнения - см. ВариантыОтчетов.ВариантыОтчетовДляВывода
//
&НаСервере
Процедура ВывестиВариантыСГруппой(ПараметрыЗаполнения)
	ПараметрыГруппы = ПараметрыЗаполнения[ПараметрыЗаполнения.ИмяГруппы]; // см. ВариантыОтчетов.ВариантыОтчетовДляВывода
	Варианты = ПараметрыГруппы.Варианты;
	КоличествоВариантов = ПараметрыГруппы.Количество;
	Если КоличествоВариантов = 0 И Не (РежимНастройки И ПараметрыЗаполнения.ИмяГруппы = "СГруппой") Тогда
		Возврат;
	КонецЕсли;
	
	// Базовые свойства группы 2 уровня.
	ГруппаУровня2Имя = ПараметрыЗаполнения.ИмяГруппы;
	ГруппаУровня2 = Элементы.Найти(ПараметрыЗаполнения.Префикс + ГруппаУровня2Имя);
	
	ВыводБезГрупп = (ГруппаУровня2Имя = "БыстрыйДоступ" Или ГруппаУровня2Имя = "СмТакже");
	
	// Сортировка вариантов (есть группы и важные).
	Варианты.Сортировать("ПодсистемаПриоритет ВОЗР, Важный УБЫВ, Наименование ВОЗР");
	НайденныеРодители = Варианты.НайтиСтроки(Новый Структура("ВерхнийУровень", Истина));
	Для Каждого ВариантРодитель Из НайденныеРодители Цикл
		НайденныеПодчиненные = Варианты.НайтиСтроки(Новый Структура("Родитель, Подсистема", ВариантРодитель.Ссылка, ВариантРодитель.Подсистема));
		ТекущийИндекс = Варианты.Индекс(ВариантРодитель);
		Для Каждого ВариантПодчиненный Из НайденныеПодчиненные Цикл
			ВариантРодитель.КоличествоПодчиненных = ВариантРодитель.КоличествоПодчиненных + 1;
			ВариантПодчиненный.ВыводитсяВместеСОсновным = Истина;
			ИндексПодчиненного = Варианты.Индекс(ВариантПодчиненный);
			Если ИндексПодчиненного < ТекущийИндекс Тогда
				Варианты.Сдвинуть(ИндексПодчиненного, ТекущийИндекс - ИндексПодчиненного);
			ИначеЕсли ИндексПодчиненного = ТекущийИндекс Тогда
				ТекущийИндекс = ТекущийИндекс + 1;
			Иначе
				Варианты.Сдвинуть(ИндексПодчиненного, ТекущийИндекс - ИндексПодчиненного + 1);
				ТекущийИндекс = ТекущийИндекс + 1;
			КонецЕсли;
		КонецЦикла;
	КонецЦикла;
	
	ДеревоРаспределения = ДеревоРаспределения();
	
	МаксимальныйУровеньВложенности = 0;
	
	Для Каждого Подсистема Из ПараметрыЗаполнения.ПодсистемыРаздела Цикл
		
		СтрокаРодителя = ДеревоРаспределения.Строки.Найти(Подсистема.РодительСсылка, "ПодсистемаСсылка", Истина);
		Если СтрокаРодителя = Неопределено Тогда
			СтрокаДерева = ДеревоРаспределения.Строки.Добавить();
		Иначе
			СтрокаДерева = СтрокаРодителя.Строки.Добавить();
		КонецЕсли;
		
		СтрокаДерева.Подсистема = Подсистема;
		СтрокаДерева.ПодсистемаСсылка = Подсистема.Ссылка;
		
		Если ВыводБезГрупп Тогда
			Если Подсистема.Ссылка = ПараметрыЗаполнения.РазделСсылка Тогда
				Для Каждого Вариант Из Варианты Цикл
					СтрокаДерева.Варианты.Добавить(Вариант);
				КонецЦикла;
			КонецЕсли;
		Иначе
			СтрокаДерева.Варианты = Варианты.НайтиСтроки(Новый Структура("Подсистема", Подсистема.Ссылка));
		КонецЕсли;
		СтрокаДерева.КоличествоВариантов = СтрокаДерева.Варианты.Количество();
		
		ЕстьВарианты = СтрокаДерева.КоличествоВариантов > 0;
		Если Не ЕстьВарианты Тогда
			СтрокаДерева.КоличествоПустыхСтрок = -1;
		КонецЕсли;
		
		// Вычисление уровня вложенности, Учет количества в иерархии (если есть варианты).
		Если СтрокаРодителя <> Неопределено Тогда
			Пока СтрокаРодителя <> Неопределено Цикл
				Если ЕстьВарианты Тогда
					СтрокаРодителя.ВсегоВложенныхВариантов = СтрокаРодителя.ВсегоВложенныхВариантов + СтрокаДерева.КоличествоВариантов;
					СтрокаРодителя.ВсегоВложенныхПодсистем = СтрокаРодителя.ВсегоВложенныхПодсистем + 1;
					СтрокаРодителя.ВсегоВложенныхПустыхСтрок = СтрокаРодителя.ВсегоВложенныхПустыхСтрок + 1;
				КонецЕсли;
				СтрокаРодителя = СтрокаРодителя.Родитель;
				СтрокаДерева.УровеньВложенности = СтрокаДерева.УровеньВложенности + 1;
			КонецЦикла;
		КонецЕсли;
		
		МаксимальныйУровеньВложенности = Макс(МаксимальныйУровеньВложенности, СтрокаДерева.УровеньВложенности);
		
	КонецЦикла;
	
	// Вычисление колонки расположения и необходимости переноса каждой подсистемы на основе данных по количеству.
	ПараметрыЗаполнения.Вставить("МаксимальныйУровеньВложенности", МаксимальныйУровеньВложенности);
	ДеревоРаспределения.Колонки.Добавить("ГруппаФормы");
	ДеревоРаспределения.Колонки.Добавить("НачатВывод", Новый ОписаниеТипов("Булево"));
	КорневаяСтрока = ДеревоРаспределения.Строки[0];
	КоличествоСтрок = КорневаяСтрока.КоличествоВариантов + КорневаяСтрока.ВсегоВложенныхВариантов + КорневаяСтрока.ВсегоВложенныхПодсистем + Макс(КорневаяСтрока.ВсегоВложенныхПустыхСтрок - 2, 0);
	
	// Переменные для поддержки динамики групп 3 уровня.
	КоличествоКолонок = ГруппаУровня2.ПодчиненныеЭлементы.Количество();
	Если КорневаяСтрока.КоличествоВариантов = 0 Тогда
		Если КоличествоКолонок > 1 И КорневаяСтрока.ВсегоВложенныхВариантов <= 5 Тогда
			КоличествоКолонок = 1;
		ИначеЕсли КоличествоКолонок > 2 И КорневаяСтрока.ВсегоВложенныхВариантов <= 10 Тогда
			КоличествоКолонок = 2;
		КонецЕсли;
	КонецЕсли;
	// Количество вариантов для вывода в одной колонке.
	ГруппаУровня3Отсечка = Макс(Цел(КоличествоСтрок / КоличествоКолонок), 2);
	
	ПорядокВывода = ПорядокВывода();
	
	Рекурсия = Новый Структура;
	Рекурсия.Вставить("ВсегоОсталосьВывести", КоличествоСтрок);
	Рекурсия.Вставить("СвободноКолонок", КоличествоКолонок - 1);
	Рекурсия.Вставить("КоличествоКолонок", КоличествоКолонок);
	Рекурсия.Вставить("ГруппаУровня3Отсечка", ГруппаУровня3Отсечка);
	Рекурсия.Вставить("НомерТекущейКолонки", 1);
	Рекурсия.Вставить("ЭтоПоследняяКолонка", Рекурсия.НомерТекущейКолонки = Рекурсия.КоличествоКолонок Или КоличествоСтрок <= 6);
	Рекурсия.Вставить("СвободноСтрок", ГруппаУровня3Отсечка);
	Рекурсия.Вставить("НачатВыводВТекущейКолонке", Ложь);
	
	ЗаполнитьПорядокВывода(ПорядокВывода, Неопределено, КорневаяСтрока, Рекурсия, ПараметрыЗаполнения);
	
	// Вывод в форму
	НомерТекущейКолонки = 0;
	Для Каждого СтрокаПорядкаВывода Из ПорядокВывода Цикл
		
		Если НомерТекущейКолонки <> СтрокаПорядкаВывода.НомерКолонки Тогда
			НомерТекущейКолонки = СтрокаПорядкаВывода.НомерКолонки;
			ТекущийУровеньВложенности = 0;
			ТекущаяГруппа = ГруппаУровня2.ПодчиненныеЭлементы.Получить(НомерТекущейКолонки - 1);
			ТекущиеГруппыПоУровнямВложенности = Новый Соответствие;
			ТекущиеГруппыПоУровнямВложенности.Вставить(0, ТекущаяГруппа);
		КонецЕсли;
		
		Если СтрокаПорядкаВывода.ЭтоПодсистема Тогда
			
			Если СтрокаПорядкаВывода.ПодсистемаСсылка = ПараметрыЗаполнения.РазделСсылка Тогда
				ТекущийУровеньВложенности = 0;
				ТекущаяГруппа = ТекущиеГруппыПоУровнямВложенности.Получить(0);
			Иначе
				ТекущийУровеньВложенности = СтрокаПорядкаВывода.УровеньВложенности;
				ВГруппу = ТекущиеГруппыПоУровнямВложенности.Получить(СтрокаПорядкаВывода.УровеньВложенности - 1);
				ТекущаяГруппа = ДобавитьГруппуПодсистемы(ПараметрыЗаполнения, СтрокаПорядкаВывода, ВГруппу);
				ТекущиеГруппыПоУровнямВложенности.Вставить(ТекущийУровеньВложенности, ТекущаяГруппа);
			КонецЕсли;
			
		ИначеЕсли СтрокаПорядкаВывода.ЭтоВариант Тогда
			
			Если ТекущийУровеньВложенности <> СтрокаПорядкаВывода.УровеньВложенности Тогда
				ТекущийУровеньВложенности = СтрокаПорядкаВывода.УровеньВложенности;
				ТекущаяГруппа = ТекущиеГруппыПоУровнямВложенности.Получить(ТекущийУровеньВложенности);
			КонецЕсли;
			
			ДобавитьЭлементыВариантаОтчета(ПараметрыЗаполнения, СтрокаПорядкаВывода.Вариант, ТекущаяГруппа, СтрокаПорядкаВывода.УровеньВложенности);
			
			Если СтрокаПорядкаВывода.Вариант.КоличествоПодчиненных > 0 Тогда
				ТекущийУровеньВложенности = ТекущийУровеньВложенности + 1;
				ТекущаяГруппа = ДобавитьГруппуСОтступом(ПараметрыЗаполнения, СтрокаПорядкаВывода, ТекущаяГруппа);
				ТекущиеГруппыПоУровнямВложенности.Вставить(ТекущийУровеньВложенности, ТекущаяГруппа);
			КонецЕсли;
			
		ИначеЕсли СтрокаПорядкаВывода.ЭтоПустаяСтрока Тогда
			
			ВГруппу = ТекущиеГруппыПоУровнямВложенности.Получить(СтрокаПорядкаВывода.УровеньВложенности - 1);
			ДобавитьПустуюДекорацию(ПараметрыЗаполнения, ВГруппу);
			
		КонецЕсли;
		
	КонецЦикла;
	
	Для НомерКолонки = 3 По ГруппаУровня2.ПодчиненныеЭлементы.Количество() Цикл
		Найденные = ПорядокВывода.НайтиСтроки(Новый Структура("НомерКолонки, ЭтоПодсистема", НомерКолонки, Ложь));
		Если Найденные.Количество() = 0 Тогда
			ГруппаУровня3 = ГруппаУровня2.ПодчиненныеЭлементы.Получить(НомерКолонки - 1);
			ДобавитьПустуюДекорацию(ПараметрыЗаполнения, ГруппаУровня3);
		КонецЕсли;
	КонецЦикла;
	
КонецПроцедуры

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

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

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

// Параметры:
//  ПараметрыЗаполнения - см. ВариантыОтчетов.ВариантыОтчетовДляВывода
//  СтрокаПорядкаВывода - см. ПорядокВывода
//  ВГруппу - ГруппаФормы
//
// Возвращаемое значение:
//  ГруппаФормы, КнопкаФормы, ТаблицаФормы, ПолеФормы, Произвольный, ДекорацияФормы
// 
&НаСервере
Функция ДобавитьГруппуПодсистемы(ПараметрыЗаполнения, СтрокаПорядкаВывода, ВГруппу)
	Подсистема = СтрокаПорядкаВывода.Подсистема;
	СтрокаДерева = СтрокаПорядкаВывода.СтрокаДерева;
	Если СтрокаДерева.КоличествоВариантов = 0
		И СтрокаДерева.ВсегоВложенныхВариантов = 0
		И Не (РежимНастройки И ПараметрыЗаполнения.ИмяГруппы = "СГруппой") Тогда
		Возврат ВГруппу;
	КонецЕсли;
	ПодсистемаПредставление = Подсистема.Представление;
	
	Подсистема.НомерЭлемента = Подсистема.НомерЭлемента + 1;
	ГруппаПодсистемыИмя = Подсистема.ИмяЭлемента + "_" + Формат(Подсистема.НомерЭлемента, "ЧГ=0");
	
	Пока Элементы.Найти(ГруппаПодсистемыИмя) <> Неопределено Цикл
		Подсистема.НомерЭлемента = Подсистема.НомерЭлемента + 1;
		ГруппаПодсистемыИмя = Подсистема.ИмяЭлемента + "_" + Формат(Подсистема.НомерЭлемента, "ЧГ=0");
	КонецЦикла;
	
	// Добавление отступа слева.
	Если СтрокаПорядкаВывода.УровеньВложенности > 1 Тогда
		// Группа.
		ГруппаОтступа = Элементы.Вставить(ГруппаПодсистемыИмя + "_ГруппаОтступа", Тип("ГруппаФормы"), ВГруппу);
		ГруппаОтступа.Вид                      = ВидГруппыФормы.ОбычнаяГруппа;
		ГруппаОтступа.Группировка              = ГруппировкаПодчиненныхЭлементовФормы.ГоризонтальнаяВсегда;
		ГруппаОтступа.Отображение              = ОтображениеОбычнойГруппы.Нет;
		ГруппаОтступа.ОтображатьЗаголовок      = Ложь;
		ГруппаОтступа.РастягиватьПоГоризонтали = Истина;
		
		// Картинка.
		КартинкаОтступа = Элементы.Вставить(ГруппаПодсистемыИмя + "_КартинкаОтступа", Тип("ДекорацияФормы"), ГруппаОтступа);
		ЗаполнитьЗначенияСвойств(КартинкаОтступа, ПараметрыЗаполнения.Шаблоны.КартинкаОтступа);
		КартинкаОтступа.Ширина = СтрокаПорядкаВывода.УровеньВложенности - 1;
		Если СтрокаПорядкаВывода.СтрокаДерева.КоличествоВариантов = 0 И СтрокаПорядкаВывода.СтрокаДерева.ВсегоВложенныхВариантов = 0 Тогда
			КартинкаОтступа.Видимость = Ложь;
		КонецЕсли;
		
		// Подмена группы верхнего уровня.
		ВГруппу = ГруппаОтступа;
		
		ШрифтЗаголовка = ШрифтОбычнойГруппы;
		ОтображениеГруппыПодсистемы = ОтображениеОбычнойГруппы.Нет;
	Иначе
		ШрифтЗаголовка = ШрифтВажнойГруппы;
		ОтображениеГруппыПодсистемы = ОтображениеОбычнойГруппы.ОбычноеВыделение;
	КонецЕсли;
	
	ГруппаПодсистемы = Элементы.Вставить(ГруппаПодсистемыИмя, Тип("ГруппаФормы"), ВГруппу);
	ГруппаПодсистемы.Вид = ВидГруппыФормы.ОбычнаяГруппа;
	ГруппаПодсистемы.РастягиватьПоГоризонтали = Истина;
	ГруппаПодсистемы.Группировка = ГруппировкаПодчиненныхЭлементовФормы.Вертикальная;
	ГруппаПодсистемы.Отображение = ОтображениеГруппыПодсистемы;
	
	ТребуетсяПодсветка = Ложь;
	Если ПараметрыЗаполнения.ИспользоватьПодсветку Тогда
		ПараметрыПодсветки = ПараметрыЗаполнения.РезультатПоиска.ПодсветкаПодсистем.Получить(Подсистема.Ссылка);
		Если ПараметрыПодсветки <> Неопределено Тогда
			ПодсветкаПредставления = ПараметрыПодсветки.НаименованиеПодсистемы;
			Если ПодсветкаПредставления.КоличествоНайденныхСлов > 0 Тогда
				ТребуетсяПодсветка = Истина;
			КонецЕсли;
		КонецЕсли;
	КонецЕсли;
	
	Если ТребуетсяПодсветка Тогда
		Если СтрокаПорядкаВывода.ЭтоПродолжение Тогда
			Суффикс = НСтр("ru = '(продолжение)'");
			Если Не СтрЗаканчиваетсяНа(ПодсветкаПредставления.Значение, Суффикс) Тогда
				ПодсветкаПредставления.Значение = ПодсветкаПредставления.Значение + " " + Суффикс;
			КонецЕсли;
		КонецЕсли;
		
		ГруппаПодсистемы.ОтображатьЗаголовок = Ложь;
		ГруппаПодсистемы.ОтображениеПодсказки = ОтображениеПодсказки.ОтображатьСверху;
		
		ФорматированнаяСтрока = СформироватьСтрокуСПодсветкой(ПодсветкаПредставления);
		
		ЗаголовокПодсистемы = Элементы.Вставить(ГруппаПодсистемы.Имя + "_РасширеннаяПодсказка", Тип("ДекорацияФормы"), ГруппаПодсистемы);
		ЗаголовокПодсистемы.Заголовок = ФорматированнаяСтрока;
		ЗаголовокПодсистемы.ЦветТекста = ЦветГруппыВариантовОтчетов;
		ЗаголовокПодсистемы.Шрифт = ШрифтЗаголовка;
		ЗаголовокПодсистемы.РастягиватьПоГоризонтали = Истина;
		ЗаголовокПодсистемы.Высота = 1;
		
	Иначе
		Если СтрокаПорядкаВывода.ЭтоПродолжение Тогда
			ПодсистемаПредставление = ПодсистемаПредставление + " " + НСтр("ru = '(продолжение)'");
		КонецЕсли;
		
		ГруппаПодсистемы.ОтображатьЗаголовок = Истина;
		ГруппаПодсистемы.Заголовок = ПодсистемаПредставление;
	КонецЕсли;
	
	СтрокаДерева.ГруппаФормы = ГруппаПодсистемы;
	
	Возврат ГруппаПодсистемы;
КонецФункции

&НаСервере
Функция ДобавитьГруппуСОтступом(ПараметрыЗаполнения, СтрокаПорядкаВывода, ВГруппу)
	ПараметрыЗаполнения.ВыведеноЭлементовВариантов = ПараметрыЗаполнения.ВыведеноЭлементовВариантов + 1;
	
	ГруппаОтступаИмя   = "ГруппаОтступа_" + Формат(ПараметрыЗаполнения.ВыведеноЭлементовВариантов, "ЧГ=0");
	КартинкаОтступаИмя = "КартинкаОтступа_" + Формат(ПараметрыЗаполнения.ВыведеноЭлементовВариантов, "ЧГ=0");
	ГруппаВыводаИмя    = "ГруппаВывода_" + Формат(ПараметрыЗаполнения.ВыведеноЭлементовВариантов, "ЧГ=0");
	
	// Отступ.
	ГруппаОтступа = Элементы.Вставить(ГруппаОтступаИмя, Тип("ГруппаФормы"), ВГруппу);
	ГруппаОтступа.Вид                      = ВидГруппыФормы.ОбычнаяГруппа;
	ГруппаОтступа.Группировка              = ГруппировкаПодчиненныхЭлементовФормы.ГоризонтальнаяВсегда;
	ГруппаОтступа.Отображение              = ОтображениеОбычнойГруппы.Нет;
	ГруппаОтступа.ОтображатьЗаголовок      = Ложь;
	ГруппаОтступа.РастягиватьПоГоризонтали = Истина;
	
	// Картинка.
	КартинкаОтступа = Элементы.Вставить(КартинкаОтступаИмя, Тип("ДекорацияФормы"), ГруппаОтступа);
	ЗаполнитьЗначенияСвойств(КартинкаОтступа, ПараметрыЗаполнения.Шаблоны.КартинкаОтступа);
	КартинкаОтступа.Ширина = 1;
	
	// Вывод.
	ГруппаВывода = Элементы.Вставить(ГруппаВыводаИмя, Тип("ГруппаФормы"), ГруппаОтступа);
	ГруппаВывода.Вид                      = ВидГруппыФормы.ОбычнаяГруппа;
	ГруппаВывода.Группировка              = ГруппировкаПодчиненныхЭлементовФормы.Вертикальная;
	ГруппаВывода.Отображение              = ОтображениеОбычнойГруппы.Нет;
	ГруппаВывода.ОтображатьЗаголовок      = Ложь;
	ГруппаВывода.РастягиватьПоГоризонтали = Истина;
	
	Возврат ГруппаВывода;
КонецФункции

// Параметры:
//  ПараметрыЗаполнения - см. ВариантыОтчетов.ВариантыОтчетовДляВывода
//  Вариант - СтрокаТаблицыЗначений:
//    * Ссылка - СправочникСсылка.ВариантыОтчетов
//    * Подсистема - СправочникСсылка.ИдентификаторыОбъектовМетаданных
//                 - СправочникСсылка.ИдентификаторыОбъектовРасширений
//    * ПодсистемаПредставление - Строка
//    * ПодсистемаПриоритет - Строка
//    * РазделСсылка - СправочникСсылка.ИдентификаторыОбъектовМетаданных
//                   - СправочникСсылка.ИдентификаторыОбъектовРасширений
//    * БезГруппы - Булево
//    * Важный - Булево
//    * СмТакже - Булево
//    * Дополнительный - Булево
//    * Видимость - Булево
//    * БыстрыйДоступ - Булево
//    * ИмяОтчета - Строка
//    * Наименование - Строка
//    * Описание - Строка
//    * Автор - СправочникСсылка.Пользователи
//            - СправочникСсылка.ВнешниеПользователи
//    * Отчет - СправочникСсылка.ИдентификаторыОбъектовМетаданных
//            - СправочникСсылка.ИдентификаторыОбъектовРасширений
//            - СправочникСсылка.ДополнительныеОтчетыИОбработки
//            - Строка
//    * ТипОтчета - ПеречислениеСсылка.ТипыОтчетов
//    * КлючВарианта - Строка
//    * Родитель - СправочникСсылка.ВариантыОтчетов
//    * ВерхнийУровень - Булево
//    * КлючЗамеров - Строка
//  ВГруппу - ГруппаФормы
//          - КнопкаФормы
//          - ТаблицаФормы
//          - ПолеФормы
//          - Произвольный
//  УровеньВложенности - Число
//
// Возвращаемое значение:
//  ГруппаФормы, КнопкаФормы, ТаблицаФормы, ПолеФормы, ДекорацияФормы
//
&НаСервере
Функция ДобавитьЭлементыВариантаОтчета(ПараметрыЗаполнения, Вариант, ВГруппу, УровеньВложенности = 0)
	
	// Уникальное имя добавляемого элемента.
	НадписьИмя = "Вариант_" + ОтчетыСервер.ПривестиИдентификаторКИмени(Вариант.Ссылка.УникальныйИдентификатор());
	Если ЗначениеЗаполнено(Вариант.Подсистема) Тогда
		НадписьИмя = НадписьИмя
			+ "_Подсистема_"
			+ ОтчетыСервер.ПривестиИдентификаторКИмени(Вариант.Подсистема.УникальныйИдентификатор());
	КонецЕсли;
	Если Не ПараметрыЗаполнения.ТолькоТекущийРаздел И Элементы.Найти(НадписьИмя) <> Неопределено Тогда
		Если ЗначениеЗаполнено(Вариант.РазделСсылка) Тогда
			Номер = 0;
			Суффикс = "_Раздел_" + ОтчетыСервер.ПривестиИдентификаторКИмени(Вариант.РазделСсылка.УникальныйИдентификатор());
		Иначе
			Номер = 1;
			Суффикс = "_1";
		КонецЕсли;
		Пока Элементы.Найти(НадписьИмя + Суффикс) <> Неопределено Цикл
			Номер = Номер + 1;
			Суффикс = "_" + XMLСтрока(Номер);
		КонецЦикла;
		НадписьИмя = НадписьИмя + Суффикс;
	КонецЕсли;
	
	Если РежимНастройки Тогда
		ГруппаВариантаИмя = "Группа_" + НадписьИмя;
		ГруппаВарианта = Элементы.Вставить(ГруппаВариантаИмя, Тип("ГруппаФормы"), ВГруппу);
		ЗаполнитьЗначенияСвойств(ГруппаВарианта, ПараметрыЗаполнения.Шаблоны.ГруппаВарианта);
	Иначе
		ГруппаВарианта = ВГруппу;
	КонецЕсли;
	
	// Добавление флажка (для быстрого доступа не используется).
	Если РежимНастройки Тогда
		ФлажокИмя = "Флажок_" + НадписьИмя;
		
		РеквизитФормы = Новый РеквизитФормы(ФлажокИмя, Новый ОписаниеТипов("Булево"), , , Ложь);
		ПараметрыЗаполнения.ДобавляемыеРеквизиты.Добавить(РеквизитФормы);
		
		Флажок = Элементы.Вставить(ФлажокИмя, Тип("ПолеФормы"), ГруппаВарианта);
		Флажок.Вид = ВидПоляФормы.ПолеФлажка;
		Флажок.ПоложениеЗаголовка = ПоложениеЗаголовкаЭлементаФормы.Нет;
		Флажок.Видимость = (ПараметрыЗаполнения.ИмяГруппы <> "БыстрыйДоступ");
		Флажок.УстановитьДействие("ПриИзменении", "Подключаемый_ВидимостьВариантаПриИзменении");
	КонецЕсли;
	
	// Добавление надписи-гиперссылки варианта отчета.
	Надпись = Элементы.Вставить(НадписьИмя, Тип("ДекорацияФормы"), ГруппаВарианта);
	ЗаполнитьЗначенияСвойств(Надпись, ПараметрыЗаполнения.Шаблоны.НадписьВарианта);
	Надпись.Заголовок = СокрЛП(Вариант.Наименование);
	Если ЗначениеЗаполнено(Вариант.Описание) Тогда
		Надпись.Подсказка = СокрЛП(Вариант.Описание);
	КонецЕсли;
	Если ЗначениеЗаполнено(Вариант.Автор) Тогда
		Надпись.Подсказка = СокрЛ(Надпись.Подсказка + Символы.ПС) + НСтр("ru = 'Автор:'") + " " + СокрЛП(Строка(Вариант.Автор));
	КонецЕсли;
	Надпись.УстановитьДействие("Нажатие", "Подключаемый_ВариантНажатие");
	Если Не Вариант.Видимость Тогда
		Надпись.ЦветТекста = ЦветСкрытыхВариантов;
	ИначеЕсли Не Вариант.ВидимостьПоНазначению Тогда
		Надпись.ЦветТекста = ЦветСкрытыхПоНазначениюВариантов;
	КонецЕсли;
	Если Вариант.Важный
		И ПараметрыЗаполнения.ИмяГруппы <> "СмТакже"
		И ПараметрыЗаполнения.ИмяГруппы <> "БыстрыйДоступ" Тогда
		Надпись.Шрифт = ШрифтВажнойНадписи;
	КонецЕсли;
	Надпись.АвтоМаксимальнаяШирина = Ложь;
	
	СоставПодсказки = Новый Массив;
	ОпределитьСоставПодсказкиВарианта(ПараметрыЗаполнения, Вариант, СоставПодсказки, Надпись);
	ВывестиПодсказкуВарианта(Надпись, СоставПодсказки);
	
	Если РежимНастройки Тогда
		Для Каждого КлючИЗначение Из ПараметрыЗаполнения.КонтекстноеМеню Цикл
			КомандаИмя = КлючИЗначение.Ключ;
			КнопкаИмя = КомандаИмя + "_" + НадписьИмя;
			Кнопка = Элементы.Вставить(КнопкаИмя, Тип("КнопкаФормы"), Надпись.КонтекстноеМеню);
			Если ОбщегоНазначения.ЭтоВебКлиент() Тогда
				Команда = Команды.Добавить(КнопкаИмя);
				ЗаполнитьЗначенияСвойств(Команда, Команды[КомандаИмя]);
				Кнопка.ИмяКоманды = КнопкаИмя;
			Иначе
				Кнопка.ИмяКоманды = КомандаИмя;
			КонецЕсли;
			ЗаполнитьЗначенияСвойств(Кнопка, КлючИЗначение.Значение);
		КонецЦикла;
	КонецЕсли;
	
	// Регистрация добавленной надписи.
	СтрокаТаблицы = ДобавленныеВарианты.Добавить();
	ЗаполнитьЗначенияСвойств(СтрокаТаблицы, Вариант);
	СтрокаТаблицы.ГруппаУровня2Имя     = ПараметрыЗаполнения.ИмяГруппы;
	СтрокаТаблицы.НадписьИмя           = НадписьИмя;
	
	ПараметрыЗаполнения.ПоискВариантов[НадписьИмя] = СтрокаТаблицы.ПолучитьИдентификатор();
	
	Возврат Надпись;
	
КонецФункции

// Параметры:
//  ПараметрыЗаполнения - см. ВариантыОтчетов.ВариантыОтчетовДляВывода
//  Вариант - СтрокаТаблицыЗначений:
//    * КоличествоПодчиненных - Число
//  СоставПодсказки - Массив
//  Надпись - ГруппаФормы
//          - КнопкаФормы
//          - ТаблицаФормы
//          - ПолеФормы
//          - ДекорацияФормы
//
&НаСервере
Процедура ОпределитьСоставПодсказкиВарианта(ПараметрыЗаполнения, Вариант, СоставПодсказки, Надпись)
	ПодсказкаВыведена = Ложь;
	Если ПараметрыЗаполнения.ИспользоватьПодсветку Тогда
		ПараметрыПодсветки = ПараметрыЗаполнения.РезультатПоиска.ПодсветкаВариантов.Получить(Вариант.Ссылка); // Структура
		Если ПараметрыПодсветки <> Неопределено Тогда
			Если ПараметрыПодсветки.НаименованиеВарианта.КоличествоНайденныхСлов > 0 Тогда
				Надпись.Заголовок = СформироватьСтрокуСПодсветкой(ПараметрыПодсветки.НаименованиеВарианта);
			КонецЕсли;
			Если ПараметрыПодсветки.Описание.КоличествоНайденныхСлов > 0 Тогда
				СформироватьСтрокуСПодсветкой(ПараметрыПодсветки.Описание, СоставПодсказки);
				ПодсказкаВыведена = Истина;
			КонецЕсли;
			Если ПараметрыПодсветки.ПредставлениеАвтора.КоличествоНайденныхСлов > 0 Тогда
				Если СоставПодсказки.Количество() > 0 Тогда
					СоставПодсказки.Добавить(Символы.ПС);
				КонецЕсли;
				СоставПодсказки.Добавить(НСтр("ru = 'Автор:'") + " ");
				СформироватьСтрокуСПодсветкой(ПараметрыПодсветки.ПредставлениеАвтора, СоставПодсказки);
				СоставПодсказки.Добавить(".");
				ПодсказкаВыведена = Истина;
			КонецЕсли;
			Если ПараметрыПодсветки.НаименованияПользовательскихНастроек.КоличествоНайденныхСлов > 0 Тогда
				Если СоставПодсказки.Количество() > 0 Тогда
					СоставПодсказки.Добавить(Символы.ПС);
				КонецЕсли;
				СоставПодсказки.Добавить(НСтр("ru = 'Сохраненные настройки:'") + " ");
				СформироватьСтрокуСПодсветкой(ПараметрыПодсветки.НаименованияПользовательскихНастроек, СоставПодсказки);
				СоставПодсказки.Добавить(".");
				ПодсказкаВыведена = Истина;
			КонецЕсли;
			Если ПараметрыПодсветки.НаименованияПолей.КоличествоНайденныхСлов > 0 Тогда
				Если СоставПодсказки.Количество() > 0 Тогда
					СоставПодсказки.Добавить(Символы.ПС);
				КонецЕсли;
				СоставПодсказки.Добавить(НСтр("ru = 'Поля:'") + " ");
				СформироватьСтрокуСПодсветкой(ПараметрыПодсветки.НаименованияПолей, СоставПодсказки);
				СоставПодсказки.Добавить(".");
				ПодсказкаВыведена = Истина;
			КонецЕсли;
			Если ПараметрыПодсветки.НаименованияПараметровИОтборов.КоличествоНайденныхСлов > 0 Тогда
				Если СоставПодсказки.Количество() > 0 Тогда
					СоставПодсказки.Добавить(Символы.ПС);
				КонецЕсли;
				СоставПодсказки.Добавить(НСтр("ru = 'Настройки:'") + " ");
				СформироватьСтрокуСПодсветкой(ПараметрыПодсветки.НаименованияПараметровИОтборов, СоставПодсказки);
				СоставПодсказки.Добавить(".");
				ПодсказкаВыведена = Истина;
			КонецЕсли;
			Если ПараметрыПодсветки.КлючевыеСлова.КоличествоНайденныхСлов > 0 Тогда
				Если СоставПодсказки.Количество() > 0 Тогда
					СоставПодсказки.Добавить(Символы.ПС);
				КонецЕсли;
				СоставПодсказки.Добавить(НСтр("ru = 'Ключевые слова:'") + " ");
				СформироватьСтрокуСПодсветкой(ПараметрыПодсветки.КлючевыеСлова, СоставПодсказки);
				СоставПодсказки.Добавить(".");
				ПодсказкаВыведена = Истина;
			КонецЕсли;
		КонецЕсли;
	КонецЕсли;
	Если Не ПодсказкаВыведена И ПоказыватьПодсказки Тогда
		СоставПодсказки.Добавить(СокрЛП(Надпись.Подсказка));
	КонецЕсли;
КонецПроцедуры

&НаСервере
Процедура ВывестиПодсказкуВарианта(Надпись, СоставПодсказки)
	Если СоставПодсказки.Количество() = 0 Тогда
		Возврат;
	КонецЕсли;
	
	Надпись.ОтображениеПодсказки = ОтображениеПодсказки.ОтображатьСнизу;
	
	Подсказка = Надпись.РасширеннаяПодсказка;
	Подсказка.Заголовок                = Новый ФорматированнаяСтрока(СоставПодсказки);
	Подсказка.ЦветТекста               = ЦветПодсказки;
	Подсказка.АвтоМаксимальнаяВысота   = Ложь;
	Подсказка.МаксимальнаяВысота       = 3;
	Подсказка.РастягиватьПоГоризонтали = Истина;
	Подсказка.АвтоМаксимальнаяШирина   = Ложь;
	Подсказка.МаксимальнаяШирина       = 0;
КонецПроцедуры

&НаСервере
Функция СформироватьСтрокуСПодсветкой(ОбластьПоиска, Содержимое = Неопределено)
	ВозвращатьФорматированнуюСтроку = Ложь;
	Если Содержимое = Неопределено Тогда
		ВозвращатьФорматированнуюСтроку = Истина;
		Содержимое = Новый Массив;
	КонецЕсли;
	
	ИсходныйТекст = ОбластьПоиска.Значение;
	ТекстСокращен = Ложь;
	ДлинаТекста = СтрДлина(ИсходныйТекст);
	Если ДлинаТекста > 150 Тогда
		ТекстСокращен = СократитьТекст(ИсходныйТекст, ДлинаТекста, 150);
	КонецЕсли;
	
	ОбластьПоиска.ПодсветкаСлов.СортироватьПоЗначению(НаправлениеСортировки.Возр);
	КоличествоОткрыто = 0;
	ПозицияНачалаОбычногоТекста = 1;
	ПозицияНачалаПодсветки = 0;
	Для Каждого ЭлементСписка Из ОбластьПоиска.ПодсветкаСлов Цикл
		Если ТекстСокращен И ЭлементСписка.Значение > ДлинаТекста Тогда
			ЭлементСписка.Значение = ДлинаТекста; // Корректировка подсветки если текст был сокращен.
		КонецЕсли;
		Подсвечивать = (ЭлементСписка.Представление = "+");
		КоличествоОткрыто = КоличествоОткрыто + ?(Подсвечивать, 1, -1);
		Если Подсвечивать И КоличествоОткрыто = 1 Тогда
			ПозицияНачалаПодсветки = ЭлементСписка.Значение;
			ФрагментОбычногоТекста = Сред(ИсходныйТекст, ПозицияНачалаОбычногоТекста, ПозицияНачалаПодсветки - ПозицияНачалаОбычногоТекста);
			Содержимое.Добавить(ФрагментОбычногоТекста);
		ИначеЕсли Не Подсвечивать И КоличествоОткрыто = 0 Тогда
			ПозицияНачалаОбычногоТекста = ЭлементСписка.Значение;
			ПодсвечиваемыйФрагмент = Сред(ИсходныйТекст, ПозицияНачалаПодсветки, ПозицияНачалаОбычногоТекста - ПозицияНачалаПодсветки);
			Содержимое.Добавить(Новый ФорматированнаяСтрока(ПодсвечиваемыйФрагмент, , , ЦветПодсветкиНайденныхСлов));
		КонецЕсли;
	КонецЦикла;
	Если ПозицияНачалаОбычногоТекста <= ДлинаТекста Тогда
		ФрагментОбычногоТекста = Сред(ИсходныйТекст, ПозицияНачалаОбычногоТекста);
		Содержимое.Добавить(ФрагментОбычногоТекста);
	КонецЕсли;
	
	Если ВозвращатьФорматированнуюСтроку Тогда
		Возврат Новый ФорматированнаяСтрока(Содержимое); // АПК:1356 Строка не формируется заново, а выполняется обработка существующей.
	Иначе
		Возврат Неопределено;
	КонецЕсли;
КонецФункции

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

&НаСервере
Функция ДобавитьПустуюДекорацию(ПараметрыЗаполнения, ВГруппу)
	
	ПараметрыЗаполнения.ДобавленоПустыхДекораций = ПараметрыЗаполнения.ДобавленоПустыхДекораций + 1;
	ДекорацияИмя = "ПустаяДекорация_" + Формат(ПараметрыЗаполнения.ДобавленоПустыхДекораций, "ЧГ=0");
	
	Декорация = Элементы.Вставить(ДекорацияИмя, Тип("ДекорацияФормы"), ВГруппу);
	Декорация.Вид = ВидДекорацииФормы.Надпись;
	Декорация.Заголовок = " ";
	Декорация.РастягиватьПоГоризонтали = Истина;
	
	Возврат Декорация;
	
КонецФункции

&НаКлиенте
Процедура ОписаниеМобильногоПриложенияНажатие(Элемент)
	
	ПараметрыФормы = ПараметрыКлиента.ОписаниеМобильногоПриложения;
	ОткрытьФорму(ПараметрыФормы.ИмяФормы, ПараметрыФормы.ПараметрыФормы, ЭтотОбъект); 
	
КонецПроцедуры

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

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