Перем мПлатформа;
Перем мИмяМеткиВыхода;
Перем мСписокВнешнихПараметров Экспорт;
Перем мМетоды Экспорт;
Перем КоличествоВнешнихПараметров;
Перем ТекстМодуляТекущейВнешнейОбработки;
Перем ИмяФайлаВнешнейОбработки;
Перем ВнешняяОбработка;
Перем мСмещениеНомеровСтрок;
Перем мСмещениеНомеровСтрокДоп;
Перем мСмещениеНомеровСтрокДопПорог;
Перем ДатаИзмененияВнешнейОбработки;
Перем РежимВнешнейОбработки Экспорт;
Перем АвтоПараметрыВыхода Экспорт;
Перем мСтруктураВосстановления;
Перем мИсторияФайлов;
Перем мАнализТехножурнала;
Перем ПолеТекстаАлгоритма Экспорт;
Перем мРежимРедактора Экспорт;
Перем мИмяАлгоритмаДляРедактора Экспорт;
Перем мТекущаяСтрокаДереваАлгоритмов;
Перем мАлгоритмЗагруженВКонсоль;
Перем мИмяОткрытогоФайла;
Перем мМаркерНачалаАлгоритма;
Перем мМаркерКонцаАлгоритма;
Перем НомерВставкиЗамера;
Перем мРасширениеФайла;
Перем мТекущаяСтраницаРедактора;
Перем ЛиГрупповоеВыполнение Экспорт;
Перем мИмяПеременнойЗамераСтрок;
Перем мРазрешитьАктивациюРедактора;
Перем мИмяПеременнойВозврата;
//Перем мРедакторHTML;

// @@@.КЛАСС.ПолеТекстаПрограммы

// Транслятор обработки событий нажатия на кнопки командной панели в компоненту.

// Является обязательным.

//

// Параметры:

//  Кнопка       - КнопкаКоманднойПанели.

//

Процедура КлсПолеТекстаПрограммыНажатие(Кнопка)

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

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

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

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

// @@@.КЛАСС.ПолеТекстаПрограммы
Функция КлсПолеТекстаПрограммыОбновитьКонтекст(Знач Компонента = Неопределено, Знач Кнопка = Неопределено) Экспорт 

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

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

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

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

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

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


// @@@.КЛАСС.ПолеТекстаПрограммы
Процедура КлсПолеТекстаПрограммыАвтоОбновитьСправку()
	
	ПолеТекстаАлгоритма.АвтоОбновитьСправку();
	
КонецПроцедуры
                    
Процедура ВнешнееСобытие(Источник, Событие, Данные) Экспорт
	
	Если ПолеТекстаАлгоритма = Неопределено Или Не Открыта() Тогда
		Возврат;
	КонецЕсли; 
	#Если Сервер И Не Сервер Тогда
	    ПолеТекстаАлгоритма = Обработки.ирКлсПолеТекстаПрограммы.Создать();
	#КонецЕсли
	// @@@.КЛАСС.ПолеТекстаПрограммы
	ПолеТекстаАлгоритма.ВнешнееСобытиеОбъекта(Источник, Событие, Данные);
	
КонецПроцедуры


Процедура ПриОткрытии()

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


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

Процедура ПодготовитьГлобальныйКонтекст() 
	ПолеТекстаАлгоритма.ПодготовитьГлобальныйКонтекст();
КонецПроцедуры

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

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

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

Функция ИмяСлужебногоФайла()
	
	Файл1 = Новый Файл(ИмяФайлаВнешнейОбработки);
	Результат = Файл1.Путь + Файл1.ИмяБезРасширения + ".tim";
	Возврат Результат;

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


Процедура ОбновитьЗначенияПараметровВыхода(СтруктураПараметров, РазрешитьДесериализацию = Истина)

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

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

// @@@.КЛАСС.ПолеТекстаПрограммы

// Процедура служит для выполнения программы поля текстового документа в локальном контексте.

// Вызывается из компоненты ирКлсПолеТекстаПрограммы в режиме внутреннего языка.

// Не является обязательной.

//

// Параметры:

//  ТекстДляВыполнения - Строка;

