Перем ПолеТела Экспорт;
Перем мРежимРедактора;
Перем мФоновыйЗапросХттп;

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

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

Функция СохраняемаяНастройкаФормы(выхНаименование, выхИменаСвойств) Экспорт 
КонецФункции

Функция СвойстваГлобализуемые() Экспорт
	Результат = Новый Структура;
	Результат.Вставить("ШиринаГенерируемогоТекста");
	//! ЗаполнитьЗначенияСвойств(ЭтаФорма, Результат)
	Возврат Результат;
КонецФункции

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

Функция ИмяПараметраРезультата() Экспорт
	Возврат "<Результат>";
КонецФункции

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

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

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

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

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

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

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

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

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

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

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

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

Функция ИмяПараметраВозврата() Экспорт
	Возврат "ПараметрВозврата";
КонецФункции

//.
// Возвращаемое значение:
//    - 
Функция ИмяПараметраДом() Экспорт
	Возврат "Дом";
КонецФункции

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

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

Процедура ПриЗакрытии()
	
	ирКлиент.Форма_ПриЗакрытииЛкс(ЭтаФорма);
	
	// +++.КЛАСС.ПолеТекстаПрограммы
	// Уничтожение всех экземпляров компоненты. Обязательный блок.
	ПолеТела.Уничтожить();
	// ---.КЛАСС.ПолеТекстаПрограммы
	
КонецПроцедуры

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

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

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

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

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

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

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

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

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

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

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

Процедура ТаблицаПараметровПередУдалением(Элемент, Отказ)
	
	Отказ = Истина;
	
КонецПроцедуры

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

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

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

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

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

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

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

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

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

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

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

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

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

Процедура ЧистыйКонтекстПриИзменении(Элемент)
	ЭлементыФормы.ПолеТела.УстановитьТекст(ТекстТела);
КонецПроцедуры

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

Функция РеквизитыДляСервера(Параметры) Экспорт 
	Возврат Новый Структура;
КонецФункции

Процедура ДействияФормыЗаполнитьИИ(Кнопка)
	Если Кнопка.Картинка <> ирКэш.КартинкаПоИмениЛкс("ирОстановить") Тогда
		ПараметрыЗаполненияМетода = ПараметрыЗаполненияМетодаИИ();
		Если ПараметрыЗаполненияМетода = Неопределено Тогда
			Возврат;
		КонецЕсли;
		ТекстМодуля = ОбновитьПолноеОпределение(ПараметрыЗаполненияМетода.ЗаменятьТелоМетода);
		Если ПараметрыЗаполненияМетода.ПередаватьКонтекст Тогда
			КонтекстИИ = КонтекстИИ(Описание, ТаблицаПараметров, ЧистыйКонтекст, ДирективаКомлиляции);
		КонецЕсли;
		ТекстЗапроса = ТекстЗапросаИИДляМетода(ТекстМодуля, КонтекстИИ, ШиринаГенерируемогоТекста, ПараметрыЗаполненияМетода);
		Если ПараметрыЗаполненияМетода.ПоказатьЗапрос Тогда
			Если ирКлиент.ОткрытьТекстЛкс(ТекстЗапроса, "Подтвердите запрос ИИ",,,,,, Истина) = Неопределено Тогда
				Возврат;
			КонецЕсли;
		КонецЕсли;
	КонецЕсли;
	БлокируемыеЭлементы = Новый Массив;
	БлокируемыеЭлементы.Добавить(ЭтаФорма);
	ПараметрыЗадания = Новый Структура;
	ПараметрыЗадания.Вставить("Текст", ТекстЗапроса);
	ПараметрыЗадания.Вставить("ПараметрыЗаполнения", ПараметрыЗаполненияМетода);
	мФоновыйЗапросХттп.ОтправитьЗапросИИ(ПараметрыЗадания, ЭтаФорма, "ЗаполнитьИИКонец", БлокируемыеЭлементы, Кнопка);

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

