Перем мТекущийИндексНайденнойСтроки;
Перем мТекущаяСтрока;
Перем мСерверныеМетаданныеФормы;
Перем мВсеОбработчикиСобытий;
Перем мСочетанияКлавишОбщие;

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

Функция ПолучитьПервогоРодителяПоТипу(Знач СтрокаДерева, Тип)
	
	Пока СтрокаДерева.Родитель <> Неопределено Цикл 
		СтрокаДерева = СтрокаДерева.Родитель;
		Если СтрокаДерева.Тип = Тип Тогда 
			Прервать;
		КонецЕсли; 
	КонецЦикла; 
	Возврат СтрокаДерева;
	
КонецФункции

Функция ПолучитьПоследнегоРодителяПоТипу(Знач СтрокаДерева, Тип)
	
	Пока Истина
		И СтрокаДерева.Родитель <> Неопределено 
		И СтрокаДерева.Родитель.Тип = Тип
	Цикл
		СтрокаДерева = СтрокаДерева.Родитель;
	КонецЦикла; 
	Возврат СтрокаДерева;
	
КонецФункции

Процедура ИндикацияТекущегоЭлемента()
	
	Если Не АктивнаяПодсветка Тогда
		ВосстановитьСвойстваЭлементовФормы(); 
		ЭлементыФормы.АктивнаяПодсветка.ЦветТекста = Новый Цвет;
	Иначе
		ЭлементыФормы.АктивнаяПодсветка.ЦветТекста = WebЦвета.Красный;
	КонецЕсли; 
	НачалоИндикации = ТекущаяУниверсальнаяДатаВМиллисекундах();
	ТекущаяСтрока = ЭлементыФормы.Дерево.ТекущаяСтрока;
	Если ТекущаяСтрока = Неопределено Тогда
		Перейти ~Конец;
	КонецЕсли; 
	Если РежимПодсистемы Тогда
		Форма = ФормаИзСтрокиЭлемента(ТекущаяСтрока);
	КонецЕсли; 
	Если Форма = Неопределено Тогда
		Перейти ~Конец;
	КонецЕсли; 
	//Попытка
	//	ТекущаяСтрока.Видимость = ЭлементФормыСтрокиДерева(ТекущаяСтрока).Видимость;
	//Исключение
	//КонецПопытки; 
	//Попытка
	//	ТекущаяСтрока.Доступность = ЭлементФормыСтрокиДерева(ТекущаяСтрока).Доступность;
	//Исключение
	//КонецПопытки; 
	ЭлементФормы = ЭлементФормыСтрокиДерева(ТекущаяСтрока);
	Если ЭлементФормы = Неопределено Тогда
		//
	ИначеЕсли ТекущаяСтрока.Тип = Тип("КнопкаКоманднойПанели") Тогда
		СтрокаДереваКоманднойПанели = ПолучитьПервогоРодителяПоТипу(ТекущаяСтрока, Тип("КоманднаяПанель"));
		ПоказатьВложенныйЭлементФормы(СтрокаДереваКоманднойПанели);
		СтрокаВерхнегоПодменю = ПолучитьПоследнегоРодителяПоТипу(ТекущаяСтрока, Тип("КнопкаКоманднойПанели"));
		ЭлементФормы = ЭлементФормыСтрокиДерева(СтрокаВерхнегоПодменю); 
		ИндикацияЭлементаФормыСЗаголовком(СтрокаВерхнегоПодменю, Новый Структура("Пометка, Отображение", Не ЭлементФормы.Пометка, ОтображениеКнопкиКоманднойПанели.НадписьКартинка), "Текст");
	ИначеЕсли ТекущаяСтрока.Тип = Тип("КолонкаТабличногоПоля") Тогда
		СтрокаДереваТабличногоПоля = ПолучитьПервогоРодителяПоТипу(ТекущаяСтрока, Тип("ТабличноеПоле"));
		ирОбщий.ПрисвоитьЕслиНеРавноЛкс(Форма.ТекущийЭлемент, ЭлементФормыСтрокиДерева(СтрокаДереваТабличногоПоля),, Истина);
		ЭлементФормы = ЭлементФормыСтрокиДерева(ТекущаяСтрока);
		ИндикацияЭлементаФормыСЗаголовком(ТекущаяСтрока, Новый Структура("ОтображатьВШапке, ЦветФонаПоля, ЦветФонаШапки, ЦветТекстаШапки, ЦветФонаПодвала, ЦветТекстаПодвала", Истина), "ТекстШапки");
		ЭлементФормы.Видимость = Истина;
		ирКлиент.ТабличноеПолеУстановитьТекущуюКолонкуЛкс(ЭлементФормыСтрокиДерева(СтрокаДереваТабличногоПоля), ЭлементФормы);
		//Форма.Обновить(); // Почему то колонки таблицы результат в консоли запросов не перерисовывались без этого
	ИначеЕсли ТекущаяСтрока.Тип = Тип("СтраницаПанели") Тогда
		СтрокаДереваПанели = ПолучитьПервогоРодителяПоТипу(ТекущаяСтрока, Тип("Панель"));
		ирОбщий.ПрисвоитьЕслиНеРавноЛкс(Форма.ТекущийЭлемент, ЭлементФормыСтрокиДерева(СтрокаДереваПанели));
		Если ТекущаяСтрока.Видимость Тогда
			ирОбщий.ПрисвоитьЕслиНеРавноЛкс(ЭлементФормыСтрокиДерева(СтрокаДереваПанели).ТекущаяСтраница, ЭлементФормыСтрокиДерева(ТекущаяСтрока),, Истина);
			ИндикацияЭлементаФормыСЗаголовком(ТекущаяСтрока);
		КонецЕсли; 
	ИначеЕсли Ложь
		Или ТекущаяСтрока.Тип = Тип("КнопкаФормы") 
		Или (Истина
			И ТекущаяСтрока.Тип = Тип("ГруппаФормы") 
			И (Ложь
				Или ЭлементФормы.Вид = ВидГруппыФормы.Подменю
				Или ЭлементФормы.Вид = ВидГруппыФормы.ГруппаКнопок))
	Тогда
		СтрокаВерхнегоПодменю = ТекущаяСтрока;
		ТекущийРодитель = ТекущаяСтрока;
		Пока Истина
			И ТекущийРодитель.Родитель.ЭлементФормы <> Форма 
			И ТекущийРодитель.Родитель.ЭлементФормы.Вид <> ВидГруппыФормы.КоманднаяПанель 
			И ТекущийРодитель.Родитель.ЭлементФормы.Вид <> ВидГруппыФормы.КонтекстноеМеню
		Цикл
			ТекущийРодитель = ТекущийРодитель.Родитель;
			Если ТекущийРодитель.ЭлементФормы.Вид = ВидГруппыФормы.Подменю Тогда
				СтрокаВерхнегоПодменю = ТекущийРодитель;
			КонецЕсли; 
		КонецЦикла; 
		ЭлементФормы = ЭлементФормыСтрокиДерева(СтрокаВерхнегоПодменю);
		Если ТипЗнч(ЭлементФормы) = Тип("КнопкаФормы") Тогда
			//СтруктураСвойств = Новый Структура("Отображение, ЦветФона, ЦветТекста", ОтображениеКнопки.Текст);
			СтруктураСвойств = Новый Структура("ЦветФона, ЦветТекста");
			СтруктураСвойств.Вставить("Пометка", Не ЭлементФормы.Пометка);
		Иначе
			СтруктураСвойств = Новый Структура("ЦветТекстаЗаголовка");
		КонецЕсли; 
		Если ирКэш.НомерВерсииПлатформыЛкс() >= 803008 Тогда
			СтруктураСвойств.Вставить("ОтображениеФигуры", Вычислить("ОтображениеФигурыКнопки.Всегда"));
		КонецЕсли; 
		ИндикацияЭлементаФормыСЗаголовком(СтрокаВерхнегоПодменю, СтруктураСвойств);
	ИначеЕсли ТекущаяСтрока.Тип = Тип("ПолеФормы") Тогда 
		//  Антибаг платформы 8.3.15 После присвоения Неопределено свойству ТекущийЭлемент таблицы формы можно присвоить колонку с отключенной пользовательской видимостью https://partners.v8.1c.ru/forum/topic/1912733
		ТаблицаФормы = ирОбщий.РодительЭлементаУправляемойФормыЛкс(ЭлементФормы, Тип("ТаблицаФормы"));
		МожетБратьФокус = Истина;
		Если ТаблицаФормы <> Неопределено Тогда
			СтараяТекущаяКолонка = ТаблицаФормы.ТекущийЭлемент;
		ИначеЕсли ЭлементФормы.Вид = ВидПоляФормы.ПолеНадписи Тогда 
			МожетБратьФокус = Ложь;
		КонецЕсли; 
		Если МожетБратьФокус Тогда
			Форма.ТекущийЭлемент = ЭлементФормы;
			Если ТекущаяСтрока.Доступность Тогда
				ТекущаяСтрока.Видимость = Ложь
					Или Форма.ТекущийЭлемент = ЭлементФормы
					Или ТипЗнч(Форма.ТекущийЭлемент) = Тип("ТаблицаФормы") И Форма.ТекущийЭлемент.ТекущийЭлемент = ЭлементФормы;
				//  Антибаг платформы 8.3.15 После присвоения Неопределено свойству ТекущийЭлемент таблицы формы можно присвоить колонку с отключенной пользовательской видимостью https://partners.v8.1c.ru/forum/topic/1912733
				Если ТаблицаФормы <> Неопределено И ТаблицаФормы.ТекущийЭлемент <> ЭлементФормы Тогда
					ТаблицаФормы.ТекущийЭлемент = СтараяТекущаяКолонка;
				КонецЕсли; 
			КонецЕсли; 
		КонецЕсли;
		Если ирОбщий.РодительЭлементаУправляемойФормыЛкс(ЭлементФормы, Тип("ТаблицаФормы")) <> Неопределено Тогда 
			ИндикацияЭлементаФормыСЗаголовком(ТекущаяСтрока, Новый Структура("ОтображатьВШапке, ЦветТекстаЗаголовка, ЦветФонаЗаголовка", Истина));
		Иначе
			ИндикацияЭлементаФормыСЗаголовком(ТекущаяСтрока, Новый Структура("ЦветТекстаЗаголовка, ЦветФона, ЦветФонаЗаголовка, ЦветРамки"));
		КонецЕсли; 
	ИначеЕсли ТекущаяСтрока.Тип = Тип("ГруппаФормы") Тогда 
		Форма.ТекущийЭлемент = ЭлементФормы;
		Если ЭлементФормы.Вид = ВидГруппыФормы.ОбычнаяГруппа Тогда 
			ИндикацияЭлементаФормыСЗаголовком(ТекущаяСтрока, Новый Структура("ЦветТекстаЗаголовка, ЦветФона"));
		ИначеЕсли ЭлементФормы.Вид = ВидГруппыФормы.ГруппаКолонок Тогда 
			ИндикацияЭлементаФормыСЗаголовком(ТекущаяСтрока, Новый Структура("ОтображатьЗаголовок, ОтображатьВШапке, ЦветТекстаЗаголовка, ЦветФонаЗаголовка", Истина, Истина));
		Иначе
			ИндикацияПроизвольногоЭлемента(ТекущаяСтрока);
		КонецЕсли; 
	ИначеЕсли ТекущаяСтрока.Тип = Тип("ДекорацияФормы") Тогда 
		Форма.ТекущийЭлемент = ЭлементФормы;
		ИндикацияЭлементаФормыСЗаголовком(ТекущаяСтрока, Новый Структура("ЦветТекста, ЦветРамки"));
	ИначеЕсли ТекущаяСтрока.Видимость Тогда
		ирОбщий.ПрисвоитьЕслиНеРавноЛкс(Форма.ТекущийЭлемент, ЭлементФормы); // Для обычной формы важно не злоупотреблять установкой значения свойству "ТекущийЭлемент", т.к. оно влечет потерю мигания каретки в активной форме https://www.hostedredmine.com/issues/953160
		Если Форма.ТекущийЭлемент <> ЭлементФормы Тогда
			ПоказатьВложенныйЭлементФормы(ТекущаяСтрока);
		КонецЕсли; 
		ИндикацияПроизвольногоЭлемента(ТекущаяСтрока);
	КонецЕсли;
