Перем мИсторияФайлов;
Перем мИмяОткрытогоФайла;
Перем СтараяТаблицаКолонок;
Перем ЭтоДерево;
Перем РасширениеФайла;
Перем мКнопкаРежимаОтображения;
Перем мЧислоСтатичныхКолонокКолонок;

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

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

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

Функция ПолучитьРезультат()
	
	ЭтаФорма.ПараметрАтрибутыКолонок = Новый Структура;
	Для Каждого СтрокаКолонки Из ТаблицаКолонок Цикл
		АтрибутыКолонки = Новый Структура;
		Для Индекс = мЧислоСтатичныхКолонокКолонок По ТаблицаКолонок.Колонки.Количество()-1 Цикл
			ИмяАтрибута = ТаблицаКолонок.Колонки[Индекс].Имя;
			АтрибутыКолонки.Вставить(ИмяАтрибута, СтрокаКолонки[ИмяАтрибута]);
		КонецЦикла;
		Если АтрибутыКолонки.Количество() = 0 Тогда
			Прервать;
		КонецЕсли;
		ПараметрАтрибутыКолонок.Вставить(СтрокаКолонки.Имя, АтрибутыКолонки);
	КонецЦикла;
	Возврат Коллекция;
	
КонецФункции

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

Процедура ОбновитьТаблицуКолонок()

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

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

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

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

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

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

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

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

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

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

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

// https://partners.v8.1c.ru/forum/t/1632942/m/1632942
Процедура ПереустановитьТекущуюКолонку()
	
	Если ЭлементыФормы.Коллекция.ТекущаяКолонка.Видимость Тогда
		ЭлементыФормы.Коллекция.ТекущаяКолонка = ЭлементыФормы.Коллекция.ТекущаяКолонка;
	КонецЕсли;
	
КонецПроцедуры

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

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

Функция ЛиОсновнойПриемникФайл()
	Возврат Не ЭтаФорма.МодальныйРежим И ЭтаФорма.ВладелецФормы = Неопределено;
КонецФункции

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

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

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

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

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

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

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

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

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

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

Процедура ЯчейкаОкончаниеВводаТекста(Элемент, Текст, Значение, СтандартнаяОбработка)
	
	ирКлиент.ПолеВвода_ОкончаниеВводаТекстаЛкс(Элемент, Текст, Значение, СтандартнаяОбработка);

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

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

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

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

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

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

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

Функция КоманднаяПанельТаблицаСохранитьВТекущийФайл(Кнопка)
	СохранитьВФайл();
КонецФункции

Функция КоманднаяПанельТаблицаСохранитьВФайл(Кнопка)
	СохранитьВФайл(Ложь);
КонецФункции

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

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

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

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

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

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

Функция ЧислоВСтрокуПодробно(Число)
	
	Возврат Формат(Число, "ЧН=; ЧВН=; ЧГ=0");
	
КонецФункции

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

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

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

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

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

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

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

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

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

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

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

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

Процедура КоманднаяПанельТаблицаВыбратьИЗаполнитьОбъектБД(Кнопка)
	
	Если ТипЗнч(Коллекция) = Тип("ДеревоЗначений") Тогда
		Возврат;
	КонецЕсли; 
	ирКлиент.ВыбратьИЗаполнитьТабличнуюЧастьОбъектаБДЛкс(Коллекция);
	
КонецПроцедуры

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

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

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

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

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

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

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

Процедура КоманднаяПанельТаблицаПоказатьНеуникальные(Кнопка)
	
	ирКлиент.ПоказатьНеуникальныеСтрокиТабличногоПоляЛкс(ЭлементыФормы.Коллекция);
	
КонецПроцедуры

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

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

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

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

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

Процедура ТолькоПросмотрПриИзменении(Элемент = Неопределено)
	
	ЭлементыФормы.Коллекция.ТолькоПросмотр = рТолькоПросмотр Или КоллекцияИспользоватьОтбор;
	ЭтаФорма.ТолькоПросмотр = рТолькоПросмотр;
	
КонецПроцедуры

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

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

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

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

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

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

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

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

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

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

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

Процедура КоманднаяПанельТаблицаВТаблицуЗначений(Кнопка)
	
	ирКлиент.ОткрытьЗначениеЛкс(ирОбщий.ДеревоЗначенийВТаблицуЛкс(ПолучитьРезультат()),,,, Ложь);
	
КонецПроцедуры

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

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

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

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

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

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

Процедура КоманднаяПанельТаблицаВБуферОбмена(Кнопка)
	
	ирКлиент.БуферОбменаПриложения_УстановитьЗначениеЛкс(ПолучитьРезультат());
	
КонецПроцедуры

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

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

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

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

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

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

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

Процедура ТаблицаКолонокПеретаскивание(Элемент, ПараметрыПеретаскивания, СтандартнаяОбработка, Строка, Колонка)
	Если ПараметрыПеретаскивания.Действие = ДействиеПеретаскивания.Копирование Тогда 
		ПараметрыПеретаскивания.Действие = ДействиеПеретаскивания.Отмена;
	КонецЕсли;
КонецПроцедуры

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

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

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

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

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