Функция ТекстЗапросаИИДляМетода(Знач ТекстМетода, Знач ДопИнфоКонтекст = "", Знач ШиринаГенерируемогоТекста = 180, Знач ПараметрыЗаполнения) Экспорт
	СистемнаяИнформация = Новый СистемнаяИнформация;
	Результат = 
	"Analyze the provided 1C method code and generate documentation in JSON format.
	|- Extract the method's purpose and provide a clear description.
	|- Identify and list each parameter by name, specifying its type and description.
	|- Determine the return value and describe it, including its type.
	// Возможно это не помогает
	|- In result JSON descriptions insert \n by word boundaries after every " + ШиринаГенерируемогоТекста + " characters. 
	|
	|# Steps
	|**Identify Parameters**: Identify the parameters used in the method, detailing their name, type, and purpose.
	|**Determine Return Value**: Examine the method to understand what it returns, noting the type and a brief description.";
	Если ПараметрыЗаполнения.ЗаменятьИмяМетода Тогда
		Результат = Результат + "
		|**Replace method name**: Generate new name for method no longer than 60 characters.";
	КонецЕсли;
	Если ПараметрыЗаполнения.ЗаменятьТелоМетода Тогда
		Результат = Результат + "
		|**Replace method body**: generate code in method body based on method name, description and parameters:
		|- 1C platform - " + СистемнаяИнформация.ВерсияПриложения + "
		|- 1C standard subsystems library - " + ирКэш.ВерсияБСПЛкс() + "
		|- In 1C, a cycle with a counter has a fixed step +1 and the following syntax: Для <Переменная> = <МеньшееВыражение> По <БольшееВыражение> Цикл ... КонецЦикла
		|- In 1C, the numbering of elements of all collections starts from 0
		|- Do not use ""Перем"" keyword in variable definition, just set its value: <Переменная> = <Выражение>;
		|- Do not use operators: ""+="", ""++""";
	Иначе
		Результат = Результат + "
		|**Extract Description**: understand the functionality and purpose of the method from the code.";
	КонецЕсли;
	Если ПараметрыЗаполнения.ЗаменятьКомментарииВКоде Тогда
		Результат = Результат + "
		// Зачем я указал как размещать новые комментарии?
		|**Add comments in body**: add only important comments, place new comments in new lines or at end of existing lines
		|**Do not change in body**: leading whitespace and multiline text literals, for example:
		|```1C
		|	Текст = ""ВЫБРАТЬ 1
		|	|ИЗ Константы"";
		|```";
	КонецЕсли;
	Результат = Результат + "
	|
	|# Output Format
	|Provide ONLY VALID JSON object in the following format:
	|```json
	|{
	|  ""name"": ""<имя метода>"",
	|  ""description"": ""<описание метода в целом, максимум 500 символов>"",
	|  ""parameters"": [
	|    {
	|      ""name"": ""<имя параметра>"",
	|      ""type"": ""<тип 1 параметра>, <тип 2 параметра>, ..."",
	|      ""descr"": ""<описание параметра>""
	|    }
	|  ],
	|  ""return_descr"": ""<описание возвращаемого значения, максимум 100 символов, только для функции>""
	|  ""return_type"": ""<тип возвращаемого значения, только для функции>""
	|  ""body"": ""<текст между началом и концом метода>""
	|}```
	|
	|# Examples
	|**Example Input:**
	|```1C
	|&НаСервере
	|Функция ИмяСотрудникаПоИдентификатору(ИдСотрудника)
	|	Возврат ?(ПустаяСтрока(ИдСотрудника), Неопределено, Справочники.Сотрудники.НайтиПоКоду(ИдСотрудника).Имя);
	|КонецФункции
	|```
	|
	|**Example Output:**
	|```json
	|" + ОбразецДокументацииМетодаЖСОН() + "
	|```
	|
	|# Notes
	|- Ensure accuracy in describing the method's function, parameters, and return values.
	|- Handle any edge cases such as optional parameters or lack of return values gracefully.
	|- Descriptions are in Russian.
	|
	|# Context
	|<knowledge>
	|" + ДопИнфоКонтекст + "
	|</knowledge>
	|
	|# Code to Analyze:
	|```1C
	|" + ТекстМетода + "
	|```";
    Возврат Результат;
КонецФункции

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

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

//.
// Параметры:
//   СостояниеЗадания -  - 
//   РезультатЗадания - см. ирОбщий.ОтправитьЗапросИИЛкс - 
Процедура ЗаполнитьИИКонец(Знач СостояниеЗадания, Знач РезультатЗадания) Экспорт
	Если РезультатЗадания = Неопределено Тогда
		Возврат;
	КонецЕсли;
	Ответ = РезультатЗадания.Ответ;
	ПараметрыЗаполнения = РезультатЗадания.ПараметрыЗаполнения;  // см. ПараметрыЗаполненияИИ
	ТекстЖСОН = ирОбщий.ТекстМеждуМаркерамиЛкс(РезультатЗадания.Ответ, "```json", "```", Ложь,,, Ложь);
	Если ПустаяСтрока(ТекстЖСОН) Тогда
		ирОбщий.СообщитьЛкс("ИИ вернул ответ, не соответствующий запрошенному формату. Если проблема повторяется, выберите другую модель ИИ.");
		Возврат;
	КонецЕсли;
	РезультатИИ = ирОбщий.ОбъектИзТекстаЖСОНЛкс(ТекстЖСОН); // см. ПрочитатьJSON(ОбразецДокументацииМетодаЖСОН())
	Если ПустаяСтрока(ИмяМетода) Или ПараметрыЗаполнения.ЗаменятьИмяМетода Тогда
		ЭтаФорма.ИмяМетода = РезультатИИ.name;
	КонецЕсли;
	Если Истина
		И ПараметрыЗаполнения.КомментарийМетода
		И (Ложь
			Или ПустаяСтрока(Описание)
			Или ПараметрыЗаполнения.ЗаменятьКомментарийМетода)
	Тогда
		ЭтаФорма.Описание = РезультатИИ.description;
	КонецЕсли;
	СтрокаРезультата = ТаблицаПараметров.Найти(Истина, "ЭтоРезультат");
	Если Истина
		И СтрокаРезультата <> Неопределено
		И ПараметрыЗаполнения.КомментарииПараметров
		И (Ложь
			Или ПараметрыЗаполнения.ЗаменятьКомментарииПараметров
			Или ПустаяСтрока(СтрокаРезультата.Комментарий))
	Тогда
		СтрокаРезультата.Комментарий = РезультатИИ.return_descr;
	КонецЕсли;
	Если Истина
		И СтрокаРезультата <> Неопределено
		И ПараметрыЗаполнения.ТипыПараметров
		И (Ложь
			Или ПараметрыЗаполнения.ЗаменятьТипыПараметров
			Или ПустаяСтрока(СтрокаРезультата.ТипЗначения))
	Тогда
		СтрокаРезультата.ТипЗначения = РезультатИИ.return_type;
	КонецЕсли;
	Для Каждого СтруктураПараметра Из РезультатИИ.parameters Цикл
		СтрокаПараметра = ТаблицаПараметров.Найти(НРег(СтруктураПараметра.name), "НИмя");
		Если СтрокаПараметра = Неопределено Тогда
			Продолжить;
		КонецЕсли;
		Если Истина
			И ПараметрыЗаполнения.КомментарииПараметров
			И (Ложь
				Или ПараметрыЗаполнения.ЗаменятьКомментарииПараметров
				Или ПустаяСтрока(СтрокаПараметра.Комментарий))
		Тогда
			СтрокаПараметра.Комментарий = СтруктураПараметра.descr;
		КонецЕсли;
		Если Истина
			И ПараметрыЗаполнения.ТипыПараметров
			И (Ложь
				Или ПараметрыЗаполнения.ЗаменятьТипыПараметров
				Или ПустаяСтрока(СтрокаПараметра.ТипЗначения))
		Тогда
			СтрокаПараметра.ТипЗначения = СтруктураПараметра.type;
		КонецЕсли;
	КонецЦикла;
	Если Ложь
		Или ПараметрыЗаполнения.КомментарииВКоде
		Или ПараметрыЗаполнения.ЗаменятьТелоМетода
	Тогда
		ПолеТела.УстановитьТекст(РезультатИИ.body);
	КонецЕсли;

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

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

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

Процедура СлужебноеПолеХТМЛonclick(Элемент, pEvtObj) Экспорт
	мФоновыйЗапросХттп.ОбработатьОтвет(ЭтаФорма);
КонецПроцедуры

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