~Конец:
	Если Истина
		И Открыта() 
		И ТекущийЭлемент = ЭлементыФормы.ДеревоСтрокаПоиска
	Тогда
		// Обеспечивает мигание каретки https://www.hostedredmine.com/issues/949816
		//Форма.Открыть();
		//Открыть(); // !!! Закрывает все контекстные меню и сбрасывает таймер события АвтоподборТекста
		Если ЭлементыФормы.ДеревоСтрокаПоиска.Значение <> ДеревоСтрокаПоиска Тогда
			СтрокаПоискаАвтоПодборТекста(ЭлементыФормы.ДеревоСтрокаПоиска, ЭлементыФормы.ДеревоСтрокаПоиска.Значение, "", Истина);
		КонецЕсли;
	КонецЕсли;
	
	Если ТекущаяСтрока <> Неопределено Тогда
		Интервал = ТекущаяУниверсальнаяДатаВМиллисекундах() - НачалоИндикации;
		Если Ложь
			Или ТекущаяСтрока.СтарыеСвойства <> Неопределено
			Или Интервал < 300 И АктивнаяПодсветка 
		Тогда
			#Если Сервер И Не Сервер Тогда
				ИндикацияТекущегоЭлемента();
			#КонецЕсли
			ПодключитьОбработчикОжидания("ИндикацияТекущегоЭлемента", 0.5, Истина);
		КонецЕсли; 
	КонецЕсли;
	
КонецПроцедуры

Процедура ИндикацияПроизвольногоЭлемента(Знач ТекущаяСтрока)
	
	ЭлементФормы = ЭлементФормыСтрокиДерева(ТекущаяСтрока);
	Если ТипЗнч(Форма) = Тип("Форма") Тогда 
		ИмяСвойства = "ЦветРамки";
		Если Ложь
			Или ТекущаяСтрока.Тип = Тип("Надпись")
			Или ТекущаяСтрока.Тип = Тип("Флажок")
			Или ТекущаяСтрока.Тип = Тип("КоманднаяПанель")
			Или ТекущаяСтрока.Тип = Тип("ПолеВвода")
			Или ТекущаяСтрока.Тип = Тип("ПолеВыбора")
		Тогда
			Если Истина
				И (Ложь
					Или ТекущаяСтрока.Тип = Тип("ПолеВвода") 
					Или ТекущаяСтрока.Тип = Тип("ПолеВыбора"))
				И Не ЭлементФормы.ТолькоПросмотр
				И ЭлементФормы.Доступность
			Тогда 
				ИмяСвойства = "ЦветФонаПоля";
			Иначе
				ИмяСвойства = "ЦветФона";
			КонецЕсли; 
		КонецЕсли; 
		Если ТипЗнч(ЭлементФормы) = Тип("КоманднаяПанель") Тогда 
			ДопСвойства = Новый Структура("ПрозрачныйФон", Ложь); // https://www.hostedredmine.com/issues/923456
		КонецЕсли; 
	Иначе
		ИмяСвойства = "";
		// Только для колонок
		Если Истина
			И ИмяСвойства = "" 
			И ТипЗнч(ЭлементФормы) <> Тип("ТаблицаФормы") // Антибаг платформы 8.3.17 Аварийно завершается на некоторых формах (список Алгоритмы). Видимо из-за свойства ЦветТекстаЗаголовка https://partners.v8.1c.ru/forum/t/1911713/m/1911713 , http://www.hostedredmine.com/issues/872715
			И (Ложь
				Или ирОбщий.РодительЭлементаУправляемойФормыЛкс(ЭлементФормы, Тип("ТаблицаФормы")) <> Неопределено 
				Или (Истина
			И ТипЗнч(ЭлементФормы) = Тип("ГруппаФормы") 
			И ЭлементФормы.Вид = ВидГруппыФормы.КоманднаяПанель))
		Тогда
			ИмяСвойства = "ЦветТекстаЗаголовка";
			Попытка
				ТекущийЦвет = ЭлементФормы[ИмяСвойства];
			Исключение
				ИмяСвойства = "";
			КонецПопытки; 
		КонецЕсли; 
		Если ИмяСвойства = "" И ТекущаяСтрока.Тип <> Тип("ПолеФормы") Тогда
			ИмяСвойства = "ЦветРамки";
			Попытка
				ТекущийЦвет = ЭлементФормы[ИмяСвойства];
			Исключение
				ИмяСвойства = "";
			КонецПопытки; 
		КонецЕсли; 
		Если ИмяСвойства = "" Тогда
			ИмяСвойства = "ЦветФона";
			Попытка
				ТекущийЦвет = ЭлементФормы[ИмяСвойства];
			Исключение
				ИмяСвойства = "";
			КонецПопытки;
		КонецЕсли; 
	КонецЕсли; 
	Если ЗначениеЗаполнено(ИмяСвойства) Тогда
		Если Истина
			И ТекущаяСтрока.СтарыеСвойства <> Неопределено
			И ТекущаяСтрока.СтарыеСвойства[ИмяСвойства] <> ТекущийЦвет 
		Тогда
			ВосстановитьСтарыеСвойстваЭлементаФормы(ТекущаяСтрока); 
		Иначе
			СохранитьСтарыеСвойстваЭлементаФормы(ТекущаяСтрока, ИмяСвойства, ДопСвойства);
			Если ДопСвойства <> Неопределено Тогда
				ЗаполнитьЗначенияСвойств(ЭлементФормы, ДопСвойства); 
			КонецЕсли; 
			ЦветПодсветки = ПолучитьЦветИндикации(ИмяСвойства, ЭлементФормы);
			ЭлементФормы[ИмяСвойства] = ЦветПодсветки;
		КонецЕсли; 
	КонецЕсли;

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