//  *ЛиСинтаксическийКонтроль - Булево, *Ложь - признак вызова только для синтаксического контроля.

//

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

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

Функция РежимВнешнейОбработки()
	Возврат Ложь
		Или РежимВнешнейОбработки 
		Или ПолеТекстаАлгоритма.ЭтоМодуль;
КонецФункции

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

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

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

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

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

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

// Предопределеный метод
Процедура ПроверкаЗавершенияФоновыхЗаданий() Экспорт 
	
	ирКлиент.ПроверитьЗавершениеФоновыхЗаданийФормыЛкс(ЭтаФорма);
	
КонецПроцедуры

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

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

Функция ПолучитьИмяМодуляВнешнейОбработки()

	ИмяМодуля = "ВнешняяОбработка." + ИмяВнешнейОбработки() + ".МодульОбъекта";
	Возврат ИмяМодуля;

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

Функция ИмяВнешнейОбработки()
	
	ИмяОбработки = БазовоеИмяВнешнейОбработки();
	Возврат ИмяОбработки;

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

Функция БазовоеИмяВнешнейОбработки()
	
	Возврат "DynamicExternalProcessorOfCodeConsole";

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


Процедура ПриЗакрытии()

	

	ирКлиент.Форма_ПриЗакрытииЛкс(ЭтаФорма);
	ирКлиент.УдалитьФайлВосстановленияКонсолиСБлокировкойЛкс(мСтруктураВосстановления);
	
	// +++.КЛАСС.ПолеТекстаПрограммы

	// Уничтожение всех экземпляров компоненты. Обязательный блок.
	#Если Сервер И Не Сервер Тогда
		ПолеТекстаАлгоритма = Обработки.ирКлсПолеТекстаПрограммы.Создать();
	#КонецЕсли

	ПолеТекстаАлгоритма.Уничтожить();
	// ---.КЛАСС.ПолеТекстаПрограммы



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


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

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

Процедура ПодключитьОбновлениеКонтекстаОтложенно() Экспорт
	ПодключитьОбработчикОжидания("ОбновитьКонтекстОтложенно", 0.1, Истина);
КонецПроцедуры

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

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

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

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

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

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

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

Процедура ПараметрыПередУдалением(Элемент, Отказ)
	
	Отказ = (Элемент.ТекущиеДанные.Позиция > 0 Или Элемент.ТекущиеДанные.Фиксированный);
	
КонецПроцедуры

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

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

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

Процедура АктивироватьКолонкуЗначение()
	ЭлементыФормы.Параметры.ТекущаяКолонка = ЭлементыФормы.Параметры.Колонки.Имя; 
КонецПроцедуры

Процедура ПараметрыНачалоПеретаскивания(Элемент, ПараметрыПеретаскивания, Выполнение)
	
	// Пришлось пожертвовать этой возможностью ради перетаскивания параметров между алгоритмами
	//ПараметрыПеретаскивания.Значение = Элемент.ТекущаяСтрока.Имя;
	
КонецПроцедуры

Процедура КоманднаяПанельВстроенныйЯзыкСсылкаНаОбъектБД(Кнопка)

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

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

Процедура ЗаполнитьСтрокуНовогоПараметра(СтрокаПараметра)
	
	//СтрокаПараметра.НИмя = НРег(СтрокаПараметра.Имя);
	СтрокаПараметра.Вход = Истина;
	СтрокаПараметра.Выход = Ложь;
	СтрокаПараметра.Модуль = Истина;
	ОбновитьПредставлениеИТипЗначенияВСтроке(СтрокаПараметра);

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

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

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

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

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

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

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

Процедура ЗаполнитьПараметры(Знач ПараметрыВхода = Истина, Знач ПараметрыВыхода = Истина, Знач РазобратьТекущийКонтекст = Истина)

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

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

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

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

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

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

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

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

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

Функция ОбновитьФайлВнешнейОбработкиИнтерактивно(СтруктураПараметров = Неопределено, выхВерсияАлгоритма = Неопределено) Экспорт

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

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

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

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

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

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

Функция ИмяГлавногоМетода()
	
	Возврат "Главный";

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

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

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

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

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

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

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

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

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

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

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