Процедура КоманднаяПанельТаблицаВТекстJSON(Кнопка)
	
	Таблица = ПолучитьРезультат();
	Результат = ирОбщий.ТаблицаЗначенийВЖСОНЛкс(Таблица);
	ирКлиент.ОткрытьТекстЛкс(Результат);
	
КонецПроцедуры

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

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

Процедура КоманднаяПанельТаблицаПередатьВExcel(Кнопка)
	ВывестиТаблицуЗначенийВExcel(ПолучитьРезультат());
КонецПроцедуры

Процедура ВывестиТаблицуЗначенийВExcel(Знач Таблица) Экспорт 
	
	#Если Сервер И Не Сервер Тогда
		Таблица = Новый ТаблицаЗначений;
	#КонецЕсли
	Эксель = Новый COMОбъект("Excel.Application");
	Эксель.DisplayAlerts = Ложь;
	Эксель.Visible = Истина;
	Книга = Эксель.Workbooks.Add();
	Лист = Книга.Worksheets(1);
	ВсегоКолонок = Таблица.Колонки.Количество();
	ВсегоСтрок = Таблица.Количество();
	МассивКом = Новый COMSafeArray("VT_Variant", ВсегоКолонок, ВсегоСтрок);
	Стр = 0;
	Для Кол = 0 По ВсегоКолонок - 1 Цикл
		КолонкаИсточника = Таблица.Колонки[Кол];
		Лист.Cells(1, Кол+1).Value = КолонкаИсточника.Имя;
		Если КолонкаИсточника.ТипЗначения.Типы().Количество() = 1 Тогда 
			Если КолонкаИсточника.ТипЗначения.СодержитТип(Тип("Число")) Тогда
				Формат = "0";
			ИначеЕсли КолонкаИсточника.ТипЗначения.СодержитТип(Тип("Булево")) Тогда
				Формат = "0";
			ИначеЕсли КолонкаИсточника.ТипЗначения.СодержитТип(Тип("Дата")) Тогда
				Формат = "ДД.ММ.ГГГГ чч:мм:сс";
			Иначе
				Формат = "@"; // Строка
			КонецЕсли;
			Лист.Columns(Кол+1).NumberFormat = Формат;
		КонецЕсли;
	КонецЦикла;
	НачальнаяСтрока = 1;
	РазрешенныеТипы = Новый ОписаниеТипов("Строка, Дата, Число, Булево");
	_РежимОтладки = Ложь;
	Если _РежимОтладки Тогда // Можно менять на Истина в точке останова, например условием ирОбщий.Пр(_РежимОтладки, 1, 1)
		// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
		Для Стр = 0 По ВсегоСтрок - 1 Цикл
			СтрокаТаблицы = Таблица[Стр];
			Для Кол = 0 По ВсегоКолонок - 1 Цикл
				ЗначениеЯчейки = СтрокаТаблицы[Кол];
				ТипЗначения = ТипЗнч(ЗначениеЯчейки);
				Если ЗначениеЯчейки = Дата(1,1,1) Тогда 
					ЗначениеЯчейки = Неопределено;
				ИначеЕсли ТипЗначения = Тип("Булево") Тогда 
					ЗначениеЯчейки = 0 + ЗначениеЯчейки; // Без добавки нуля - ноль, полученный из Ложь, вызывал прерывание вывода в EXCEL
				ИначеЕсли Ложь
					Или Не РазрешенныеТипы.СодержитТип(ТипЗначения) 
					Или ТипЗначения = Тип("Дата") И ЗначениеЯчейки < Дата(1900, 1, 1) // Ограничение EXCEL по году даты
				Тогда 
					ЗначениеЯчейки = "" + ЗначениеЯчейки;
				КонецЕсли;
				МассивКом.SetValue(Кол, Стр, ЗначениеЯчейки);
			КонецЦикла;
		КонецЦикла;
	Иначе
		// Однострочный код использован для ускорения при разрешенной отладке. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика"
		Для Стр = 0 По ВсегоСтрок - 1 Цикл  			СтрокаТаблицы = Таблица[Стр];  			Для Кол = 0 По ВсегоКолонок - 1 Цикл  				ЗначениеЯчейки = СтрокаТаблицы[Кол];  				ТипЗначения = ТипЗнч(ЗначениеЯчейки);  				Если ЗначениеЯчейки = Дата(1,1,1) Тогда  					ЗначениеЯчейки = Неопределено;  				ИначеЕсли ТипЗначения = Тип("Булево") Тогда  					ЗначениеЯчейки = 0 + ЗначениеЯчейки;  				ИначеЕсли Ложь  					Или Не РазрешенныеТипы.СодержитТип(ТипЗначения)  					Или ТипЗначения = Тип("Дата") И ЗначениеЯчейки < Дата(1900, 1, 1)  				Тогда  					ЗначениеЯчейки = "" + ЗначениеЯчейки;  				КонецЕсли;  				МассивКом.SetValue(Кол, Стр, ЗначениеЯчейки);  			КонецЦикла;  		КонецЦикла;  
	КонецЕсли;
	Лист.Range(Лист.Cells(НачальнаяСтрока + 1, 1), Лист.Cells(НачальнаяСтрока + ВсегоСтрок, ВсегоКолонок)).Value = МассивКом;

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

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

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

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

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

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

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

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

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

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

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

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