Процедура ИндикацияЭлементаФормыСЗаголовком(Знач ТекущаяСтрока, СтруктураСвойств = Неопределено, ИмяСвойстваЗаголовок = "Заголовок")
	
	Если Не АктивнаяПодсветка Тогда
		Возврат;
	КонецЕсли; 
	Если СтруктураСвойств = Неопределено Тогда
		СтруктураСвойств = Новый Структура;
	КонецЕсли; 
	ЭлементФормы = ЭлементФормыСтрокиДерева(ТекущаяСтрока);
	Если ТекущаяСтрока.СтарыеСвойства <> Неопределено Тогда
		ВосстановитьСтарыеСвойстваЭлементаФормы(ТекущаяСтрока); 
	Иначе
		Если Ложь
			Или ТипЗнч(Форма) = Тип("Форма") 
			//Или ТипЗнч(ЭлементФормы) <> Тип("КнопкаФормы") // https://www.hostedredmine.com/issues/953040
		Тогда
			Маркер = Лев("===========================================================", СтрДлина(ТекущаяСтрока.Текст) + 1);
			СтруктураСвойств.Вставить(ИмяСвойстваЗаголовок, Маркер);
		КонецЕсли;
		ИменаСвойств = Новый Массив;
		Для Каждого КлючИЗначение Из СтруктураСвойств Цикл
			Если КлючИЗначение.Значение = Неопределено Тогда
				Если Найти(КлючИЗначение.Ключ, "Цвет") > 0 Тогда
					Попытка
						ТекущийЦвет = ЭлементФормы[КлючИЗначение.Ключ];
					Исключение
						ТекущийЦвет = Неопределено;
					КонецПопытки;
					Если ТекущийЦвет <> Неопределено Тогда
						СтруктураСвойств.Вставить(КлючИЗначение.Ключ, ПолучитьЦветИндикации(КлючИЗначение.Ключ, ЭлементФормы));
					КонецЕсли; 
				КонецЕсли; 
			КонецЕсли; 
			ИменаСвойств.Добавить(КлючИЗначение.Ключ);
		КонецЦикла; 
		СохранитьСтарыеСвойстваЭлементаФормы(ТекущаяСтрока, ирОбщий.СтрСоединитьЛкс(ИменаСвойств));
		Если ТипЗнч(ЭлементФормы) = Тип("КнопкаФормы") Тогда
			ЭлементФормы = ЭлементФормы.Родитель.ПодчиненныеЭлементы[ЭлементФормы.Имя];
		КонецЕсли; 
		ЗаполнитьЗначенияСвойств(ЭлементФормы, СтруктураСвойств);
	КонецЕсли;

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

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

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

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

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

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

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

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

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

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

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

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