Процедура КоманднаяПанельВстроенныйЯзыкЗамерВремени(Кнопка)
	
	Кнопка.Пометка = Не Кнопка.Пометка;
	ЛиЗамерВремени = Кнопка.Пометка;
	
КонецПроцедуры

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

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

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

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

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

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

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

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

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

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

Процедура ДействияФормыСохранитьФайл(Кнопка)
	
	СохранитьВФайл();
	
КонецПроцедуры

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

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

Процедура ОчиститьПараметрыВыхода(Знач ПараметрыСтроки = Неопределено)
	
	Если ПараметрыСтроки = Неопределено Тогда
		ПараметрыСтроки = Параметры;
	КонецЕсли; 
	НачальноеКоличество = ПараметрыСтроки.Количество(); 
	Для СчетчикПараметры = 1 По НачальноеКоличество Цикл
		СтрокаПараметра = ПараметрыСтроки[НачальноеКоличество - СчетчикПараметры];
		Если СтрокаПараметра.Выход И Не СтрокаПараметра.Вход Тогда
			ПараметрыСтроки.Удалить(СтрокаПараметра);
		КонецЕсли;
	КонецЦикла;

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

Процедура КоманднаяПанельВстроенныйЯзыкВыполнитьАнализТрассы(Кнопка)
	
	Если мАнализТехножурнала <> Неопределено Тогда
		#Если Сервер И Не Сервер Тогда
		    мАнализТехножурнала = Обработки.ирАнализТехножурнала.Создать();
		#КонецЕсли
		мАнализТехножурнала.ПоказатьТрассу(,,, 0,, Истина, Истина);
	КонецЕсли; 
	
КонецПроцедуры

Функция НовыйКлючЗамераДляВставкиВАлгоритм()
	
	НомерВставкиЗамера = НомерВставкиЗамера + 1;
	Возврат "Замер" + XMLСтрока(НомерВставкиЗамера);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Процедура ЗагрузитьДанныеТекущейСтроки()

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

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

Процедура УстановитьТекстПоляАлгоритма(Текст)
	
	ПолеТекстаАлгоритма.УстановитьТекст(Текст,, Текст);

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

Процедура КП_ДеревоДобавитьГруппу(Кнопка)
	
	ЭлементыФормы.ДеревоАлгоритмов.ДобавитьСтроку();
	ЭлементыФормы.ДеревоАлгоритмов.ТекущаяСтрока.ЭтоГруппа = Истина;
	
КонецПроцедуры

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

Процедура СоздатьФайл(Отладка = Ложь) Экспорт 

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

Процедура ПриИзмененииДереваАлгоритмов()

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

Процедура ОбновитьДоступностьПанелиАлгоритма() Экспорт

	НоваяДоступность = Истина
		И мАлгоритмЗагруженВКонсоль
		И мТекущаяСтрокаДереваАлгоритмов <> Неопределено
		И Не мТекущаяСтрокаДереваАлгоритмов.ЭтоГруппа;
	ЭлементыФормы.КоманднаяПанельПараметры.Доступность = НоваяДоступность;
	ЭлементыФормы.Параметры.Доступность = НоваяДоступность;
	ЭлементыФормы.КоманднаяПанельВстроенныйЯзык.Доступность = НоваяДоступность;
	ЭлементыФормы.ПанельРедактора.Доступность = НоваяДоступность;

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

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

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

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

Процедура ОчиститьДанные()
	
	ДеревоАлгоритмов.Строки.Очистить();
	мТекущаяСтрокаДереваАлгоритмов = Неопределено;
	УстановитьТекстПоляАлгоритма("");
	Параметры.Очистить();
	
КонецПроцедуры

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

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

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

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

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

Функция БазовоеИмяНовойСтроки()
	
	Возврат "Алгоритм";

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

Процедура ДействияФормыСохранитьКак(Кнопка)
	
	СохранитьВФайл(Ложь, Истина);

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

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

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

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

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

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

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

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

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

Процедура ДеревоАлгоритмовПриОкончанииРедактирования(Элемент, НоваяСтрока, ОтменаРедактирования)
	
	ирКлиент.ДеревоКонсолиПриОкончанииРедактированияЛкс(мТекущаяСтрокаДереваАлгоритмов);

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

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

