Перем _Значение_ Экспорт;
Перем БазовоеВыражение Экспорт;
Перем СтруктураТипаКоллекции;
Перем СтруктураТипаЭлементаКоллекции;
Перем МаркерСловаЗначения;
Перем Коллекция;
Перем ПутьКДаннымКоллекции;
Перем ОписанияКолонок;
Перем СвойстваЭлементовКоллекции;
Перем мПлатформа;

Функция УстановитьИсследуемоеЗначение(Знач НоваяКоллекция, Знач ПутьКДанным = Неопределено, Знач пСтруктураТипаКоллекции = Неопределено, Знач БезСлужебныхКолонок = Ложь) Экспорт 

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

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

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

Процедура ОбновитьДанные()

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

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

Процедура ОткрытьТекущийЭлемент(Знач ВОтдельномОкне = Ложь)

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

Функция ОбновитьМетаданныеВСтруктуреТипаЭлементаКоллекции(ТекущаяСтрока)

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

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

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

Процедура КоманднаяПанельКоллекцииОткрыватьИсследовать(Кнопка)

	ОткрыватьИсследовать = Кнопка.Пометка;
	Кнопка.Пометка = Не ОткрыватьИсследовать;

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

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

Процедура ТаблицаКоллекцииПередНачаломИзменения(Элемент, Отказ)
	
	//Отказ = Истина;
	//ОткрытьТекущийЭлемент();
	
КонецПроцедуры

Процедура ПереключитьСлужебныеКолонки(Видимость)

	Колонки = ЭлементыФормы.ТаблицаКоллекции.Колонки;
	//Колонки._ЗначениеЭлементаКоллекции.Видимость = Видимость;
	Колонки._ТипЭлементаКоллекции.Видимость = Видимость;
	ЭлементыФормы.КоманднаяПанельКоллекции.Кнопки.БезСлужебных.Пометка = Не Видимость;

КонецПроцедуры // БезСлужебныхКолонок()

Процедура КоманднаяПанельКоллекцииБезСлужебных(Кнопка)
	
	ПереключитьСлужебныеКолонки(Кнопка.Пометка);
	
КонецПроцедуры

Процедура КоманднаяПанельКоллекцииЯчейкаСтрока(Кнопка)
	
	ЯчейкаСтрока = Не Кнопка.Пометка;
	Кнопка.Пометка = ЯчейкаСтрока;
	
КонецПроцедуры

Процедура ЯчейкаПриИзменении(Элемент)

	ТабличноеПоле = ЭлементыФормы.ТаблицаКоллекции;
	ТекущаяКолонка = ТабличноеПоле.ТекущаяКолонка;
	ТекущаяСтрока = ТабличноеПоле.ТекущаяСтрока;
	Попытка
		ТекущаяСтрока._ЗначениеЭлементаКоллекции[ТекущаяКолонка.Данные] = Элемент.Значение;
		БылаОшибка = Ложь;
	Исключение
		Сообщить(ирОбщий.ПолучитьИнформациюОбОшибкеБезВерхнегоМодуляЛкс(ИнформацияОбОшибке(), 1), СтатусСообщения.Внимание);
	КонецПопытки;
	Элемент.Значение = ТекущаяСтрока._ЗначениеЭлементаКоллекции[ТекущаяКолонка.Данные];

КонецПроцедуры // ЯчейкиПриИзменении()

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

Процедура КоманднаяПанельКоллекцииСправка(Кнопка)

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

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

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

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

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

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

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

Процедура ОбработчикОжиданияСПараметрамиЛкс() Экспорт 
	
	ирКлиент.ОбработчикОжиданияСПараметрамиЛкс();

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

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

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

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

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

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

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

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

Процедура КоманднаяПанельКоллекцииИсследоватьВОтдельномОкне(Кнопка)
	
	ОткрытьТекущийЭлемент(Истина);
	
КонецПроцедуры

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

ирКлиент.ИнициироватьФормуЛкс(ЭтаФорма, "Обработка.ирИсследовательОбъектов.Форма.ИсследовательКоллекций");

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