Процедура ДобавитьФорму(Форма, КорневаяСтрокаФормы = Неопределено)
	
	Если Форма = Неопределено Тогда
		Возврат;
	КонецЕсли; 
	СтрокаФормы = ЗначениеВСтрокуВнутр(Форма);
	Если СтрДлина(СтрокаФормы) > 1000000 Тогда
		Ответ = Вопрос("Форма содержит слишком большой табличный документ. Для ее анализа он будет очищен. Продолжить?", РежимДиалогаВопрос.ОКОтмена);
		Если Ответ <> КодВозвратаДиалога.ОК Тогда
			Возврат;
		КонецЕсли;
		Если ТипЗнч(Форма) = Тип("Форма") Тогда
			Для Каждого ЭлементФормы Из Форма.ЭлементыФормы Цикл
				Если ТипЗнч(ЭлементФормы) = Тип("ПолеТабличногоДокумента") Тогда
					ЭлементФормы.Очистить();
				КонецЕсли;
			КонецЦикла;
		ИначеЕсли ТипЗнч(Форма) = ирОбщий.ТипУправляемаяФормаЛкс() Тогда
			Для Каждого ЭлементФормы Из Форма.Элементы Цикл
				Если ТипЗнч(ЭлементФормы) = Тип("ПолеФормы") И ЭлементФормы.Вид = ВидПоляФормы.ПолеТабличногоДокумента Тогда
					ЭлементФормы.Очистить();
				КонецЕсли;
			КонецЦикла;
		КонецЕсли;
	КонецЕсли;
	XMLСтрокаФормы = ирОбщий.СтрокаВнутрВХМЛТелоЛкс(СтрокаФормы);
	//ирОбщий.Ис(XMLСтрокаФормы)
	ДокументDOM = ирОбщий.ТекстВДокументDOMЛкс(XMLСтрокаФормы);
	#Если Сервер И Не Сервер Тогда
		ДокументDOM = Новый ДокументDOM;
	#КонецЕсли
	РазыменовательПИ = Новый РазыменовательПространствИменDOM(ДокументDOM);
	Если ТипЗнч(Форма) = Тип("Форма") Тогда
		Если КорневаяСтрокаФормы = Неопределено Тогда
			КорневаяСтрокаФормы = Дерево.Строки.Добавить();
			КорневаяСтрокаФормы.Видимость = Истина;
			КорневаяСтрокаФормы.Доступность = Истина;
			КорневаяСтрокаФормы.ЭлементФормы = Форма;
			ЗаголовокФормы = "";
			РезультатXPath = ДокументDOM.ВычислитьВыражениеXPath("/e/e[1]/e[1]/e[1]/e[1]/e/d[1]", ДокументDOM, РазыменовательПИ, ТипРезультатаDOMXPath.НеупорядоченныйИтераторУзлов);
			Пока Истина Цикл
				Узел = РезультатXPath.ПолучитьСледующий();
				Если Узел = Неопределено Тогда
					Прервать;
				КонецЕсли; 
				Если ирОбщий.СтрокиРавныЛкс(ирОбщий.ТекстИзВстроенногоЯзыкаЛкс(Узел.ТекстовоеСодержимое), ТекущийЯзык().КодЯзыка) Тогда
					ЗаголовокФормы = ирОбщий.ТекстИзВстроенногоЯзыкаЛкс(Узел.СледующийСоседний.ТекстовоеСодержимое);
					Прервать;
				КонецЕсли;
			КонецЦикла;
			Если ЗначениеЗаполнено(ЗаголовокФормы) Тогда
				КорневаяСтрокаФормы.Текст = ЗаголовокФормы;
			КонецЕсли;
		КонецЕсли; 
		КорневаяСтрокаФормы.Тип = ТипЗнч(Форма);
		КорневаяСтрокаФормы.ПредставлениеТипа = КорневаяСтрокаФормы.Тип;
		Если Не ЗначениеЗаполнено(КорневаяСтрокаФормы.Текст) Тогда
			КорневаяСтрокаФормы.Текст = КорневаяСтрокаФормы.ПредставлениеТипа; 
		КонецЕсли;
		СлужебныеДанныеФормы = ирОбщий.СлужебныеДанныеФормыЛкс(Форма);
		Если СлужебныеДанныеФормы.Свойство("ИмяФормы") Тогда
			КорневаяСтрокаФормы.Имя = СлужебныеДанныеФормы.ИмяФормы;
		КонецЕсли; 
		ПутьЭлемента = "/e/e/e[1]/e[2]/e[2]";
		РезультатXPath = ДокументDOM.ВычислитьВыражениеXPath(ПутьЭлемента, ДокументDOM, РазыменовательПИ, ТипРезультатаDOMXPath.НеупорядоченныйИтераторУзлов);
		Узел = РезультатXPath.ПолучитьСледующий();
		КорневойЭлемент = Форма.Панель;
		Если КорневойЭлемент.Страницы.Количество() = 1 Тогда
			СтрокаДЗ = КорневаяСтрокаФормы;
			КорневойЭлемент = КорневойЭлемент.Страницы[0];
		Иначе
			СтрокаДЗ = КорневаяСтрокаФормы.Строки.Добавить();
			СтрокаДЗ.ЭлементФормы = Форма.Панель;
			ЗаполнитьСтрокуЭлементаОбычнойФормы(КорневаяСтрокаФормы);
		КонецЕсли; 
		Если Узел <> Неопределено Тогда
			ОбойтиУзелДереваЭлементовОбычнойФормы(КорневаяСтрокаФормы, Форма, Узел, СтрокаДЗ, КорневойЭлемент);
			//Если КорневойЭлемент <> Неопределено Тогда
			//	КорневаяСтрокаФормы.Строки.Удалить(КорневаяСтрокаФормы.Строки.Найти(Форма.Панель, "ЭлементФормы"));
			//КонецЕсли; 
		КонецЕсли;
		Для Каждого КлючИЗначение Из ИменаРеквизитовФормы(ДокументDOM).Все Цикл
			СтрокаРеквизита = РеквизитыФормы.Строки.Добавить();
			СтрокаРеквизита.Имя = КлючИЗначение.Ключ;  
			Попытка
				ЗначениеРеквизита = ТипЗнч(Форма[КлючИЗначение.Ключ]);
			Исключение
				ЗначениеРеквизита = Неопределено;
			КонецПопытки;
			СтрокаРеквизита.ТипЗначения = Новый ОписаниеТипов(ирОбщий.ЗначенияВМассивЛкс(ЗначениеРеквизита));
		КонецЦикла;
	Иначе
		#Если Сервер И Не Сервер Тогда
			ирОбщий.УправляемаяФормаБСП_СерверныеМетаданныеЛкс();
		#КонецЕсли
		ПутьЭлементаЗаголовка = "/e/e[1]/e[1]/e[1]/e[1]/d[2]";
		Если КорневаяСтрокаФормы = Неопределено Тогда
			КорневаяСтрокаФормы = Дерево.Строки.Добавить();
			КорневаяСтрокаФормы.Видимость = Истина;
			КорневаяСтрокаФормы.Доступность = Истина;
			КорневаяСтрокаФормы.ЭлементФормы = Форма;
			ЗаголовокФормы = ДокументDOM.ВычислитьВыражениеXPath(ПутьЭлементаЗаголовка, ДокументDOM, РазыменовательПИ, ТипРезультатаDOMXPath.ЛюбойНеупорядоченныйУзел).ОдиночныйУзелЗначение;
			Если ЗаголовокФормы <> Неопределено Тогда
				ЗаголовокФормы = ЗаголовокФормы.ТекстовоеСодержимое;
				ЗаголовокФормы = ирОбщий.ТекстИзВстроенногоЯзыкаЛкс(ЗаголовокФормы);
				Если ЗначениеЗаполнено(ЗаголовокФормы) Тогда
					КорневаяСтрокаФормы.Текст = ЗаголовокФормы;
				КонецЕсли;
			КонецЕсли;
		КонецЕсли; 
		КорневаяСтрокаФормы.Тип = ТипЗнч(Форма);
		КорневаяСтрокаФормы.ПредставлениеТипа = КорневаяСтрокаФормы.Тип;
		Если Не ЗначениеЗаполнено(КорневаяСтрокаФормы.Текст) Тогда
			КорневаяСтрокаФормы.Текст = КорневаяСтрокаФормы.ПредставлениеТипа; 
		КонецЕсли;
		КорневаяСтрокаФормы.Имя = Форма.ИмяФормы;
		СтруктураЗаголовков = Новый Структура;
		НаборыКолонок = Новый Структура;
		НаборыКнопок = Новый Структура;
		// XPATH
		// http://internetka.in.ua/xpath-start-part2/ - Оси
		// http://internetka.in.ua/xpath-start-part3/ - функции
		ТаблицаИндексов = Новый ТаблицаЗначений;
		ТаблицаИндексов.Колонки.Добавить("Индекс");
		ТаблицаИндексов.Колонки.Добавить("Имя");
		ИндексЗаголовокаПоля = Неопределено;
		НастройкиФормыDOM = Неопределено;
		КлючОбъекта = КлючОбъектаДляСохраненияНастроекФормы(Форма, "НастройкиФормы");
		НастройкиФормы = ХранилищеСистемныхНастроек.Загрузить(КлючОбъекта);
		Если НастройкиФормы <> Неопределено Тогда
			СтрокаНастроекФормы = ЗначениеВСтрокуВнутр(НастройкиФормы);
			XMLСтрокаНастроекФормы = ирОбщий.СтрокаВнутрВХМЛТелоЛкс(СтрокаНастроекФормы);
			//ирОбщий.Ис(XMLСтрокаНастроекФормы)
			НастройкиФормыDOM = ирОбщий.ТекстВДокументDOMЛкс(XMLСтрокаНастроекФормы);
			#Если Сервер И Не Сервер Тогда
				НастройкиФормыDOM = Новый ДокументDOM;
			#КонецЕсли
			НастройкиФормыРазыменовательПИ = Новый РазыменовательПространствИменDOM(НастройкиФормыDOM);
		КонецЕсли; 
		ПутьЭлемента = "//d[not(text()='0' or text()='4294967295' or contains(text(),'""'))]/following-sibling::d[1][contains(text(),'""') and not(text()='""""' or contains(text(),' ') or contains(text(),'$') or contains(text(),'/'))]";
		РезультатXPath = ДокументDOM.ВычислитьВыражениеXPath(ПутьЭлемента, ДокументDOM, РазыменовательПИ, ТипРезультатаDOMXPath.НеупорядоченныйИтераторУзлов);
		Пока Истина Цикл
			УзелЭлемента = РезультатXPath.ПолучитьСледующий();
			Если УзелЭлемента = Неопределено Тогда
				Прервать;
			КонецЕсли; 
			ИмяГрафическогоЭлемента = СобратьМногострочнуюСтроку(УзелЭлемента);
			Если Истина
				И Найти(ИмяГрафическогоЭлемента, "#") > 0
				И Не ирОбщий.СтрКончаетсяНаЛкс(ИмяГрафическогоЭлемента, "#title")
			Тогда
				Продолжить;
			КонецЕсли; 
			СтрокаЭлемента = ТаблицаИндексов.Добавить();
			Если ирКэш.НомерРежимаСовместимостиЛкс() > 803000 Тогда
				ИндексЭлемента = УзелЭлемента.ПредыдущийСоседний.ТекстовоеСодержимое;
				ИмяГрафическогоЭлемента = ирОбщий.ПервыйФрагментЛкс(ИмяГрафическогоЭлемента, "#");
			Иначе
				ИндексЭлемента = УзелЭлемента.РодительскийУзел.РодительскийУзел.ДочерниеУзлы[1].ТекстовоеСодержимое;
				ИмяГрафическогоЭлемента = ирОбщий.ПервыйФрагментЛкс(ИмяГрафическогоЭлемента, "_text");
			КонецЕсли; 
			СтрокаЭлемента.Индекс = ИндексЭлемента;
			СтрокаЭлемента.Имя = ИмяГрафическогоЭлемента;
		КонецЦикла; 
		ТаблицаИндексов.Индексы.Добавить("Индекс");
		ОписанияЭлементов = Новый Соответствие;
		ПутьЭлемента = "//d[contains(text(),'-') and not(starts-with(text(),'-'))]/following-sibling::d[1][not(text()='0' or text()='4294967295' or contains(text(),'""'))]";
		РезультатXPath = ДокументDOM.ВычислитьВыражениеXPath(ПутьЭлемента, ДокументDOM, РазыменовательПИ, ТипРезультатаDOMXPath.НеупорядоченныйИтераторУзлов);
		Пока Истина Цикл
			БазовыйУзел = РезультатXPath.ПолучитьСледующий();
			Если БазовыйУзел = Неопределено Тогда
				Прервать;
			КонецЕсли;
			ИндексЭлемента = БазовыйУзел.ТекстовоеСодержимое;
			// following-sibling::e[1]
			Пока БазовыйУзел <> Неопределено И БазовыйУзел.ИмяУзла <> "e" Цикл
				БазовыйУзел = БазовыйУзел.СледующийСоседний; 
			КонецЦикла; 
			Если БазовыйУзел = Неопределено Тогда
				Продолжить;
			КонецЕсли; 
			ПодходящиеСтрокиЭлементов = ТаблицаИндексов.НайтиСтроки(Новый Структура("Индекс", ИндексЭлемента));
			Для Каждого СтрокаЭлемента Из ПодходящиеСтрокиЭлементов Цикл
				ОписаниеЭлемента = Неопределено;
				Если Истина
					И ОписанияЭлементов[СтрокаЭлемента.Имя] <> Неопределено
					И ОписанияЭлементов[СтрокаЭлемента.Имя].ЗаголовкиЗаполнены
				Тогда
					Продолжить;
				КонецЕсли; 
				ОписаниеЭлемента = Новый Структура("Индекс, ЗаголовкиЗаполнены, Заголовок, Подсказка", ИндексЭлемента, Ложь, "", "");
				ОписанияЭлементов.Вставить(СтрокаЭлемента.Имя, ОписаниеЭлемента);
				ЗаголовокЭлемента = "";
				Если БазовыйУзел.ДочерниеУзлы.Количество() > 4 Тогда
					ЗаголовокЭлемента = СобратьМногострочнуюСтроку(БазовыйУзел.ДочерниеУзлы[4]);
				КонецЕсли; 
				Если Не ЗначениеЗаполнено(ЗаголовокЭлемента) Тогда
					ПутьЭлемента = "e[2]/e[1]/d[2][contains(text(),'""')]/..";
					РезультатXPath2 = ДокументDOM.ВычислитьВыражениеXPath(ПутьЭлемента, БазовыйУзел, РазыменовательПИ, ТипРезультатаDOMXPath.НеупорядоченныйИтераторУзлов);
					УзелЗаголовка = РезультатXPath2.ПолучитьСледующий();
					Если УзелЗаголовка <> Неопределено Тогда
						ЗаголовокЭлемента = СобратьМногострочнуюСтроку(УзелЗаголовка.ДочерниеУзлы[1]);
					КонецЕсли; 
				КонецЕсли;
				ОписаниеЭлемента.Заголовок = ЗаголовокЭлемента;
				ПутьЭлемента = "e[1]/e[10]/e[1]/d[2][contains(text(),'""')]/.."; // 10-й узел вероятно подойдет только для ПолеФормы
				ИтераторЗаголовка = ДокументDOM.ВычислитьВыражениеXPath(ПутьЭлемента, БазовыйУзел, РазыменовательПИ, ТипРезультатаDOMXPath.НеупорядоченныйИтераторУзлов);
				УзелПодсказки = ИтераторЗаголовка.ПолучитьСледующий();
				Если УзелПодсказки <> Неопределено Тогда
					ОписаниеЭлемента.Подсказка = СобратьМногострочнуюСтроку(УзелПодсказки.ДочерниеУзлы[1]);
				КонецЕсли; 
				Если Ложь
					Или ОписаниеЭлемента.Заголовок <> ""
					Или ОписаниеЭлемента.Подсказка <> ""
				Тогда
					ОписаниеЭлемента.ЗаголовкиЗаполнены = Истина;
					//Для Каждого СтрокаЭлемента Из ПодходящиеСтрокиЭлементов Цикл
					//	ТаблицаИндексов.Удалить(СтрокаЭлемента);
					//КонецЦикла;
					Прервать;
				КонецЕсли; 
			КонецЦикла;
		КонецЦикла;
		//Для Каждого СтрокаЭлемента Из ТаблицаИндексов Цикл
		//	ОписаниеЭлемента = Новый Структура("Индекс, ЗаголовкиЗаполнены, Заголовок, Подсказка", СтрокаЭлемента.Индекс, Ложь "", "");
		//	ОписанияЭлементов.Вставить(СтрокаЭлемента.Имя, ОписаниеЭлемента);
		//КонецЦикла;
		ТаблицаИндексов = Неопределено;
		Для Каждого ЭлементФормы Из Форма.Элементы Цикл
			Попытка
				ИмяЭлемента = ЭлементФормы.Имя;
			Исключение
				// https://partners.v8.1c.ru/forum/topic/1830402#m_1830402
				// Тип("ОсновнойЭлементФормы") и Неопределено - какие то недоработки платформы
				Продолжить;
			КонецПопытки;
			Если ТипЗнч(ЭлементФормы) = Тип("ТаблицаФормы") Тогда
				Колонки = Новый Структура;
				ОписаниеЭлемента = ОписанияЭлементов[ИмяЭлемента];
				Если ОписаниеЭлемента <> Неопределено Тогда
					ИндексПоля = ОписаниеЭлемента.Индекс;
					ПутьЭлемента = "//d[text()='6d38aadb-3b55-46c6-9b24-abddca02bec9']/following-sibling::d[1][text()=" + ИндексПоля + "]/..//d[contains(text(),'""Колонка')]";
					ИтераторКолонок = ДокументDOM.ВычислитьВыражениеXPath(ПутьЭлемента, ДокументDOM, РазыменовательПИ, ТипРезультатаDOMXPath.НеупорядоченныйИтераторУзлов);
					Пока Истина Цикл
						УзелКолонки = ИтераторКолонок.ПолучитьСледующий();
						Если УзелКолонки = Неопределено Тогда
							Прервать;
						КонецЕсли;
						ВнутреннееИмяКолонки = Вычислить(УзелКолонки.ТекстовоеСодержимое);
						Если Не ирОбщий.ЛиИмяПеременнойЛкс(ВнутреннееИмяКолонки) Тогда
							// https://www.hostedredmine.com/issues/953365
							Продолжить;
						КонецЕсли;
						ЭффективныеСвойстваКолонки = Новый Структура;
						ПутьЭлемента = "../e[1]/e[1]";
						ИтераторЗаголовка = ДокументDOM.ВычислитьВыражениеXPath(ПутьЭлемента, УзелКолонки, РазыменовательПИ, ТипРезультатаDOMXPath.НеупорядоченныйИтераторУзлов);
						УзелЗаголовка = ИтераторЗаголовка.ПолучитьСледующий();
						Если УзелЗаголовка <> Неопределено Тогда
							ЗаголовокКолонки = СобратьМногострочнуюСтроку(УзелЗаголовка.ДочерниеУзлы[1]);
						Иначе
							ЗаголовокКолонки = "";
						КонецЕсли; 
						ЭффективныеСвойстваКолонки.Вставить("Заголовок", ЗаголовокКолонки);
						ПутьЭлемента = "../e[3]/e[1]";
						ИтераторЗаголовка = ДокументDOM.ВычислитьВыражениеXPath(ПутьЭлемента, УзелКолонки, РазыменовательПИ, ТипРезультатаDOMXPath.НеупорядоченныйИтераторУзлов);
						УзелПодсказки = ИтераторЗаголовка.ПолучитьСледующий();
						Если УзелПодсказки <> Неопределено Тогда
							ПодсказкаКолонки = СобратьМногострочнуюСтроку(УзелПодсказки.ДочерниеУзлы[1]);
						Иначе
							ПодсказкаКолонки = "";
						КонецЕсли; 
						ЭффективныеСвойстваКолонки.Вставить("Подсказка", ПодсказкаКолонки);
						Колонки.Вставить(ВнутреннееИмяКолонки, ЭффективныеСвойстваКолонки);
					КонецЦикла;
				КонецЕсли; 
				Если НастройкиФормыDOM <> Неопределено Тогда
					ПутьЭлемента = "//e/d[1][text()='""" + ИмяЭлемента + """']/../e/e[2]";
					РезультатXPath = НастройкиФормыDOM.ВычислитьВыражениеXPath(ПутьЭлемента, НастройкиФормыDOM, НастройкиФормыРазыменовательПИ, ТипРезультатаDOMXPath.НеупорядоченныйИтераторУзлов);
					УзелНастроек = РезультатXPath.ПолучитьСледующий();
					Если УзелНастроек <> Неопределено Тогда
						ИзмененияСоставаКолонок = УзелНастроек.ПервыйДочерний;
						Для Счетчик = 2 По ИзмененияСоставаКолонок.ДочерниеУзлы.Количество() Цикл
							СвойстваКолонки = Новый Структура;
							ИмяКолонки = Вычислить(ИзмененияСоставаКолонок.ДочерниеУзлы[Счетчик - 1].ТекстовоеСодержимое);
							ПозицияКолонки = Вычислить(ИзмененияСоставаКолонок.ДочерниеУзлы[Счетчик].ТекстовоеСодержимое);
							Счетчик = Счетчик + 1;
							Если Форма.Элементы.Найти(ИмяКолонки) = Неопределено Тогда
								СтрокаXPath1 = "//e/d[1][text()='""" + ИмяКолонки + """']/../e/d[12]";
								РезультатXPath1 = НастройкиФормыDOM.ВычислитьВыражениеXPath(СтрокаXPath1, НастройкиФормыDOM, НастройкиФормыРазыменовательПИ, ТипРезультатаDOMXPath.НеупорядоченныйИтераторУзлов);
								УзелДобавленнойКолонки = РезультатXPath1.ПолучитьСледующий();
								Если УзелДобавленнойКолонки <> Неопределено Тогда
									ПутьКДаннымКолонки = Вычислить(УзелДобавленнойКолонки.ТекстовоеСодержимое);
								Иначе
									ПутьКДаннымКолонки = "";
								КонецЕсли; 
								СвойстваКолонки.Вставить("ПутьКДанным", ПутьКДаннымКолонки);
							КонецЕсли; 
							СвойстваКолонки.Вставить("Имя", ИмяКолонки);
							Колонки.Вставить("ИзменениеПозиции" + ПозицияКолонки, СвойстваКолонки);
						КонецЦикла;
					КонецЕсли; 
				КонецЕсли; 
				НаборыКолонок.Вставить(ИмяЭлемента, Колонки);
			ИначеЕсли Истина
				И ТипЗнч(ЭлементФормы) = Тип("ГруппаФормы")
				И (Ложь
					//Или ЭлементФормы.Вид = ВидГруппыФормы.КонтекстноеМеню // Контекстные меню здесь точно отсутствуют
					Или ЭлементФормы.Вид = ВидГруппыФормы.КоманднаяПанель) 
			Тогда
				ПолныеКнопки = Новый Массив;
				ОписаниеЭлемента = ОписанияЭлементов[ИмяЭлемента];
				Если ОписаниеЭлемента <> Неопределено Тогда
					ИндексПоля = ОписаниеЭлемента.Индекс;
					ГруппыКнопок = Новый ТаблицаЗначений;
					ГруппыКнопок.Колонки.Добавить("Индекс");
					ГруппыКнопок.Колонки.Добавить("Кнопки");
					СоответствиеКнопокКорня = Новый Соответствие;
					ИндексПодменюЕще = 0;
					ИндексКорняПанели = 4; // отображаемый набор кнопок непосредственно в командной панели
					ПутьЭлемента = "//d[text()='18a60f47-8dfd-4f2e-a693-026b98f58b2e']/following-sibling::d[1][text()=" + ИндексПоля + "]/following-sibling::e[2]/e[1]/e";
					ИтераторНабора = ДокументDOM.ВычислитьВыражениеXPath(ПутьЭлемента, ДокументDOM, РазыменовательПИ, ТипРезультатаDOMXPath.НеупорядоченныйИтераторУзлов);
					Пока Истина Цикл
						УзелНабора = ИтераторНабора.ПолучитьСледующий();
						Если УзелНабора = Неопределено Тогда
							Прервать;
						КонецЕсли;
						Кнопки = Новый Массив;
						СоответствиеКнопокНабора = Новый Соответствие;
						ПутьЭлемента = "e[*]";
						ИтераторКнопок = ДокументDOM.ВычислитьВыражениеXPath(ПутьЭлемента, УзелНабора, РазыменовательПИ, ТипРезультатаDOMXPath.НеупорядоченныйИтераторУзлов);
						Пока Истина Цикл
							УзелКнопки = ИтераторКнопок.ПолучитьСледующий();
							Если УзелКнопки = Неопределено Тогда
								Прервать;
							КонецЕсли;
							УзелЗаголовка = УзелКнопки.ДочерниеУзлы[7];
							ЗаголовокКнопки = СобратьМногострочнуюСтроку(УзелЗаголовка, УзелЗаголовка);
							ПодсказкиКнопки = СобратьМногострочнуюСтроку(УзелЗаголовка, УзелЗаголовка);
							ИДКартинки = ДокументDOM.ВычислитьВыражениеXPath("e[1]/e[1]/e[1]/d[2]/text()", УзелКнопки, РазыменовательПИ, ТипРезультатаDOMXPath.Строка).СтроковоеЗначение;
							Картинка = КартинкаИзБиблиотекиПоИдентификатору(ИДКартинки);
							ИндексПодменю = ДокументDOM.ВычислитьВыражениеXPath("e[7]/e[1]/d[3]/text()", УзелКнопки, РазыменовательПИ, ТипРезультатаDOMXPath.Строка).СтроковоеЗначение;
							Кнопки.Добавить(Новый Структура("Заголовок, Подсказка, ИндексПодменю, ЧислоПодчиненных, Видимость, Картинка", ЗаголовокКнопки, ПодсказкиКнопки, ИндексПодменю, 0, Истина, Картинка));
							Если Истина
								И ЗначениеЗаполнено(ИндексПодменю) 
								И (ЗаголовокКнопки = "Еще" Или ЗаголовокКнопки = "Все действия")
							Тогда
								ИндексПодменюЕще = Число(ИндексПодменю);
								СоответствиеКнопокКорня = СоответствиеКнопокНабора;
							КонецЕсли; 
							СоответствиеКнопокНабора.Вставить(ЗаголовокКнопки, 1);
						КонецЦикла;
						СтрокаНабора = ГруппыКнопок.Добавить();
						СтрокаНабора.Кнопки = Кнопки;
						СтрокаНабора.Индекс = Число(ДокументDOM.ВычислитьВыражениеXPath("preceding-sibling::d[1]/text()", УзелНабора, РазыменовательПИ, ТипРезультатаDOMXPath.Строка).СтроковоеЗначение);
					КонецЦикла;
					ТочкаОстанова = 0;
					ГруппаКнопок = ГруппыКнопок.Найти(ИндексПодменюЕще, "Индекс");
					Если ГруппаКнопок = Неопределено Тогда
						ГруппаКнопок = ГруппыКнопок.Найти(ИндексКорняПанели, "Индекс");
					КонецЕсли; 
					Для Каждого ОписаниеКнопки Из ГруппаКнопок.Кнопки Цикл
						Если ЗначениеЗаполнено(ОписаниеКнопки.ИндексПодменю) Тогда
							Если ОписаниеКнопки.Заголовок = "Управление поиском" Тогда
								ВиртуальнаяГруппа = Новый Структура;
								ВиртуальнаяГруппа.Вставить("Имя", "");
								ВиртуальнаяГруппа.Вставить("Картинка");
								ВиртуальнаяГруппа.Вставить("Заголовок", ОписаниеКнопки.Заголовок);
								ВиртуальнаяГруппа.Вставить("Видимость", Истина);
								ВиртуальнаяГруппа.Вставить("Вид", ВидГруппыФормы.Подменю);
								ВиртуальнаяГруппа.Вставить("ПодчиненныеЭлементы", Новый Массив);
								ДочерниеКнопки = ГруппыКнопок.Найти(Число(ОписаниеКнопки.ИндексПодменю), "Индекс").Кнопки;
								ДобавитьОписаниеКнопкиВПолныйСписокКнопок(ОписаниеКнопки, ПолныеКнопки, СоответствиеКнопокКорня, ВиртуальнаяГруппа);
								Для Каждого ДочерняяКнопка Из ДочерниеКнопки Цикл
									ДочерняяКнопка.Вставить("Имя", "");
									ДочерняяКнопка.Вставить("ПодчиненныеЭлементы", Новый Массив);
									ВиртуальнаяГруппа.ПодчиненныеЭлементы.Добавить(ДочерняяКнопка);
									ДобавитьОписаниеКнопкиВПолныйСписокКнопок(ДочерняяКнопка, ПолныеКнопки, СоответствиеКнопокКорня);
								КонецЦикла; 
							Иначе
								ДобавитьОписаниеКнопкиВПолныйСписокКнопок(ОписаниеКнопки, ПолныеКнопки, СоответствиеКнопокКорня);
								ДочерниеКнопки = ГруппыКнопок.Найти(Число(ОписаниеКнопки.ИндексПодменю), "Индекс").Кнопки;
								ОписаниеКнопки.ЧислоПодчиненных = ДочерниеКнопки.Количество();
								Для Каждого ДочерняяКнопка Из ДочерниеКнопки Цикл
									ДобавитьОписаниеКнопкиВПолныйСписокКнопок(ДочерняяКнопка, ПолныеКнопки, СоответствиеКнопокКорня,, СоответствиеКнопокКорня[ОписаниеКнопки.Заголовок] = Неопределено);
								КонецЦикла; 
							КонецЕсли; 
						Иначе
							ДобавитьОписаниеКнопкиВПолныйСписокКнопок(ОписаниеКнопки, ПолныеКнопки, СоответствиеКнопокКорня);
						КонецЕсли; 
					КонецЦикла; 
				КонецЕсли;
				НаборыКнопок.Вставить(ИмяЭлемента, ПолныеКнопки);
			КонецЕсли;
		КонецЦикла;
		СтарыйТекущийЭлемент = Форма.ТекущийЭлемент;
		ДобавитьЗависимуюКоманднуюПанель(КорневаяСтрокаФормы, Форма, НаборыКнопок);
		ДобавитьГруппуФормы(КорневаяСтрокаФормы, ДокументDOM, НаборыКолонок, НаборыКнопок, РазыменовательПИ, ОписанияЭлементов);
		ЗаполнитьСтрокуЭлементаУправляемойФормы(КорневаяСтрокаФормы);
		Форма.ТекущийЭлемент = СтарыйТекущийЭлемент;
		//Если мУсловноеОформлениеФормы <> Неопределено Тогда
		//	ИмитаторДоступныхПолей = Новый ТаблицаЗначений;
		//	ИмитаторДоступныхПолей.Колонки.Добавить();
		//	СхемаКомпоновки = ирОбщий.СоздатьСхемуПоТаблицеЗначенийЛкс(ИмитаторДоступныхПолей);
		//КонецЕсли; 
		ДобавитьРеквизитыУправляемойФормы(РеквизитыФормы, Форма);
	КонецЕсли;
	РеквизитыФормы.Строки.Сортировать("Имя");
	ПодключитьОбработчикОжидания("ЗапроситьСерверныеМетаданные", 0.1, Истина);

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

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

Процедура ЗапроситьСерверныеМетаданные()

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

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

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

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

Функция КартинкаИзБиблиотекиПоИдентификатору(ИДКартинки)
	
	Картинка = Неопределено;
	Если ЗначениеЗаполнено(ИДКартинки) И Найти(ИДКартинки, "-") > 1 Тогда
		Попытка
			Картинка = ЗначениеИзСтрокиВнутр("{""#"",e6f51714-91cb-4dce-94fe-90ae3e3e1ad1,{4,1,{0," + ИДКартинки + "},"""",-1,-1,0,0,""""}}");
		Исключение
			Пустышка = 0;
		КонецПопытки; 
	КонецЕсли;
	Возврат Картинка;

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

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

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

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

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

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

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

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

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

Процедура ДобавитьГруппуКолонокФормы(СтрокаДЗ, ГруппаТаблицыФормы, СвойстваКолонок, КоличествоВидимыхДобавлено = 0, Группировка = Неопределено)
	
	#Если Сервер И Не Сервер Тогда
		СвойстваКолонок = Новый Структура;
	#КонецЕсли
	ТаблицаФормы = ирОбщий.РодительЭлементаУправляемойФормыЛкс(ГруппаТаблицыФормы, Тип("ТаблицаФормы"));
	ПодчиненныеЭлементы = Новый ТаблицаЗначений;
	ПодчиненныеЭлементы.Колонки.Добавить("Приоритет");
	ПодчиненныеЭлементы.Колонки.Добавить("Элемент");
	Для Каждого ПодчиненныйЭлемент Из ГруппаТаблицыФормы.ПодчиненныеЭлементы Цикл
		СтрокаЭлемента = ПодчиненныеЭлементы.Добавить();
		ЗаполнитьПриоритетКолонкиТаблицыФормы(ПодчиненныйЭлемент, СтрокаЭлемента);
	КонецЦикла;
	Для Позиция = 0 По ПодчиненныеЭлементы.Количество() - 1 Цикл
		ИмяПозиции = "ИзменениеПозиции" + Позиция;
		Если СвойстваКолонок.Свойство(ИмяПозиции) Тогда 
			НастройкиКолонки = СвойстваКолонок[ИмяПозиции];
			ИмяКолонки = НастройкиКолонки.Имя;
			Колонка = Форма.Элементы.Найти(ИмяКолонки);
			Если Колонка <> Неопределено Тогда
				СтрокаЭлемента = ПодчиненныеЭлементы.Найти(Колонка, "Элемент");
				Если СтрокаЭлемента <> Неопределено Тогда
					ПодчиненныеЭлементы.Сдвинуть(СтрокаЭлемента, Позиция - ПодчиненныеЭлементы.Индекс(СтрокаЭлемента));
				Иначе
					// Пользователь поменял подчиненность поля
				КонецЕсли;
			Иначе
				НастройкиКолонки.Вставить("КартинкаШапки");
				НастройкиКолонки.Вставить("Видимость", Истина);
				НастройкиКолонки.Вставить("Доступность", Истина);
				НастройкиКолонки.Вставить("ОтображатьВШапке", Истина);
				НастройкиКолонки.Вставить("ФиксацияВТаблице", );
				НастройкиКолонки.Вставить("РодительскоеПоле", ?(ПустаяСтрока(НастройкиКолонки.ПутьКДанным), "", ирОбщий.СтрРазделитьЛкс(НастройкиКолонки.ПутьКДанным)[1]));
				СтрокаЭлемента = ПодчиненныеЭлементы.Вставить(Позиция);
				ЗаполнитьПриоритетКолонкиТаблицыФормы(НастройкиКолонки, СтрокаЭлемента);
			КонецЕсли; 
		КонецЕсли; 
	КонецЦикла;
	ПодчиненныеЭлементы.Сортировать("Приоритет");
	ПодчиненныеЭлементы = ПодчиненныеЭлементы.ВыгрузитьКолонку("Элемент");
	Для Каждого ПодчиненныйЭлемент Из ПодчиненныеЭлементы Цикл
		СтрокаДочерняяСтрока = СтрокаДЗ.Строки.Добавить();
		СтрокаДочерняяСтрока.ЭлементФормы = ПодчиненныйЭлемент;
		СтрокаДочерняяСтрока.Картинка = ПодчиненныйЭлемент.КартинкаШапки;
		Если ТипЗнч(ПодчиненныйЭлемент) = Тип("Структура") Тогда
			СтрокаДочерняяСтрока.Тип = Тип("ПолеФормы");
		КонецЕсли; 
		ЭффективнаяВидимость = ПодчиненныйЭлемент.Видимость;
		Если Истина
			И ТипЗнч(ПодчиненныйЭлемент) <> Тип("ГруппаФормы")
			И ПодчиненныйЭлемент.Доступность 
			И ПодчиненныйЭлемент.ОтображатьВШапке 
			И ТипЗнч(ПодчиненныйЭлемент) <> Тип("Структура") 
		Тогда
			СтарыйТекущийЭлемент = ТаблицаФормы.ТекущийЭлемент;
			ТаблицаФормы.ТекущийЭлемент = ПодчиненныйЭлемент;
			Если ТаблицаФормы.ТекущийЭлемент <> ПодчиненныйЭлемент Тогда
				// Антибаг платформы 8.3.15 После присвоения Неопределено свойству ТекущийЭлемент таблицы формы можно присвоить колонку с отключенной пользовательской видимостью https://partners.v8.1c.ru/forum/topic/1912733
				ТаблицаФормы.ТекущийЭлемент = СтарыйТекущийЭлемент; 
				ЭффективнаяВидимость = Ложь;
			КонецЕсли; 
		КонецЕсли; 
		ЗаполнитьСтрокуЭлементаУправляемойФормы(СтрокаДочерняяСтрока,, ЭффективнаяВидимость);
		Если ЭффективнаяВидимость Тогда
			Если ПодчиненныйЭлемент.ОтображатьВШапке Тогда
				КоличествоВидимыхДобавлено = КоличествоВидимыхДобавлено + 1;
			КонецЕсли;
			Если Истина
				И ТипЗнч(ПодчиненныйЭлемент) <> Тип("ГруппаФормы") 
				И ПодчиненныйЭлемент.ОтображатьВШапке 
			Тогда
				ЗаполнитьСтрокуДереваДляКолонкиТаблицы(КоличествоВидимыхДобавлено, СвойстваКолонок, СтрокаДочерняяСтрока);
			КонецЕсли; 
			Если ТипЗнч(ПодчиненныйЭлемент) = Тип("ГруппаФормы") Тогда
				ДобавитьГруппуКолонокФормы(СтрокаДочерняяСтрока, ПодчиненныйЭлемент, СвойстваКолонок, КоличествоВидимыхДобавлено, ПодчиненныйЭлемент.Группировка);
			КонецЕсли; 
		КонецЕсли; 
	КонецЦикла;
	
КонецПроцедуры

Процедура ЗаполнитьПриоритетКолонкиТаблицыФормы(Знач ПодчиненныйЭлемент, Знач СтрокаЭлемента)
	
	Если ПодчиненныйЭлемент.ФиксацияВТаблице = ФиксацияВТаблице.Лево Тогда
		СтрокаЭлемента.Приоритет = 1;
	ИначеЕсли ПодчиненныйЭлемент.ФиксацияВТаблице = ФиксацияВТаблице.Право Тогда
		СтрокаЭлемента.Приоритет = 3;
	Иначе
		СтрокаЭлемента.Приоритет = 2;
	КонецЕсли;
	СтрокаЭлемента.Элемент = ПодчиненныйЭлемент;

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

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

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

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

Функция НайтиГруппуКомандКонфигурации(ИмяКнопки)
	
	Для Каждого ГруппаКоманд Из Метаданные.ГруппыКоманд Цикл
		Если Найти(ИмяКнопки, ГруппаКоманд.Имя) > 0 Тогда
			Возврат ГруппаКоманд;
		КонецЕсли; 
	КонецЦикла;
	Возврат Неопределено;
	
КонецФункции

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

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

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

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

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

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

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

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

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

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

Процедура ЗаполнитьСтрокиИзКнопокОбычнойФормы(Кнопки, СтрокиДерева)
	
	Для Каждого Кнопка Из Кнопки Цикл
		Если Ложь
			Или Кнопка.ТипКнопки = ТипКнопкиКоманднойПанели.Разделитель 
			//Или Кнопка.Имя = "СтруктураКоманднойПанели"
		Тогда
			Продолжить;
		КонецЕсли; 
		СтрокаДерева = СтрокиДерева.Добавить();
		СтрокаДерева.ЭлементФормы = Кнопка;
		ЗаполнитьЗначенияСвойств(СтрокаДерева, Кнопка); 
		Если СтрокаДерева.Подсказка = СтрокаДерева.Текст Тогда
			СтрокаДерева.Подсказка = "";
		КонецЕсли; 
		ПредставлениеСочетаниеКлавиш = ирОбщий.ПредставлениеСочетанияКлавишЛкс(СтрокаДерева.СочетаниеКлавиш, "");
		Окончание = "";
		Действие = "" + Кнопка.Действие;
		Если Действие = "Переместить вверх" Тогда 
			Окончание = "Up";
		ИначеЕсли Действие = "Переместить вниз" Тогда
			Окончание = "Down";
		ИначеЕсли Ложь
			Или Действие = "Удалить" 
			Или Действие = "Установить пометку удаления"
		Тогда
			Окончание = "Del";
		ИначеЕсли Действие = "Добавить" Тогда
			Окончание = "Ins";
		КонецЕсли; 
		Если Не ирОбщий.СтрКончаетсяНаЛкс(ПредставлениеСочетаниеКлавиш, Окончание) Тогда
			// Видимо антибаг платформы. На 8.3.23 вроде бы не обнаруживается 
			ПредставлениеСочетаниеКлавиш = ПредставлениеСочетаниеКлавиш + Окончание;
		КонецЕсли;
		Если ЗначениеЗаполнено(ПредставлениеСочетаниеКлавиш) Тогда
			СтрокаДерева.ПредставлениеСочетаниеКлавиш = ПредставлениеСочетаниеКлавиш;
		КонецЕсли; 
		// Тупик. Этот идентификатор оказался не от картинки
		//Если СтрокаДерева.Картинка.Вид = ВидКартинки.Пустая Тогда
		//	СтрокаВнутр = ЗначениеВСтрокуВнутр(Кнопка);
		//	// {"#",365b8b83-672d-4c9f-b2d7-5d8331db6c7c,
		//	//{8,"Действие",0,0,
		//	//{1,1,
		//	//{"ru","&Добавить"}
		//	//},0,6f8d70fc-66dc-47aa-84cd-dae08452935d,2511,99,0,0,1,0,1,0,0}
		//	//}
		//	СтрокаВнутр = ирОбщий.ПоследнийФрагментЛкс(СтрокаВнутр, "},");
		//	Фрагменты = ирОбщий.СтрРазделитьЛкс(СтрокаВнутр, ",");
		//	ИДКартинки = Фрагменты[1];
		//	Картинка = КартинкаИзБиблиотекиПоИдентификатору(ИДКартинки);
		//	Если Картинка <> Неопределено Тогда
		//		СтрокаДерева.Картинка = Картинка;
		//	КонецЕсли; 
		//КонецЕсли; 
		ЗаполнитьСтрокуЭлементаОбычнойФормы(СтрокаДерева);
		Если Кнопка.ТипКнопки = ТипКнопкиКоманднойПанели.Подменю Тогда
			ЗаполнитьСтрокиИзКнопокОбычнойФормы(Кнопка.Кнопки, СтрокаДерева.Строки);
		КонецЕсли; 
	КонецЦикла;

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

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

Функция РезультирующийПризнакСтрокиДерева(Знач СтрокаДерева)

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

КонецФункции
 
Процедура ПриЗакрытии()
	
	ирКлиент.Форма_ПриЗакрытииЛкс(ЭтаФорма);
	ВосстановитьСвойстваЭлементовФормы(Истина);
	мТекущаяСтрока = Неопределено;
	
КонецПроцедуры

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

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

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

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

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

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

Процедура СтрокаПоискаПриИзменении(Элемент)
	
	ирКлиент.ПолеВводаСИсториейВыбора_ПриИзмененииЛкс(Элемент, ЭтаФорма);
	НайтиСтрокиДерева();
	
КонецПроцедуры

Процедура СтрокаПоискаНачалоВыбораИзСписка(Элемент, СтандартнаяОбработка)
	
	ирОбщий.ПолеВводаСИсториейВыбора_ОбновитьСписокЛкс(Элемент, ЭтаФорма);
	
КонецПроцедуры

Процедура ВпередНажатие(Элемент)
	
	ирКлиент.СледующееВхождениеСтрокиПоискаВТабличномПолеЛкс(ЭтаФорма, ЭлементыФормы.Дерево);
	
КонецПроцедуры

Процедура НазадНажатие(Элемент)
	
	ирКлиент.ПредыдущееВхождениеСтрокиПоискаВТабличномПолеЛкс(ЭтаФорма, ЭлементыФормы.Дерево);

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

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

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

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

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

Процедура ПоказатьСвязаннуюФорму()
	
	Если Форма <> Неопределено Тогда
		ирКлиент.Форма_АктивироватьОткрытьЛкс(Форма);
	КонецЕсли; 
	ЭтаФорма.Активизировать();

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

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

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

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

Функция ТекущийОбъектИсследователя()
	
	Возврат мТекущаяСтрока.ЭлементФормы;

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

Процедура КоманднаяПанельДереваСсылкаНаМодуль(Кнопка)
	
	ирКлиент.ПоказатьСсылкуНаМодульКонфигурацииЛкс(Дерево.Строки[0].Имя + ".Форма");
	
КонецПроцедуры

Процедура АктивнаяПодсветкаПриИзменении(Элемент)
	
	ИндикацияТекущегоЭлемента();
	
КонецПроцедуры

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

Процедура КлсКомандаНажатие(Кнопка)
	
	ирКлиент.УниверсальнаяКомандаФормыЛкс(ЭтаФорма, Кнопка);
	
КонецПроцедуры

Процедура ПодсказкаОткрытие(Элемент, СтандартнаяОбработка)
	
	СтандартнаяОбработка = Ложь;
	ОткрытьТекстПодсказки(ОписаниеТекущейСтроки);

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

Процедура СтрокаПоискаАвтоПодборТекста(Элемент, Текст, ТекстАвтоПодбора, СтандартнаяОбработка)
	
	Если ирКлиент.ПромежуточноеОбновлениеСтроковогоЗначенияПоляВводаЛкс(ЭтаФорма, Элемент, Текст) Тогда 
		НайтиСтрокиДерева();
	КонецЕсли;
	
КонецПроцедуры

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

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

Процедура ВнешнееСобытие(Источник, Событие, Данные) Экспорт
	
	ирКлиент.Форма_ВнешнееСобытиеЛкс(ЭтаФорма, Источник, Событие, Данные);

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

Процедура ТабличноеПолеПриПолученииДанных(Элемент, ОформленияСтрок) Экспорт 
	
	ирКлиент.ТабличноеПолеПриПолученииДанныхЛкс(ЭтаФорма, Элемент, ОформленияСтрок);

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

Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник) Экспорт 
	
	ирКлиент.Форма_ОбработкаОповещенияЛкс(ЭтаФорма, ИмяСобытия, Параметр, Источник); 
	
КонецПроцедуры

Процедура ПоказатьСвернутьНайденные()

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

Процедура СвернутьПанели()
	ПоказатьСвернутьНайденные();
КонецПроцедуры
	
Процедура ПередЗакрытием(Отказ, СтандартнаяОбработка)
	
	Если Не Отказ Тогда
		ПоказатьСвернутьНайденные();
	КонецЕсли; 

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

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

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

Процедура УсловноеОформлениеПриАктивизацииСтроки(Элемент)
	
	ирКлиент.ТабличноеПолеПриАктивизацииСтрокиЛкс(ЭтаФорма, Элемент);
	
КонецПроцедуры

Процедура УсловноеОформлениеПриВыводеСтроки(Элемент, ОформлениеСтроки, ДанныеСтроки) Экспорт
	
	ирКлиент.УсловноеОформлениеПриВыводеСтрокиЛкс(ЭтаФорма, Элемент, ОформлениеСтроки, ДанныеСтроки);
	
КонецПроцедуры

Процедура ОбновлениеОтображения()
	
	ирКлиент.Форма_ОбновлениеОтображенияЛкс(ЭтаФорма);
	
КонецПроцедуры

Процедура СортироватьПоПоложению(Кнопка)
	СортироватьСтроки("Верх, Лево");
КонецПроцедуры

Процедура СортироватьПоТипу(Кнопка)
	СортироватьСтроки("Тип, Текст");
КонецПроцедуры

Процедура СортироватьПоТексту(Кнопка)
	СортироватьСтроки("Текст");
КонецПроцедуры

Процедура ОбновитьОтбор()
	ирКлиент.ТабличноеПолеСДаннымиПоискаУстановитьОтборПоПодстрокеЛкс(ЭтаФорма, ЭлементыФормы.СистемныеСочетанияКлавиш, ПодстрокаПоиска);
КонецПроцедуры

Процедура ПодстрокаПоискаПриИзменении(Элемент)
	ирКлиент.ПолеВводаСИсториейВыбора_ПриИзмененииЛкс(Элемент, ЭтаФорма);
	ОбновитьОтбор();
КонецПроцедуры

Процедура ПодстрокаПоискаНачалоВыбораИзСписка(Элемент, СтандартнаяОбработка)
	ирОбщий.ПолеВводаСИсториейВыбора_ОбновитьСписокЛкс(Элемент, ЭтаФорма);
КонецПроцедуры

Процедура ПодстрокаПоискаАвтоПодборТекста(Элемент, Текст, ТекстАвтоПодбора, СтандартнаяОбработка)
	Если ирКлиент.ПромежуточноеОбновлениеСтроковогоЗначенияПоляВводаЛкс(ЭтаФорма, Элемент, Текст) Тогда 
		ОбновитьОтбор();
	КонецЕсли;
КонецПроцедуры

Процедура СистемныеСочетанияКлавишПриАктивизацииСтроки(Элемент)
	ирКлиент.ТабличноеПолеПриАктивизацииСтрокиЛкс(ЭтаФорма, Элемент);
КонецПроцедуры

Процедура СистемныеСочетанияКлавишПриВыводеСтроки(Элемент, ОформлениеСтроки, ДанныеСтроки) Экспорт
	ирКлиент.ТабличноеПолеПриВыводеСтрокиЛкс(ЭтаФорма, Элемент, ОформлениеСтроки, ДанныеСтроки);
КонецПроцедуры

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

Процедура ОбработчикиСобытийВыбор(Элемент, ВыбраннаяСтрока, Колонка, СтандартнаяОбработка)

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

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

Функция ФайлМодуля()
	
	Возврат мПлатформа.ФайлМодуляИзИмениМодуля(Дерево.Строки[0].Имя + ".Форма.Модуль");

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

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

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

Процедура КоманднаяПанельДереваОткрытьМодульИзКэша(Кнопка)
	ирКлиент.ОткрытьПолеТекстаМодуляКонфигурацииЛкс(ИмяМодуля());
КонецПроцедуры

Функция ИмяМодуля()
	
	Возврат Дерево.Строки[0].Имя + ".Форма.Модуль";

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

Процедура РеквизитыФормыПриАктивизацииСтроки(Элемент)
	ирКлиент.ТабличноеПолеПриАктивизацииСтрокиЛкс(ЭтаФорма, Элемент);
КонецПроцедуры

Процедура РеквизитыФормыПриВыводеСтроки(Элемент, ОформлениеСтроки, ДанныеСтроки)
	ирКлиент.ТабличноеПолеПриВыводеСтрокиЛкс(ЭтаФорма, Элемент, ОформлениеСтроки, ДанныеСтроки,, "ТипЗначения");
КонецПроцедуры

Процедура РеквизитыФормыВыбор(Элемент, ВыбраннаяСтрока, Колонка, СтандартнаяОбработка)
	Если Колонка = ЭлементыФормы.РеквизитыФормы.Колонки.ТипЗначения Тогда
		ирКлиент.ЯчейкаТабличногоПоляРасширенногоЗначения_ВыборЛкс(ЭтаФорма, Элемент, СтандартнаяОбработка,,,,, ВыбраннаяСтрока.Имя);
	КонецЕсли;
КонецПроцедуры

Процедура КоманднаяПанельДереваМетодыМодуля(Кнопка)
	
	
	
КонецПроцедуры

Процедура КоманднаяПанельДереваОткрытьВКонфигураторе(Кнопка)
	
	ПолноеИмяФормы = Дерево.Строки[0].Имя;  
	ПутьВОбъекте = "";
	Если ЭлементыФормы.Дерево.ТекущаяСтрока <> Дерево.Строки[0] Тогда
		БлижайшийЭлементФормы = ЭлементыФормы.Дерево.ТекущаяСтрока;
		Пока Ложь
			Или БлижайшийЭлементФормы.Тип = Тип("КолонкаТабличногоПоля") 
			Или БлижайшийЭлементФормы.Тип = Тип("КнопкаКоманднойПанели") 
		Цикл
			БлижайшийЭлементФормы = БлижайшийЭлементФормы.Родитель;
		КонецЦикла;
		Если Дерево.Строки[0].Тип = ирОбщий.ТипУправляемаяФормаЛкс() Тогда
			ПутьВОбъекте = ".Элементы.";
		Иначе
			ПутьВОбъекте = ".ЭлементыФормы.";
		КонецЕсли;
		ПутьВОбъекте = ПутьВОбъекте + БлижайшийЭлементФормы.Имя;
	КонецЕсли;
	ирКлиент.ПерейтиКОбъектуМетаданныхВКонфигуратореЛкс(ПолноеИмяФормы, ПутьВОбъекте);
	
КонецПроцедуры

Процедура ПередОткрытием(Отказ, СтандартнаяОбработка)
	ОбновитьДерево();
	Отказ = Дерево.Строки.Количество() = 0;
КонецПроцедуры

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