Процедура ДеревоАлгоритмовПередУдалением(Элемент, Отказ)
	
	мТекущаяСтрокаДереваАлгоритмов = Неопределено;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Процедура КоманднаяПанельВстроенныйЯзыкВОднострочныйВид(Кнопка)
	
	// https://www.forum.mista.ru/topic.php?id=659371&page=2
	// https://infostart.ru/public/71130/
	// https://partners.v8.1c.ru/forum/t/1134075/m/1134075
	// При компиляции 1С модулей, компилятор вставляет специальную команду перед первой выполняющейся инструкцией в строке исходного кода.
	// Эта команда используется для служебных целей платформы, например обработки прерывания выполнения кода, работы отладчика и т.п.
	// Обычно, обработка этой команды очень слабо влияет на производительность 1С кода
	// При обработке опкода новой строки "на клиенте предотвращается "замерзание" интерфейса, а на сервере отслеживается потеря связи с клиентом и убитие соединения администратором
	// "Код "переменная1 = 342" практически ничего не делает, т.к. 342 это константа, сконструированная при компиляции модуля, а присваивание ее переменной очень дешевая операция.
	АктивноеПолеТекста = ПолеТекстаАлгоритма.ПолеТекста;
	#Если Сервер И Не Сервер Тогда
		ПолеТекстаАлгоритма = Обработки.ирКлсПолеТекстаПрограммы.Создать();
		АктивноеПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
	#КонецЕсли
	НомерСтрокиКаретки = 0;
	
	АктивноеПолеТекста.ПолучитьГраницыВыделения(НомерСтрокиКаретки, 1, 1, 1);
	ВесьТекст = Ложь;
	Если СтрДлина(АктивноеПолеТекста.ВыделенныйТекст()) = 0 Тогда
		ВесьТекст = Истина;
		Текст = ПолеТекстаАлгоритма.ПолеТекста.ПолучитьТекст();
		НомерСтрокиКаретки = 1;
	Иначе
		Текст = АктивноеПолеТекста.ВыделенныйТекст();
	КонецЕсли;
	ОднострочныйТекст = Новый ЗаписьXML;
	ОднострочныйТекст.УстановитьСтроку("");
	МногострочныйТекст = Текст;
	Если Прав(МногострочныйТекст, 1) = Символы.ПС Тогда
		МногострочныйТекст = Сред(МногострочныйТекст, 1, СтрДлина(МногострочныйТекст) - 1);
	КонецЕсли; 
	Если Найти(НРег(Текст), НРег("ОбработкаПрерыванияПользователя();")) > 0 Тогда
		ирОбщий.СообщитьЛкс("Метод ОбработкаПрерыванияПользователя() в однострочном варианте фактически не будет работать", СтатусСообщения.Информация);
	КонецЕсли; 
	Комментарии = "";
	Текст = ПолеТекстаАлгоритма.УдалитьКомментарии(Текст);
	ТекстовыйДокумент = Новый ТекстовыйДокумент;
	ТекстовыйДокумент.УстановитьТекст(Текст);
	ПерваяСтрокаТекста = ТекстовыйДокумент.ПолучитьСтроку(1);
	Отступ = Лев(ПерваяСтрокаТекста, СтрДлина(ПерваяСтрокаТекста) - СтрДлина(СокрЛ(ПерваяСтрокаТекста)));
	ОткрытаИнструкцияДляПодсказки = Ложь;
	Для Счетчик = 1 По ТекстовыйДокумент.КоличествоСтрок() Цикл 
		СтрокаТекста = ТекстовыйДокумент.ПолучитьСтроку(Счетчик);
		//Если Лев(СокрЛ(СтрокаТекста), 2) = "//" Тогда
		//	Продолжить;
		//КонецЕсли; 
		Если Лев(СокрЛ(СтрокаТекста), 1) = "|" Тогда
			ирОбщий.СообщитьЛкс("В однострочном коде не допускаются многострочные строковые литералы", СтатусСообщения.Внимание);
			АктивноеПолеТекста.УстановитьГраницыВыделения(НомерСтрокиКаретки + Счетчик - 1, 1, НомерСтрокиКаретки + Счетчик - 1, 1000);
			Возврат;
		КонецЕсли;
		ИнструкцияДляПодсказки = "#Если Сервер И Не Сервер Тогда";
		Если НРег(СокрЛП(СтрокаТекста)) = НРег(ИнструкцияДляПодсказки) Тогда
			СтрокаТекста = СтрЗаменить(СтрокаТекста, ИнструкцияДляПодсказки, "Если Ложь Тогда");
			ОткрытаИнструкцияДляПодсказки = Истина;
		КонецЕсли; 
		Если ОткрытаИнструкцияДляПодсказки И СокрЛП(СтрокаТекста) = "#КонецЕсли" Тогда
			СтрокаТекста = СтрЗаменить(СтрокаТекста, "#КонецЕсли", "КонецЕсли;");
			ОткрытаИнструкцияДляПодсказки = Ложь;
		КонецЕсли; 
		Если Лев(СокрЛ(СтрокаТекста), 1) = "#" Тогда
			ирОбщий.СообщитьЛкс("В однострочном коде не допускаются инструкции препроцессора", СтатусСообщения.Внимание);
			АктивноеПолеТекста.УстановитьГраницыВыделения(НомерСтрокиКаретки + Счетчик - 1, 1, НомерСтрокиКаретки + Счетчик - 1, 1000);
			Возврат;
		КонецЕсли; 
		ОднострочныйТекст.ЗаписатьБезОбработки(СокрП(СтрокаТекста) + " " + Символы.НПП);
	КонецЦикла;
	ВыходнойТекст = ""
		+ Сред(Отступ, 2) + "_РежимОтладки = Ложь;"
		+ Символы.ПС + Сред(Отступ, 2) + "Если _РежимОтладки Тогда // Можно менять на Истина в точке останова, например условием ирОбщий.Пр(_РежимОтладки, 1, 1)"
		+ Символы.ПС + Отступ + "// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах."
		+ Символы.ПС + МногострочныйТекст
		+ Символы.ПС + Сред(Отступ, 2) + "Иначе"
		+ Символы.ПС + Отступ + КомментарийОднострочногоВида() 
		+ Символы.ПС + Отступ + СокрЛ(ОднострочныйТекст.Закрыть())
		+ Символы.ПС + Сред(Отступ, 2) + "КонецЕсли;"
		+ Символы.ПС;
	Если ВесьТекст Тогда
		АктивноеПолеТекста.УстановитьГраницыВыделения(1, СтрДлина(ЭлементыФормы.РедакторВстроенный.ПолучитьТекст()) + 1);
		АктивноеПолеТекста.ВыделенныйТекст(ВыходнойТекст);
		АктивноеПолеТекста.УстановитьГраницыВыделения(1, 1);
	Иначе
		АктивноеПолеТекста.ВыделенныйТекст(ВыходнойТекст);
		АктивноеПолеТекста.УстановитьГраницыВыделения(НомерСтрокиКаретки, 1, НомерСтрокиКаретки, 1);
	КонецЕсли; 
	
КонецПроцедуры

Функция КомментарийОднострочногоВида()
	
	Возврат "// Однострочный код использован для ускорения при разрешенной отладке. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах."
		+ " Преобразовано консолью кода из подсистемы ""Инструменты разработчика""";

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

Процедура КоманднаяПанельВстроенныйЯзыкИзОднострочногоВида(Кнопка)

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

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

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

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

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

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

Процедура КоманднаяПанельВстроенныйЯзыкЗагрузитьИзмененияИзВнешнейОбработки(Кнопка)
	
	СравнитьЗагрузитьИзмененияИзВнешнейОбработки(Ложь);
	
КонецПроцедуры

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

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

Процедура КоманднаяПанельВстроенныйЯзыкСравнитьЗагрузитьИзмененияИзВнешнейОбработки(Кнопка)
	
	СравнитьЗагрузитьИзмененияИзВнешнейОбработки(Истина);
	
КонецПроцедуры

Процедура ДействияФормыОткрытьИТС(Кнопка)
	
	ирКлиент.ОткрытьСсылкуИТСЛкс("https://its.1c.ru/db/v?doc#bookmark:dev:TI000000116");
	
КонецПроцедуры

Процедура ПараметрыВходПриИзменении(Элемент)
	
	ОбработатьИзменениеПометокПараметров();
	
КонецПроцедуры

Процедура ПараметрыВыходПриИзменении(Элемент)
	
	ОбработатьИзменениеПометокПараметров();
	
КонецПроцедуры

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

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

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

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

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

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

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

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

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

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

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

Процедура КоманднаяПанельВстроенныйЯзыкЕсли(Кнопка)
	
	#Если Сервер И Не Сервер Тогда
	    ПолеТекстаАлгоритма = Обработки.ирКлсПолеТекстаПрограммы.Создать();
	#КонецЕсли
	ПолеТекстаАлгоритма.ОкружитьВыделенныеСтроки("Если  Тогда", "КонецЕсли;");

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

Процедура КоманднаяПанельВстроенныйЯзыкЦиклДляКаждого(Кнопка)
	
	#Если Сервер И Не Сервер Тогда
	    ПолеТекстаАлгоритма = Обработки.ирКлсПолеТекстаПрограммы.Создать();
	#КонецЕсли
	ПолеТекстаАлгоритма.ОкружитьВыделенныеСтроки("Для Каждого  Из  Цикл", "КонецЦикла;");

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

Процедура КоманднаяПанельВстроенныйЯзыкЦиклДляПо(Кнопка)
	
	#Если Сервер И Не Сервер Тогда
	    ПолеТекстаАлгоритма = Обработки.ирКлсПолеТекстаПрограммы.Создать();
	#КонецЕсли
	ПолеТекстаАлгоритма.ОкружитьВыделенныеСтроки("Для Счетчик = 1 По  Цикл", "КонецЦикла;");
	
КонецПроцедуры

Процедура КоманднаяПанельВстроенныйЯзыкЦиклПока(Кнопка)
	
	#Если Сервер И Не Сервер Тогда
	    ПолеТекстаАлгоритма = Обработки.ирКлсПолеТекстаПрограммы.Создать();
	#КонецЕсли
	ПолеТекстаАлгоритма.ОкружитьВыделенныеСтроки("Пока  Цикл", "КонецЦикла;");

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

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

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

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

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

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

Процедура ЗначениеПараметраПриИзменении(Элемент)
	
	ПараметрыПредставлениеЗначениеПриИзменении(, Элемент.Значение);

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

///////////////////////////
//  HTML редактор кода 

Функция РедакторВстроенный()
	
	Возврат ЭлементыФормы.РедакторВстроенный;

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

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

Функция РедакторHTML()
	Возврат ПолеТекстаАлгоритма.ПолеТекста.РедакторHTML();
КонецФункции

Процедура РедакторHTMLДокументСформирован(Элемент)
	#Если Сервер И Не Сервер Тогда
		ПолеТекстаАлгоритма = Обработки.ирКлсПолеТекстаПрограммы.Создать();
	#КонецЕсли
	ПолеТекстаАлгоритма.РедакторHTML_Инициировать(Элемент);       
	Если ЭлементыФормы.ПанельРедактора.ТекущаяСтраница = ЭлементыФормы.ПанельРедактора.Страницы.РедакторHTML Тогда
		ПанельРедактораПриСменеСтраницы(ЭлементыФормы.ПанельРедактора,);
	КонецЕсли;
КонецПроцедуры

// Мультиметка343281883
Функция ВводДоступенЛкс() Экспорт 
	
	Если ЭтаФорма.ТекущийЭлемент = ЭлементыФормы.РедакторHTML Тогда
		РедакторHTML = РедакторHTML();
		Результат = Ложь
			Или РедакторHTML <> Неопределено И РедакторHTML.hasTextFocus()
			Или ВводДоступен();
	Иначе
		Результат = ВводДоступен();
	КонецЕсли; 
	Возврат Результат;
КонецФункции

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

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

Процедура РедакторHTMLonclick(Элемент, ДанныеСобытия)
	РедакторHTMLonclickДинамический(ДанныеСобытия);
КонецПроцедуры

// Для подключения через ДобавитьОбработчик внутри РедакторHTML_Инициировать
Процедура РедакторHTMLonclickДинамический(ДанныеСобытия) Экспорт
	
	#Если Сервер И Не Сервер Тогда
		ПолеТекстаАлгоритма = Обработки.ирКлсПолеТекстаПрограммы.Создать();
	#КонецЕсли
	Событие = ДанныеСобытия.eventData1C;
	Если Событие <> Неопределено Тогда
		Если Событие.event = "EVENT_CONTENT_CHANGED" Тогда
			ЭтаФорма.Модифицированность = Истина;
			ПолеТекстаАлгоритма.ПолеТекста.УстановитьДекорации();
		ИначеЕсли Событие.event = "EVENT_ON_LINK_CLICK" Тогда
			#Если Сервер И Не Сервер Тогда
				ПерейтиКОпределениюВФорме();
				ВычислитьВыражение();
			#КонецЕсли
			ПолеТекстаАлгоритма.РедакторHTML_ОбработатьКликНаГиперссылке(Событие, "ПерейтиКОпределениюВФорме", "ВычислитьВыражение");
		ИначеЕсли Событие.event = "EVENT_BEFORE_HOVER" Тогда
			#Если Сервер И Не Сервер Тогда
				ВычислитьВыражение();
			#КонецЕсли
			ПолеТекстаАлгоритма.РедакторHTML_ПередПоказомПодсказкиУдержания(Событие, "ВычислитьВыражение");
		Иначе
			ПолеТекстаАлгоритма.РедакторHTML_ОбработатьСобытие(Событие);
		КонецЕсли;
	КонецЕсли;
	
КонецПроцедуры

////////////////////////////

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

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

Процедура КоманднаяПанельВстроенныйЯзыкПараметрыСУБД(Кнопка)
	
	ирКлиент.ОткрытьФормуСоединенияСУБДЛкс();

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

Процедура КоманднаяПанельВстроенныйЯзыкНастройкаТехножурнала(Кнопка)
	ирКлиент.ОткрытьНастройкуТехножурналаПоПользователюЛкс();
КонецПроцедуры

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

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

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

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

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

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

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

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

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

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

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

Функция СтрокиПараметровТолькоВыхода()
	
	ПараметрыВыхода = Параметры.НайтиСтроки(Новый Структура("Вход, Выход", Ложь, Истина));
	Возврат ПараметрыВыхода;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Функция ТелоГлавногоМетода()
	#Если Сервер И Не Сервер Тогда
	    ПолеТекстаАлгоритма = Обработки.ирКлсПолеТекстаПрограммы.Создать();
	#КонецЕсли
	ИмяГлавногоМетода = ИмяГлавногоМетода();
	ТекстАлгоритма = ПолеТекстаАлгоритма.ПолеТекста.ПолучитьТекст();
	Если Истина
		И ПолеТекстаАлгоритма.ЭтоМодуль 
		И ПолеТекстаАлгоритма.мМодульМетаданных.Методы.Количество() > 0
	Тогда
		ТекстАлгоритма = ПолеТекстаАлгоритма.ТелоМетода(ПолеТекстаАлгоритма.мМодульМетаданных.Методы[0]);
	КонецЕсли;
	Возврат ТекстАлгоритма;

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

Процедура ДеревоАлгоритмовЭтоМодульПриИзменении(Элемент)
	ОбновитьСтруктуруАлгоритма();
	ОбновитьДоступностьКнопок();
КонецПроцедуры

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

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

Функция ОпределениеГлавногоМетодаИзТела(Знач ТелоМетода = Неопределено)

	#Если Сервер И Не Сервер Тогда
	    ПолеТекстаАлгоритма = Обработки.ирКлсПолеТекстаПрограммы.Создать();
	#КонецЕсли
	Если ТелоМетода = Неопределено Тогда
		ТелоМетода = ПолеТекстаАлгоритма.ПолеТекста.ПолучитьТекст();
	КонецЕсли;
	ТекстАлгоритма =
	"Функция " + ИмяГлавногоМетода() + "()
	|" + ТелоМетода + "
	|КонецФункции
	|";
	Возврат ТекстАлгоритма;

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

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

Процедура ПараметрыПослеУдаления(Элемент)
	ПодключитьОбновлениеКонтекстаОтложенно();
КонецПроцедуры

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

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

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

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