
// Устанавливаются снаружи
Перем мКонфигурация Экспорт;
Перем мСтараяСтраницаПанелиЧасти Экспорт;
Перем мСтараяСтраницаПанелиОсновная Экспорт;

Перем мНомерБазовойСтрокиВТексте;
Перем мТекущаяСтрокаСвязи;
Перем мТекущаяСтрокаУсловияСвязи;
Перем мТекущаяСтрокаВыбранногоПоля;
Перем мТекущаяСтрокаУсловия;
Перем мТекущаяСтрокаПараметраТаблицы;
Перем мТекущаяЧастьОбъединения; // см. ЧастиОбъединения[0]
Перем мТекущийЗапросПакета; // см. ЗапросыПакета[0]
Перем мТекущаяСтрокаВыбранныеТаблицы;
Перем мТекущаяСтрокаГруппируемогоПоля;
Перем мТекущееИмяОсновнойТаблицы;
Перем мТекущееИмяВыбраннойТаблицы;
Перем мТекущееИмяПараметра;
Перем мТекущееИмяДоступнойТаблицы;
Перем мЧислоСтатическихКолонокТЗПоляПсевдонимовПолей;
Перем мЧислоСтатическихКолонокТППоляПсевдонимовПолей;
Перем мРежимРедактированияТекста Экспорт;
Перем ПараметрыДиалектаSQL;
Перем мСтрокаНачальногоЗапроса;
Перем мСтрокаНачальнойЧастиОбъединения;
Перем мРазборПоследнийТокенРазделитель;
Перем мРазборИндексПринимающегоПоля; // Используется при разборе текста запроса для INSERT
Перем мЗапросКорневогоПакетаДляДоступностиВременныхТаблиц;
Перем мРежимПоказаОшибки;
Перем мНомерТекущейСтрокиВСобранномТексте Экспорт ; // Вычисляется при сборке текста по текущему запросу пакета
Перем мРегВычислительВыразить;
Перем мИсторияПереходов;
Перем ЗапрещеноОформлениеТабличныхПолей;
Перем _РежимОтладки;

// +++.КЛАСС.ПолеТекстаПрограммы
Перем ПолеТекстаПрограммы Экспорт;
// ---.КЛАСС.ПолеТекстаПрограммы

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

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

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

Функция ПолучитьТекущуюКомпонентуКонтекстнойПодсказки(Кнопка = Неопределено)

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

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

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

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

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

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

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

Функция ОбновитьРежимПакетногоЗапроса()

	ЭтаФорма.ЛиПакетныйЗапрос = Ложь
		Или ЗапросыПакета.Количество() > 1 
		Или ЗапросыПакета.Количество() > 0 И ЗапросыПакета[0].ТипЗапроса = 1;
	ИзменитьСвернутостьПанельПакета(ЛиПакетныйЗапрос);
	Возврат Неопределено;

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

Процедура ОбновитьРежимОбъединения()
	
	ИзменитьСвернутостьПанельЧастей(РежимОбъединения);

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

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

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

Функция СобратьСлужебныйТекстПакетаПостроителя(пЗапросыПакета = Неопределено)

	Если пЗапросыПакета = Неопределено Тогда
		пЗапросыПакета = ЗапросыПакета;
	КонецЕсли; 
	ТекстПакета = "";
	Для ИндексЗапроса = 0 По пЗапросыПакета.Количество() - 1 Цикл
		ЗапросПакета = пЗапросыПакета[ИндексЗапроса];
		ТекстЗапросаПакета = "";
		Для ИндексЧасти = 0 По ЗапросПакета.ЧастиОбъединения.Количество() - 1 Цикл
			ЧастьОбъединения = ЗапросПакета.ЧастиОбъединения[ИндексЧасти];
			ТекстЧастиОбъединения = ЧастьОбъединения.ТекстРасширения;
			Для Каждого СтрокаВложенногоЗапроса Из ЧастьОбъединения.ВыбранныеТаблицы.НайтиСтроки(Новый Структура("ПолноеИмя", "")) Цикл
				ТекстВложенногоЗапроса = СобратьСлужебныйТекстПакетаПостроителя(СтрокаВложенногоЗапроса.ВложенныйПакет);
				Если ЗначениеЗаполнено(ТекстВложенногоЗапроса) Тогда
					ТекстЧастиОбъединения = ТекстЧастиОбъединения + "
					|#EmbeddedQuery " + XMLСтрока(ЧастьОбъединения.ВыбранныеТаблицы.Индекс(СтрокаВложенногоЗапроса)) + "
					|(" + ТекстВложенногоЗапроса + ")";
				КонецЕсли; 
			КонецЦикла;
			Если ЗначениеЗаполнено(ТекстЧастиОбъединения) Тогда
				ТекстЗапросаПакета = ТекстЗапросаПакета + "
				|#UnionPart " + XMLСтрока(ИндексЧасти) + "
				|" + ТекстЧастиОбъединения;
			КонецЕсли; 
		КонецЦикла;
		ТекстЗапросаПакета = ТекстЗапросаПакета + "
			|" + ЗапросПакета.ТекстРасширения;
		Если ЗначениеЗаполнено(ТекстЗапросаПакета) Тогда
			Если пЗапросыПакета = ЗапросыПакета Тогда // Пакет
				Если ТекстПакета <> "" Тогда
					ТекстПакета = ТекстПакета + ";";
				КонецЕсли; 
				ТекстПакета = ТекстПакета + "#Root " + XMLСтрока(ИндексЗапроса) + ТекстЗапросаПакета;
			Иначе
				ТекстПакета = ТекстПакета + ТекстЗапросаПакета;
			КонецЕсли; 
		КонецЕсли;
	КонецЦикла;
	Возврат ТекстПакета;

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

Функция НайтиДобавитьВыбраннуюТаблицуВСвязи(СтрокаВыбраннойТаблицы, ЧастьОбъединения = Неопределено)

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

КонецФункции
 
Процедура ОбработатьЗапросПослеУстановкиДанных(ЗапросПакета)
	
	ОбновитьНаименованиеЗапроса(ЗапросПакета);
	Если Истина
		И ЗапросПакета.ТипЗапроса <> 2 // DROP 
		//И ЗапросПакета.ТипЗапроса <> 3 // INSERT // https://www.hostedredmine.com/issues/917697
		И ЗапросПакета.ТипЗапроса <> 6 // TRUNCATE
	Тогда
		ПерваяЧасть = ЗапросПакета.ЧастиОбъединения[0];
		НеуникальныеКлючи = ирОбщий.НеуникальныеКлючиТаблицыЛкс(ПерваяЧасть.ВыбранныеПоля, "НИмя", Новый Структура("НИмя", ""));
		Если НеуникальныеКлючи.Количество() > 0 Тогда
			СтрокаДубля = ПерваяЧасть.ВыбранныеПоля.НайтиСтроки(НеуникальныеКлючи[0])[1];
			ВызватьИсключение "Повторяющийся псевдоним выбранного поля """ + СтрокаДубля.Определение + " КАК " + СтрокаДубля.Имя + """";
		КонецЕсли; 
		Для Каждого ЧастьОбъединения Из ЗапросПакета.ЧастиОбъединения Цикл
			ОбновитьНаименованиеЧасти(ЧастьОбъединения);
			Для Каждого СтрокаВыбраннойТаблицы Из ЧастьОбъединения.ВыбранныеТаблицы Цикл
				Если СтрокаВыбраннойТаблицы.ВложенныйПакет = Неопределено Тогда
					Если ИсточникДанных1С = "" Тогда 
						Фрагменты = ирОбщий.СтрРазделитьЛкс(СтрокаВыбраннойТаблицы.ПолноеИмя);
						Если Истина
							И Фрагменты.Количество() = 4
							И ирОбщий.ЛиКорневойТипВнешнегоИсточникаДанныхЛкс(Фрагменты[0]) 
						Тогда 
							ИсточникДанных1С = Фрагменты[1];
							ЗаполнитьДоступныеТаблицы1С();
						КонецЕсли; 
					КонецЕсли; 
					НайтиДобавитьДоступнуюВременнуюТаблицу(СтрокаВыбраннойТаблицы.ПолноеИмя,,, ИсточникДанных1С);
				КонецЕсли; 
				НайтиДобавитьВыбраннуюТаблицуВСвязи(СтрокаВыбраннойТаблицы, ЧастьОбъединения);
				//ПолучитьИмяВыбраннойТаблицы(СтрокаВыбраннойТаблицы);
			КонецЦикла;
			ГруппировкиСПустымКомментарием = ЧастьОбъединения.Группировки.НайтиСтроки(Новый Структура("Комментарий", ""));
			ЕстьАгрегатыВЧастиОбъединения = ЕстьАгрегатыВЧастиОбъединения(ЧастьОбъединения);
			ЕстьГруппировка = Ложь
				Или ЕстьАгрегатыВЧастиОбъединения
				Или ЧастьОбъединения.Группировки.Количество() > 0;
			ЧастьОбъединения.Автогруппировки = Истина
				И ЕстьАгрегатыВЧастиОбъединения
				И ГруппировкиСПустымКомментарием.Количество() = ЧастьОбъединения.Группировки.Количество();
			КоличествоОдинаковыхПолейИГруппировок = 0;
			ИндексВыбранногоПоля = 0;
			ОбновитьКомпоновщик = Ложь;
			ВыбранныеЗвездочкамиТаблицы = Новый ТаблицаЗначений();
			ВыбранныеЗвездочкамиТаблицы.Колонки.Добавить("ВыбраннаяТаблица");
			ВыбранныеЗвездочкамиТаблицы.Колонки.Добавить("Позиция");
			СчетчикБезымянныхПолей = Неопределено;
			Пока ИндексВыбранногоПоля < ЧастьОбъединения.ВыбранныеПоля.Количество() Цикл
				ВыбранноеПоле = ЧастьОбъединения.ВыбранныеПоля[ИндексВыбранногоПоля];
				ИмяПоля = ирОбщий.ПоследнийФрагментЛкс(ВыбранноеПоле.Определение);
				Если ИмяПоля = "*" Тогда
					ИмяТаблицы = Лев(ВыбранноеПоле.Определение, СтрДлина(ВыбранноеПоле.Определение) - 2);
					ЧастьОбъединения.ВыбранныеПоля.Удалить(ИндексВыбранногоПоля);
					Если ИмяТаблицы = "" Тогда
						//ИмяТаблицы = ЧастьОбъединения.ВыбранныеТаблицы[0].Имя;
						Для Каждого ВыбраннаяТаблица Из ЧастьОбъединения.ВыбранныеТаблицы Цикл
							СтрокаВыбраннойЗвездочкойТаблицы = ВыбранныеЗвездочкамиТаблицы.Добавить();
							СтрокаВыбраннойЗвездочкойТаблицы.ВыбраннаяТаблица = ВыбраннаяТаблица;
							СтрокаВыбраннойЗвездочкойТаблицы.Позиция = ИндексВыбранногоПоля;
						КонецЦикла;
					Иначе
						СтрокаВыбраннойТаблицы = ЧастьОбъединения.ВыбранныеТаблицы.Найти(НРег(ИмяТаблицы), "НИмя");
						Если СтрокаВыбраннойТаблицы = Неопределено Тогда
							СтрокаВыбраннойТаблицы = ДобавитьВыбраннуюТаблицу(ЧастьОбъединения);
							СтрокаВыбраннойТаблицы.Имя = ирОбщий.АвтоУникальноеИмяВКоллекцииЛкс(ЧастьОбъединения.ВыбранныеТаблицы,  ИмяТаблицы);
							СтрокаВыбраннойТаблицы.ПолноеИмя = ИмяТаблицы;
							СтрокаВыбраннойТаблицы.Обязательная = Истина;
							ирОбщий.ОбновитьКопиюСвойстваВНижнемРегистреЛкс(СтрокаВыбраннойТаблицы);
							НайтиДобавитьВыбраннуюТаблицуВСвязи(СтрокаВыбраннойТаблицы, ЧастьОбъединения);
							ОбновитьКомпоновщик = Истина;
						КонецЕсли; 
						СтрокаВыбраннойЗвездочкойТаблицы = ВыбранныеЗвездочкамиТаблицы.Добавить();
						СтрокаВыбраннойЗвездочкойТаблицы.ВыбраннаяТаблица = СтрокаВыбраннойТаблицы;
						СтрокаВыбраннойЗвездочкойТаблицы.Позиция = ИндексВыбранногоПоля;
					КонецЕсли; 
					ИндексВыбранногоПоля = ИндексВыбранногоПоля - 1;
				Иначе
					Если ПерваяЧасть = ЧастьОбъединения Тогда
						Если ЗапросПакета.ТипЗапроса = 3 Тогда // INSERT
							ВыбранноеПоле.Имя = ЗапросПакета.ПринимающиеПоля[ИндексВыбранногоПоля].Поля;
						КонецЕсли; 
						Если Не ЗначениеЗаполнено(ВыбранноеПоле.Имя) Тогда
							ВыбранноеПоле.Имя = ПолучитьАвтоПсевдонимПоля(ВыбранноеПоле, ЧастьОбъединения, СчетчикБезымянныхПолей);
						КонецЕсли;
					КонецЕсли;
					Если Истина
						И ЕстьГруппировка
						И ЧастьОбъединения.Автогруппировки 
					Тогда
						Группировка = Неопределено;
						Если ВыбранноеПоле.ЕстьАгрегаты = "ЕстьПоля" Тогда
							Группировка = ЧастьОбъединения.Группировки.Найти(НРег(ВыбранноеПоле.Определение), "НОпределение");
						КонецЕсли; 
						Если Истина
							И ВыбранноеПоле.ЕстьАгрегаты <> Истина
							И Группировка = Неопределено
						Тогда
							ЧастьОбъединения.Автогруппировки = Ложь;
						ИначеЕсли ВыбранноеПоле.ЕстьАгрегаты = "ЕстьПоля" Тогда 
							КоличествоОдинаковыхПолейИГруппировок = КоличествоОдинаковыхПолейИГруппировок + 1;
						КонецЕсли; 
					КонецЕсли; 
					ирОбщий.ОбновитьКопиюСвойстваВНижнемРегистреЛкс(ВыбранноеПоле); // Нужно для разрешения конфликтов динамических псмевдонимов
				КонецЕсли; 
				ИндексВыбранногоПоля = ИндексВыбранногоПоля + 1;
			КонецЦикла;
			Если Истина
				И ЧастьОбъединения.Автогруппировки
				И ЕстьГруппировка
				И (Ложь
					Или КоличествоОдинаковыхПолейИГруппировок < ЧастьОбъединения.ВыбранныеПоля.НайтиСтроки(Новый Структура("ЕстьАгрегаты", "ЕстьПоля")).Количество()
					Или КоличествоОдинаковыхПолейИГруппировок <> ЧастьОбъединения.Группировки.Количество())
			Тогда
				ЧастьОбъединения.Автогруппировки = Ложь;
			КонецЕсли;
			//Если ОбновитьКомпоновщик Или ВыбранныеЗвездочкамиТаблицы.Количество() > 0 Тогда
				ОбновитьКомпоновщикЧастиОбъединения(ЧастьОбъединения, Ложь);
			//КонецЕсли;
			// Можно отключить для неинтерактивного режима - даст 10% экономии времени
			Для Каждого ВыбранноеПоле Из ЧастьОбъединения.ВыбранныеПоля Цикл
				ВыбранноеПоле.ТипЗначения = ТипЗначенияВыражения(ВыбранноеПоле.Токен, ЧастьОбъединения);
			КонецЦикла;
			Для ИндексТаблицыИзЗвездочки = 1 По ВыбранныеЗвездочкамиТаблицы.Количество() Цикл
				СтрокаВыбраннойЗвездочкойТаблицы = ВыбранныеЗвездочкамиТаблицы[ВыбранныеЗвездочкамиТаблицы.Количество() - ИндексТаблицыИзЗвездочки];
				ВыбраннаяТаблица = СтрокаВыбраннойЗвездочкойТаблицы.ВыбраннаяТаблица; 
				ВыбраннаяТаблица.ВсеПоля = Истина;
				КоличествоВыбранныхПолей = ЧастьОбъединения.ВыбранныеПоля.Количество();
				СдвигИндексаПослеДобавления = 0;
				Если КоличествоВыбранныхПолей > 0 Тогда
					СдвигИндексаПослеДобавления = -(КоличествоВыбранныхПолей - СтрокаВыбраннойЗвездочкойТаблицы.Позиция);
				КонецЕсли; 
				ДобавитьВсеПоляТаблицыКомпоновщикаВВыбранныеПоля(ВыбраннаяТаблица.Имя, ЗапросПакета, ЧастьОбъединения, СдвигИндексаПослеДобавления);
			КонецЦикла;
			Если ПерваяЧасть <> ЧастьОбъединения Тогда
				Для ИндексВыбранногоПоля = 0 По ЧастьОбъединения.ВыбранныеПоля.Количество() - 1 Цикл
					ВыбранноеПоле = ЧастьОбъединения.ВыбранныеПоля[ИндексВыбранногоПоля];
					Если ПерваяЧасть.ВыбранныеПоля.Количество() = ИндексВыбранногоПоля Тогда
						Если Не ЗначениеЗаполнено(ВыбранноеПоле.Имя) Тогда
							ВыбранноеПоле.Имя = ПолучитьАвтоПсевдонимПоля(ВыбранноеПоле, ЧастьОбъединения, СчетчикБезымянныхПолей);
						КонецЕсли; 
						ВыбранноеПолеПервойЧасти = ПерваяЧасть.ВыбранныеПоля.Добавить();
						ВыбранноеПолеПервойЧасти.ИД = Новый УникальныйИдентификатор;
						ВыбранноеПолеПервойЧасти.Определение = "NULL";
						ВыбранноеПолеПервойЧасти.Имя = ВыбранноеПоле.Имя;
						ирОбщий.ОбновитьКопиюСвойстваВНижнемРегистреЛкс(ВыбранноеПолеПервойЧасти);
					Иначе
						НовоеИмя = ПерваяЧасть.ВыбранныеПоля[ИндексВыбранногоПоля].Имя;
						Если ЗначениеЗаполнено(ВыбранноеПоле.Имя) И Не ирОбщий.СтрокиРавныЛкс(ВыбранноеПоле.Имя, НовоеИмя) Тогда
							ВыбранноеПоле.Комментарий = "Старое имя - " + ВыбранноеПоле.Имя;
							ирОбщий.СообщитьЛкс(ирОбщий.СтрШаблонЛкс("В запросе[%1] переименовано поле части[%3] объединения %4->%2. Старое имя в комментарии.", ЗапросПакета.Имя, ВыбранноеПоле.Имя, 
								ирОбщий.ПервыйФрагментЛкс(ЧастьОбъединения.Имя, ","), НовоеИмя), СтатусСообщения.Внимание);
						КонецЕсли;
						ВыбранноеПоле.Имя = НовоеИмя;
						ирОбщий.ОбновитьКопиюСвойстваВНижнемРегистреЛкс(ВыбранноеПоле);
					КонецЕсли; 
				КонецЦикла;
			КонецЕсли; 
		КонецЦикла;
		ОбновитьПоляОбъединенияЗапроса(ЗапросПакета);
		ОбновитьНаименованиеЗапроса(ЗапросПакета);
	КонецЕсли; 
	
КонецПроцедуры

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

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

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

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

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

// В СлужебноеПолеТекстовгоДокумента должен находиться текст, из которого сформированы токены.
//
// Параметры:
//  Токен				 - Token {GoldParserForNet.Parser} - 
//  Стек				 - 	 - 
//  ЗапросПакета		 - см. ЗапросыПакета[0] - 
//  ЧастьОбъединения	 - см. ЧастиОбъединения[0] - 
//  Индикатор			 - Неопределено	 - автоиндикатор, можно передать Null для блокировки автосоздания индикатора
//  РазборРасширений	 - 				 - 
//  ТаблицаКомментариев	 - 				 - 
//  ТекущаяСвязьТаблиц	 - 				 - 
//  УровеньВложенности	 - 				 - 
// 
// Возвращаемое значение:
//  Строка, см. СвязиТаблиц.Строки[0] - 
//
Функция ЗаполнитьПоТокену(Знач Токен, Стек = Неопределено, Знач ЗапросПакета = Неопределено, Знач ЧастьОбъединения = Неопределено, Индикатор = Неопределено,
	РазборРасширений = Ложь, ТаблицаКомментариев = Неопределено, Знач ТекущаяСвязьТаблиц = Неопределено, Знач УровеньВложенности = 0) Экспорт
	
	Данные = Токен.Data; // Reduction {GoldParserForNet.Parser}  
	Если Ложь
		Или Данные = Неопределено 
		//Или Данные.TokenCount = 0 // так делать нельзя, т.к. пустые позиции будут пропускаться, например параметры вирт. таблиц
	Тогда
		Возврат Неопределено;
	КонецЕсли;
	УровеньВложенности = УровеньВложенности + 1;
	Если УровеньВложенности > 1000 Тогда
		ВызватьИсключение "Слишком много частей в объединении или запросов в пакете";
	КонецЕсли; 
	Если Стек = Неопределено Тогда
		Стек = Новый Массив();
	КонецЕсли;
	Если Индикатор = Неопределено Тогда
		ИндикаторБылСоздан = Истина;
		Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(, "Структура запроса");
	КонецЕсли;
	Если Индикатор <> Null Тогда
		ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
	КонецЕсли; 
	Результат = Неопределено;
	ИмяПравила = Данные.RuleText();
	Стек.Вставить(0, ИмяПравила);
	КоличествоДочерних = Данные.TokenCount;
	Если ИмяПравила = "<EmbeddedQuery>" Тогда
		ВложенныйПакет = ЗапросыПакета.СкопироватьКолонки();
		ВложенныйЗапрос = ДобавитьЗапросПакета(ВложенныйПакет);
		ДобавленЗапрос = Истина;
		ТекущийУзел = ЧастьОбъединения.ВыбранныеТаблицы[ЧастьОбъединения.ВыбранныеТаблицы.Количество() - 1];              
		//Если ТекущийУзел.Параметры <> Неопределено Тогда
		//	ВызватьИсключение "Неверный тип выбранной таблицы для вложенного запроса";
		//КонецЕсли; 
		ТекущийУзел.ВложенныйПакет = ВложенныйПакет;
		ЗаполнитьПоТокену(Токен.Data.Tokens(1),, ВложенныйЗапрос,, Индикатор, РазборРасширений, ТаблицаКомментариев);
	ИначеЕсли ИмяПравила = "<ExtEmbeddedQuery>" Тогда
		ИндексВложенногоЗапроса = Данные.Tokens(1).Data;
		ИндексВложенногоЗапроса = Число(ИндексВложенногоЗапроса);
		ВложенныйПакет = ЧастьОбъединения.ВыбранныеТаблицы[ИндексВложенногоЗапроса].ВложенныйПакет;
		ЗаполнитьПоТокену(Данные.Tokens(3), , ВложенныйПакет[0],, Индикатор, РазборРасширений, ТаблицаКомментариев);
	ИначеЕсли ИмяПравила = "<Join>" Тогда
		Если ТекущаяСвязьТаблиц = Неопределено Тогда
			ТекущаяСвязьТаблиц = ЧастьОбъединения.СвязиТаблиц;
		КонецЕсли; 
		//<TableOrJoin>.<TableWithName>
		ЛевыйУзел = ЗаполнитьПоТокену(Данные.Tokens(0).Data.Tokens(0), Стек, ЗапросПакета, ЧастьОбъединения, Индикатор, РазборРасширений, ТаблицаКомментариев, ТекущаяСвязьТаблиц);
		Если ЛевыйУзел = "FixedTables" Тогда // 02.12.2015
			ТекущаяСвязьТаблиц = ТекущаяСвязьТаблиц.Строки[0];
		ИначеЕсли ТипЗнч(ЛевыйУзел) = Тип("Строка") Тогда
			ТекущаяСвязьТаблиц = ТекущаяСвязьТаблиц.Строки.Добавить(); 
			ТекущаяСвязьТаблиц.Таблица = ЛевыйУзел;
		Иначе
			ТекущаяСвязьТаблиц = ЛевыйУзел; // см. СвязиТаблиц.Строки[0]
		КонецЕсли;   
		//<TableOrJoin>.<TableWithName>
		ПравыйУзел = ЗаполнитьПоТокену(Данные.Tokens(3).Data.Tokens(0), Стек, ЗапросПакета, ЧастьОбъединения, Индикатор, РазборРасширений, ТаблицаКомментариев, ТекущаяСвязьТаблиц);
		Если ТипЗнч(ПравыйУзел) = Тип("Строка") Тогда
			ТекущаяСвязьТаблиц = ТекущаяСвязьТаблиц.Строки.Добавить(); 
			ТекущаяСвязьТаблиц.Таблица = ПравыйУзел;    
		Иначе
			ТекущаяСвязьТаблиц = ПравыйУзел; // см. СвязиТаблиц.Строки[0]
		КонецЕсли; 
		ТипCOMОбъекта = Данные.Tokens(1).Data; //"<JoinType>"
		Если ТипCOMОбъекта.TokenCount > 0 Тогда
			ТипCOMОбъекта = ТипCOMОбъекта.Tokens(0).Name;
		Иначе
			ТипCOMОбъекта = Неопределено;
		КонецЕсли; 
		Если Ложь
			Или ТипCOMОбъекта = "LEFT"
			Или ТипCOMОбъекта = "LEFT OUTER"
		Тогда
			ТекущаяСвязьТаблиц.ТипСвязи = "LEFT";    
		ИначеЕсли Ложь
			Или ТипCOMОбъекта = "RIGHT"
			Или ТипCOMОбъекта = "RIGHT OUTER"
		Тогда
			ТекущаяСвязьТаблиц.ТипСвязи = "RIGHT";
		ИначеЕсли Ложь
			//Или ТипCOMОбъекта = "OUTER"
			Или ТипCOMОбъекта = "FULL"
		Тогда
			ТекущаяСвязьТаблиц.ТипСвязи = "FULL";
		ИначеЕсли Ложь
			Или ТипCOMОбъекта = "INNER"
			Или ПустаяСтрока(ТипCOMОбъекта)
		Тогда
			ТекущаяСвязьТаблиц.ТипСвязи = "INNER";
		Иначе
			ВызватьИсключение "Неизвестный тип связи таблиц """ + ТипCOMОбъекта + """";
		КонецЕсли;
		ТокенУсловия = Данные.Tokens(5);
		НастройкиКомпоновки = Новый НастройкиКомпоновкиДанных;
		ПостроитьДеревоЛогическогоВыражения(НастройкиКомпоновки.Отбор, ТокенУсловия, ЗапросПакета, ЧастьОбъединения); 
		ТекущаяСвязьТаблиц.Условие = НастройкиКомпоновки;
		СобратьКомментарийТокена(ТокенУсловия, ТаблицаКомментариев, ТекущаяСвязьТаблиц.Комментарий);
		//ирОбщий.ОбновитьКопиюСвойстваВНижнемРегистреЛкс(ТекущаяСвязьТаблиц, "Таблица");
		Результат = ТекущаяСвязьТаблиц.Родитель;
	ИначеЕсли ИмяПравила = "<ParameterOfTable>" Тогда
		ВыбраннаяТаблица = ЧастьОбъединения.ВыбранныеТаблицы[ЧастьОбъединения.ВыбранныеТаблицы.Количество() - 1];    
		ТекущийУзел = ВыбраннаяТаблица.Параметры.Добавить();              
		ТекущийУзел.Номер = ВыбраннаяТаблица.Параметры.Количество();                         
		ТекущийУзел.Определение = СобратьВыражениеЗапроса(Токен,, ЗапросПакета, ЧастьОбъединения);  
		ТекущийУзел.Токен = Токен;
	ИначеЕсли ИмяПравила = "<Allowed>" Тогда
		ЗапросПакета.ОпцияРазрешенные = Истина;   
	ИначеЕсли ИмяПравила = "<AutoOrder>" Тогда
		Если ПолучитьТекстИзТокена(Токен) <> "" Тогда
			ЗапросПакета.ОпцияАвтоупорядочивание = Истина; 
		КонецЕсли; 
	ИначеЕсли ИмяПравила = "<Distinct>" Тогда
		ЧастьОбъединения.ОпцияРазличные = Истина;
	ИначеЕсли ИмяПравила = "<ForUpdate>" Тогда
		Если Данные.TokenCount > 0 Тогда
			ЧастьОбъединения.ОпцияДляИзменения = Истина;
			ПоследнийТокен = Данные.Tokens(Данные.TokenCount - 1);
			Если ПоследнийТокен.Kind = 0 Тогда
				ЗаполнитьПоТокену(ПоследнийТокен, Стек, ЗапросПакета, ЧастьОбъединения, Индикатор, РазборРасширений, ТаблицаКомментариев);
			КонецЕсли; 
		КонецЕсли; 
	ИначеЕсли ИмяПравила = "<Top>" Тогда
		ЧастьОбъединения.ОпцияПервые = Истина;
		Если Данные.TokenCount > 1 Тогда
			Если Данные.Tokens(1).Type = 1 Тогда
				ЧастьОбъединения.ПервыеКоличество = Данные.Tokens(1).Data;
			Иначе
				ТокенКоличества = Данные.Tokens(1).Data.Tokens(0);
				Если ТокенКоличества.text = "<Parameter>" Тогда
					ЧастьОбъединения.ПервыеКоличество = СобратьВыражениеЗапроса(ТокенКоличества,, ЗапросПакета, ЧастьОбъединения);  
				Иначе
					ЧастьОбъединения.ПервыеКоличество = Число(ТокенКоличества.Data);
				КонецЕсли; 
			КонецЕсли; 
		КонецЕсли; 
	ИначеЕсли ИмяПравила = "<Limit>" Тогда
		Если Данные.TokenCount > 0 Тогда
			ЗапросПакета.ОпцияПервые = Истина;
			Если Данные.Tokens(1).Type = 1 Тогда
				ЗапросПакета.ПервыеКоличество = Данные.Tokens(1).Data; 
			Иначе
				ТокенКоличества = Данные.Tokens(1).Data.Tokens(0);
				Если ТокенКоличества.text = "<Parameter>" Тогда
					ЗапросПакета.ПервыеКоличество = СобратьВыражениеЗапроса(ТокенКоличества,, ЗапросПакета, ЧастьОбъединения);
				Иначе
					ЗапросПакета.ПервыеКоличество = Число(ТокенКоличества.Data);
				КонецЕсли; 
			КонецЕсли; 
		КонецЕсли; 
	ИначеЕсли ИмяПравила = "<Fetch>" Тогда
		ЗапросПакета.ОпцияПервые = Истина;
		ТокенКоличества = Данные.Tokens(2).Data.Tokens(0);
		Если ТокенКоличества.text = "<Parameter>" Тогда
			ЗапросПакета.ПервыеКоличество = СобратьВыражениеЗапроса(ТокенКоличества,, ЗапросПакета, ЧастьОбъединения);
		Иначе
			ЗапросПакета.ПервыеКоличество = Число(ТокенКоличества.Data);
		КонецЕсли; 
	ИначеЕсли ИмяПравила = "<Offset>" Тогда
		Если Данные.TokenCount > 0 Тогда
			Сообщить("Оператор OFFSET проигнорирован, т.к. не поддерживается конструктором");
		КонецЕсли; 
	//ИначеЕсли ИмяПравила = "<MultiField>" Тогда
	//	ТекущийУзел = ЧастьОбъединения.ВыбранныеПоля[ЧастьОбъединения.ВыбранныеПоля.Количество() - 1];
	//	ТекущийУзел.Определение = ПолучитьТекстИзТокена(Токен);
	ИначеЕсли ИмяПравила = "<Where>" Тогда
		Если Данные.TokenCount > 0 Тогда
			ПостроитьДеревоЛогическогоВыражения(ЧастьОбъединения.Компоновщик.Настройки.Отбор, Данные.Tokens(1), ЗапросПакета, ЧастьОбъединения);
			СобратьКомментарийТокена(Токен, ТаблицаКомментариев, ЧастьОбъединения.КомментарийОтбора);
		КонецЕсли; 
	ИначеЕсли ИмяПравила = "<Having>" Тогда
		Если Данные.TokenCount > 0 Тогда
			ПостроитьДеревоЛогическогоВыражения(ЧастьОбъединения.Компоновщик.Настройки.Отбор, Данные.Tokens(1), ЗапросПакета, ЧастьОбъединения);
			СобратьКомментарийТокена(Токен, ТаблицаКомментариев, ЧастьОбъединения.КомментарийОтбора);
		КонецЕсли; 
	ИначеЕсли ИмяПравила = "<SelectExpr>" Тогда
		ТекущийУзел = ЧастьОбъединения.ВыбранныеПоля.Добавить(); 
		ТекущийУзел.Токен = Данные.Tokens(0);
		ТекущийУзел.ИД = Новый УникальныйИдентификатор(); 
		ЕстьАгрегаты = Ложь;
		ТекущийУзел.Определение = СобратьВыражениеЗапроса(ТекущийУзел.Токен,, ЗапросПакета, ЧастьОбъединения,,, ЕстьАгрегаты);
		ТекущийУзел.ЕстьАгрегаты = ЕстьАгрегаты;
		//ТекущийУзел.ТипЗначения = ПолучитьТипЗначенияВыражения(ТекущийУзел.Токен, ЧастьОбъединения); // Перенесено в ОбработатьЗапросПослеУстановкиДанных
		Если КоличествоДочерних = 2 Тогда
			ЗаполнитьПсевдонимПоляИзТокена(ТекущийУзел, Данные.Tokens(1));
		КонецЕсли; 
		СобратьКомментарийТокена(Токен, ТаблицаКомментариев, ТекущийУзел.Комментарий);
	ИначеЕсли ИмяПравила = "<GroupExpr>" Тогда
		ТекущийУзел = ЧастьОбъединения.Группировки.Добавить();
		ТекущийУзел.Токен = Данные.Tokens(0);
		ТекущийУзел.Определение = СобратьВыражениеЗапроса(ТекущийУзел.Токен,, ЗапросПакета, ЧастьОбъединения); 
		ирОбщий.ОбновитьКопиюСвойстваВНижнемРегистреЛкс(ТекущийУзел, "Определение");
		СобратьКомментарийТокена(Токен, ТаблицаКомментариев, ТекущийУзел.Комментарий);
	ИначеЕсли ИмяПравила = "<SetExpr>" Тогда
		ТекущийУзел = ЗапросПакета.ПринимающиеПоля.Добавить();   
		ТекущийУзел.Токен = Данные.Tokens(1).Data.Tokens(1);
		ТекущийУзел.Поля = ПолучитьТекстИзТокена(Данные.Tokens(0)); 
		ТекущийУзел.Определение = СобратьВыражениеЗапроса(ТекущийУзел.Токен,, ЗапросПакета, ЧастьОбъединения);
		//ТекущийУзел.Комментарий = ПолучитьКомментарийИзТокенов(Данные.Tokens(0), Данные.Tokens(Данные.TokenCount - 1));
	ИначеЕсли ИмяПравила = "<InsertField>" Тогда
		ТекущийУзел = ЗапросПакета.ПринимающиеПоля.Добавить(); 
		ТекущийУзел.Поля = ПолучитьТекстИзТокена(Данные.Tokens(0));
	ИначеЕсли ИмяПравила = "<InsertExpr>" Тогда
		ТекущийУзел = ЗапросПакета.ПринимающиеПоля[мРазборИндексПринимающегоПоля];
		ТекущийУзел.Токен = Данные.Tokens(0);
		ТекущийУзел.Определение = СобратьВыражениеЗапроса(ТекущийУзел.Токен,, ЗапросПакета, ЧастьОбъединения);         
		мРазборИндексПринимающегоПоля = мРазборИндексПринимающегоПоля + 1;
	ИначеЕсли ИмяПравила = "<TotalsExpr>" Тогда
		ТекущийУзел = ЗапросПакета.ГруппирующиеПоляИтогов.Добавить();
		ДанныеHierExpr = Данные.Tokens(0).Data;
		ТекущийУзел.Токен = ДанныеHierExpr.Tokens(0);
		ТекущийУзел.Определение = СобратьВыражениеЗапроса(ТекущийУзел.Токен,, ЗапросПакета);
		ТокенТипаИтога = ДанныеHierExpr.Tokens(1);
		ДанныеHierMode = ТокенТипаИтога.Data;
		Если ДанныеHierMode.TokenCount = 0 Тогда
			ТипИтогов = "";
		Иначе
			ПервыйТокен = ДанныеHierMode.Tokens(0);
			Если Истина
				И ПервыйТокен.Kind = 0 
			Тогда 
				ТипИтогов = "Иерархия";
			ИначеЕсли Истина
				И ПервыйТокен.Kind = 1 
				И ПервыйТокен.Name = "ONLY"
			Тогда 
				ТипИтогов = "ТолькоИерархия";
			ИначеЕсли Истина
				И ПервыйТокен.Kind = 1 
			Тогда 
				ТипИтогов = СобратьВыражениеЗапроса(ТокенТипаИтога,, ЗапросПакета); 
			КонецЕсли; 
		КонецЕсли; 
		ТекущийУзел.ТипИтогов = ТипИтогов;
		ЗаполнитьПсевдонимПоляИзТокена(ТекущийУзел, Данные.Tokens(1));
	ИначеЕсли ИмяПравила = "<OrderExpr>" Тогда
		ТекущийУзел = ЗапросПакета.ПоляПорядка.Добавить();
		ТекущийУзел.Токен = Данные.Tokens(0);
		ТекущийУзел.Определение = СобратьВыражениеЗапроса(ТекущийУзел.Токен,, ЗапросПакета, ЧастьОбъединения);
		СобратьКомментарийТокена(Токен, ТаблицаКомментариев, ТекущийУзел.Комментарий);
		ТокенНаправления = Данные.Tokens(Данные.TokenCount - 1).Data.Tokens(0);
		Если Истина
			И ТокенНаправления <> Неопределено
			И ТокенНаправления.Kind = 1 
			И ТокенНаправления.Name = "DESC" 
		Тогда
			ТекущийУзел.Направление = НаправлениеСортировки.Убыв;
		Иначе
			ТекущийУзел.Направление = НаправлениеСортировки.Возр;
		КонецЕсли; 
		ТокенИерархии = Данные.Tokens(1);
		Если ТокенИерархии.Data.TokenCount > 0 Тогда
			ТекущийУзел.Иерархия = Истина;
		Иначе
			ТекущийУзел.Иерархия = Ложь;
		КонецЕсли; 
	ИначеЕсли ИмяПравила = "<AgregatExpr>" Тогда
		ТекущийУзел = ЗапросПакета.ГруппируемыеПоляИтогов.Добавить();
		ТекущийУзел.Токен = Данные.Tokens(0);
		ТекущийУзел.Определение = СобратьВыражениеЗапроса(ТекущийУзел.Токен,, ЗапросПакета, ЧастьОбъединения);
		СобратьКомментарийТокена(Токен, ТаблицаКомментариев, ТекущийУзел.Комментарий);
		ЗаполнитьПсевдонимПоляИзТокена(ТекущийУзел, Данные.Tokens(1));
	ИначеЕсли ИмяПравила = "<IndexExpr>" Тогда
		ТекущийУзел = ЗапросПакета.ПоляИндекса.Добавить();
		ТекущийУзел.Имя = СобратьВыражениеЗапроса(Данные.Tokens(0),, ЗапросПакета, ЧастьОбъединения);
		СобратьКомментарийТокена(Токен, ТаблицаКомментариев, ТекущийУзел.Комментарий);
		//ТекущийУзел.Токен = Токен;
	ИначеЕсли ИмяПравила = "<ExtSelectExpr>" Тогда
		ДанныеПоля = Данные.Tokens(0).Data;
		ТекущийУзел = ЧастьОбъединения.ПоляВыбораПостроителя.Добавить();
		ТекущийУзел.Токен = ДанныеПоля.Tokens(0); 
		ТекущийУзел.ИспользоватьДочерние = ТекущийУзел.Токен.Data.Tokens(1).Data.TokenCount > 0;  
		Если ТекущийУзел.ИспользоватьДочерние Тогда
			ТекущийУзел.Токен = ТекущийУзел.Токен.Data.Tokens(0);
		КонецЕсли;  
		ТекущийУзел.Определение = СобратьВыражениеЗапроса(ТекущийУзел.Токен,, ЗапросПакета, ЧастьОбъединения);
		СобратьКомментарийТокена(Токен, ТаблицаКомментариев, ТекущийУзел.Комментарий);
		ЗаполнитьПсевдонимПоляИзТокена(ТекущийУзел, ДанныеПоля.Tokens(1));
	ИначеЕсли ИмяПравила = "<ExtWhereExpr>" Тогда
		ДанныеПоля = Данные.Tokens(0).Data;
		ТекущийУзел = ЧастьОбъединения.ПоляОтбораПостроителя.Добавить();
		ТекущийУзел.Токен = ДанныеПоля.Tokens(0);
		ТекущийУзел.ИспользоватьДочерние = ТекущийУзел.Токен.Data.Tokens(1).Data.TokenCount > 0;
		Если ТекущийУзел.ИспользоватьДочерние Тогда
			ТекущийУзел.Токен = ТекущийУзел.Токен.Data.Tokens(0);
		КонецЕсли; 
		ТекущийУзел.Определение = СобратьВыражениеЗапроса(ТекущийУзел.Токен,, ЗапросПакета, ЧастьОбъединения);
		СобратьКомментарийТокена(Токен, ТаблицаКомментариев, ТекущийУзел.Комментарий);
		ЗаполнитьПсевдонимПоляИзТокена(ТекущийУзел, ДанныеПоля.Tokens(1));
	ИначеЕсли ИмяПравила = "<ExtOrderExpr>" Тогда
		ДанныеПоля = Данные.Tokens(0).Data;
		ТекущийУзел = ЗапросПакета.ПоляПорядкаПостроителя.Добавить();
		ТекущийУзел.Токен = ДанныеПоля.Tokens(0);
		ТекущийУзел.ИспользоватьДочерние = ТекущийУзел.Токен.Data.Tokens(1).Data.TokenCount > 0;
		Если ТекущийУзел.ИспользоватьДочерние Тогда
			ТекущийУзел.Токен = ТекущийУзел.Токен.Data.Tokens(0);
		КонецЕсли; 
		ТекущийУзел.Определение = СобратьВыражениеЗапроса(ТекущийУзел.Токен,, ЗапросПакета);
		СобратьКомментарийТокена(Токен, ТаблицаКомментариев, ТекущийУзел.Комментарий);
		ЗаполнитьПсевдонимПоляИзТокена(ТекущийУзел, ДанныеПоля.Tokens(1));
	ИначеЕсли ИмяПравила = "<ExtTotalExpr>" Тогда
		ДанныеПоля = Данные.Tokens(0).Data;
		ТекущийУзел = ЗапросПакета.ПоляИтоговПостроителя.Добавить();
		ТекущийУзел.Токен = ДанныеПоля.Tokens(0);
		ТекущийУзел.ИспользоватьДочерние = ТекущийУзел.Токен.Data.Tokens(1).Data.TokenCount > 0;
		Если ТекущийУзел.ИспользоватьДочерние Тогда
			ТекущийУзел.Токен = ТекущийУзел.Токен.Data.Tokens(0);
		КонецЕсли; 
		ТекущийУзел.Определение = СобратьВыражениеЗапроса(ТекущийУзел.Токен,, ЗапросПакета);
		СобратьКомментарийТокена(Токен, ТаблицаКомментариев, ТекущийУзел.Комментарий);
		ЗаполнитьПсевдонимПоляИзТокена(ТекущийУзел, ДанныеПоля.Tokens(1));
	ИначеЕсли Истина
		И ИмяПравила = "<TableName>" 
		И Стек[1] = "<TableNames>"
	Тогда
		ТекстОпределения = СобратьВыражениеЗапроса(Токен,, ЗапросПакета, ЧастьОбъединения);
		//СтрокаДоступнойТаблицы = ДоступныеТаблицы.Найти(НРег(ТекстОпределения), "НПолноеИмя"); // Так для неизвестных таблиц не будет работать
		ВыбраннаяТаблица = ЧастьОбъединения.ВыбранныеТаблицы.Найти(ТекстОпределения, "ПолноеИмя");
		Если ВыбраннаяТаблица <> Неопределено Тогда
			ВыбраннаяТаблица.ДляИзменения = Истина;
		КонецЕсли; 
	ИначеЕсли Истина
		И ИмяПравила = "<TablePseudoname>" 
		И (Ложь
			Или Стек[1] = "<TableWithName>"
			Или Стек[1] = "<FromUnion>")
	Тогда
		ТокенПсевдонима = Неопределено;
		Если Данные.TokenCount > 0 Тогда
			ТокенПсевдонима = Данные.Tokens(Данные.TokenCount - 1);
		КонецЕсли; 
		Если ТокенПсевдонима = Неопределено Тогда
			ТекстОпределения = "";
		Иначе
			ТекстОпределения = СобратьВыражениеЗапроса(ТокенПсевдонима,, ЗапросПакета, ЧастьОбъединения);
		КонецЕсли; 
		ТекущийУзел = ЧастьОбъединения.ВыбранныеТаблицы[ЧастьОбъединения.ВыбранныеТаблицы.Количество() - 1];
		ТекущийУзел.Имя = ТекстОпределения;
		ТекущийУзел.Имя = ИмяБезКвадратныхСкобок(ТекущийУзел.Имя);
		СкорректироватьИмяВыбраннойТаблицы(ТекущийУзел,, Ложь);
		Если Не ТекущийУзел.Обязательная Тогда
			ОписаниеПоСсылке = ЧастьОбъединения.ВыбранныеТаблицы.Найти(ТекущийУзел.НИмя, "НИмя"); // Могли быть создана по ссылке от полей, если таблица необязательная 
			Если ОписаниеПоСсылке <> ТекущийУзел Тогда
				ЗаполнитьЗначенияСвойств(ТекущийУзел, ОписаниеПоСсылке, "ВсеПоля"); 
				ЧастьОбъединения.ВыбранныеТаблицы.Удалить(ОписаниеПоСсылке);
			КонецЕсли; 
		КонецЕсли; 
		Результат = ТекущийУзел.Имя;
	ИначеЕсли ИмяПравила = "<TableWith>" Тогда
		Если Данные.TokenCount > 0 Тогда
			ТокенУровняИзоляции = Данные.Tokens(2);
			лУровеньИзоляции = ПолучитьТекстИзТокена(ТокенУровняИзоляции);
			Если Стек[1] = "<TableWithName>" Тогда
				ТекущийУзел = ЧастьОбъединения.ВыбранныеТаблицы[ЧастьОбъединения.ВыбранныеТаблицы.Количество() - 1];
				ТекущийУзел.УровеньИзоляции = ПолучитьТекстИзТокена(ТокенУровняИзоляции);  
			Иначе
				ЗапросПакета.УровеньИзоляции = лУровеньИзоляции; 
			КонецЕсли; 
		КонецЕсли; 
	ИначеЕсли Ложь
		Или ИмяПравила = "<CreateQuery>"
		Или ИмяПравила = "<SelectQuery>"
		Или ИмяПравила = "<Query>"
	Тогда
		Если ИмяПравила = "<CreateQuery>" Тогда  // FromTables
			ИндексТокенаВыбранныхТаблиц = 4;
		Иначе
			ИндексТокенаВыбранныхТаблиц = 3;
		КонецЕсли; 
		ЗаполнитьПоТокену(Данные.Tokens(ИндексТокенаВыбранныхТаблиц), Стек, ЗапросПакета, ЧастьОбъединения, Индикатор, РазборРасширений, ТаблицаКомментариев);
		Для ИндексТокена = 1 По КоличествоДочерних - 1 Цикл
			Если ИндексТокена = ИндексТокенаВыбранныхТаблиц Тогда
				Продолжить;
			КонецЕсли; 
			ТокенВниз = Данные.Tokens(ИндексТокена); // Token {GoldParserForNet.Parser} 
			Если ТокенВниз.Kind = 0 Тогда
				ЗаполнитьПоТокену(ТокенВниз, Стек, ЗапросПакета, ЧастьОбъединения, Индикатор, РазборРасширений, ТаблицаКомментариев);
			КонецЕсли;
		КонецЦикла;
		ИмяЗапросаИзКомментария = "";
		ИмяЧастиОбъединенияИзКомментария = "";
		СобратьКомментарийТокена(Токен, ТаблицаКомментариев, ЧастьОбъединения.Комментарий, , ИмяЗапросаИзКомментария, ИмяЧастиОбъединенияИзКомментария,
			ИмяПравила = "<CreateQuery>" Или ИмяПравила = "<SelectQuery>");
		Если ЗначениеЗаполнено(ИмяЗапросаИзКомментария) Тогда
			Если ЗапросПакета.ЧастиОбъединения.Количество() = 1 Тогда
				ЗапросПакета.Имя = ИмяЗапросаИзКомментария;
				ЗапросПакета.РучноеИмя = Истина;
				Если Не ЗначениеЗаполнено(ЗапросПакета.ИмяОсновнойТаблицы) Тогда
					ЗапросПакета.ИмяОсновнойТаблицы = ИмяЗапросаИзКомментария;
				КонецЕсли; 
			КонецЕсли; 
		КонецЕсли; 
		Если ЗначениеЗаполнено(ИмяЧастиОбъединенияИзКомментария) Тогда
			ЧастьОбъединения.Имя = ИмяЧастиОбъединенияИзКомментария;
			ЧастьОбъединения.РучноеИмя = Истина;
		КонецЕсли; 
	Иначе
		Если Ложь
			Или ИмяПравила = "<SelectRoot>"
			Или ИмяПравила = "<CreateRoot>"
			Или ИмяПравила = "<DropRoot>"
			Или ИмяПравила = "<TruncateRoot>"
			Или ИмяПравила = "<InsertRoot>"
			Или ИмяПравила = "<UpdateRoot>"
			Или ИмяПравила = "<DeleteRoot>"
		Тогда
			ЗапросПакета = ДобавитьЗапросПакета();
			Если Истина
				И мНомерБазовойСтрокиВТексте <> Неопределено
				И мСтрокаНачальногоЗапроса = Неопределено 
			Тогда 
				НачальныйТокен = Токен.GetBorderToken(0, Истина);
				КонечныйТокен = Токен.GetBorderToken(1, Истина);
				НачальнаяСтрокаТокена = НачальныйТокен.LineNumber;
				КонечнаяСтрокаТокена = КонечныйТокен.LineNumber;
				Если Истина
					И НачальнаяСтрокаТокена <= мНомерБазовойСтрокиВТексте
					И мНомерБазовойСтрокиВТексте <= КонечнаяСтрокаТокена 
				Тогда 
					мСтрокаНачальногоЗапроса = ЗапросПакета;
				КонецЕсли; 
			КонецЕсли; 
			Если ЛиКорневойЗапрос() Тогда
				ОбновитьДоступныеВременныеТаблицы(, Ложь);
			КонецЕсли; 
			Если ИмяПравила = "<SelectRoot>" Тогда
				ЗапросПакета.ТипЗапроса = 0;
			ИначеЕсли ИмяПравила = "<CreateRoot>" Тогда
				ЗапросПакета.ТипЗапроса = 1;
			ИначеЕсли ИмяПравила = "<DropRoot>" Тогда
				ЗапросПакета.ТипЗапроса = 2;
				СобратьКомментарийТокена(Токен, ТаблицаКомментариев, ЗапросПакета.Комментарий,,,, Истина);
				ЗапросПакета.ИмяОсновнойТаблицы = ПолучитьТекстИзТокена(Данные.Tokens(2));
			ИначеЕсли ИмяПравила = "<InsertRoot>" Тогда
				ЗапросПакета.ТипЗапроса = 3;
				ЗапросПакета.ЗначенияИзВыборки = Истина;
				СобратьКомментарийТокена(Токен, ТаблицаКомментариев, ЗапросПакета.Комментарий,,,, Истина);
				ЗапросПакета.ИмяОсновнойТаблицы = ПолучитьТекстИзТокена(Данные.Tokens(2));
			ИначеЕсли ИмяПравила = "<UpdateRoot>" Тогда
				ЗапросПакета.ТипЗапроса = 4;
				ЗапросПакета.ИмяОсновнойТаблицы = ПолучитьТекстИзТокена(Данные.Tokens(2));
				ЧастьОбъединения = ДобавитьЧастьОбъединения(ЗапросПакета);
				СобратьКомментарийТокена(Токен, ТаблицаКомментариев, ЧастьОбъединения.Комментарий,,,, Истина);
			ИначеЕсли ИмяПравила = "<DeleteRoot>" Тогда
				ЗапросПакета.ТипЗапроса = 5;
				СобратьКомментарийТокена(Токен, ТаблицаКомментариев, ЗапросПакета.Комментарий,,,, Истина);
				ЗапросПакета.ИмяОсновнойТаблицы = ПолучитьТекстИзТокена(Данные.Tokens(3));
				ЧастьОбъединения = ДобавитьЧастьОбъединения(ЗапросПакета);
				СобратьКомментарийТокена(Токен, ТаблицаКомментариев, ЧастьОбъединения.Комментарий,,,, Истина);
			ИначеЕсли ИмяПравила = "<TruncateRoot>" Тогда
				ЗапросПакета.ТипЗапроса = 6;
				СобратьКомментарийТокена(Токен, ТаблицаКомментариев, ЗапросПакета.Комментарий,,,, Истина);
				ЗапросПакета.ИмяОсновнойТаблицы = ПолучитьТекстИзТокена(Данные.Tokens(2));
			КонецЕсли; 
		ИначеЕсли ИмяПравила = "<ExtRoot>" Тогда
			ИндексЗапроса = Данные.Tokens(1).Data;
			ИндексЗапроса = Число(ИндексЗапроса);
			ЗапросПакета = ЗапросыПакета[ИндексЗапроса];
		ИначеЕсли ИмяПравила = "<ExtUnionPart>" Тогда
			ИндексЧасти = Данные.Tokens(1).Data;
			ИндексЧасти = Число(ИндексЧасти);
			ЧастьОбъединения = ЗапросПакета.ЧастиОбъединения[ИндексЧасти];    
		ИначеЕсли Истина
			И ИмяПравила = "<TableWithName>"
			И КоличествоДочерних > 1
		Тогда
			ТекущийУзел = ДобавитьВыбраннуюТаблицу(ЧастьОбъединения);
			ТекущийУзел.Обязательная = Не РазборРасширений;
			СобратьКомментарийТокена(Токен, ТаблицаКомментариев, ТекущийУзел.Комментарий);
		ИначеЕсли Истина
			И ИмяПравила = "<FromUnion>" 
			//И КоличествоДочерних > 1
		Тогда
			ТекущийУзел = ДобавитьВыбраннуюТаблицу(ЧастьОбъединения);
			ТекущийУзел.Обязательная = Не РазборРасширений;
		ИначеЕсли Ложь
			Или ИмяПравила = "<SelectUnion>"
			Или ИмяПравила = "<CreateUnion>"
			Или ИмяПравила = "<SimpleUnion>"
		Тогда
			ЧастьОбъединения = ДобавитьЧастьОбъединения(ЗапросПакета);
		ИначеЕсли Ложь
			Или ИмяПравила = "<UnionPart>"
		Тогда
			ЧастьОбъединения = ДобавитьЧастьОбъединения(ЗапросПакета);
			ЧастьОбъединения.БезДублей = Данные.Tokens(1).Data.TokenCount = 0;
			Если Истина
				И мНомерБазовойСтрокиВТексте <> Неопределено
				//И мСтрокаНачальнойЧастиОбъединения = Неопределено 
				И ЗапросПакета = мСтрокаНачальногоЗапроса
			Тогда 
				НачальныйТокен = Токен.GetBorderToken(0, Истина);
				КонечныйТокен = Токен.GetBorderToken(1, Истина);
				НачальнаяСтрокаТокена = НачальныйТокен.LineNumber;
				КонечнаяСтрокаТокена = КонечныйТокен.LineNumber;
				Если Истина
					И НачальнаяСтрокаТокена <= мНомерБазовойСтрокиВТексте
					И мНомерБазовойСтрокиВТексте <= КонечнаяСтрокаТокена 
				Тогда 
					мСтрокаНачальнойЧастиОбъединения = ЧастьОбъединения;
				КонецЕсли; 
			КонецЕсли; 
		ИначеЕсли Ложь
			Или ИмяПравила = "<InsertExprs>"
		Тогда
			ЗапросПакета.ЗначенияИзВыборки = Ложь;
		ИначеЕсли Истина
			И ИмяПравила = "<Table>" 
			И Стек[1] = "<TableWithName>"
		Тогда
			ТекстОпределенияТаблицы = СобратьВыражениеЗапроса(Данные.Tokens(0),, ЗапросПакета, ЧастьОбъединения);
			ТекущийУзел = ЧастьОбъединения.ВыбранныеТаблицы[ЧастьОбъединения.ВыбранныеТаблицы.Количество() - 1];
			//Фрагменты = ирОбщий.СтрРазделитьЛкс(ТекстОпределенияТаблицы);
			//ПолноеИмя = "";
			//Для Каждого Фрагмент Из Фрагменты Цикл
			//	Если ПолноеИмя <> "" Тогда
			//		ПолноеИмя = ПолноеИмя + ".";
			//	КонецЕсли; 
			//	ПолноеИмя = ПолноеИмя + ПолучитьИмяБезКвадратныхСкобок(Фрагмент);
			//КонецЦикла;
			Если Найти(ТекстОпределенияТаблицы, ".") = 0 Тогда
				ПолноеИмя = ИмяБезКвадратныхСкобок(ТекстОпределенияТаблицы);
			Иначе
				ПолноеИмя = ТекстОпределенияТаблицы;
			КонецЕсли; 
			ЧастьОбъединения.КомпоновщикАктуален = Ложь;
			ТекущийУзел.ПолноеИмя = ирОбщий.ПервыйФрагментЛкс(ПолноеИмя, "(");
			//Перейти ~Выход; // Еще параметры виртуальной таблицы надо разбирать
		ИначеЕсли ИмяПравила = "<Into>" Тогда
			//ЗапросПакета.ТипЗапроса = 1;
			ЗапросПакета.ИмяОсновнойТаблицы = КраткоеИмяВременнойТаблицы(ПолучитьТекстИзТокена(Данные.Tokens(2)));
			ОбновитьНаименованиеЗапроса(ЗапросПакета);
		КонецЕсли;
		Для ИндексТокена = 0 По КоличествоДочерних - 1 Цикл
			ТокенВниз = Данные.Tokens(ИндексТокена);
			Если ТокенВниз.Kind = 0 Тогда
				// Не терминальный токен
				ПсевдонимСнизу = ЗаполнитьПоТокену(ТокенВниз, Стек, ЗапросПакета, ЧастьОбъединения, Индикатор, РазборРасширений, ТаблицаКомментариев, ТекущаяСвязьТаблиц, УровеньВложенности);
				Если ПсевдонимСнизу <> Неопределено Тогда 
					Если Ложь
						Или ИмяПравила = "<FromUnion>" 
						Или ИмяПравила = "<JoinSide>" 
						Или ИмяПравила = "<TableWithName>" 
						Или ИмяПравила = "<TablePseudoname>" 
					Тогда 
						Результат = ПсевдонимСнизу;
					КонецЕсли; 
				КонецЕсли;
			Иначе
				ИмяТерминала = ТокенВниз.Data;
				Если ИмяТерминала = "(" Или ИмяТерминала = "," Тогда
					мРазборПоследнийТокенРазделитель = ТокенВниз;
				КонецЕсли; 
			КонецЕсли;
		КонецЦикла;
		Если Истина
			И ИмяПравила = "<FromUnion>" 
			//И КоличествоДочерних > 1
		Тогда
			СобратьКомментарийТокена(Токен, ТаблицаКомментариев, ТекущийУзел.Комментарий);
		КонецЕсли; 
	КонецЕсли;
	Если Ложь
		Или ИмяПравила = "<SelectRoot>"
		Или ИмяПравила = "<CreateRoot>"
		Или ИмяПравила = "<DropRoot>"
		Или ИмяПравила = "<InsertRoot>"
		Или ИмяПравила = "<UpdateRoot>"
		Или ИмяПравила = "<DeleteRoot>"
		Или ИмяПравила = "<EmbeddedRoot>"
	Тогда
		ОбработатьЗапросПослеУстановкиДанных(ЗапросПакета);
	КонецЕсли; 
	Если ТаблицаКомментариев <> Неопределено Тогда
		// Расширения языка запросов 1С
		Если Ложь
			Или ИмяПравила = "<ParameterOfTable>"
		Тогда
			ПараметрыВыбраннойТаблицы = ЧастьОбъединения.ВыбранныеТаблицы[ЧастьОбъединения.ВыбранныеТаблицы.Количество() - 1].Параметры;
			СобратьКомментарийТокена(Токен, ТаблицаКомментариев, ПараметрыВыбраннойТаблицы[ПараметрыВыбраннойТаблицы.Количество() - 1].ТекстРасширения, Истина);
		КонецЕсли; 
		Если Ложь
			Или ИмяПравила = "<FromTables>"
		Тогда
			НачальныйТерминал = Токен.GetBorderToken(0);
			Если НачальныйТерминал <> Неопределено Тогда
				КонечныйТерминал = Токен.GetBorderToken(1, Истина);
				ПозицияНачальногоТокена = ПолучитьОтносительнуюПозициюТокена(НачальныйТерминал);
				ПозицияКонечногоТокена = ПолучитьОтносительнуюПозициюТокена(КонечныйТерминал);
				Для Каждого СтрокаРасширения Из ТаблицаКомментариев Цикл
					Если Истина
						И СтрокаРасширения.ЭтоРасширение
						И СтрокаРасширения.Позиция >= ПозицияНачальногоТокена 
						И СтрокаРасширения.Позиция <= ПозицияКонечногоТокена
					Тогда
						СтрокаРасширения.Текст = "FROM #FixedTables# КАК FixedTables" + Символы.ПС + СтрокаРасширения.Текст;
						Прервать;
					КонецЕсли;
				КонецЦикла;
			КонецЕсли; 
		КонецЕсли; 
		Если Ложь
			Или (Истина
				И ИмяПравила = "<TableWithName>"
				И КоличествоДочерних > 1)
			Или (Истина
				И ИмяПравила = "<FromUnion>" 
				//И КоличествоДочерних > 1
				)
		Тогда
			НачальныйТерминал = Токен.GetBorderToken(0, Истина);
			Если НачальныйТерминал <> Неопределено Тогда
				ПозицияНачальногоТокена = ПолучитьОтносительнуюПозициюТокена(НачальныйТерминал);
				НачальноеКоличество = ТаблицаКомментариев.Количество(); 
				Для СчетчикРасширения = 1 По НачальноеКоличество Цикл
					СтрокаРасширения = ТаблицаКомментариев[НачальноеКоличество - СчетчикРасширения];
					Если Истина
						И СтрокаРасширения.Позиция <= ПозицияНачальногоТокена 
						И Лев(СтрокаРасширения.Текст, 1) = "#"
					Тогда
						ТекущийУзел.НомерГруппы = Число(Сред(СтрокаРасширения.Текст, 2)) + 1; // +1 сделано 02.12.2015
						Прервать;
					КонецЕсли;
				КонецЦикла;
			КонецЕсли; 
		КонецЕсли; 
		Если Ложь
			Или ИмяПравила = "<SelectUnion>"
			Или ИмяПравила = "<CreateUnion>"
			Или ИмяПравила = "<SimpleUnion>"
			//Или ИмяПравила = "<UnionPart>" // Заменил 08.09.2019
			Или ИмяПравила = "<Union>"
		Тогда
			НачальныйТерминал = Токен.GetBorderToken(0, Истина);
			КонечныйТерминал = Токен.GetBorderToken(1, Истина);
			НачальноеКоличество = ТаблицаКомментариев.Количество(); 
			ПозицияНачальногоТокена = ПолучитьОтносительнуюПозициюТокена(НачальныйТерминал);
			ПозицияКонечногоТокена = ПолучитьОтносительнуюПозициюТокена(КонечныйТерминал);
			Для СчетчикТаблицаТекстаРасширения = 1 По НачальноеКоличество Цикл
				ИндексРасширения = НачальноеКоличество - СчетчикТаблицаТекстаРасширения;
				СтрокаРасширения = ТаблицаКомментариев[ИндексРасширения];
				Если Истина
					И СтрокаРасширения.ЭтоРасширение
					И СтрокаРасширения.Позиция >= ПозицияНачальногоТокена 
					И СтрокаРасширения.Позиция <= ПозицияКонечногоТокена
					// Криво https://www.hostedredmine.com/issues/920099
					И Не ирОбщий.СтрНачинаетсяСЛкс(СтрокаРасширения.Текст, "УПОРЯДОЧИТЬ")
					И Не ирОбщий.СтрНачинаетсяСЛкс(СтрокаРасширения.Текст, "ORDER")
				Тогда
					Если ЧастьОбъединения.ТекстРасширения <> "" Тогда
						//ЧастьОбъединения.ТекстРасширения = "#" + ЧастьОбъединения.ТекстРасширения;
						ЧастьОбъединения.ТекстРасширения = Символы.ПС + ЧастьОбъединения.ТекстРасширения ;
					КонецЕсли; 
					ЧастьОбъединения.ТекстРасширения = "{#" + ИндексРасширения + "}" + СтрокаРасширения.Текст + ЧастьОбъединения.ТекстРасширения;
					ТаблицаКомментариев.Удалить(СтрокаРасширения);
				КонецЕсли;
			КонецЦикла;
		КонецЕсли; 
		Если Ложь
			Или ИмяПравила = "<SelectRoot>"
			Или ИмяПравила = "<CreateRoot>"
			Или ИмяПравила = "<DropRoot>"
			Или ИмяПравила = "<EmbeddedRoot>"
		Тогда
			СобратьКомментарийТокена(Токен, ТаблицаКомментариев, ЗапросПакета.ТекстРасширения, Истина);
		КонецЕсли; 
		Если Ложь
			Или ИмяПравила = "<ExtUnionPart>"
		Тогда
			СтрокаСлужебнойТаблицы = ЧастьОбъединения.ВыбранныеТаблицы.Найти("#FixedTables#", "ПолноеИмя");
			Если СтрокаСлужебнойТаблицы <> Неопределено Тогда
				СтрокиСвязи = ЧастьОбъединения.СвязиТаблиц.Строки.НайтиСтроки(Новый Структура("Таблица", СтрокаСлужебнойТаблицы.Имя), Истина);
				Для Каждого СтрокаСвязи Из СтрокиСвязи Цикл
					СтрокаОбязательнойТаблицы = ЧастьОбъединения.ВыбранныеТаблицы.Найти(Истина, "Обязательная");
					Если СтрокаОбязательнойТаблицы <> Неопределено Тогда
						СтрокаСвязи.Таблица = СтрокаОбязательнойТаблицы.Имя;
					Иначе
						ЧастьОбъединения.СвязиТаблиц.Строки.Удалить(СтрокаСвязи);
					КонецЕсли; 
				КонецЦикла;
				ЧастьОбъединения.ВыбранныеТаблицы.Удалить(СтрокаСлужебнойТаблицы);
			КонецЕсли; 
			КонечныйТерминал = Токен.GetBorderToken(1, Истина);
			ПозицияКонечногоТокена = ПолучитьОтносительнуюПозициюТокена(КонечныйТерминал);
			НачальноеКоличество = ТаблицаКомментариев.Количество(); 
			Для СчетчикРасширения = 1 По НачальноеКоличество Цикл
				СтрокаРасширения = ТаблицаКомментариев[НачальноеКоличество - СчетчикРасширения];
				Если Истина
					И СтрокаРасширения.Позиция <= ПозицияКонечногоТокена 
					И Лев(СтрокаРасширения.Текст, 1) = "#"
				Тогда
					ТаблицаКомментариев.Удалить(СтрокаРасширения);
				КонецЕсли;
			КонецЦикла;
		КонецЕсли; 
	КонецЕсли; 
	Стек.Удалить(0);
	Если ИндикаторБылСоздан = Истина Тогда
		ирОбщий.ОсвободитьИндикаторПроцессаЛкс(Индикатор);
	КонецЕсли; 
	Возврат Результат;
	
КонецФункции

// Процедура - Собрать комментарий токена
//
// Параметры:
//  Токен								 - Token {GoldParserForNet.Parser} - 
//  ТаблицаКомментариев					 - 	 - 
//  ТекстКомментария					 - 	 - 
//  РежимРасширения						 - 	 - 
//  выхИмяЗапросаИзКомментария			 - 	 - 
//  выхИмяЧастиОбъединенияИзКомментария	 - 	 - 
//  ОчиститьМоноКомментарий				 - 	 - 
//
Процедура СобратьКомментарийТокена(Знач Токен, Знач ТаблицаКомментариев, ТекстКомментария, Знач РежимРасширения = Ложь, выхИмяЗапросаИзКомментария = Неопределено,
	выхИмяЧастиОбъединенияИзКомментария = Неопределено, ОчиститьМоноКомментарий = Ложь)
	
	НачальныйТерминал = Токен.GetBorderToken(0, Истина);
	КонечныйТерминал = Токен.GetBorderToken(1, Истина);
	Если ТаблицаКомментариев = Неопределено Тогда
		Возврат;
	КонецЕсли;
	НачальноеКоличество = ТаблицаКомментариев.Количество(); 
	Если НачальныйТерминал = Неопределено И КонечныйТерминал = Неопределено Тогда
		Если Токен.Name = "ParameterOfTable" И мРазборПоследнийТокенРазделитель.EndNoise <> Неопределено Тогда
			ПозицияНачальногоТокена = ПолучитьОтносительнуюПозициюТокена(мРазборПоследнийТокенРазделитель) + 1;
			ПозицияКонечногоТокена = ПолучитьОтносительнуюПозициюТокена(мРазборПоследнийТокенРазделитель.EndNoise);
		Иначе
			Возврат;
		КонецЕсли;
	Иначе
		ПозицияНачальногоТокена = ПолучитьОтносительнуюПозициюТокена(НачальныйТерминал);
		ПозицияКонечногоТокена = ПолучитьОтносительнуюПозициюТокена(КонечныйТерминал);
	КонецЕсли; 
	Для СчетчикТаблицаТекстаРасширения = 1 По НачальноеКоличество Цикл
		БлокаКомментария = ТаблицаКомментариев[НачальноеКоличество - СчетчикТаблицаТекстаРасширения];
		Если Истина
			И РежимРасширения = БлокаКомментария.ЭтоРасширение
			И БлокаКомментария.Позиция >= ПозицияНачальногоТокена// - 1
			И БлокаКомментария.Позиция <= ПозицияКонечногоТокена// + 1
		Тогда
			Если ТекстКомментария <> "" Тогда
				//ТекстРасширения = "#" + ЗапросПакета.ТекстРасширения;
				ТекстКомментария = Символы.ПС + ТекстКомментария;
			КонецЕсли; 
			ТекстКомментария = БлокаКомментария.Текст + ТекстКомментария;
			ТаблицаКомментариев.Удалить(БлокаКомментария);
			СтрокаПорядкаОтладки = "";
			РазобратьКомментарий(ТекстКомментария, выхИмяЗапросаИзКомментария, выхИмяЧастиОбъединенияИзКомментария, СтрокаПорядкаОтладки);
			Если ЗначениеЗаполнено(СтрокаПорядкаОтладки) Тогда
				ЗапросПакета = ЗапросыПакета[ЗапросыПакета.Количество() - 1]; // Опасно. Правильнее передавать явно сверху
				ЧастьОбъединения = ЗапросПакета.ЧастиОбъединения[ЗапросПакета.ЧастиОбъединения.Количество() - 1]; // Опасно. Правильнее передавать явно сверху
				ЧастьОбъединения.ОпцияАвтоупорядочиваниеОтладки = Ложь;
				Для Каждого Выражение Из ирОбщий.СтрРазделитьЛкс(СтрокаПорядкаОтладки, ",", Истина) Цикл
					Фрагменты = ирОбщий.СтрРазделитьЛкс(Выражение, " ", Истина);
					ТекущийУзел = ЧастьОбъединения.ПоляПорядкаОтладки.Добавить();
					ТекущийУзел.Определение = Фрагменты[0];
					Фрагменты.Удалить(0);
					Для Каждого Фрагмент Из Фрагменты Цикл
						Если Ложь
							Или ирОбщий.СтрокиРавныЛкс(Фрагмент, "AUTOORDER")
							Или ирОбщий.СтрокиРавныЛкс(Фрагмент, "АВТОУПОРЯДОЧИВАНИЕ")
						Тогда
							ЧастьОбъединения.ОпцияАвтоупорядочиваниеОтладки = Истина;
						ИначеЕсли Ложь
							Или ирОбщий.СтрокиРавныЛкс(Фрагмент, "DESC")
							Или ирОбщий.СтрокиРавныЛкс(Фрагмент, "Убыв")
						Тогда
							ТекущийУзел.Направление = НаправлениеСортировки.Убыв;
						Иначе
							ТекущийУзел.Направление = НаправлениеСортировки.Возр;
						КонецЕсли;
					КонецЦикла;
				КонецЦикла;
			КонецЕсли;
		КонецЕсли;
	КонецЦикла;
	Если ОчиститьМоноКомментарий Тогда
		Если СтрЧислоВхождений(ТекстКомментария, Лев(мПараметрыДиалектаSQL.СтрочныйКомментарий, 1)) = СтрДлина(ТекстКомментария) Тогда
			ТекстКомментария = "";
		КонецЕсли;
	КонецЕсли; 

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

Процедура ЗаполнитьПсевдонимПоляИзТокена(ТекущийУзел, Знач Токен)

	Данные = Токен.Data;
	Если Данные.TokenCount = 0 Тогда // Для нового движка
		Возврат;
	КонецЕсли; 
	Токен = Данные.Tokens(Данные.TokenCount - 1);
	Если Токен = Неопределено Тогда // для старого движка
		Возврат;
	КонецЕсли; 
	Данные = Токен.Data;
	Токен = Данные.Tokens(Данные.TokenCount - 1);
	ТекстИмени = Токен.Data.Tokens(0).Data;
	//ТекстИмени = ПолучитьТекстИзТокена(Токен); // Так была ошибка https://www.hostedredmine.com/issues/967483
	ТекущийУзел.Имя = ТекстИмени;
	ТекущийУзел.Имя = ИмяБезКвадратныхСкобок(ТекущийУзел.Имя);
	ирОбщий.ОбновитьКопиюСвойстваВНижнемРегистреЛкс(ТекущийУзел);

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

Функция ПроверитьДобавитьПараметр(выхИмяПараметра, ОписаниеТипов = Неопределено)

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

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

// Попытка оптимизации пересборки большого числа выражений.
// По сути проверяет, что выражение является полем или литералом значения.
Функция ЛиВыражениеЯвляетсяПолемИлиТерминалом(ВыражениеЗапроса) Экспорт
	
	ВычислительРегулярныхВыражений = мПлатформа.RegExp;
	ВычислительРегулярныхВыражений.Multiline = Ложь;
	ФрагментШаблона = "(?:[" + мПлатформа.шБуква + "][" + мПлатформа.шБуква + "\d]*|\[[^\]]+\])";
	ВычислительРегулярныхВыражений.Pattern = "^" + ФрагментШаблона + "(?:\." + ФрагментШаблона + ")*$";
	Результат = ВычислительРегулярныхВыражений.Проверить(ВыражениеЗапроса);
	Возврат Результат;
	
КонецФункции

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

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

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

Функция ПредставлениеСравненияНаЯзыке(ПредставлениеЛевогоПоля, Знач ВидСравнения, ДоступноеПолеИлиОписаниеТипов = Неопределено, Отступ = "") Экспорт
	
	ДоступныВидыСравненияПодобноШаблон = ирКэш.ДоступныВидыСравненияПодобноШаблонЛкс();
	Результат = ПредставлениеЛевогоПоля + " ";
	Если ВидСравнения = ВидСравненияКомпоновкиДанных.Равно Тогда
		Результат = Результат + "=";
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиДанных.НеРавно Тогда
		Результат = Результат + "<>";
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиДанных.Больше Тогда
		Результат = Результат + ">";
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиДанных.БольшеИлиРавно Тогда
		Результат = Результат + ">=";
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиДанных.Меньше Тогда
		Результат = Результат + "<";
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиДанных.МеньшеИлиРавно Тогда
		Результат = Результат + "<=";
	ИначеЕсли Ложь
		Или ВидСравнения = ВидСравненияКомпоновкиДанных.Содержит 
		Или ВидСравнения = ВидСравненияКомпоновкиДанных.НеСодержит
		Или (Истина
			И ДоступныВидыСравненияПодобноШаблон
			И (Ложь
				Или ВидСравнения = ВидСравненияКомпоновкиДанных.Подобно 
				Или ВидСравнения = ВидСравненияКомпоновкиДанных.НеПодобно
				Или ВидСравнения = ВидСравненияКомпоновкиДанных.НачинаетсяС 
				Или ВидСравнения = ВидСравненияКомпоновкиДанных.НеНачинаетсяС))
	Тогда
		Результат = Результат + СловоЯзыкаЗапросовВФорме("LIKE");
		Если Ложь
			Или ВидСравнения = ВидСравненияКомпоновкиДанных.НеСодержит 
			Или (Истина
				И ДоступныВидыСравненияПодобноШаблон
				И (Ложь
					Или ВидСравнения = ВидСравненияКомпоновкиДанных.НеПодобно
					Или ВидСравнения = ВидСравненияКомпоновкиДанных.НеНачинаетсяС))
		Тогда
			Результат = СловоЯзыкаЗапросовВФорме("NOT") + " " + Результат;
		КонецЕсли; 
	ИначеЕсли Ложь
		Или ВидСравнения = ВидСравненияКомпоновкиДанных.НеЗаполнено 
		Или ВидСравнения = ВидСравненияКомпоновкиДанных.Заполнено 
	Тогда
		Если ТипЗнч(ДоступноеПолеИлиОписаниеТипов) = Тип("ОписаниеТипов") Тогда
			ОписаниеТипов = ДоступноеПолеИлиОписаниеТипов;
			ТипыПоля = ОписаниеТипов.Типы();
		Иначе
			//! ДоступноеПолеИлиОписаниеТипов = 0; // ДоступноеПолеКомпоновкиДанных
			ОписаниеТипов = ДоступноеПолеИлиОписаниеТипов.ТипЗначения;
			ТипыПоля = ОписаниеТипов.Типы();
			Если Истина
				И ДоступноеПолеИлиОписаниеТипов.Родитель <> Неопределено 
				И Не ДоступноеПолеИлиОписаниеТипов.Родитель.Папка 
			Тогда
				ТипыПоля.Добавить(Тип("Null"));
			КонецЕсли; 
		КонецЕсли; 
		Смещение = ирОбщий.СтрокаПовторомЛкс(Символы.Таб, Отступ);
		ПредставлениеСписка = "";
		Если ТипыПоля.Количество() > 1 Тогда
			ПредставлениеСписка = СловоЯзыкаЗапросовВФорме("UNDEFINED");
		КонецЕсли;
		СписокВыражений = Новый СписокЗначений;
		Для Каждого Тип Из ТипыПоля Цикл
			Если Ложь
				Или Тип = Тип("Null") 
				// Или Тип = Тип("Булево") // Раскомментировать для соответствия встроенному языку
			Тогда
				Продолжить;
			КонецЕсли; 
			СписокВыражений.Добавить(ирОбщий.ВыражениеПриведенияТипаНаЯзыкеЗапросовЛкс(Тип, ОписаниеТипов));
		КонецЦикла;
		СписокВыражений.СортироватьПоЗначению();
		Для Каждого ЭлементСписка Из СписокВыражений Цикл
			Если ПредставлениеСписка <> "" Тогда
				ПредставлениеСписка = ПредставлениеСписка + ", " + Символы.ПС + Смещение;
			КонецЕсли; 
			ПредставлениеСписка = ПредставлениеСписка + ЭлементСписка.Значение;
		КонецЦикла;
		Если ТипыПоля.Найти(Тип("Null")) <> Неопределено Тогда
			Результат1 = СловоЯзыкаЗапросовВФорме("IS");
			Результат2 = СловоЯзыкаЗапросовВФорме("NULL");
			Результат = Результат + Результат1 + " " + Результат2;
			Если ПредставлениеСписка <> "" Тогда
				Результат = Результат + Символы.ПС + Смещение + СловоЯзыкаЗапросовВФорме("OR") + " " + ПредставлениеЛевогоПоля + " ";
			КонецЕсли; 
		КонецЕсли; 
		Если ПредставлениеСписка <> "" Тогда
			Результат = Результат + СловоЯзыкаЗапросовВФорме("IN") + " (" + ПредставлениеСписка + ")";
		КонецЕсли; 
		Если ВидСравнения = ВидСравненияКомпоновкиДанных.Заполнено Тогда
			Результат = СловоЯзыкаЗапросовВФорме("NOT") + " (" + Результат + ")";
		КонецЕсли; 
	ИначеЕсли Ложь
		Или ВидСравнения = ВидСравненияКомпоновкиДанных.ВИерархии 
		Или ВидСравнения = ВидСравненияКомпоновкиДанных.НеВИерархии
	Тогда
		Результат1 = СловоЯзыкаЗапросовВФорме("IN");
		Результат2 = СловоЯзыкаЗапросовВФорме("HIERARCHYIN");
		Результат1 = Результат1 + " " + Результат2;
		Если ВидСравнения = ВидСравненияКомпоновкиДанных.НеВИерархии Тогда
			Результат1 = СловоЯзыкаЗапросовВФорме("NOT") + " " + Результат1;
		КонецЕсли; 
		Результат = Результат + Результат1;
	ИначеЕсли Ложь
		Или ВидСравнения = ВидСравненияКомпоновкиДанных.ВСписке 
		Или ВидСравнения = ВидСравненияКомпоновкиДанных.НеВСписке
	Тогда
		Результат1 = СловоЯзыкаЗапросовВФорме("IN");
		Если ВидСравнения = ВидСравненияКомпоновкиДанных.НеВСписке Тогда
			Результат1 = СловоЯзыкаЗапросовВФорме("NOT") + " " + Результат1;
		КонецЕсли; 
		Результат = Результат + Результат1;
	Иначе
		ВызватьИсключение "Вид сравнения " + ВидСравнения + " компоновки не поддерживается";
	КонецЕсли; 
	Возврат Результат;
	
КонецФункции

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

	Результат = ИмяПоля;
	ПолеНайдено = Ложь;
	РазрешитьПроверкуСуществованияТаблиц = Ложь;
	РазрешитьНормализациюИмен = Ложь;
	Если СтруктураПолей <> Неопределено Тогда 
		Если СтруктураПолей.Режим = "ГлобальнаяЗамена" Тогда
			СтруктураПолей.КоличествоПолей = СтруктураПолей.КоличествоПолей + 1;
		КонецЕсли; 
		РазрешитьПроверкуСуществованияТаблиц = СтруктураПолей.РазрешитьПроверкуСуществованияТаблиц;
		РазрешитьНормализациюИмен = СтруктураПолей.РазрешитьНормализациюИмен;
		Если Истина
			И СтруктураПолей.ДоступныВыбранныеПоля 
			И Найти(Результат, ".") = 0
		Тогда 
			СтрокаВыбранногоПоля = ЗапросПакета.ПоляОбъединения.Найти(НРег(Результат), "НИмя");
			ПолеНайдено = СтрокаВыбранногоПоля <> Неопределено;
			Если Истина
				И РазрешитьПроверкуСуществованияТаблиц
				И Не ПолеНайдено 
				И (Ложь
					Или Не РазрешитьНормализациюИмен
					Или ЗапросПакета.ЧастиОбъединения.Количество() > 1)
			Тогда 
				АктивироватьЗапросИЧастьОбъединения(ЗапросПакета, ЧастьОбъединения);
				Если Не РазрешитьНормализациюИмен Тогда
					ВызватьИсключение "Поле " + Результат + " не найдено в выбранных полях.";
				Иначе
					ВызватьИсключение "В случае использования операторов ОБЪЕДИНИТЬ, поля (" + Результат + ") предложений УПОРЯДОЧИТЬ ПО и ИТОГИ должны находиться в выбранных полях.";
				КонецЕсли; 
			КонецЕсли; 
		КонецЕсли; 
	КонецЕсли; 
	Если Истина
		И Не ПолеНайдено
		И ПараметрыДиалектаSQL.МногоТаблиц
		И ЧастьОбъединения <> Неопределено 
	Тогда // Пока не проверяем другие выражения
		ВыполненаЗамена = Ложь;
		Если Найти(СтароеИмяТаблицы, ".") = 0 Тогда
			ПозицияТочки = Найти(Результат, ".");
			Если Истина
				И РазрешитьНормализациюИмен
				И ПозицияТочки = 0 
			Тогда
				//ОбновитьДоступныеВременныеТаблицы(); // Неоптимально?
				ОбновитьКомпоновщикЧастиОбъединения(ЧастьОбъединения, Ложь);
				Для Каждого ГруппаПолей Из ЧастьОбъединения.Компоновщик.Настройки.ДоступныеПоляВыбора.Элементы Цикл
					ДоступноеПоле = ГруппаПолей.Элементы.Найти("" + ГруппаПолей.Поле + "." + Результат);
					Если ДоступноеПоле <> Неопределено Тогда
						Результат = "" + ДоступноеПоле.Поле;
						выхНужноПересобратьТокены = Истина;
						// Правильно было бы проверить и другие таблицы для исключения неоднозначности привязки поля к таблице
						Прервать;
					КонецЕсли; 
				КонецЦикла;
			ИначеЕсли ЗначениеЗаполнено(СтароеИмяТаблицы) Тогда
				ИмяТаблицыПоля = Лев(Результат, ПозицияТочки - 1);
				Если ирОбщий.СтрокиРавныЛкс(ИмяТаблицыПоля, СтароеИмяТаблицы) Тогда
					Результат = НовоеИмяТаблицы + "." + Сред(Результат, ПозицияТочки + 1);
					ВыполненаЗамена = Истина;
				КонецЕсли; 
			КонецЕсли; 
		Иначе
			Фрагменты = ирОбщий.СтрРазделитьЛкс(Результат,, Истина);
			Если Фрагменты.Количество() > 1 Тогда
				ИмяПервогоПоля = Фрагменты[0] + "." + Фрагменты[1];
				Если ирОбщий.СтрокиРавныЛкс(ИмяПервогоПоля, СтароеИмяТаблицы) Тогда
					Фрагменты.Удалить(0);
					Фрагменты.Удалить(0);
					Результат = НовоеИмяТаблицы;
					Если Фрагменты.Количество() > 0 Тогда
						Результат = Результат + "." + ирОбщий.СтрСоединитьЛкс(Фрагменты);
					КонецЕсли; 
					ВыполненаЗамена = Истина;
				КонецЕсли; 
			КонецЕсли; 
		КонецЕсли; 
		Если ВыполненаЗамена Тогда 
			Если Истина
				И СтруктураПолей <> Неопределено
				И СтруктураПолей.Режим = "ГлобальнаяЗамена"
			Тогда
				СтруктураПолей.КоличествоОбнаружено = СтруктураПолей.КоличествоОбнаружено + 1;
			КонецЕсли; 
			выхНужноПересобратьТокены = Истина;
		КонецЕсли; 
		Если Истина
			И Не ВыполненаЗамена 
			И РазрешитьНормализациюИмен 
			И РазрешитьПроверкуСуществованияТаблиц 
			И Не ЛиТерминалЯзыка(Результат, Истина)  // грязно игнорируем терминалы типа МЕСЯЦ, ДЕНЬ https://www.hostedredmine.com/issues/910443
			И Не (Истина
				И СтруктураПолей <> Неопределено
				И СтруктураПолей.Режим = "ГлобальнаяЗамена")
		Тогда
			Если Найти(Результат, ".") > 0 Тогда
				Если мРегВычислительВыразить = Неопределено Тогда
					мРегВычислительВыразить = ирОбщий.НовоеРегВыражениеЛкс();
					#Если Сервер И Не Сервер Тогда
						мРегВычислительВыразить = Обработки.ирОболочкаРегВыражение.Создать();
					#КонецЕсли
					мРегВычислительВыразить.Pattern = "(?:ВЫРАЗИТЬ|CAST)\(\s*([." + мПлатформа.шБукваЦифра + "]+)\s+(?:AS|КАК)\s+(?:[." + мПлатформа.шБукваЦифра + "]+(?:\(\s*\d+(?:,\s*\d+)?\))?)\)";
				КонецЕсли;
				ПолноеИмяПоля = мРегВычислительВыразить.Заменить(Результат, "$1"); // Убираем первую вложенность "ВЫРАЗИТЬ()"
				ИмяТаблицы = ирОбщий.ПервыйФрагментЛкс(ПолноеИмяПоля);
				ЧастьОбъединенияПоля = ЧастьОбъединения;
				СтрокаВыбраннойТаблицы = ЧастьОбъединенияПоля.ВыбранныеТаблицы.Найти(НРег(ИмяТаблицы), "НИмя");
				Если Истина
					И СтрокаВыбраннойТаблицы = Неопределено 
					И СтруктураПолей <> Неопределено
					И СтруктураПолей.РодительЧастьОбъединения <> Неопределено
				Тогда 
					// Коррелированный подзапрос 
					ЧастьОбъединенияПоля = СтруктураПолей.РодительЧастьОбъединения;
					СтрокаВыбраннойТаблицы = ЧастьОбъединенияПоля.ВыбранныеТаблицы.Найти(НРег(ИмяТаблицы), "НИмя");
				КонецЕсли;
				Если СтрокаВыбраннойТаблицы = Неопределено Тогда
					АктивироватьЗапросИЧастьОбъединения(ЗапросПакета, ЧастьОбъединения);
					ВызватьИсключение "Таблица поля """ + Результат + """ не найдена в списке выбранных";
				КонецЕсли;
				ДоступнаяТаблица = ДоступнаяТаблицаПоИмениВыбранной(СтрокаВыбраннойТаблицы.ПолноеИмя); 
				Если Ложь
					Или СтрокаВыбраннойТаблицы.ВложенныйПакет <> Неопределено
					Или (Истина
						И ДоступнаяТаблица <> Неопределено 
						И (Ложь
							Или (Истина
								И ДоступнаяТаблица.Тип <> "ВременнаяТаблица" 
								И ДоступнаяТаблица.Тип <> "Параметр")
							Или (Истина
								И ДоступнаяТаблица.Тип = "ВременнаяТаблица" 
								И ЗначениеЗаполнено(ДоступнаяТаблица.ПородившийЗапрос))))
							//Или (Истина
							//	И СтрокаВыбраннойТаблицы.Тип = "Параметр" 
							//	И ТипЗнч(Параметры.Найти(НРег(Сред(СтрокаВыбраннойТаблицы.Определение, 2)), "НИмя").Значение) = Тип("ТаблицаЗначений"))
				Тогда
					МаркерТипЗначения = "." + МаркерПоляФункцииТипЗначения();
					Если Истина
						И Найти(ПолноеИмяПоля, МаркерТипЗначения) > 0 
						И ирОбщий.СтрКончаетсяНаЛкс(ПолноеИмяПоля, МаркерТипЗначения, Истина)
					Тогда
						// Для поля-функции ТипЗначения проверяем только родительское поле, т.к. при разборке текста они создаются и для полей, которым такие дочерние доступные поля-функции не добавляются (простого типа)
						ПолноеИмяПоля = Лев(ПолноеИмяПоля, СтрДлина(ПолноеИмяПоля) - СтрДлина(МаркерТипЗначения));
					КонецЕсли;
					ОбновитьКомпоновщикЧастиОбъединения(ЧастьОбъединенияПоля, Ложь);
					ДоступноеПоле = НайтиДоступноеПоле(ЧастьОбъединенияПоля.Компоновщик.Настройки.ДоступныеПоляВыбора, ПолноеИмяПоля, 2000);
					Если ДоступноеПоле = Неопределено Тогда
						АктивироватьЗапросИЧастьОбъединения(ЗапросПакета, ЧастьОбъединения);
						ВызватьИсключение "Поле """ + Результат + """ не найдено в списке доступных";
					КонецЕсли;
					Если СтруктураПолей.Режим = "ПоискПолей" Тогда 
						ДобавитьПолеВСтруктуруПолей(СтруктураПолей, "" + ДоступноеПоле.Поле);
					КонецЕсли; 
				КонецЕсли; 
			Иначе
				АктивироватьЗапросИЧастьОбъединения(ЗапросПакета, ЧастьОбъединения);
				ВызватьИсключение "Таблица поля """ + Результат + """ не подобрана. Укажите ее явно.";
			КонецЕсли; 
		КонецЕсли; 
	КонецЕсли; 
	Возврат Результат;

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

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

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

Процедура ДобавитьПробелПослеТокена(Текст, ИмяПредыдущегоТокенаВниз)
	
	// Однострочный код здесь дал бы 20% ускорение, поэтому смысла не имеет
	Если Истина // После них не ставим пробел
		И ИмяПредыдущегоТокенаВниз <> "."
		И ИмяПредыдущегоТокенаВниз <> "("
		И ИмяПредыдущегоТокенаВниз <> "&"
		И ИмяПредыдущегоТокенаВниз <> "?"
		И ИмяПредыдущегоТокенаВниз <> "@"
		И ИмяПредыдущегоТокенаВниз <> "::"
	Тогда
		Текст = Текст + " ";
	КонецЕсли; 

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

Функция СловоЯзыкаЗапросовВФорме(Ключ) Экспорт
	
	Результат = СловоЯзыкаЗапросов(Ключ, ПараметрыДиалектаSQL, Английский1С);
	Возврат Результат;
	
КонецФункции

// Функция - Собрать выражение запроса
//
// Параметры:
//  Токен						 - Token {GoldParserForNet.Parser} - 
//  Отступ						 - 	 - 
//  ЗапросПакета				 - 	 - 
//  ЧастьОбъединения			 - 	 - 
//  СтароеИмяТаблицы			 - 	 - 
//  НовоеИмяТаблицы				 - 	 - 
//  выхЕстьАгрегаты				 - 	 - 
//  выхНужноПересобратьТокены	 - 	 - 
//  СтруктураПолей				 - 	 - 
//  ТипЛогическойГруппы			 - 		 - 
// 
// Возвращаемое значение:
//   - 
//
Функция СобратьВыражениеЗапроса(Знач Токен, Знач Отступ = 0, Знач ЗапросПакета = Неопределено, Знач ЧастьОбъединения = Неопределено,
	Знач СтароеИмяТаблицы = "", Знач НовоеИмяТаблицы = "", выхЕстьАгрегаты = Ложь, выхНужноПересобратьТокены = Неопределено, Знач СтруктураПолей = Неопределено, Знач ТипЛогическойГруппы = Неопределено) Экспорт
	
	Если выхНужноПересобратьТокены = Неопределено Тогда
		выхНужноПересобратьТокены = Ложь;
	КонецЕсли; 
	Данные = Токен.Data; // Reduction {GoldParserForNet.Parser} 
	Если Данные = Неопределено Тогда
		Возврат Неопределено;
	КонецЕсли;
	Если Токен.Kind = 1 Тогда
		Возврат Данные;
	КонецЕсли; 
	ИмяПравила = Данные.RuleText();
	Если Ложь
		Или ИмяПравила = "<Parameter>"
		Или ИмяПравила = "<TableParameter>"
	Тогда
		ВыражениеПараметра = Данные.Tokens(0).Data;
		Если СтароеИмяТаблицы = ВыражениеПараметра Тогда
			ВыражениеПараметра = НовоеИмяТаблицы;
			выхНужноПересобратьТокены = Истина;
		КонецЕсли; 
		ИмяПараметра = ВыражениеПараметра;
		ОписаниеТиповПараметра = Неопределено;
		Если ИмяПравила = "<TableParameter>" Тогда
			ОписаниеТиповПараметра = Новый ОписаниеТипов("ТаблицаЗначений");
		КонецЕсли; 
		ПроверитьДобавитьПараметр(ИмяПараметра, ОписаниеТиповПараметра);
		Результат = ПараметрыДиалектаSQL.ПрефиксПараметра;
		Если Не ИменованныеПараметры И ЗначениеЗаполнено(ИмяПараметра) И Не ЭтаФорма.Открыта() Тогда
			ИменованныеПараметры = Истина;
		КонецЕсли;
		Если ИменованныеПараметры Тогда
			Результат = Результат + ИмяПараметра;
		КонецЕсли;
		Если СтруктураПолей <> Неопределено Тогда 
			Если Истина
				И СтруктураПолей.Режим = "ДопискаЗначения" 
				И Не ЛиТерминалЯзыка(Результат)
			Тогда
				ДописатьКВыражениюЕгоЗначение(Результат, СтруктураПолей);
			ИначеЕсли Истина 
				И СтруктураПолей.Режим = "ГлобальнаяЗамена"
				И ирОбщий.СтрокиРавныЛкс(СтруктураПолей.СтароеИмяТаблицыИлиПараметра, Результат)
			Тогда 
				СтруктураПолей.КоличествоОбнаружено = СтруктураПолей.КоличествоОбнаружено + 1; 
			КонецЕсли; 
		КонецЕсли;
	Иначе
		Если ИмяПравила = "<Agregate>" Тогда
			выхЕстьАгрегаты = Истина;
			Если СтруктураПолей <> Неопределено И СтруктураПолей.Режим = "Чтение" Тогда
				СтруктураПолей.ВнутриАгрегата = Истина;
			КонецЕсли; 
		КонецЕсли; 
		ЧислоТокенов = Данные.TokenCount;
		Результат = "";
		//ЛевыйОтступ = ирОбщий.СтрокаПовторомЛкс(Символы.Таб, Отступ);
		ЛевыйОтступ = Лев("														", Отступ); // Так быстрее
		Если ИмяПравила = "<Case>" Тогда
			ВыражениеВыбора = СобратьВыражениеЗапроса(Данные.Tokens(1), Отступ, ЗапросПакета, ЧастьОбъединения, СтароеИмяТаблицы, НовоеИмяТаблицы,
				выхЕстьАгрегаты, выхНужноПересобратьТокены, СтруктураПолей);
			Результат = СловоЯзыкаЗапросовВФорме("CASE");
			Если ЗначениеЗаполнено(ВыражениеВыбора) Тогда
				Результат = Результат + " " + ВыражениеВыбора;
			КонецЕсли;
			Результат = Результат + СобратьВыражениеЗапроса(Данные.Tokens(2), Отступ, ЗапросПакета, ЧастьОбъединения, СтароеИмяТаблицы, НовоеИмяТаблицы,
				выхЕстьАгрегаты, выхНужноПересобратьТокены, СтруктураПолей);
			ТекстElse = СобратьВыражениеЗапроса(Данные.Tokens(3), Отступ + 1, ЗапросПакета, ЧастьОбъединения, СтароеИмяТаблицы, НовоеИмяТаблицы,
				выхЕстьАгрегаты, выхНужноПересобратьТокены, СтруктураПолей);
			Если ЗначениеЗаполнено(ТекстElse) Тогда
				Результат = Результат + Символы.ПС + ЛевыйОтступ + "	" + ТекстElse;
			КонецЕсли; 
			Результат = Результат + Символы.ПС + ЛевыйОтступ + СловоЯзыкаЗапросовВФорме("END");
		ИначеЕсли ИмяПравила = "<WhenThen>" Тогда
			Результат = "
			|" + ЛевыйОтступ + "	" + СловоЯзыкаЗапросовВФорме("WHEN") + " " + СобратьВыражениеЗапроса(Данные.Tokens(1), Отступ + 2, ЗапросПакета, ЧастьОбъединения,
				СтароеИмяТаблицы, НовоеИмяТаблицы, выхЕстьАгрегаты, выхНужноПересобратьТокены, СтруктураПолей) + "
			|" + ЛевыйОтступ + "		" + СловоЯзыкаЗапросовВФорме("THEN") + " " + СобратьВыражениеЗапроса(Данные.Tokens(3), Отступ + 2, ЗапросПакета, ЧастьОбъединения,
				СтароеИмяТаблицы, НовоеИмяТаблицы, выхЕстьАгрегаты, выхНужноПересобратьТокены, СтруктураПолей);
			Если ЧислоТокенов > 4 Тогда
				Результат = Результат + СобратьВыражениеЗапроса(Данные.Tokens(4), Отступ, ЗапросПакета, ЧастьОбъединения, СтароеИмяТаблицы, НовоеИмяТаблицы,
					выхЕстьАгрегаты, выхНужноПересобратьТокены, СтруктураПолей);
			КонецЕсли; 
		ИначеЕсли Ложь
			Или ИмяПравила = "<AndExpr>"
			Или ИмяПравила = "<OrExpr>"
		Тогда
			Если Ложь
				Или (Истина
					И ТипЛогическойГруппы = "И"
					И ИмяПравила = "<AndExpr>")
				Или (Истина
					И ТипЛогическойГруппы = "ИЛИ"
					И ИмяПравила = "<OrExpr>")
			Тогда
				Смещение = 0;
			Иначе
				Если ТипЛогическойГруппы = "(" Тогда
					Смещение = 0;
				Иначе
					Смещение = 1;
					ЛевыйОтступ = ЛевыйОтступ + "	";
				КонецЕсли; 
				Если ИмяПравила = "<OrExpr>" Тогда
					ТипЛогическойГруппы = "ИЛИ";
				Иначе
					ТипЛогическойГруппы = "И";
				КонецЕсли; 
			КонецЕсли; 
			Если ТипЛогическойГруппы = "И" Тогда
				ЛогическийОператор = СловоЯзыкаЗапросовВФорме("AND");
			Иначе
				ЛогическийОператор = СловоЯзыкаЗапросовВФорме("OR");
			КонецЕсли; 
			ЛевыйОперанд = СобратьВыражениеЗапроса(Данные.Tokens(0), Отступ + Смещение, ЗапросПакета, ЧастьОбъединения, СтароеИмяТаблицы, НовоеИмяТаблицы, выхЕстьАгрегаты,
				выхНужноПересобратьТокены, СтруктураПолей, ТипЛогическойГруппы);
			Если Смещение = 1 И ИерархическийСтильЛогическихВыражений Тогда
				Результат = НейтральныйОперандЛогическогоОператора(ИмяПравила = "<AndExpr>");
				Если ирОбщий.СтрНачинаетсяСЛкс(Результат, ЛевыйОперанд) Тогда
					ЛевыйОперанд = "";
				Иначе
					Результат = Результат + "
					|" + ЛевыйОтступ + ЛогическийОператор + " ";
				КонецЕсли; 
			КонецЕсли; 
			Результат = Результат + ЛевыйОперанд + "
			|" + ЛевыйОтступ + ЛогическийОператор + " " + СобратьВыражениеЗапроса(Данные.Tokens(2), Отступ + Смещение, ЗапросПакета, ЧастьОбъединения,
				СтароеИмяТаблицы, НовоеИмяТаблицы, выхЕстьАгрегаты, выхНужноПересобратьТокены, СтруктураПолей, ТипЛогическойГруппы);
		ИначеЕсли ИмяПравила = "<EmbeddedQuery>" Тогда
			ВнутреннийТокен = Данные.Tokens(1); // Token {GoldParserForNet.Parser} 
			Если ВнутреннийТокен.Name = "EmbeddedRoot" Тогда
				Пакет = ЗапросыПакета.СкопироватьКолонки();
				ЗапросПакета = ДобавитьЗапросПакета(Пакет);
				ЗаполнитьПоТокену(ВнутреннийТокен, , ЗапросПакета, ЧастьОбъединения, Null);
				ОбновитьПоляОбъединенияЗапроса(ЗапросПакета); // Это уже делается в ОбработатьЗапросПослеУстановкиТекста
				СтруктураПолейДляПодзапроса = Неопределено;
				Если Истина
					И СтруктураПолей <> Неопределено
					И СтруктураПолей.Режим = "ГлобальнаяЗамена"
				Тогда
					ВложеннаяСтруктураПолей = ПереименоватьТаблицуИлиПараметр(Пакет, СтруктураПолей.СтароеИмяТаблицыИлиПараметра, СтруктураПолей.НовоеИмяТаблицыИлиПараметра,
						СтруктураПолей.СтароеИмяПоля, СтруктураПолей.НовоеИмяПоля);
					СтруктураПолей.КоличествоОбнаружено = СтруктураПолей.КоличествоОбнаружено + ВложеннаяСтруктураПолей.КоличествоОбнаружено;
					СтруктураПолей.КоличествоПолей = СтруктураПолей.КоличествоПолей + ВложеннаяСтруктураПолей.КоличествоПолей;
					выхНужноПересобратьТокены = Истина
						И СтруктураПолей.КоличествоОбнаружено > 0 
						И (Ложь
							Или СтруктураПолей.СтароеИмяТаблицыИлиПараметра <> СтруктураПолей.НовоеИмяТаблицыИлиПараметра
							Или СтруктураПолей.СтароеИмяПоля <> СтруктураПолей.НовоеИмяПоля)
				КонецЕсли; 
				ВложеннаяСтруктураПолей = НоваяВложеннаяСтруктураПолей(СтруктураПолей,, ЧастьОбъединения);
				Результат = "(" + СборкаНачалоВложенногоЗапроса() + СобратьТекстПакета(Пакет, Символы.Таб, ВложеннаяСтруктураПолей) + ")";
			Иначе
				Результат = "(" + СобратьВыражениеЗапроса(ВнутреннийТокен,,,,,,, выхНужноПересобратьТокены, СтруктураПолей) + ")";
			КонецЕсли; 
		Иначе
			// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
			ИмяПредыдущегоТокена = Неопределено;
			ЗапретитьПробелы = Ложь
				Или ИмяПравила = "<MultiField>" 
				Или ИмяПравила = "<MultiFieldBody>";
			Если Найти(ИмяПравила, "Expr") = 0 Тогда 
				ТипЛогическойГруппы = "";
			КонецЕсли; 
			ТипЛогическойГруппыВниз = ТипЛогическойГруппы;
			_РежимОтладки = Ложь;
			Если _РежимОтладки Тогда // Можно менять на Истина в точке останова, например условием ирОбщий.Пр(_РежимОтладки, 1, 1)
				// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
				Для ИндексТокена = 0 По Данные.TokenCount - 1 Цикл
					ТокенВниз = Данные.Tokens(ИндексТокена); // Token {GoldParserForNet.Parser} 
					РазрешитьРазделительБольшойСтроки = Истина
						И ИмяПредыдущегоТокена = ","
						И (Ложь
							Или ИмяПравила = "<Exprs>"
							Или ИмяПравила = "<NamedExprs>"
							Или ИмяПравила = "<EmptyTableFields>");
					Если ТокенВниз.Kind = 0 Тогда
						Если Не ПустаяСтрока(Прав(Результат, 1)) И Не ЗапретитьПробелы Тогда
							ДобавитьПробелПослеТокена(Результат, ИмяПредыдущегоТокена);
						КонецЕсли; 
						// Не терминальный токен
						РезультатСнизу = СобратьВыражениеЗапроса(ТокенВниз, Отступ, ЗапросПакета, ЧастьОбъединения, СтароеИмяТаблицы, НовоеИмяТаблицы,
							выхЕстьАгрегаты, выхНужноПересобратьТокены, СтруктураПолей, ТипЛогическойГруппыВниз);
						ИмяПредыдущегоТокена = Неопределено;
					Иначе
						ИмяТокена = ТокенВниз.Name;
						// Терминальный токен
						Если Ложь // Перед ними не ставим пробел
							Или ИмяТокена = ")"
							Или ИмяТокена = "]"
							Или ИмяТокена = ","
							Или ИмяТокена = "."
							Или ИмяТокена = ".*"
							Или ИмяТокена = "::"
							Или (Истина
								И ИндексТокена = 1
								И ИмяТокена = "(")
						Тогда
							// Закомментировано 28.02.2016
							//Если ИмяТокена = ")" Тогда 
							//	Отступ = Отступ - 1;
							//КонецЕсли; 
							РезультатСнизу = ТокенВниз.Data;
							Если ИмяТокена = ")" Тогда 
								ТипЛогическойГруппыВниз = ТипЛогическойГруппы;
							КонецЕсли; 
						ИначеЕсли Ложь
							Или ИмяТокена = "id"
							Или ИмяТокена = "BadID"
							Или ИмяТокена = "strLiteral"
							Или ИмяТокена = "numLiteral" 
							Или ИмяТокена = "refLiteral" 
							Или ИмяТокена = "Parameter" 
							Или ИмяТокена = "MultiCommentLine"
							Или ИмяТокена = "COMP_OPERATOR"
							Или ИмяТокена = "("
							Или ИмяТокена = "["
							Или ИмяТокена = "&"
							Или ИмяТокена = "?"
							Или ИмяТокена = "@"
							Или ИмяТокена = "+"
							Или ИмяТокена = "-"
							Или ИмяТокена = "*"
							Или ИмяТокена = "/"
						Тогда
							Если ИмяТокена = "(" Тогда 
								Отступ = Отступ + 1;
								ТипЛогическойГруппыВниз = "(";
							КонецЕсли; 
							Если Не ПустаяСтрока(Прав(Результат, 1)) Тогда
								ДобавитьПробелПослеТокена(Результат, ИмяПредыдущегоТокена);
							КонецЕсли; 
							РезультатСнизу = ТокенВниз.Data;
						Иначе
							Если Ложь
								Или ИмяПравила = "<ID>"
								Или ИмяПравила = "<SmartID>"
								Или ИмяПравила = "<TableAS>"
							Тогда
								РезультатСнизу = ТокенВниз.Data;
							Иначе
								Если Не ПустаяСтрока(Прав(Результат, 1)) Тогда
									ДобавитьПробелПослеТокена(Результат, ИмяПредыдущегоТокена);
								КонецЕсли; 
								РезультатСнизу = СловоЯзыкаЗапросовВФорме(ИмяТокена);
							КонецЕсли; 
						КонецЕсли; 
						ИмяПредыдущегоТокена = ИмяТокена;
					КонецЕсли;
					Если Истина
						И РазрешитьРазделительБольшойСтроки 
						И СтрДлина(СтрПолучитьСтроку(РезультатСнизу, 1)) > 50 // Минимальная длина выражения, чтобы оно располагалось с новой строки
					Тогда
						Результат = Результат + Символы.ПС + ЛевыйОтступ + РезультатСнизу;
					Иначе
						Результат = Результат + РезультатСнизу;
					КонецЕсли;
				КонецЦикла;
			Иначе
				// Однострочный код использован для ускорения при разрешенной отладке. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика"
				Для ИндексТокена = 0 По Данные.TokenCount - 1 Цикл  					ТокенВниз = Данные.Tokens(ИндексТокена);  					РазрешитьРазделительБольшойСтроки = Истина  						И ИмяПредыдущегоТокена = ","  						И (Ложь  							Или ИмяПравила = "<Exprs>"  							Или ИмяПравила = "<NamedExprs>"  							Или ИмяПравила = "<EmptyTableFields>");  					Если ТокенВниз.Kind = 0 Тогда  						Если Не ПустаяСтрока(Прав(Результат, 1)) И Не ЗапретитьПробелы Тогда  							ДобавитьПробелПослеТокена(Результат, ИмяПредыдущегоТокена);  						КонецЕсли;    						РезультатСнизу = СобратьВыражениеЗапроса(ТокенВниз, Отступ, ЗапросПакета, ЧастьОбъединения, СтароеИмяТаблицы, НовоеИмяТаблицы,  							выхЕстьАгрегаты, выхНужноПересобратьТокены, СтруктураПолей, ТипЛогическойГруппыВниз);  						ИмяПредыдущегоТокена = Неопределено;  					Иначе  						ИмяТокена = ТокенВниз.Name;    						Если Ложь  							Или ИмяТокена = ")"  							Или ИмяТокена = "]"  							Или ИмяТокена = ","  							Или ИмяТокена = "."  							Или ИмяТокена = ".*"  							Или ИмяТокена = "::"  							Или (Истина  								И ИндексТокена = 1  								И ИмяТокена = "(")  						Тогда          							РезультатСнизу = ТокенВниз.Data;  							Если ИмяТокена = ")" Тогда  								ТипЛогическойГруппыВниз = ТипЛогическойГруппы;  							КонецЕсли;  						ИначеЕсли Ложь  							Или ИмяТокена = "id"  							Или ИмяТокена = "BadID"  							Или ИмяТокена = "strLiteral"  							Или ИмяТокена = "numLiteral"  							Или ИмяТокена = "refLiteral"  							Или ИмяТокена = "Parameter"  							Или ИмяТокена = "MultiCommentLine"  							Или ИмяТокена = "COMP_OPERATOR"  							Или ИмяТокена = "("  							Или ИмяТокена = "["  							Или ИмяТокена = "&"  							Или ИмяТокена = "?"  							Или ИмяТокена = "@"  							Или ИмяТокена = "+"  							Или ИмяТокена = "-"  							Или ИмяТокена = "*"  							Или ИмяТокена = "/"  						Тогда  							Если ИмяТокена = "(" Тогда  								Отступ = Отступ + 1;  								ТипЛогическойГруппыВниз = "(";  							КонецЕсли;  							Если Не ПустаяСтрока(Прав(Результат, 1)) Тогда  								ДобавитьПробелПослеТокена(Результат, ИмяПредыдущегоТокена);  							КонецЕсли;  							РезультатСнизу = ТокенВниз.Data;  						Иначе  							Если Ложь  								Или ИмяПравила = "<ID>"  								Или ИмяПравила = "<SmartID>"  								Или ИмяПравила = "<TableAS>"  							Тогда  								РезультатСнизу = ТокенВниз.Data;  							Иначе  								Если Не ПустаяСтрока(Прав(Результат, 1)) Тогда  									ДобавитьПробелПослеТокена(Результат, ИмяПредыдущегоТокена);  								КонецЕсли;  								РезультатСнизу = СловоЯзыкаЗапросовВФорме(ИмяТокена);  							КонецЕсли;  						КонецЕсли;  						ИмяПредыдущегоТокена = ИмяТокена;  					КонецЕсли;  					Если Истина  						И РазрешитьРазделительБольшойСтроки  						И СтрДлина(СтрПолучитьСтроку(РезультатСнизу, 1)) > 50  					Тогда  						Результат = Результат + Символы.ПС + ЛевыйОтступ + РезультатСнизу;  					Иначе  						Результат = Результат + РезультатСнизу;  					КонецЕсли;  				КонецЦикла;  
			КонецЕсли;
			Если Истина
				И СтруктураПолей <> Неопределено 
				И СтруктураПолей.Режим = "Чтение"
				И СтруктураПолей.ЗапросДоГруппировки
				И Прав(Результат, 1) = ")"
				И (Ложь
					Или ИмяПравила = "<Agregate>" 
					Или ИмяПравила = "<Count>")
			Тогда
				// Экранируем агрегатную функцию
				Если Найти(Результат, СловоЯзыкаЗапросовВФорме("COUNT") + "(") = 1 Тогда 
					Результат = "(1)"; 
				Иначе
					Маркер = "(";
					ПозицияСкобки = Найти(Результат, Маркер);
					Результат = "(" + Сред(Результат, ПозицияСкобки + СтрДлина(Маркер)); 
				КонецЕсли; 
				выхНужноПересобратьТокены = Истина;
			КонецЕсли; 
		КонецЕсли;
		Если Истина
			И ИмяПравила = "<CheckValueIn>" 
			И выхЕстьАгрегаты <> Истина
		Тогда
			// https://www.hostedredmine.com/issues/907377
			ПравыйТокен = Данные.Tokens(1).Data.Tokens(0);
			Если ПравыйТокен.Text = "<InExprs>" Тогда
				ЗапрещенаГруппировка = ПравыйТокен.Data.Tokens(1).Data.Tokens(0) <> Неопределено;
			Иначе//Если ПравыйТокен.Text = "<InUnion>" Тогда
				ЗапрещенаГруппировка = Истина;
			КонецЕсли; 
			Если ЗапрещенаГруппировка Тогда
				выхЕстьАгрегаты = "НеГруппируем";
			КонецЕсли; 
		КонецЕсли; 
		Если ИмяПравила = "<Field>" Тогда
			Если выхЕстьАгрегаты = Ложь Тогда
				выхЕстьАгрегаты = "ЕстьПоля"; 
			КонецЕсли; 
			Результат = ПолучитьПолноеИмяПоляВВыражении(Результат, ЗапросПакета, ЧастьОбъединения, СтароеИмяТаблицы, НовоеИмяТаблицы, выхНужноПересобратьТокены, СтруктураПолей);
			Если СтруктураПолей <> Неопределено Тогда 
				Если СтруктураПолей.Режим = "Чтение" Тогда 
					Если Ложь
						Или СтруктураПолей.ЗапросДоГруппировки
						Или Не СтруктураПолей.ЕстьГруппировка
						Или (Истина
							И СтруктураПолей.СобиратьПоляВнеАгрегатов
							И Не СтруктураПолей.ВнутриАгрегата)
					Тогда
						Если Не ЛиТерминалЯзыка(Результат, Истина) Тогда // грязно игнорируем терминалы типа МЕСЯЦ, ДЕНЬ https://www.hostedredmine.com/issues/925042
							ДобавитьПолеВСтруктуруПолей(СтруктураПолей, Результат, Токен);
						КонецЕсли;
					КонецЕсли;
				ИначеЕсли СтруктураПолей.Режим = "ДопискаЗначения" Тогда 
					Если Не ЛиТерминалЯзыка(Результат) Тогда
						ДописатьКВыражениюЕгоЗначение(Результат, СтруктураПолей);
					КонецЕсли; 
				КонецЕсли; 
			КонецЕсли;
		КонецЕсли; 
		Если ИмяПравила = "<Agregate>" Тогда
			Если Истина
				И СтруктураПолей <> Неопределено 
				И СтруктураПолей.Режим = "Чтение"
			Тогда 
				СтруктураПолей.ВнутриАгрегата = Ложь;
				Если Не СтруктураПолей.ЗапросДоГруппировки Тогда
					ДобавитьПолеВСтруктуруПолей(СтруктураПолей, Результат, Токен, Истина);
				КонецЕсли; 
			КонецЕсли; 
		КонецЕсли; 
	КонецЕсли; 
	Возврат Результат;
	
КонецФункции

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

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

// Функция - Получить агрегатную функцию
//
// Параметры:
//  Токен					 - Token {GoldParserForNet.Parser} - 
//  выхТокенАргументаФункции - 	 - 
// 
// Возвращаемое значение:
//   - 
//
Функция ПолучитьАгрегатнуюФункцию(Токен, выхТокенАргументаФункции = Неопределено) Экспорт
	
	Результат = Неопределено;
	Если ТипЗнч(Токен) <> Тип("COMОбъект") Тогда
		Возврат Результат;
	КонецЕсли; 
	Данные = Токен.Data; // Reduction {GoldParserForNet.Parser} 
	Если Данные = Неопределено Тогда
		Возврат Результат;
	КонецЕсли;
	выхТокенАргументаФункции = Токен;
	Если Токен.Kind = 0 Тогда
		КоличествоТокенов = Данные.TokenCount;
		ИмяПравила = Данные.RuleText();
		Если ИмяПравила = "<Brackets>" Тогда
			Результат = ПолучитьАгрегатнуюФункцию(Данные.Tokens(1), выхТокенАргументаФункции);
		ИначеЕсли ИмяПравила = "<Agregate>" Тогда
			ТокенВниз = Данные.Tokens(0); // Token {GoldParserForNet.Parser} 
			Если ТокенВниз.Kind = 1 Тогда
				Результат = ТокенВниз.Name + "(";
				выхТокенАргументаФункции = Данные.Tokens(2);
			Иначе
				Результат = ПолучитьАгрегатнуюФункцию(ТокенВниз, выхТокенАргументаФункции);
			КонецЕсли; 
		ИначеЕсли ИмяПравила = "<Count>" Тогда
			ТокенВниз = Данные.Tokens(КоличествоТокенов - 2); // Token {GoldParserForNet.Parser} 
			//Если ТокенВниз.Kind = 0 Тогда
				Результат = "COUNT" + "(";
				Если КоличествоТокенов = 5 Тогда 
					Результат = Результат + " DISTINCT";
					выхТокенАргументаФункции = Данные.Tokens(3);
				Иначе
					выхТокенАргументаФункции = Данные.Tokens(2);
				КонецЕсли;
			//КонецЕсли;
		ИначеЕсли КоличествоТокенов = 1 Тогда
			Результат = ПолучитьАгрегатнуюФункцию(Данные.Tokens(0), выхТокенАргументаФункции);
		КонецЕсли; 
	КонецЕсли; 
	Возврат Результат;
	
КонецФункции

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

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

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

//.
// Параметры:
//  ФильтрацияАгрегатов - 
//		0 - агрегаты запрещены (условие связи таблиц)
// 		1 - собирать только элементы без агрегатов
//		2 - собирать только элементы с агрегатами
//
Функция СобратьВыражениеЭлементаОтбора(Знач ЭлементОтбора, Знач Отступ = 0, Знач ГруппаИзОдногоЭлемента = Ложь, выхЕстьАгрегаты = Ложь, НастройкиКомпоновки = Неопределено, Знач ФильтрацияАгрегатов = 0,
	БылиДобавленыВнешниеСкобкиЭлемента = Ложь, СтруктураПолей = Неопределено)

	ЕстьАгрегаты = Ложь;
	БылиДобавленыВнешниеСкобкиЭлемента = Ложь; 
	Если Ложь
		Или ТипЗнч(ЭлементОтбора) = Тип("ГруппаЭлементовОтбораКомпоновкиДанных") 
		Или ТипЗнч(ЭлементОтбора) = Тип("ОтборКомпоновкиДанных") 
	Тогда
		Если ГруппаИзОдногоЭлемента Тогда
			ОтступВложенный = Отступ;
		Иначе
			ОтступВложенный = Отступ + 1;
		КонецЕсли; 
		ПредставлениеЭлемента = СобратьВыражениеОтбораКомпоновки(ЭлементОтбора, ОтступВложенный, ФильтрацияАгрегатов, ЕстьАгрегаты, НастройкиКомпоновки, СтруктураПолей);
		Если Истина
			И Не ГруппаИзОдногоЭлемента 
			И ЗначениеЗаполнено(ПредставлениеЭлемента) 
			И ТипЗнч(ЭлементОтбора) = Тип("ГруппаЭлементовОтбораКомпоновкиДанных")
			И ЭлементОтбора.ТипГруппы <> ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаНе
		Тогда
			ПредставлениеЭлемента = "(" + ПредставлениеЭлемента + ")";
			БылиДобавленыВнешниеСкобкиЭлемента = Истина;
		КонецЕсли;
		Если Истина
			И ЗначениеЗаполнено(ПредставлениеЭлемента) 
			И ТипЗнч(ЭлементОтбора) = Тип("ГруппаЭлементовОтбораКомпоновкиДанных")
		Тогда
			выхЕстьАгрегаты = ЕстьАгрегаты;
		КонецЕсли;
	Иначе //! Если ТипЗнч(ЭлементОтбора) = Тип("ЭлементОтбораКомпоновкиДанных") Тогда
		//Если Истина
		//	И СтруктураПолей <> Неопределено
		//	И СтруктураПолей.РазрешитьПроверкуСуществованияТаблиц 
		//	И ЛиЗапрещенныйЭлементОтбора(ЭлементОтбора) 
		//Тогда
		//	ВызватьИсключение "Запрещенная операция сравнения";
		//КонецЕсли;
		Если НастройкиКомпоновки = Неопределено Тогда
			НастройкиКомпоновки = ЭлементыФормы.ЧастиОбъединения.ТекущаяСтрока.Компоновщик.Настройки;
			#Если Сервер И Не Сервер Тогда
			    НастройкиКомпоновки = Новый НастройкиКомпоновкиДанных;
			#КонецЕсли
		КонецЕсли;
		Если ГруппаИзОдногоЭлемента Тогда
			Отступ = Макс(Отступ - 1, 0);
		КонецЕсли; 
		Смещение = ирОбщий.СтрокаПовторомЛкс(Символы.Таб, Отступ);
		Если ЗначениеЗаполнено(ЭлементОтбора.Представление) Тогда
			Представление = ЭлементОтбора.Представление;
			Если ЭлементОтбора.ПравоеЗначение = Неопределено Тогда
				Токен = РазобратьВыражениеЗапроса(Представление);
				ЗаполнитьЭлементОтбораПроизвольногоВыражения(ЭлементОтбора, Токен, Отступ,,, СтруктураПолей);
			КонецЕсли; 
			Если СтруктураПолей <> Неопределено Тогда
				СтруктураПолей.СобиратьПоляВнеАгрегатов = Истина
					И ФильтрацияАгрегатов = 2 
					И ЭлементОтбора.ЛевоеЗначение <> Неопределено;
				ОбновитьВыражениеЗапроса(ЭлементОтбора,,,,,,,,, 0, СтруктураПолей);
				СтруктураПолей.СобиратьПоляВнеАгрегатов = Ложь;
			КонецЕсли; 
			Если Истина
				И СтруктураПолей <> Неопределено
				И СтруктураПолей.Режим = "ДопискаЗначения"
			Тогда
				Если ТипЗнч(ЭлементОтбора.ПравоеЗначение) = Тип("Строка") Тогда
					// Ранее для оптимизации мы не сформировали токен, т.к. выражение очень простое. Возможно правильнее тут будет сформировать токен
					ДописатьКВыражениюЕгоЗначение(Представление, СтруктураПолей);
				Иначе
					Представление = СобратьВыражениеЗапроса(ЭлементОтбора.ПравоеЗначение, Отступ,,,,,,, СтруктураПолей);  
				КонецЕсли; 
			КонецЕсли; 
			ПредставлениеЭлемента = "";
			// 9тюва1в79ап6
			Если ЭлементОтбора.ЛевоеЗначение <> Неопределено Тогда
				выхЕстьАгрегаты = Истина;
			КонецЕсли;
			ирОбщий.ДобавитьМногострочнуюСтрокуВТекстЛкс(ПредставлениеЭлемента, Представление, Смещение);
			//Если Истина
			//	И Не ЛиВыражениеЯвляетсяПолемИлиТерминалом(Представление)
			//	И Не ГруппаИзОдногоЭлемента 
			//Тогда
			//	ПредставлениеЭлемента = "(" + ПредставлениеЭлемента + ")";
			//КонецЕсли; 
		Иначе
			Если ТипЗнч(ЭлементОтбора.ЛевоеЗначение) = Тип("ПолеКомпоновкиДанных") Тогда
				ДоступноеПолеИлиОписаниеТипов = НайтиДоступноеПоле(НастройкиКомпоновки.ДоступныеПоляОтбора, ЭлементОтбора.ЛевоеЗначение);
				Если ДоступноеПолеИлиОписаниеТипов = Неопределено Тогда
					ДоступноеПолеИлиОписаниеТипов = Новый ОписаниеТипов("NULL");
				КонецЕсли;
			Иначе
				МассивТипов = Новый Массив();
				МассивТипов.Добавить(ТипЗнч(ЭлементОтбора.ЛевоеЗначение));
				ДоступноеПолеИлиОписаниеТипов = Новый ОписаниеТипов(МассивТипов);
			КонецЕсли; 
			ПредставлениеЛевогоПоля = ЗначениеОтбораНаЯзыкеЗапросов(ЭлементОтбора.ЛевоеЗначение, СтруктураПолей);
			ПредставлениеЭлемента = ПредставлениеСравненияНаЯзыке(ПредставлениеЛевогоПоля, ЭлементОтбора.ВидСравнения, ДоступноеПолеИлиОписаниеТипов, Отступ + 1);
			Если Истина
				И ЭлементОтбора.ВидСравнения <> ВидСравненияКомпоновкиДанных.Заполнено
				И ЭлементОтбора.ВидСравнения <> ВидСравненияКомпоновкиДанных.НеЗаполнено
			Тогда
				СтрокаПравогоЗначения = "";
				Если ТипЗнч(ЭлементОтбора.ПравоеЗначение) <> Тип("ПолеКомпоновкиДанных") Тогда
					СтрокаПравогоЗначения = ПредставлениеЗначенияВЯзыкеЗапросов(ЭлементОтбора.ПравоеЗначение);
					Если Не ЗначениеЗаполнено(СтрокаПравогоЗначения) Тогда
						XMLТип = СериализаторXDTO.XMLТипЗнч(ЭлементОтбора.ПравоеЗначение);
						Если XMLТип <> Неопределено Тогда
							Если Истина
								И Найти(XMLТип.URIПространстваИмен, "http://v8.1c.ru/8.1/data") > 0
								И Не ирОбщий.СтрокиРавныЛкс(XMLТип.ИмяТипа, "StandardBeginningDate")
							Тогда
								ЗаменитьПравоеЗначениеЭлементаОтбораПараметром(ЭлементОтбора, XMLТип);
							КонецЕсли; 
						КонецЕсли; 
					КонецЕсли; 
				КонецЕсли; 
				Если Не ЗначениеЗаполнено(СтрокаПравогоЗначения) Тогда
					СтрокаПравогоЗначения = ЗначениеОтбораНаЯзыкеЗапросов(ЭлементОтбора.ПравоеЗначение, СтруктураПолей);
				КонецЕсли; 
				Если Ложь
					Или ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Содержит 
					Или ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.НеСодержит
				Тогда
					Если ТипЗнч(ЭлементОтбора.ПравоеЗначение) = Тип("Строка") Тогда
						СтрокаПравогоЗначения = ЗначениеОтбораНаЯзыкеЗапросов("%" + ЭлементОтбора.ПравоеЗначение + "%");
					Иначе
						СтрокаПравогоЗначения = """%"" + " + СтрокаПравогоЗначения + " + ""%""";
					КонецЕсли; 
				ИначеЕсли Истина
					И ирКэш.ДоступныВидыСравненияПодобноШаблонЛкс()
					И (Ложь
						Или ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.НачинаетсяС 
						Или ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.НеНачинаетсяС)
				Тогда
					Если ТипЗнч(ЭлементОтбора.ПравоеЗначение) = Тип("Строка") Тогда
						СтрокаПравогоЗначения = ЗначениеОтбораНаЯзыкеЗапросов(ЭлементОтбора.ПравоеЗначение + "%");
					Иначе
						СтрокаПравогоЗначения = СтрокаПравогоЗначения + " + ""%""";
					КонецЕсли; 
				ИначеЕсли Ложь
					Или ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.ВИерархии
					Или ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.НеВИерархии 
					Или ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.ВСписке 
					Или ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.НеВСписке 
				Тогда
					СтрокаПравогоЗначения = "(" + СтрокаПравогоЗначения + ")";
				КонецЕсли;
				ПредставлениеЭлемента = ПредставлениеЭлемента + " " + СтрокаПравогоЗначения;
			КонецЕсли; 
		КонецЕсли;
	КонецЕсли; 
	Если Истина
		И СтруктураПолей <> Неопределено
		И СтруктураПолей.Режим = "ДопискаЗначения"
	Тогда
		Запрос = Новый Запрос;
		Запрос.Текст = "ВЫБРАТЬ " + ПредставлениеЭлемента;
		Для Каждого СтрокаПараметра Из Параметры Цикл
			Запрос.УстановитьПараметр(СтрокаПараметра.Имя, СтрокаПараметра.Значение);
		КонецЦикла;
		Для Каждого СтрокаПоля Из СтруктураПолей.Поля Цикл
			Если ЗначениеЗаполнено(СтрокаПоля.Имя) Тогда
				ИмяПодмены = "ЗначениеПоля" + СтрокаПоля.Имя;
				Запрос.УстановитьПараметр(ИмяПодмены, СтрокаПоля.РасшифровкаЗначение);
				Запрос.Текст = СтрЗаменить(Запрос.Текст, СтрокаПоля.Определение, "&" + ИмяПодмены); 
			ИначеЕсли ирОбщий.СтрНачинаетсяСЛкс(СтрокаПоля.Определение, "&") Тогда 
				Запрос.УстановитьПараметр(Сред(СтрокаПоля.Определение, 2), СтрокаПоля.РасшифровкаЗначение);
			КонецЕсли;
		КонецЦикла;
		Попытка
			ЛогическийРезультат = ЗначениеОтбораНаЯзыкеЗапросов(Запрос.Выполнить().Выгрузить()[0][0]);  
		Исключение
			// Обращение к догруппировочным полям таблиц в стадии после группировки
			ОписаниеОшибки = ОписаниеОшибки(); // Для отладки
			ЛогическийРезультат = ПредставлениеЭлемента;
		КонецПопытки; 
		Если Не ирОбщий.СтрокиРавныЛкс(ПредставлениеЭлемента, ЛогическийРезультат) Тогда
			ПредставлениеЭлемента = "{" + ЛогическийРезультат + "} " + ПредставлениеЭлемента;
		КонецЕсли;
	КонецЕсли; 
	Возврат ПредставлениеЭлемента;

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

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

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

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

Функция НейтральныйОперандЛогическогоОператора(Знач ЭтоОператорИ = Истина)
	
	Если ЭтоОператорИ Тогда
		Если мПараметрыДиалектаSQL.Это1С Тогда
			Результат = СловоЯзыкаЗапросовВФорме("TRUE");
		Иначе
			Результат = "0 = 0";
		КонецЕсли; 
	Иначе //Если ИмяПравила = "<OrExpr>" Тогда
		Если мПараметрыДиалектаSQL.Это1С Тогда
			Результат = СловоЯзыкаЗапросовВФорме("FALSE");
		Иначе
			Результат = "0 = 1";
		КонецЕсли; 
	КонецЕсли;
	Возврат Результат;

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

// Функция - Разобрать выражение запроса
//
// Параметры:
//  ВыражениеЗапроса	 - 	 - 
//  ЗаменятьПустоеНаNULL - 	 - 
// 
// Возвращаемое значение:
//  Token {GoldParserForNet.Parser}
//
Функция РазобратьВыражениеЗапроса(ВыражениеЗапроса, ЗаменятьПустоеНаNULL = Истина) Экспорт
	
	ТекстДляРазбора = УстановитьВыражениеДляРазбораВСлужебноеПоле(ВыражениеЗапроса, ЗаменятьПустоеНаNULL);
	НачальныйТокен = РазобратьТекстЗапроса(ТекстДляРазбора, , Ложь, СлужебноеПолеТекстаДолгое);   // Здесь важно получать полное, а не сокращенное дерево
	Если НачальныйТокен = Неопределено Тогда
		ВызватьИсключение "Ошибка синтаксического разбора выражения """ + ВыражениеЗапроса + """";
	КонецЕсли; 
	//НачальныйТокен = НачальныйТокен.Data.Tokens(0).Data.Tokens(0).Data.Tokens(0).Data.Tokens(0).Data.Tokens(3).Data.Tokens(0).Data.Tokens(1); // При ВЫБРАТЬ
	Результат = НачальныйТокен.Data.Tokens(0).Data.Tokens(0).Data.Tokens(5).Data.Tokens(0).Data.Tokens(1).Data.Tokens(1); // При UPDATE <UpdateRoot>
	Возврат Результат;
	
КонецФункции

Функция УстановитьВыражениеДляРазбораВСлужебноеПоле(ВыражениеЗапроса, Знач ЗаменятьПустоеНаNULL = Истина)
	
	Если Не ЗначениеЗаполнено(ВыражениеЗапроса) И ЗаменятьПустоеНаNULL Тогда
		ВыражениеЗапроса = "NULL";
	КонецЕсли; 
	//ТекстДляРазбора = "ВЫБРАТЬ " + Символы.ПС + ВыражениеЗапроса + " КАК _";
	ТекстДляРазбора = "UPDATE _ SET _ = " + Символы.ПС + ВыражениеЗапроса;
	СлужебноеПолеТекстаДолгое.УстановитьТекст(ТекстДляРазбора);
	Возврат ТекстДляРазбора;

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

Функция ДобавитьЧастьОбъединения(ЗапросПакета = Неопределено, Позиция = Неопределено)

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

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

Функция ДобавитьЗапросПакета(Пакет = Неопределено, Позиция = Неопределено)

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

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

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

Функция ИмяБезКвадратныхСкобок(Имя)
	
	Результат = Имя;
	Если Лев(Результат, 1) = "[" Тогда
		Результат = Сред(Результат, 2, СтрДлина(Результат) - 2);
	КонецЕсли; 
	Возврат Результат;
	
КонецФункции

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

Функция ОпуститьсяДоПервогоЗначимогоТокена(Токен)

	Если Токен.Kind = 0 Тогда
		Возврат Токен;
	КонецЕсли; 
	Данные = Токен.Data; // Reduction {GoldParserForNet.Parser} 
	ИмяПравила = Данные.RuleText();
	Если ИмяПравила = "<Brackets>" Тогда
		ЗначимыйТокен = ОпуститьсяДоПервогоЗначимогоТокена(Данные.Tokens(1));
		Возврат ЗначимыйТокен;
	ИначеЕсли Данные.TokenCount > 1  Тогда
		Возврат Токен;
	Иначе
		ПервыйТокен = Данные.Tokens(0); // Token {GoldParserForNet.Parser} 
		Если ПервыйТокен.Kind <> 0 Тогда
			Возврат Токен;
		Иначе
			Возврат ОпуститьсяДоПервогоЗначимогоТокена(ПервыйТокен);
		КонецЕсли; 
	КонецЕсли;
	
КонецФункции

// Процедура - Построить дерево логического выражения
//
// Параметры:
//  ГруппаОтбора	 - 	 - 
//  Токен			 - Token {GoldParserForNet.Parser} - 
//  ЗапросПакета	 - 	 - 
//  ЧастьОбъединения - 	 - 
//
Процедура ПостроитьДеревоЛогическогоВыражения(ГруппаОтбора, Токен, ЗапросПакета = Неопределено, ЧастьОбъединения = Неопределено)

	#Если Сервер И Не Сервер Тогда
	    ОтборКомпоновки1 = Новый НастройкиКомпоновкиДанных;
		ГруппаОтбора = ОтборКомпоновки1.Отбор; // ГруппаЭлементовОтбораКомпоновкиДанных
	#КонецЕсли
	Если Токен = Неопределено Тогда
		Возврат;
	КонецЕсли; 
	Если Токен.Kind = 1 Тогда
		ИмяТокена = Токен.Name;
		Если ТипЗнч(ГруппаОтбора) = Тип("ГруппаЭлементовОтбораКомпоновкиДанных") Тогда
			ТипГруппы = ГруппаОтбора.ТипГруппы; 
		Иначе
			ТипГруппы = ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаИ;
		КонецЕсли;
		Если Ложь
			Или (Истина
				И ТипГруппы = ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаИли
				И ИмяТокена = "FALSE")
			Или (Истина
				И ТипГруппы <> ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаИли
				И ТипЗнч(ГруппаОтбора) = Тип("ГруппаЭлементовОтбораКомпоновкиДанных") // На корневом уровне оставляем ИСТИНА
				И ИмяТокена = "TRUE")
		Тогда
			Возврат;
		КонецЕсли; 
		ЭлементОтбора = ГруппаОтбора.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
		ЭлементОтбора.ПравоеЗначение = Токен;
		Если Ложь
			Или ИмяТокена = "TRUE"
			Или ИмяТокена = "FALSE"
		Тогда
			ЭлементОтбора.Представление = СловоЯзыкаЗапросовВФорме(ИмяТокена);
		Иначе
			ВыражениеТокена = Токен.Data;
			ЭлементОтбора.Представление = ВыражениеТокена;
			Если Токен.text = "<Parameter>" Тогда
				ПроверитьДобавитьПараметр(ВыражениеТокена);
			КонецЕсли; 
		КонецЕсли; 
		Возврат;
	КонецЕсли; 
	Данные = Токен.Data; // Reduction {GoldParserForNet.Parser} 
	Если Данные.TokenCount = 0 Тогда
		Возврат;
	ИначеЕсли Данные.TokenCount = 1 Тогда
		ПостроитьДеревоЛогическогоВыражения(ГруппаОтбора, Данные.Tokens(0), ЗапросПакета, ЧастьОбъединения);
	Иначе
		ИмяПравила = Данные.RuleText();
		Если ИмяПравила = "<OrExpr>" Тогда
			Если Истина
				И ТипЗнч(ГруппаОтбора) = Тип("ГруппаЭлементовОтбораКомпоновкиДанных") 
				И ГруппаОтбора.ТипГруппы = ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаИли
			Тогда
				ГруппаИли = ГруппаОтбора;
			Иначе
				ГруппаИли = ГруппаОтбора.Элементы.Добавить(Тип("ГруппаЭлементовОтбораКомпоновкиДанных"));
				ГруппаИли.ТипГруппы = ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаИли;
			КонецЕсли; 
			ПостроитьДеревоЛогическогоВыражения(ГруппаИли, Данные.Tokens(0), ЗапросПакета, ЧастьОбъединения);
			ПостроитьДеревоЛогическогоВыражения(ГруппаИли, Данные.Tokens(2), ЗапросПакета, ЧастьОбъединения);
		ИначеЕсли ИмяПравила = "<AndExpr>" Тогда
			Если Истина
				И ТипЗнч(ГруппаОтбора) = Тип("ГруппаЭлементовОтбораКомпоновкиДанных") 
				И ГруппаОтбора.ТипГруппы = ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаИли
			Тогда
				ГруппаИ = ГруппаОтбора.Элементы.Добавить(Тип("ГруппаЭлементовОтбораКомпоновкиДанных"));
				ГруппаИ.ТипГруппы = ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаИ;
			Иначе
				ГруппаИ = ГруппаОтбора;
			КонецЕсли; 
			ПостроитьДеревоЛогическогоВыражения(ГруппаИ, Данные.Tokens(0), ЗапросПакета, ЧастьОбъединения);
			ПостроитьДеревоЛогическогоВыражения(ГруппаИ, Данные.Tokens(2), ЗапросПакета, ЧастьОбъединения);
		ИначеЕсли ИмяПравила = "<NotExpr>" Тогда
			ГруппаИ = ГруппаОтбора.Элементы.Добавить(Тип("ГруппаЭлементовОтбораКомпоновкиДанных"));
			ГруппаИ.ТипГруппы = ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаНе;
			ПостроитьДеревоЛогическогоВыражения(ГруппаИ, Данные.Tokens(1), ЗапросПакета, ЧастьОбъединения)
		ИначеЕсли Ложь
			Или ИмяПравила = "<CheckNULL>"
			Или ИмяПравила = "<CheckNotNULL>"
			Или ИмяПравила = "<CheckValueIn>"
			Или ИмяПравила = "<CompareExpr>"
			Или ИмяПравила = "<CheckLIKE>"
			//Или ИмяПравила = "<CheckExpr>"
		Тогда
			ЭлементОтбора = ГруппаОтбора.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
			ЛевоеЗначение = ПолучитьТерминОтбораКомпоновкиИзДанныхТокена(Данные.Tokens(0), ЗапросПакета, ЧастьОбъединения);
			Если ЛевоеЗначение = Null Тогда
				ЗаполнитьЭлементОтбораПроизвольногоВыражения(ЭлементОтбора, Токен, , ЧастьОбъединения, ЗапросПакета);
			//ИначеЕсли ИмяПравила = "<CheckNULL>" Тогда
			//	ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.НеЗаполнено;
			//ИначеЕсли ИмяПравила = "<CheckNotNULL>" Тогда
			//	ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Заполнено;
			Иначе
				Если ИмяПравила = "<CheckValueIn>" Тогда
					ПравыйТокен = Данные.Tokens(1).Data.Tokens(0);
					Отрицание = ПравыйТокен.Data.Tokens(0).Data.Tokens(0).Name = "NOT";
					ТокенИерархии = ПравыйТокен.Data.Tokens(1);
					Если ПравыйТокен.Text = "<InExprs>" Тогда
						ПравыйТокен = ПравыйТокен.Data.Tokens(3);
					Иначе//Если ПравыйТокен.Text = "<InUnion>" Тогда
						ПравыйТокен = ПравыйТокен.Data.Tokens(2);
					КонецЕсли; 
				//ИначеЕсли ИмяПравила = "<CompareExpr>" Тогда
				//	ПравыйТокен = Данные.Tokens(2);
				//ИначеЕсли ИмяПравила = "<CheckExpr>" Тогда
				//	ПравыйТокен = Данные.Tokens(3);
				Иначе
					ПравыйТокен = Данные.Tokens(2);
				КонецЕсли; 
				ПравоеЗначение = ПолучитьТерминОтбораКомпоновкиИзДанныхТокена(ПравыйТокен, ЗапросПакета, ЧастьОбъединения);
				Если ИмяПравила = "<CompareExpr>" Тогда
					ОператорСравнения = Данные.Tokens(1).Data;
					Если Истина
						И ТипЗнч(ЛевоеЗначение) <> Тип("ПолеКомпоновкиДанных")
						И ТипЗнч(ПравоеЗначение) = Тип("ПолеКомпоновкиДанных")
						И (Ложь
							Или ОператорСравнения = "=" 
							Или ОператорСравнения = "<>")
					Тогда
						БуферЗначения = ЛевоеЗначение;
						ЛевоеЗначение = ПравоеЗначение;
						ПравоеЗначение = БуферЗначения;
					КонецЕсли; 
				КонецЕсли; 
				ЭлементОтбора.ПравоеЗначение = ПравоеЗначение;
				ЭлементОтбора.ЛевоеЗначение = ЛевоеЗначение;
				Если Ложь
					Или ТипЗнч(ЛевоеЗначение) <> Тип("ПолеКомпоновкиДанных") 
					Или ПравоеЗначение = Null 
				Тогда
					ЗаполнитьЭлементОтбораПроизвольногоВыражения(ЭлементОтбора, Токен, , ЧастьОбъединения, ЗапросПакета);
				ИначеЕсли ИмяПравила = "<CompareExpr>" Тогда
					Если ОператорСравнения = "=" Тогда
						лВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
					ИначеЕсли ОператорСравнения = "<>" Тогда
						лВидСравнения = ВидСравненияКомпоновкиДанных.НеРавно;
					ИначеЕсли ОператорСравнения = ">" Тогда
						лВидСравнения = ВидСравненияКомпоновкиДанных.Больше;
					ИначеЕсли ОператорСравнения = "<" Тогда
						лВидСравнения = ВидСравненияКомпоновкиДанных.Меньше;
					ИначеЕсли ОператорСравнения = "<=" Тогда
						лВидСравнения = ВидСравненияКомпоновкиДанных.МеньшеИлиРавно;
					ИначеЕсли ОператорСравнения = ">=" Тогда
						лВидСравнения = ВидСравненияКомпоновкиДанных.БольшеИлиРавно;
					Иначе
						ВызватьИсключение "Неизвестный вид сравнения """ + ОператорСравнения + """";
					КонецЕсли; 
					ЭлементОтбора.ВидСравнения = лВидСравнения;
				ИначеЕсли ИмяПравила = "<CheckLIKE>" Тогда
					Если Истина
						И Лев(ПравоеЗначение, 1) = "%"
						И Прав(ПравоеЗначение, 1) = "%"
					Тогда
						ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Содержит;
						ЭлементОтбора.ПравоеЗначение = Сред(ПравоеЗначение, 2, СтрДлина(ПравоеЗначение) - 2);
					ИначеЕсли Истина
						И ирКэш.ДоступныВидыСравненияПодобноШаблонЛкс()
						И Прав(ПравоеЗначение, 1) = "%"
					Тогда
						ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.НачинаетсяС;
						ЭлементОтбора.ПравоеЗначение = Сред(ПравоеЗначение, 1, СтрДлина(ПравоеЗначение) - 1);
					ИначеЕсли ирКэш.ДоступныВидыСравненияПодобноШаблонЛкс() Тогда
						ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Подобно;
						ЭлементОтбора.ПравоеЗначение = ПравоеЗначение;
					Иначе
						ЗаполнитьЭлементОтбораПроизвольногоВыражения(ЭлементОтбора, Токен, , ЧастьОбъединения, ЗапросПакета);
					КонецЕсли; 
				ИначеЕсли ИмяПравила = "<CheckValueIn>" Тогда
					Если ТокенИерархии.Data.Tokens(0) = Неопределено Тогда
						Если Отрицание Тогда
							НовыйВидСравнения = ВидСравненияКомпоновкиДанных.НеВСписке;
						Иначе 
							НовыйВидСравнения = ВидСравненияКомпоновкиДанных.ВСписке;
						КонецЕсли;
					Иначе
						Если Отрицание Тогда
							НовыйВидСравнения = ВидСравненияКомпоновкиДанных.НеВИерархии;
						Иначе 
							НовыйВидСравнения = ВидСравненияКомпоновкиДанных.ВИерархии;
						КонецЕсли;
					КонецЕсли; 
					ЭлементОтбора.ВидСравнения = НовыйВидСравнения;
				КонецЕсли; 
			КонецЕсли;
		ИначеЕсли ИмяПравила = "<Brackets>" Тогда
			//Если Истина
			//	И ТипЗнч(ГруппаОтбора) = Тип("ГруппаЭлементовОтбораКомпоновкиДанных") 
			//	И ГруппаОтбора.ТипГруппы = ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаИли
			//Тогда
			//	ГруппаИ = ГруппаОтбора.Элементы.Добавить(Тип("ГруппаЭлементовОтбораКомпоновкиДанных"));
			//	ГруппаИ.ТипГруппы = ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаИ;
			//Иначе
			//	ГруппаИ = ГруппаОтбора;
			//КонецЕсли; 
			ПостроитьДеревоЛогическогоВыражения(ГруппаОтбора, Данные.Tokens(1), ЗапросПакета, ЧастьОбъединения);
		Иначе
			ЭлементОтбора = ГруппаОтбора.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
			ЗначимыйТокен = ОпуститьсяДоПервогоЗначимогоТокена(Токен);
			//ЕстьАгрегаты = Ложь;
			//ВыражениеЭлемента = СобратьВыражениеЗапроса(ЗначимыйТокен,, ЗапросПакета, ЧастьОбъединения,,, ЕстьАгрегаты);
			//ОбновитьЭлементОтбораПроизвольногоВыражения(ЕстьАгрегаты, ВыражениеЭлемента, Токен, ЭлементОтбора);
			ЗаполнитьЭлементОтбораПроизвольногоВыражения(ЭлементОтбора, ЗначимыйТокен,, ЧастьОбъединения, ЗапросПакета);
		КонецЕсли; 
	КонецЕсли; 
	
КонецПроцедуры

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

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

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

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

// Параметры:
//   ЛиСобратьПакет - Булево, *Неопределено - собирать пакет, иначе только текущего запроса пакета
//
Функция СобратьПолныйТекст(Смещение = "", ЛиСобратьПакет = Неопределено, СтруктураПолей = Неопределено) Экспорт 
	
	Если ЛиСобратьПакет = Неопределено Тогда
		ЛиСобратьПакет = ПолеТекстаОтображаетПакет;
	КонецЕсли; 
	ЗакончитьРедактированиеСвязанныхПолей();
	Если ЛиСобратьПакет Тогда
		мНомерТекущейСтрокиВСобранномТексте = 0;
		Текст = СобратьТекстПакета(,, СтруктураПолей);
		//Если Смещение = "" И ЗапросыПакета.Количество() > 1 Тогда
		//	Текст = "//" + мМаркерСлужебногоКомментария + "Текст собран конструктором из подсистемы ""Инструменты разработчика"" (http://devtool1c.ucoz.ru), который сохраняет звездочки и комментарии.
		//	|" + Текст;
		//КонецЕсли; 
	Иначе
		Состояние("Сборка текста запроса пакета...");
		Текст = СобратьТекстЗапросаПакета(,, СтруктураПолей);
	КонецЕсли; 
	Состояние();
	Возврат Текст;
	
КонецФункции

Функция СобратьТекстПакета(Пакет = Неопределено, Смещение = "", СтруктураПолей = Неопределено)

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

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

Функция СобратьТекстЗапросаПакета(ЗапросПакета = Неопределено, Смещение = "", СтруктураПолей = Неопределено) Экспорт 

	Если ЗапросПакета = Неопределено Тогда
		//ЗапросПакета = ЭлементыФормы.ЗапросыПакета.ТекущаяСтрока;
		ЗапросПакета = мТекущийЗапросПакета;
	КонецЕсли; 
	Если СтруктураПолей = Неопределено Тогда
		СтруктураПолей = НоваяСтруктураОбработкиПолей();
	КонецЕсли; 
	СтруктураПолей.РазрешитьНормализациюИмен = Истина;
	Результат = "";
	Если ЗапросПакета.ТипЗапроса = 2 Тогда
		// DROP
		Результат = Результат + ПолучитьКомментарийДляВставки(ЗапросПакета.Комментарий, Смещение);
		Если ЗначениеЗаполнено(Результат) Тогда
			Результат = Результат + Смещение;
		КонецЕсли; 
		Результат = Результат + СловоЯзыкаЗапросовВФорме("DROP") + " ";
		Если Не ПараметрыДиалектаSQL.INTOбезTABLE Тогда
			Результат = Результат + СловоЯзыкаЗапросовВФорме("TABLE") + " ";
		КонецЕсли; 
		Результат = Результат + ЗапросПакета.ИмяОсновнойТаблицы;
		Возврат Результат;
	ИначеЕсли ЗапросПакета.ТипЗапроса = 6 Тогда
		// TRUNCATE
		Результат = Результат + ПолучитьКомментарийДляВставки(ЗапросПакета.Комментарий, Смещение);
		Если ЗначениеЗаполнено(Результат) Тогда
			Результат = Результат + Смещение;
		КонецЕсли; 
		Результат = Результат + СловоЯзыкаЗапросовВФорме("TRUNCATE") + " ";
		Если Не ПараметрыДиалектаSQL.INTOбезTABLE Тогда
			Результат = Результат + СловоЯзыкаЗапросовВФорме("TABLE") + " ";
		КонецЕсли; 
		Результат = Результат + ЗапросПакета.ИмяОсновнойТаблицы;
		Возврат Результат;
	ИначеЕсли ЗапросПакета.ТипЗапроса = 3 Тогда
		// INSERT
		Результат = Результат + ПолучитьКомментарийДляВставки(ЗапросПакета.Комментарий, Смещение);
		Если ЗначениеЗаполнено(Результат) Тогда
			Результат = Результат + Смещение;
		КонецЕсли; 
		ТекстПринимающиеПоля = "";
		ТекстВыраженияЗначений = "";
		Для Каждого ПринимающееПоле Из ЗапросПакета.ПринимающиеПоля Цикл
			Если ТекстПринимающиеПоля <> "" Тогда
				ТекстПринимающиеПоля = ТекстПринимающиеПоля + ", ";
				ТекстВыраженияЗначений = ТекстВыраженияЗначений + "," + Смещение + Символы.Таб;
			КонецЕсли; 
			ТекстПринимающиеПоля = ТекстПринимающиеПоля + ПринимающееПоле.Поля;
			Если Не ЗапросПакета.ЗначенияИзВыборки Тогда
				ВыражениеПоля = ОбновитьВыражениеЗапроса(ПринимающееПоле,,,,,,,,, 0);
				ТекстВыраженияЗначений = ТекстВыраженияЗначений + ВыражениеПоля;
				ТекстВыраженияЗначений = ТекстВыраженияЗначений + " " + ПолучитьКомментарийДляВставки(ПринимающееПоле.Поля, Смещение + Символы.Таб);
			КонецЕсли; 
		КонецЦикла;
		Результат = Результат + "INSERT INTO " + ЗапросПакета.ИмяОсновнойТаблицы;
		Если ЗначениеЗаполнено(ЗапросПакета.УровеньИзоляции) Тогда
			Результат = Результат + " WITH(" + ЗапросПакета.УровеньИзоляции + ")";
		КонецЕсли; 
		Результат = Результат + " (" + ТекстПринимающиеПоля + ")" + Символы.ПС;
		Если Не ЗапросПакета.ЗначенияИзВыборки Тогда
			Результат = Результат + "VALUES (" + ТекстВыраженияЗначений + ")";
			Возврат Результат;
		КонецЕсли; 
	ИначеЕсли ЗапросПакета.ТипЗапроса = 4 Тогда
		// UPDATE
		ЧастьОбъединения = ЗапросПакета.ЧастиОбъединения[0];
		Результат = Результат + ПолучитьКомментарийДляВставки(ЧастьОбъединения.Комментарий, Смещение);
		Если ЗначениеЗаполнено(Результат) Тогда
			Результат = Результат + Смещение;
		КонецЕсли; 
		ТекстПринимающиеПоля = "";
		Для Каждого ПринимающееПоле Из ЗапросПакета.ПринимающиеПоля Цикл
			Если ТекстПринимающиеПоля <> "" Тогда
				ТекстПринимающиеПоля = ТекстПринимающиеПоля + "," + Символы.ПС + Смещение + Символы.Таб;
			КонецЕсли; 
			ТекстПринимающиеПоля = ТекстПринимающиеПоля + ПринимающееПоле.Поля + " = ";
			ТекстПринимающиеПоля = ТекстПринимающиеПоля + ОбновитьВыражениеЗапроса(ПринимающееПоле,,,,,,,,, 0);
		КонецЦикла;
		Если ТекстПринимающиеПоля <> "" Тогда
			Результат = Результат + "UPDATE " + ЗапросПакета.ИмяОсновнойТаблицы;
			Если ЗначениеЗаполнено(ЗапросПакета.УровеньИзоляции) Тогда
				Результат = Результат + " WITH(" + ЗапросПакета.УровеньИзоляции + ")";
			КонецЕсли; 
			Результат = Результат + " SET " + Символы.ПС + Смещение + Символы.Таб + ТекстПринимающиеПоля;
		КонецЕсли; 
		ТекстИЗ = СобратьТекстИЗ(ЗапросПакета, ЧастьОбъединения, Смещение);
		Результат = Результат + ТекстИЗ;
		ТекстУсловия = СобратьВыражениеОтбораКомпоновки(ЧастьОбъединения.Компоновщик.Настройки.Отбор, 1,,, ЧастьОбъединения.Компоновщик.Настройки);
		ДобавитьТекстОтбора(Результат, Смещение, ТекстУсловия, ЧастьОбъединения);
		Возврат Результат;
	ИначеЕсли ЗапросПакета.ТипЗапроса = 5 Тогда
		// DELETE
		ЧастьОбъединения = ЗапросПакета.ЧастиОбъединения[0];
		Результат = Результат + ПолучитьКомментарийДляВставки(ЧастьОбъединения.Комментарий, Смещение);
		Если ЗначениеЗаполнено(Результат) Тогда
			Результат = Результат + Смещение;
		КонецЕсли; 
		Результат = Результат + "DELETE FROM " + ЗапросПакета.ИмяОсновнойТаблицы;
		Если ЗначениеЗаполнено(ЗапросПакета.УровеньИзоляции) Тогда
			Результат = Результат + " WITH(" + ЗапросПакета.УровеньИзоляции + ")";
		КонецЕсли; 
		ТекстИЗ = СобратьТекстИЗ(ЗапросПакета, ЧастьОбъединения, Смещение);
		Результат = Результат + ТекстИЗ;
		ТекстУсловия = СобратьВыражениеОтбораКомпоновки(ЧастьОбъединения.Компоновщик.Настройки.Отбор, 1,,, ЧастьОбъединения.Компоновщик.Настройки);
		ДобавитьТекстОтбора(Результат, Смещение, ТекстУсловия, ЧастьОбъединения);
		Возврат Результат;
	КонецЕсли; 
	
	ТекстОбъединения = "";
	Для Каждого ЧастьОбъединения Из ЗапросПакета.ЧастиОбъединения Цикл
		СтруктураПолей.СоответствиеПолей.Очистить(); // Иначе Автодополнение состава группировок будет использовать общие поля для всех объединений
		ТекстЧасти = СобратьТекстЧастиОбъединения(ЗапросПакета, ЧастьОбъединения, Смещение, ЗапросПакета.ЧастиОбъединения.Количество() > 1, СтруктураПолей);
		Если ТекстОбъединения <> "" Тогда
			ТекстОбъединения = ТекстОбъединения + "
			|" + Смещение + СловоЯзыкаЗапросовВФорме("UNION");
			Если Не ЧастьОбъединения.БезДублей Тогда
				ТекстОбъединения = ТекстОбъединения + " " + СловоЯзыкаЗапросовВФорме("ALL");
			КонецЕсли; 
			ТекстОбъединения = ТекстОбъединения + Символы.ПС + Смещение;
		КонецЕсли; 
		Если ЧастьОбъединения.РучноеИмя Тогда
			ТекстОбъединения = ТекстОбъединения + ПараметрыДиалектаSQL.СтрочныйКомментарий + мПлатформа.мМаркерИмениЧастиОбъединения + ЧастьОбъединения.Имя + " " 
				+ ирОбщий.СтрокаПовторомЛкс(ПараметрыДиалектаSQL.СтрочныйКомментарий, 20);
			ТекстОбъединения = ТекстОбъединения + Символы.ПС + Смещение;
		КонецЕсли; 
		ТекстОбъединения = ТекстОбъединения + ТекстЧасти;
	КонецЦикла;
	Если ЗначениеЗаполнено(ТекстОбъединения) Тогда
		Результат = Результат + ТекстОбъединения;
	КонецЕсли; 
	
	// ORDER BY
	СтруктураПолей.ДоступныВыбранныеПоля = Истина;
	ТекстПорядок = "";
	Для Каждого ЭлементПорядка Из ЗапросПакета.ПоляПорядка Цикл
		Если ТекстПорядок <> "" Тогда
			ТекстПорядок = ТекстПорядок + "," + Символы.ПС + Смещение + Символы.Таб;
		КонецЕсли; 
		ТекстПорядок = ТекстПорядок + ПолучитьКомментарийДляВставки(ЭлементПорядка.Комментарий, Смещение + Символы.Таб);
		ТекстВыражения = ОбновитьВыражениеЗапроса(ЭлементПорядка, ЭлементыФормы.ПоляПорядка, ЗапросПакета,,,,,,, 0, СтруктураПолей);
		ТекстПорядок = ТекстПорядок + ТекстВыражения;
		Если ЭлементПорядка.Иерархия Тогда
			ТекстПорядок = ТекстПорядок + " " + СловоЯзыкаЗапросовВФорме("HIERARCHYON");
		КонецЕсли; 
		Если ЭлементПорядка.Направление = НаправлениеСортировки.Убыв Тогда
			ТекстПорядок = ТекстПорядок + " " + СловоЯзыкаЗапросовВФорме("DESC");
		КонецЕсли; 
	КонецЦикла;
	Если ТекстПорядок <> "" Тогда
		Результат = Результат + Символы.ПС + Смещение + СловоЯзыкаЗапросовВФорме("ORDER") + " " + СловоЯзыкаЗапросовВФорме("BY") 
			+ Символы.ПС + Смещение + Символы.Таб + ТекстПорядок;
	КонецЕсли; 
	
	Если Не РежимКомпоновкиДанных Тогда
		ДобавитьТекстПредложенияПостроителя(Результат, СловоЯзыкаЗапросовВФорме("ORDER") + " " + СловоЯзыкаЗапросовВФорме("BY"),
			ЗапросПакета.ПоляПорядкаПостроителя, ЭлементыФормы.ПоляПорядкаПостроителя, ЗапросПакета, , Смещение);
	ИначеЕсли ЗапросПакета.ПоляПорядкаПостроителя.Количество() > 0 Тогда 
		ирОбщий.СообщитьЛкс("Удалена запрещенная в режиме компоновки секция УПОРЯДОЧИТЬ");
	КонецЕсли;
	
	Если ПараметрыДиалектаSQL.INTOпослеORDER Тогда
		Если ирОбщий.СтрокиРавныЛкс(ЗапросПакета.ТипЗапроса, 1) Тогда
			Результат = Результат + Символы.ПС + Смещение + СловоЯзыкаЗапросовВФорме("INTO") + " ";
			Если Не ПараметрыДиалектаSQL.INTOбезTABLE Тогда
				Результат = Результат + СловоЯзыкаЗапросовВФорме("TABLE") + " ";
			КонецЕсли; 
			Результат = Результат + ЗапросПакета.ИмяОсновнойТаблицы;
		КонецЕсли; 
	КонецЕсли; 
	
	Если ЗапросПакета.ТипЗапроса = 1 Тогда
		// INDEX BY
		СтруктураПолей.РазрешитьНормализациюИмен = Ложь;
		ТекстИндекс = "";
		Для Каждого ЭлементИндекса Из ЗапросПакета.ПоляИндекса Цикл
			Если ТекстИндекс <> "" Тогда
				ТекстИндекс = ТекстИндекс + "," + Символы.ПС + Смещение + Символы.Таб;
			КонецЕсли; 
			ТекстИндекс = ТекстИндекс + ПолучитьКомментарийДляВставки(ЭлементИндекса.Комментарий, Смещение + Символы.Таб);
			ТекстВыражения = ОбновитьВыражениеПоляСсылкиНаВыбранноеПоле(ЗапросПакета, СтруктураПолей, ЧастьОбъединения, ЭлементИндекса, ЭлементыФормы.ПоляИндекса);
			ТекстИндекс = ТекстИндекс + ТекстВыражения;
		КонецЦикла;
		Если ТекстИндекс <> "" Тогда
			Результат = Результат + Символы.ПС + Смещение + СловоЯзыкаЗапросовВФорме("INDEX") 
				+ " " + СловоЯзыкаЗапросовВФорме("BY") + Символы.ПС + Смещение + Символы.Таб + ТекстИндекс;
		КонецЕсли; 
	КонецЕсли; 
	
	Если ЗапросПакета.ТипЗапроса = 0 И Не РежимКомпоновкиДанных Тогда
		// TOTALS
		СтруктураПолей.РазрешитьНормализациюИмен = Истина;
		ТекстГруппирующиеПоля = "";
		Если ЗапросПакета.ОпцияОбщиеИтоги Тогда
			ТекстГруппирующиеПоля = ТекстГруппирующиеПоля + СловоЯзыкаЗапросовВФорме("OVERALL");
		КонецЕсли; 
		Для Каждого СтрокаПоля Из ЗапросПакета.ГруппирующиеПоляИтогов Цикл
			Если ТекстГруппирующиеПоля <> "" Тогда
				ТекстГруппирующиеПоля = ТекстГруппирующиеПоля + "," + Символы.ПС + Смещение + Символы.Таб;
			КонецЕсли; 
			ТекстГруппирующиеПоля = ТекстГруппирующиеПоля + ПолучитьКомментарийДляВставки(СтрокаПоля.Комментарий, Смещение + Символы.Таб);
			ТекстВыражения = ОбновитьВыражениеЗапроса(СтрокаПоля, ЭлементыФормы.ГруппирующиеПоляИтогов, ЗапросПакета,,,,,,, 0, СтруктураПолей);
			ТекстГруппирующиеПоля = ТекстГруппирующиеПоля + ТекстВыражения;
			Если Истина
				И ПараметрыДиалектаSQL.МногоТаблиц
				И ЗначениеЗаполнено(СтрокаПоля.Имя) 
			Тогда
				ТекстГруппирующиеПоля = ТекстГруппирующиеПоля + " " + СловоЯзыкаЗапросовВФорме("AS") + " " + ИмяСНеобходимымиСкобками(СтрокаПоля.Имя);
			КонецЕсли; 
			Если ирОбщий.СтрокиРавныЛкс(СтрокаПоля.ТипИтогов, "Иерархия") Тогда
				ТекстГруппирующиеПоля = ТекстГруппирующиеПоля + " " + СловоЯзыкаЗапросовВФорме("HIERARCHYON");
			ИначеЕсли ирОбщий.СтрокиРавныЛкс(СтрокаПоля.ТипИтогов, "ТолькоИерархия") Тогда
				ТекстГруппирующиеПоля = ТекстГруппирующиеПоля + " " + СловоЯзыкаЗапросовВФорме("ONLY") + " " + СловоЯзыкаЗапросовВФорме("HIERARCHYON");
			Иначе
				ТекстГруппирующиеПоля = ТекстГруппирующиеПоля + " " + СтрокаПоля.ТипИтогов; // Грязно
			КонецЕсли; 
		КонецЦикла;
		ТекстИтоговыеПоля = "";
		Для Каждого СтрокаПоля Из ЗапросПакета.ГруппируемыеПоляИтогов Цикл
			Если ТекстИтоговыеПоля <> "" Тогда
				ТекстИтоговыеПоля = ТекстИтоговыеПоля  + "," + Символы.ПС + Смещение + Символы.Таб;
			КонецЕсли; 
			ТекстИтоговыеПоля = ТекстИтоговыеПоля + ПолучитьКомментарийДляВставки(СтрокаПоля.Комментарий, Смещение + Символы.Таб);
			ТекстВыражения = ОбновитьВыражениеЗапроса(СтрокаПоля, ЭлементыФормы.ГруппируемыеПоляИтогов, ЗапросПакета,,,,,,, 0, СтруктураПолей);
			ТекстИтоговыеПоля = ТекстИтоговыеПоля + ТекстВыражения;
			Если Истина
				И ПараметрыДиалектаSQL.МногоТаблиц 
				И ЗначениеЗаполнено(СтрокаПоля.Имя) 
			Тогда
				ТекстИтоговыеПоля = ТекстИтоговыеПоля + " " + СловоЯзыкаЗапросовВФорме("AS") + " " + ИмяСНеобходимымиСкобками(СтрокаПоля.Имя);
			КонецЕсли; 
		КонецЦикла;
		Если Ложь
			Или ТекстГруппирующиеПоля <> ""
			Или ТекстИтоговыеПоля <> ""
		Тогда
			Результат = Результат + Символы.ПС + Смещение + СловоЯзыкаЗапросовВФорме("TOTALS");
			Если ЗначениеЗаполнено(ТекстИтоговыеПоля) Тогда
				Результат = Результат + Символы.ПС + Смещение + Символы.Таб + ТекстИтоговыеПоля;
			КонецЕсли; 
			Результат = Результат + Символы.ПС + Смещение + СловоЯзыкаЗапросовВФорме("BY");
			Если ЗначениеЗаполнено(ТекстГруппирующиеПоля) Тогда
				Результат = Результат + Символы.ПС + Смещение + Символы.Таб + ТекстГруппирующиеПоля;
			КонецЕсли; 
		КонецЕсли; 
		СтруктураПолей.ДоступныВыбранныеПоля = Ложь;
		ДобавитьТекстПредложенияПостроителя(Результат, СловоЯзыкаЗапросовВФорме("TOTALS") + " " + СловоЯзыкаЗапросовВФорме("BY"),
			ЗапросПакета.ПоляИтоговПостроителя, ЭлементыФормы.ПоляИтоговПостроителя, ЗапросПакета, , Смещение);
	ИначеЕсли Ложь
		Или ЗапросПакета.ГруппирующиеПоляИтогов.Количество() > 0
		Или ЗапросПакета.ГруппируемыеПоляИтогов.Количество() > 0
		Или ЗапросПакета.ПоляИтоговПостроителя.Количество() > 0
	Тогда 
		ирОбщий.СообщитьЛкс("Удалена запрещенная в режиме компоновки секция ИТОГИ");
	КонецЕсли; 
	Если ЗапросПакета.ОпцияПервые Тогда
		Результат = Результат + Символы.ПС + Смещение + СловоЯзыкаЗапросовВФорме("LIMIT") + " " + XMLСтрока(ЗапросПакета.ПервыеКоличество);
	КонецЕсли; 
	Если Истина
		И ПараметрыДиалектаSQL.Это1С
		И ЗапросПакета.ОпцияАвтоупорядочивание 
	Тогда
		Результат = Результат + Символы.ПС + Смещение + СловоЯзыкаЗапросовВФорме("AUTOORDER");
	КонецЕсли; 

	//Если ЗначениеЗаполнено(ЗапросПакета.ТекстРасширения) Тогда
	//	Результат = Результат + Символы.ПС + "{" + ЗапросПакета.ТекстРасширения + "}";
	//КонецЕсли; 
	
	Возврат Результат;

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

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

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

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

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

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

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

Функция ПолучитьОбновитьВыражениеПоляПостроителя(ПолеПостроителя, ТабличноеПоле = Неопределено, Знач ЗапросПакета, Знач ЧастьОбъединения = Неопределено)

	ТекстВыражения = ОбновитьВыражениеЗапроса(ПолеПостроителя, ТабличноеПоле, ЗапросПакета, ЧастьОбъединения,,,,,, 0);
	Если ПолеПостроителя.ИспользоватьДочерние Тогда
		Если Истина
			И Лев(ТекстВыражения, 1) <> "(" 
			И Не ЛиВыражениеЯвляетсяПолемИлиТерминалом(ТекстВыражения)
		Тогда
			ТекстВыражения = "(" + ТекстВыражения + ")";
		КонецЕсли; 
		ТекстВыражения = ТекстВыражения + ".*";
	КонецЕсли; 
	Возврат ТекстВыражения;

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

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

Функция СобратьТекстЧастиОбъединения(ЗапросПакета = Неопределено, ЧастьОбъединения = Неопределено, Смещение = "", Знач РазвернутьАвтополя = Ложь, Знач СтруктураПолей = Неопределено)

	Если ЗапросПакета = Неопределено Тогда
		//ЗапросПакета = ЭлементыФормы.ЗапросыПакета.ТекущаяСтрока;
		ЗапросПакета = мТекущийЗапросПакета;
	КонецЕсли; 
	Если ЧастьОбъединения = Неопределено Тогда
		//ЧастьОбъединения = ЭлементыФормы.ЧастиОбъединения.ТекущаяСтрока;
		ЧастьОбъединения = мТекущаяЧастьОбъединения;
	КонецЕсли; 
	Результат = "";
	Если СтруктураПолей = Неопределено Тогда
		СтруктураПолей = НоваяСтруктураОбработкиПолей();
	КонецЕсли; 
	СтруктураПолей.ЕстьГруппировка = Ложь
		Или ЕстьАгрегатыВЧастиОбъединения(ЧастьОбъединения)
		Или ЧастьОбъединения.Группировки.Количество() > 0;
	РазвернутьАвтополя = РазвернутьАвтополя Или СтруктураПолей.ЕстьГруппировка;
	Если СтруктураПолей.РазрешитьПроверкуСуществованияТаблиц Тогда
		// В СобратьВыражениеОтбора() не передается табличное поле и оно не выбрасывает исключения.
		ОбновитьВыраженияОтбора(ЧастьОбъединения.Компоновщик.Настройки.Отбор, ЭлементыФормы.ДеревоУсловия, ЗапросПакета, ЧастьОбъединения,,,, СтруктураПолей);
	КонецЕсли; 
	
	// SELECT
	Результат = Результат + ПолучитьКомментарийДляВставки(ЧастьОбъединения.Комментарий, Смещение);
	Если ЗначениеЗаполнено(Результат) Тогда
		Результат = Результат + Смещение;
	КонецЕсли; 
	Результат = Результат + СловоЯзыкаЗапросовВФорме("SELECT");
	Если ЧастьОбъединения = ЗапросПакета.ЧастиОбъединения[0] Тогда
		Если Истина
			И ПараметрыДиалектаSQL.Это1С
			И ЗапросПакета.ОпцияРазрешенные 
		Тогда
			Результат = Результат + " " + СловоЯзыкаЗапросовВФорме("ALLOWED");
		КонецЕсли; 
	КонецЕсли; 
	Если ЧастьОбъединения.ОпцияРазличные Тогда
		Результат = Результат + " " + СловоЯзыкаЗапросовВФорме("DISTINCT");
	КонецЕсли; 
	Если ЧастьОбъединения.ОпцияПервые Тогда
		Результат = Результат + " " + СловоЯзыкаЗапросовВФорме("TOP") + " " + XMLСтрока(ЧастьОбъединения.ПервыеКоличество);
	КонецЕсли; 
	ТекстПоляВыбора = "";
	ДобавленныеТаблицыВсеПоля = Новый Массив();
	ИндексПоля = 0;
	Для Каждого СтрокаПоляОбъединения Из ЗапросПакета.ПоляОбъединения Цикл
		ВыбранноеПоле = ЧастьОбъединения.ВыбранныеПоля.Найти(СтрокаПоляОбъединения["_" + ЧастьОбъединения.Номер], "ИД");
		Если ЗапросПакета.ТипЗапроса = 3 Тогда
			ПсевдонимПоля = ЗапросПакета.ПринимающиеПоля[ИндексПоля].Поля;
		Иначе
			ПсевдонимПоля = СтрокаПоляОбъединения.Имя;
			Если Не мПараметрыДиалектаSQL.Это1С И Не ирОбщий.ЛиИмяПеременнойЛкс(ПсевдонимПоля) Тогда
				ПсевдонимПоля = "[" + ПсевдонимПоля + "]";
			КонецЕсли; 
		КонецЕсли;
		Если ВыбранноеПоле <> Неопределено Тогда
			Если ВыбранноеПоле.Автополе И СтруктураПолей.ЕстьГруппировка Тогда 
				Если ЭтоЗапрещенныйТипЗначенияПоляДляГруппировки(ВыбранноеПоле.ТипЗначения) Тогда
					Продолжить;
				КонецЕсли; 
			КонецЕсли; 
			СтруктураПолей.СобиратьПоляВнеАгрегатов = ВыбранноеПоле.ЕстьАгрегаты = Истина;
		КонецЕсли; 
		ТекстКомментария = "";
		Если ВыбранноеПоле = Неопределено Тогда
			ТекстВыражения = СловоЯзыкаЗапросовВФорме("NULL");
		ИначеЕсли ВыбранноеПоле.Автополе И Не РазвернутьАвтополя И мПараметрыДиалектаSQL.МногоТаблиц Тогда
			ПсевдонимПоля = "";
			ИмяТаблицы = ирОбщий.ПервыйФрагментЛкс(ВыбранноеПоле.Определение);
			Если Истина
				И ЧастьОбъединения.ВыбранныеТаблицы.Количество() = 1
				//И Лев(ЧастьОбъединения.ВыбранныеТаблицы[0].ПолноеИмя, 1) = "&"
			Тогда
				// Чтобы потом в консоли запросов не было ошибки при вызове НайтиПараметры https://partners.v8.1c.ru/forum/t/1626426/m/1781150
				ТекстВыражения = "*";
			Иначе
				ТекстВыражения = ИмяТаблицы + ".*";
			КонецЕсли; 
			КлючТаблицы = НРег(ИмяТаблицы);
			Если ДобавленныеТаблицыВсеПоля.Найти(КлючТаблицы) = Неопределено Тогда
				ДобавленныеТаблицыВсеПоля.Добавить(КлючТаблицы);
			Иначе
				Продолжить;
			КонецЕсли; 
		Иначе
			ТекстВыражения = ОбновитьВыражениеЗапроса(ВыбранноеПоле, ЭлементыФормы.ВыбранныеПоля, ЗапросПакета, ЧастьОбъединения,,,,,, 0, СтруктураПолей);
			Если Истина
				И СтруктураПолей.ЕстьГруппировка 
				И ВыбранноеПоле.ЕстьАгрегаты = "ЕстьПоля" 
				И СтруктураПолей.Режим = "Чтение"
			Тогда
				ДобавитьПолеВСтруктуруПолей(СтруктураПолей, ТекстВыражения);
			КонецЕсли; 
			Если Не ЗначениеЗаполнено(ТекстВыражения) Тогда
				ТекстВыражения = "NULL";
			КонецЕсли; 
			ТекстКомментария = ПолучитьКомментарийДляВставки(ВыбранноеПоле.Комментарий, Смещение + Символы.Таб);
		КонецЕсли; 
		Если ТекстПоляВыбора <> "" Тогда
			ТекстПоляВыбора = ТекстПоляВыбора + "," + Символы.ПС + Смещение + Символы.Таб;
		КонецЕсли; 
		ТекстПоляВыбора = ТекстПоляВыбора + ТекстКомментария;
		ирОбщий.ДобавитьМногострочнуюСтрокуВТекстЛкс(ТекстПоляВыбора, ТекстВыражения, Смещение + Символы.Таб);
		Если ПараметрыДиалектаSQL.МногоТаблиц И ЗначениеЗаполнено(ПсевдонимПоля) Тогда
			ТекстПоляВыбора = ТекстПоляВыбора + " " + СловоЯзыкаЗапросовВФорме("AS") + " " + ПсевдонимПоля;
		КонецЕсли;
		ИндексПоля = ИндексПоля + 1;
	КонецЦикла;
	Если Не РазвернутьАвтополя И мПараметрыДиалектаSQL.МногоТаблиц Тогда
		Для Каждого СтрокаВыбраннойТаблицы Из ЧастьОбъединения.ВыбранныеТаблицы.НайтиСтроки(Новый Структура("ВсеПоля", Истина)) Цикл
			Если ДобавленныеТаблицыВсеПоля.Найти(СтрокаВыбраннойТаблицы.НИмя) = Неопределено Тогда
				Если ТекстПоляВыбора <> "" Тогда
					ТекстПоляВыбора = ТекстПоляВыбора + "," + Символы.ПС + Смещение + Символы.Таб;
				КонецЕсли; 
				Если ЧастьОбъединения.ВыбранныеТаблицы.Количество() = 1 Тогда
					ТекстВыражения = "*";
				Иначе
					ТекстВыражения = СтрокаВыбраннойТаблицы.Имя + ".*";
				КонецЕсли; 
				ирОбщий.ДобавитьМногострочнуюСтрокуВТекстЛкс(ТекстПоляВыбора, ТекстВыражения, Смещение + Символы.Таб);
			КонецЕсли; 
		КонецЦикла;
		Если Не ЗначениеЗаполнено(ТекстПоляВыбора) Тогда
			ТекстПоляВыбора = "*";
		КонецЕсли; 
	КонецЕсли; 
	Результат = Результат + Символы.ПС + Смещение + Символы.Таб + ТекстПоляВыбора;
	
	ДобавитьТекстПредложенияПостроителя(Результат, СловоЯзыкаЗапросовВФорме("SELECT"),
		ЧастьОбъединения.ПоляВыбораПостроителя, ЭлементыФормы.ПоляВыбораПостроителя, ЗапросПакета, ЧастьОбъединения, Смещение);
		
	Если Не ПараметрыДиалектаSQL.INTOпослеORDER Тогда
		Если ЧастьОбъединения = ЗапросПакета.ЧастиОбъединения[0] Тогда
			Если ЗапросПакета.ТипЗапроса = 1 Тогда // Создание временной таблицы
				Результат = Результат + Символы.ПС + Смещение + СловоЯзыкаЗапросовВФорме("INTO") + " ";
				Если Не ПараметрыДиалектаSQL.INTOбезTABLE Тогда
					Результат = Результат + СловоЯзыкаЗапросовВФорме("TABLE") + " ";
				КонецЕсли; 
				Результат = Результат + ПолноеИмяВременнойТаблицы(ЗапросПакета.ИмяОсновнойТаблицы, ИсточникДанных1С);
			КонецЕсли; 
		КонецЕсли; 
	КонецЕсли; 
	
	Если СтруктураПолей.Режим = "ГлобальнаяЗамена" Тогда
		//! СтруктураПолей.Вставить("СтароеИмя");
		//! СтруктураПолей.Вставить("НовоеИмя");
		Для Каждого СтрокаВыбраннойТаблицы Из ЧастьОбъединения.ВыбранныеТаблицы Цикл
			Если ирОбщий.СтрокиРавныЛкс(СтрокаВыбраннойТаблицы.ПолноеИмя, СтруктураПолей.СтароеИмя) Тогда
				СтрокаВыбраннойТаблицы.ПолноеИмя = СтруктураПолей.НовоеИмя;
				СтруктураПолей.КоличествоОбнаружено = СтруктураПолей.КоличествоОбнаружено + 1;
			КонецЕсли; 
		КонецЦикла;
	КонецЕсли; 
	ТекстИЗ = СобратьТекстИЗ(ЗапросПакета, ЧастьОбъединения, Смещение, СтруктураПолей);
	Результат = Результат + ТекстИЗ;
	
	// WHERE
	СтруктураПолей.СобиратьПоляВнеАгрегатов = Ложь;
	ТекстУсловия = СобратьВыражениеОтбораКомпоновки(ЧастьОбъединения.Компоновщик.Настройки.Отбор, 1, 1,, ЧастьОбъединения.Компоновщик.Настройки, СтруктураПолей);
	ДобавитьТекстОтбора(Результат, Смещение, ТекстУсловия, ЧастьОбъединения);
	СтруктураПолей.СобиратьПоляВнеАгрегатов = Истина;
	
	// HAVING
	ТекстУсловияПослеГруппировки = СобратьВыражениеОтбораКомпоновки(ЧастьОбъединения.Компоновщик.Настройки.Отбор, 1, 2,, ЧастьОбъединения.Компоновщик.Настройки, СтруктураПолей);
	
	ДобавитьТекстПредложенияПостроителя(Результат, СловоЯзыкаЗапросовВФорме("WHERE"),
		ЧастьОбъединения.ПоляОтбораПостроителя, ЭлементыФормы.ПоляОтбораПостроителя, ЗапросПакета, ЧастьОбъединения, Смещение);
	
	// GROUP BY
	ТекстГруппировки = "";
	КопияГруппировок = Неопределено;
	Если Истина
		И ЧастьОбъединения.Автогруппировки 
		И СтруктураПолей.ЕстьГруппировка
		И ЧастьОбъединения.Группировки.Количество() > 0 
	Тогда
		КопияГруппировок = ЧастьОбъединения.Группировки.Скопировать();
		ЧастьОбъединения.Группировки.Очистить();
	КонецЕсли; 
	Если Истина
		И СтруктураПолей.ЕстьГруппировка 
		//И СтруктураПолей.Режим <> "ДопискаЗначения" 
	Тогда
		Для Каждого СтрокаПоля Из СтруктураПолей.СоответствиеПолей Цикл
			Если СтрокаПоля.ЭтоАгрегат Тогда
				Продолжить;
			КонецЕсли; 
			Группировка = ЧастьОбъединения.Группировки.Найти(СтрокаПоля.Ключ, "НОпределение");
			Если Группировка = Неопределено Тогда
				Группировка = ЧастьОбъединения.Группировки.Добавить();
				Группировка.Определение = СтрокаПоля.Значение;
				Группировка.Токен = СтрокаПоля.Токен; // !Опасно
				ирОбщий.ОбновитьКопиюСвойстваВНижнемРегистреЛкс(Группировка, "Определение");
			КонецЕсли; 
			Если КопияГруппировок <> Неопределено Тогда
				СтрокаКопииГруппировки = КопияГруппировок.Найти(СтрокаПоля.Ключ, "НОпределение");
				Если СтрокаКопииГруппировки <> Неопределено Тогда
					Группировка.Комментарий = СтрокаКопииГруппировки.Комментарий;
				КонецЕсли; 
			КонецЕсли; 
		КонецЦикла;
	КонецЕсли; 
	Для Каждого Группировка Из ЧастьОбъединения.Группировки Цикл
		Если ТекстГруппировки <> "" Тогда
			ТекстГруппировки = ТекстГруппировки + "," + Символы.ПС + Смещение + Символы.Таб;
		КонецЕсли; 
		ТекстГруппировки = ТекстГруппировки + ПолучитьКомментарийДляВставки(Группировка.Комментарий, Смещение + Символы.Таб);
		ТекстВыражения = ОбновитьВыражениеЗапроса(Группировка, ЭлементыФормы.Группировки, ЗапросПакета, ЧастьОбъединения,,,,,, 0, СтруктураПолей);
		ирОбщий.ДобавитьМногострочнуюСтрокуВТекстЛкс(ТекстГруппировки, ТекстВыражения, Смещение + Символы.Таб);
	КонецЦикла;
	Если ТекстГруппировки <> "" Тогда
		Результат = Результат + Символы.ПС + Смещение + СловоЯзыкаЗапросовВФорме("GROUP") 
			+ " " + СловоЯзыкаЗапросовВФорме("BY") + Символы.ПС + Смещение + Символы.Таб + ТекстГруппировки;
	КонецЕсли; 
	
	Если ТекстУсловияПослеГруппировки <> "" Тогда
		Результат = Результат + Символы.ПС + Смещение + СловоЯзыкаЗапросовВФорме("HAVING");
		Если ИерархическийСтильЛогическихВыражений Тогда
			Результат = Результат + " ";
		Иначе
			Результат = Результат + Символы.ПС + Смещение + Символы.Таб;
		КонецЕсли; 
		ирОбщий.ДобавитьМногострочнуюСтрокуВТекстЛкс(Результат, ТекстУсловияПослеГруппировки, Смещение);
	КонецЕсли; 
	
	Если ЧастьОбъединения.ОпцияДляИзменения Тогда
		Результат = Результат + Символы.ПС + Смещение + СловоЯзыкаЗапросовВФорме("FOR") + " " + СловоЯзыкаЗапросовВФорме("UPDATE");
		ТекстТаблицДляИзменения = "";
		Для Каждого СтрокаВыбраннойТаблицы Из ЧастьОбъединения.ВыбранныеТаблицы.НайтиСтроки(Новый Структура("ДляИзменения", Истина)) Цикл
			Если ТекстТаблицДляИзменения <> "" Тогда
				ТекстТаблицДляИзменения = ТекстТаблицДляИзменения + ",";
			КонецЕсли; 
			ТекстТаблицДляИзменения = ТекстТаблицДляИзменения + Символы.ПС + Смещение + Символы.Таб + СтрокаВыбраннойТаблицы.ПолноеИмя;
		КонецЦикла;
		Результат = Результат + ТекстТаблицДляИзменения;
	КонецЕсли;
		
	//Порядок отладки
	ТекстПорядокОтладки = "";
	Для Каждого ЭлементПорядка Из ЧастьОбъединения.ПоляПорядкаОтладки Цикл
		Если ТекстПорядокОтладки <> "" Тогда
			ТекстПорядокОтладки = ТекстПорядокОтладки + ", ";
		КонецЕсли; 
		//ТекстВыражения = ОбновитьВыражениеЗапроса(ЭлементПорядка, ЭлементыФормы.ПоляПорядкаОтладки, ЗапросПакета, ЧастьОбъединения,,,,, Ложь, 0, СтруктураПолей);
		ТекстВыражения = "" + ЭлементПорядка.Определение;
		ТекстПорядокОтладки = ТекстПорядокОтладки + ТекстВыражения;
		Если ЭлементПорядка.Направление = НаправлениеСортировки.Убыв Тогда
			ТекстПорядокОтладки = ТекстПорядокОтладки + " " + СловоЯзыкаЗапросовВФорме("DESC");
		КонецЕсли; 
	КонецЦикла;
	Если ТекстПорядокОтладки <> "" Тогда
		Если Истина
			И ПараметрыДиалектаSQL.Это1С
			И ЧастьОбъединения.ОпцияАвтоупорядочиваниеОтладки 
		Тогда
			ТекстПорядокОтладки = ТекстПорядокОтладки + " " + СловоЯзыкаЗапросовВФорме("AUTOORDER");
		КонецЕсли; 
		Результат = Результат + Символы.ПС + Смещение + ПараметрыДиалектаSQL.СтрочныйКомментарий + мМаркерПорядкаОтладки + ТекстПорядокОтладки;
	КонецЕсли; 
	
	//Если ЗначениеЗаполнено(ЧастьОбъединения.ТекстРасширения) Тогда
	//	Результат = Результат + Символы.ПС + "{" + ЧастьОбъединения.ТекстРасширения + "}";
	//КонецЕсли; 
	
	Возврат Результат;

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

Функция ЭтоЗапрещенныйТипЗначенияПоляДляГруппировки(Знач ТипЗначения)
	
	Возврат ирОбщий.ЛиОписаниеТиповНеограниченнойДлиныЛкс(ТипЗначения);

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

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

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

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

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

// Текст FROM
Функция СобратьТекстИЗ(ЗапросПакета = Неопределено, ЧастьОбъединения = Неопределено, Знач Смещение = "", СтруктураПолей = Неопределено)

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

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

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

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

Функция ЗакончитьРедактированиеСвязанныхПолей(РазрешитьДобавлениеАвтополей = Истина)

	СохранитьЗапросПакета(РазрешитьДобавлениеАвтополей);
	Возврат Неопределено;

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

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

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

Функция ДобавитьДоступнуюТаблицуВВыбранные(СтрокаДоступнойТаблицы, ПроверятьУникальность = Ложь)

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

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

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

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

Функция ЭтоВыборкаИзТаблицыПараметра()
	
	Возврат Истина
		И ВыбранныеТаблицы.Количество() > 0
		И Лев(ВыбранныеТаблицы[0].ПолноеИмя, 1) = "&";

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

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

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

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

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

// Функция - Добавить доступное поле в таблицу выражений
//
// Параметры:
//  СтрокаДоступногоПоля			 - ДоступноеПолеКомпоновкиДанных, ДоступноеПолеОтбораКомпоновкиДанных, см. ДоступныеВыбранныеПоляЧасти[0]  - 
//  ТабличноеПолеИлиТаблицаВыражений - 	 - 
//  ЗапросПакета					 - 	 - 
//  ЧастьОбъединения				 - 	 - 
//  СдвигИндексаПослеДобавления		 - 	 - 
//  ИмяСвойстваИсточникаНеКомпоновки - 	 - 
//  ИмяКлючаПриемника				 - 	 - 
//  СвойстваНового					 - 	 - 
//  КонтролироватьУникальность		 - 	 - 
//  ИмяСвойстваИмениПриемника		 - 	 - 
//  ЗапретитьНегруппируемыеТипы		 - 	 - 
// 
// Возвращаемое значение:
//   - 
//
Функция ДобавитьДоступноеПолеВТаблицуВыражений(СтрокаДоступногоПоля, ТабличноеПолеИлиТаблицаВыражений, ЗапросПакета = Неопределено, ЧастьОбъединения = Неопределено,
	СдвигИндексаПослеДобавления = 0, ИмяСвойстваИсточникаНеКомпоновки = "Имя", ИмяКлючаПриемника = "Определение", СвойстваНового = Неопределено, КонтролироватьУникальность = Истина,
	ИмяСвойстваИмениПриемника = "Имя", ЗапретитьНегруппируемыеТипы = Истина)

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

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

// Процедура - Добавить доступное поле с дочерними в выбранные поля
//
// Параметры:
//  СтрокаДоступногоПоля		 - ДоступноеПолеКомпоновкиДанных - 
//  Автополе					 - 	 - 
//  ЗапросПакета				 - 	 - 
//  ЧастьОбъединения			 - 	 - 
//  СдвигИндексаПослеДобавления	 - 	 - 
//  КонтролироватьУникальность	 - 	 - 
//  ОбновитьПоляОбъединения		 - 	 - 
//
Процедура ДобавитьДоступноеПолеСДочернимиВВыбранныеПоля(СтрокаДоступногоПоля, Автополе = Ложь, ЗапросПакета = Неопределено,
	ЧастьОбъединения = Неопределено, СдвигИндексаПослеДобавления = 0, КонтролироватьУникальность = Ложь, ОбновитьПоляОбъединения = Истина)

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

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

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

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

Функция ДобавитьДоступноеПолеВВыбранныеПоля(Знач СтрокаДоступногоПоля, Знач Автополе = Ложь, Знач ЗапросПакета = Неопределено, Знач ЧастьОбъединения = Неопределено,
	Знач СдвигИндексаПослеДобавления = 0, Знач КонтролироватьУникальность = Ложь, Знач ОбновитьПоляОбъединения = Истина)

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

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

Функция ПолучитьАвтоПсевдонимПоля(СтрокаПоля, _ЧастьОбъединения = Неопределено, СчетчикБезымянныхПолей = Неопределено)

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

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

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

Функция ПанельЧастиОбновитьТекущуюСтраницу()

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

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

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

Процедура ОбновитьКомпоновщикПроверкиУсловияСвязи()
	
	КомпоновщикПроверкиУсловияСвязи.Инициализировать(мТекущаяЧастьОбъединения.ИсточникНастроек);

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

Процедура ПересобратьВременныйТекстЧасти()

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

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

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

Функция ОбновитьКомпоновщикЧастиОбъединения(ЧастьОбъединения = Неопределено, Принудительно = Истина)

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

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

Функция МаркерПоляФункцииТипЗначения()
	
	Возврат "_ТипЗначения";

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

Функция МаркерПоляФункцииЧастиДат()
	
	Возврат ".ЧастиДат.";

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

Функция МаркерПоляФункцииДатыКонца()
	
	Возврат ".ДатыКонца.";

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

Функция МаркерПоляФункцииДатыНачала()
	
	Возврат ".ДатыНачала.";

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

Функция ЭтоИмяПериода(Имя)
	
	Результат = Ложь
		Или Имя = "Год"
		Или Имя = "Месяц"
		Или Имя = "Неделя"
		Или Имя = "День"
		Или Имя = "Час"
		Или Имя = "Минута"
		//Или Имя = "Секунда"
		Или Имя = "НачалоГода"
		Или Имя = "НачалоМесяца"
		Или Имя = "НачалоНедели"
		Или Имя = "НачалоДня"
		Или Имя = "НачалоЧаса"
		Или Имя = "НачалоМинуты"
		Или Имя = "КонецГода"
		Или Имя = "КонецМесяца"
		Или Имя = "КонецНедели"
		Или Имя = "КонецДня"
		Или Имя = "КонецЧаса"
		Или Имя = "КонецМинуты"
		;
	Возврат Результат;
	
КонецФункции

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

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

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

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

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

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

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

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

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

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

Функция КлючХраненияПоследнихВыбранных()
	
	Возврат ДиалектSQL + ?(мПараметрыДиалектаSQL.Это1С И ЗначениеЗаполнено(ИсточникДанных1С), "-" + ИсточникДанных1С, "");

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

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

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

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

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

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

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

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

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

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

КонецФункции // ВычислитьВФорме()

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

Процедура ЗаполнитьДоступныеТаблицы1С()

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

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

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

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

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

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

Функция ПриВыводеСтрокиДоступныхТаблицСвязи(ОформлениеСтроки, ДанныеСтроки)

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

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

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

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

Процедура ВыборПравойТаблицыСвязиПриВыводеСтроки(Элемент, ОформлениеСтроки, ДанныеСтроки) Экспорт
	
	ПриВыводеСтрокиДоступныхТаблицСвязи(ОформлениеСтроки, ДанныеСтроки);
	ВыбранныеТаблицыПриВыводеСтроки(Элемент, ОформлениеСтроки, ДанныеСтроки);

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

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

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

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

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

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

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

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

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

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

Процедура ПриУстановкеПравойТаблицыСвязи()
	
	// Надо раскрыть ветвь ее доступных полей
	
КонецПроцедуры

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

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

Процедура ПриИзмененииВыраженияВыбранногоПоля(ВыбранноеПоле = Неопределено, ЗапросПакета = Неопределено, ЧастьОбъединения = Неопределено,
	ОбновитьПоляОбъединения = Истина)

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

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

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

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

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

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

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

Процедура ЗагрузитьВыражениеУсловияСвязи()

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Процедура ЗагрузитьВыбранноеПоле()

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

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

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

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

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

// .
//
// Параметры:
//  ВыражениеИлиТокен	 - Token {GoldParserForNet.Parser} - 
//  ЧастьОбъединения	 - 	 - 
//  Глубокое			 - 	 - Булево, *Ложь - вычислять на полную глубину, по умолчанию отключено для ускорения
// 
// Возвращаемое значение:
//   - 
//
Функция ТипЗначенияВыражения(ВыражениеИлиТокен, ЧастьОбъединения = Неопределено, Глубокое = Ложь)

	Если ЧастьОбъединения = Неопределено Тогда
		//ЧастьОбъединения = ЭлементыФормы.ЧастиОбъединения.ТекущаяСтрока;
		ЧастьОбъединения = мТекущаяЧастьОбъединения;
	КонецЕсли;
	Если ТипЗнч(ВыражениеИлиТокен) = Тип("Строка") Тогда
		Токен = РазобратьВыражениеЗапроса(ВыражениеИлиТокен);
	Иначе
		Токен = ВыражениеИлиТокен;
	КонецЕсли; 
	Если ТипЗнч(Токен) = Тип("COMОбъект") Тогда
		Если Токен.Kind = 0 Тогда 
			ДанныеТокена = Токен.Data; // Reduction {GoldParserForNet.Parser}   
			ИмяПравила = ДанныеТокена.RuleText();
			Если ИмяПравила = "<Field>" Тогда
				Попытка
					//ПолноеИмяПоля = ПолучитьТекстИзТокена(Токен);
					ПолноеИмяПоля = СобратьВыражениеЗапроса(Токен,,, ЧастьОбъединения);
				Исключение
					// Нельзя допускать выброс исключения при логической ошибке в выражении поля, т.к. могут возникнуть многократные и даже циклические интерактивные эффекты
					ПолноеИмяПоля = Неопределено;
				КонецПопытки; 
				Если ПолноеИмяПоля = Неопределено <> Неопределено Тогда
					ДоступноеПоле = НайтиДоступноеПоле(ЧастьОбъединения.Компоновщик.Настройки.ДоступныеПоляВыбора, ПолноеИмяПоля);
					Если ДоступноеПоле <> Неопределено Тогда
						Результат = ДоступноеПоле.ТипЗначения;
					КонецЕсли; 
				КонецЕсли; 
			ИначеЕсли ИмяПравила = "<Parameter>" Тогда
				ПолноеИмяПоля = ДанныеТокена.Item(0).Data;
				ДоступноеПоле = НайтиДоступноеПоле(ЧастьОбъединения.Компоновщик.Настройки.ДоступныеПоляВыбора, ПолноеИмяПоля);
				Если ДоступноеПоле <> Неопределено Тогда
					Результат = ДоступноеПоле.ТипЗначения;
				КонецЕсли; 
			ИначеЕсли Ложь
				Или ИмяПравила = "<Datetime>"
				Или ИмяПравила = "<DateAdd>"
				Или ИмяПравила = "<BeginOfPeriod>"
				Или ИмяПравила = "<EndOfPeriod>"
			Тогда
				Результат = Новый ОписаниеТипов("Дата");
			ИначеЕсли Ложь
				Или ИмяПравила = "<Substring>"
			Тогда
				Результат = Новый ОписаниеТипов("Строка",,,, Новый КвалификаторыСтроки(1000)); // Квалификатор задаем чтобы в группировках участвовать могло
			ИначеЕсли Ложь
				Или ИмяПравила = "<DateDiff>"
				Или ИмяПравила = "<Count>" 
				Или ИмяПравила = "<ZeroFunc>" И ДанныеТокена.Tokens(0).Data.Tokens(0).Name = "RECORDAUTONUMBER" 
			Тогда
				Результат = Новый ОписаниеТипов("Число");
			ИначеЕсли ИмяПравила = "<Cast>" Тогда
				Результат = ПолучитьТипФункцииCast(ДанныеТокена.Tokens(4), ЧастьОбъединения);
			ИначеЕсли Ложь
				Или ИмяПравила = "<Type>"
				Или ИмяПравила = "<ValueType>"
			Тогда
				Результат = Новый ОписаниеТипов("Тип");
			ИначеЕсли ИмяПравила = "<Meaning>" Тогда
				ПолноеИмяПредопределенного = СобратьВыражениеЗапроса(ДанныеТокена.Tokens(2));
				Фрагменты = ирОбщий.СтрРазделитьЛкс(ПолноеИмяПредопределенного);
				Фрагменты.Удалить(Фрагменты.ВГраница());
				ИмяСсылочногоТипа = ирОбщий.СтрСоединитьЛкс(Фрагменты, ".");
				Если Фрагменты.Количество() = 2 Тогда
					ИмяСсылочногоТипа = ирОбщий.ИмяТипаИзПолногоИмениТаблицыБДЛкс(ИмяСсылочногоТипа);
				КонецЕсли; 
				Попытка
					Результат = Новый ОписаниеТипов(ИмяСсылочногоТипа);
				Исключение
				КонецПопытки;
			ИначеЕсли ИмяПравила = "<Round>" Тогда 
				Результат = Новый ОписаниеТипов("Число",,, Новый КвалификаторыЧисла(0));
			ИначеЕсли ИмяПравила = "<MonoFunc>" Тогда 
				ИмяФункции = ДанныеТокена.Tokens(0).Data.Tokens(0).Name;
				Если Ложь
					Или ИмяФункции = "ASIN"
					Или ИмяФункции = "ATAN"
					Или ИмяФункции = "COS"
					Или ИмяФункции = "DATASIZE"
					Или ИмяФункции = "DAY" 
					Или ИмяФункции = "DAYOFYEAR" 
					Или ИмяФункции = "EXP"
					Или ИмяФункции = "HALFYEAR"
					Или ИмяФункции = "HOUR"
					Или ИмяФункции = "LOG"
					Или ИмяФункции = "MINUTE"
					Или ИмяФункции = "MONTH"
					Или ИмяФункции = "QUARTER"
					Или ИмяФункции = "SIN"
					Или ИмяФункции = "STRINGLENGTH"
					Или ИмяФункции = "SQRT"
					Или ИмяФункции = "TAN"
					Или ИмяФункции = "WEEK"
					Или ИмяФункции = "WEEKDAY" 
					Или ИмяФункции = "YEAR"
				Тогда 
					Результат = Новый ОписаниеТипов("Число",,, Новый КвалификаторыЧисла(0));
				ИначеЕсли Ложь
					Или ИмяФункции = "LOWER" 
					Или ИмяФункции = "TRIMALL" 
					Или ИмяФункции = "TRIML" 
					Или ИмяФункции = "TRIMR"
					//Или ИмяФункции = "PRESENTATION"
					//Или ИмяФункции = "PRESENTATIONREFS"
					Или ИмяФункции = "UPPER"
				Тогда 
					Результат = Новый ОписаниеТипов("Строка",,, Новый КвалификаторыЧисла(1000)); ; // Квалификатор задаем чтобы в группировках участвовать могло
				ИначеЕсли ИмяФункции = "VALUETYPE" Тогда 
					Результат = Новый ОписаниеТипов("Тип");
				ИначеЕсли ИмяФункции = "UUID" Тогда 
					Результат = Новый ОписаниеТипов("УникальныйИдентификатор");
				КонецЕсли; 
			// Далее идут правила, допускающие напрямую вложенные правила
			ИначеЕсли ДанныеТокена.TokenCount = 1 Тогда
				Результат = ТипЗначенияВыражения(ДанныеТокена.Tokens(0), ЧастьОбъединения, Глубокое);
			ИначеЕсли Ложь
				Или ИмяПравила = "<AddExpr>" 
			Тогда
				Результат = ТипЗначенияВыражения(ДанныеТокена.Tokens(0), ЧастьОбъединения, Глубокое);
			ИначеЕсли Ложь
				Или ИмяПравила = "<MultExpr>" 
			Тогда
				Результат = Новый ОписаниеТипов("Число");
			ИначеЕсли Ложь
				Или ИмяПравила = "<NotExpr>" 
				Или ИмяПравила = "<AndExpr>" 
				Или ИмяПравила = "<OrExpr>" 
				Или ИмяПравила = "<CheckNULL>" 
				Или ИмяПравила = "<CheckNotNULL>" 
				Или ИмяПравила = "<CheckLIKE>" 
				Или ИмяПравила = "<CheckValueIn>" 
				Или ИмяПравила = "<CheckExpr>" 
			Тогда
				Результат = Новый ОписаниеТипов("Булево");
			ИначеЕсли ИмяПравила = "<Brackets>" Тогда
				Результат = ТипЗначенияВыражения(ДанныеТокена.Tokens(1), ЧастьОбъединения, Глубокое);
			ИначеЕсли ИмяПравила = "<Agregate>" Тогда
				лИмяТокена = ДанныеТокена.Tokens(0).Name;
				Если Ложь
					Или лИмяТокена = "MAX"
					Или лИмяТокена = "MIN"
				Тогда
					Результат = ТипЗначенияВыражения(ДанныеТокена.Tokens(2), ЧастьОбъединения, Глубокое);
				ИначеЕсли Ложь
					Или лИмяТокена = "AVG"
					Или лИмяТокена = "SUM"
				Тогда
					Результат = Новый ОписаниеТипов("Число");
				КонецЕсли; 
			ИначеЕсли ИмяПравила = "<Case>" Тогда
				Результат = ТипЗначенияВыражения(ДанныеТокена.Tokens(2), ЧастьОбъединения, Глубокое);
			ИначеЕсли ИмяПравила = "<WhenThen>" Тогда
				Результат = ТипЗначенияВыражения(ДанныеТокена.Tokens(3), ЧастьОбъединения, Глубокое);
				Если ДанныеТокена.TokenCOunt = 5 Тогда
					Результат2 = ТипЗначенияВыражения(ДанныеТокена.Tokens(4), ЧастьОбъединения, Глубокое);
					#Если Сервер И Не Сервер Тогда
						Результат2 = Новый ОписаниеТипов;
					#КонецЕсли
					Результат = Новый ОписаниеТипов(Результат, Результат2.Типы());
				КонецЕсли; 
			ИначеЕсли ИмяПравила = "<IsNull>" Тогда
				Результат = ТипЗначенияВыражения(ДанныеТокена.Tokens(2), ЧастьОбъединения, Глубокое);
				Результат2 = ТипЗначенияВыражения(ДанныеТокена.Tokens(4), ЧастьОбъединения, Глубокое);
				#Если Сервер И Не Сервер Тогда
					Результат2 = Новый ОписаниеТипов;
				#КонецЕсли
				Результат = Новый ОписаниеТипов(Результат, Результат2.Типы());
			КонецЕсли; 
		Иначе
			ИмяТокена = Токен.Name;
			Если ирОбщий.СтрокиРавныЛкс(ИмяТокена, "numLiteral") Тогда
				Результат = Новый ОписаниеТипов("Число");
			ИначеЕсли ирОбщий.СтрокиРавныЛкс(ИмяТокена, "strLiteral") Тогда
				//Результат = Новый ОписаниеТипов("Строка",,,, Новый КвалификаторыСтроки(СтрДлина(ирОбщий.ТекстИзВстроенногоЯзыкаЛкс(Токен.Data))));
				Результат = Новый ОписаниеТипов("Строка",,,, Новый КвалификаторыСтроки(1000)); // Квалификатор задаем чтобы в группировках участвовать могло
			ИначеЕсли Ложь
				Или ирОбщий.СтрокиРавныЛкс(ИмяТокена, "TRUE")
				Или ирОбщий.СтрокиРавныЛкс(ИмяТокена, "FALSE")
			Тогда
				Результат = Новый ОписаниеТипов("Булево");
			ИначеЕсли ирОбщий.СтрокиРавныЛкс(ИмяТокена, "NULL") Тогда
				Результат = Новый ОписаниеТипов("Null");
			Иначе
				Результат = Новый ОписаниеТипов();
			КонецЕсли; 
		КонецЕсли;
	КонецЕсли;
	Если Результат = Неопределено Тогда
		Результат = Новый ОписаниеТипов();
	КонецЕсли; 
	Возврат Результат;

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

// Функция - Получить тип функции cast
//
// Параметры:
//  ТокенТипа		 - Token {GoldParserForNet.Parser} - 
//  ЧастьОбъединения - 	 - 
// 
// Возвращаемое значение:
//   - 
//
Функция ПолучитьТипФункцииCast(ТокенТипа, ЧастьОбъединения)

	ПервыйТокен = ТокенТипа.Data.Tokens(0); // Token {GoldParserForNet.Parser}
	Если Истина
		И ПервыйТокен.Kind = 1
		И ПервыйТокен.Data = "(" 
	Тогда
		Результат = ПолучитьТипФункцииCast(ТокенТипа.Data.Tokens(1), ЧастьОбъединения);
	ИначеЕсли ПервыйТокен.Kind = 1 Тогда
		Результат = Новый ОписаниеТипов(ПервыйТокен.Data);
	Иначе
		ИмяПравилаТипа = ПервыйТокен.Data.RuleText();
		Если ИмяПравилаТипа = "<NumericType>" Тогда
			Результат = Новый ОписаниеТипов("Число");
		ИначеЕсли ИмяПравилаТипа = "<StringType>" Тогда
			Результат = Новый ОписаниеТипов("Строка");
		ИначеЕсли ИмяПравилаТипа = "<DateType>" Тогда
			Результат = Новый ОписаниеТипов("Дата");
		ИначеЕсли ИмяПравилаТипа = "<BinaryType>" Тогда
			Результат = Новый ОписаниеТипов("ХранилищеЗначения");
		ИначеЕсли ИмяПравилаТипа = "<TableName>" Тогда
			ИмяСсылочногоТипа = СобратьВыражениеЗапроса(ПервыйТокен);
			ИмяСсылочногоТипа = ирОбщий.ИмяТипаИзПолногоИмениТаблицыБДЛкс(ИмяСсылочногоТипа);
			Попытка
				Результат = Новый ОписаниеТипов(ИмяСсылочногоТипа);
			Исключение
			КонецПопытки; 
		ИначеЕсли ИмяПравилаТипа = "<Brackets>" Тогда
		Иначе
			ВызватьИсключение "Неизвестный тип " + ИмяПравилаТипа + " в функции CAST";
		КонецЕсли; 
	КонецЕсли; 
	Возврат Результат;

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

// Функция - Получить термин отбора компоновки из данных токена
//
// Параметры:
//  Токен			 - Token {GoldParserForNet.Parser} - 
//  ЗапросПакета	 - 	 - 
//  ЧастьОбъединения - 	 - 
// 
// Возвращаемое значение:
//   - 
//
Функция ПолучитьТерминОтбораКомпоновкиИзДанныхТокена(Токен, ЗапросПакета, ЧастьОбъединения)
	
	Результат = Null;
	ДанныеТокена = Токен.Data; // Reduction {GoldParserForNet.Parser}
	Если Токен.Kind = 0 Тогда
		ИмяПравила = ДанныеТокена.RuleText();
		Если ИмяПравила = "<Field>" Тогда
			//Результат = ПолучитьТекстИзТокена(Токен);
			Выражение = СобратьВыражениеЗапроса(Токен,,, ЧастьОбъединения);
			Если Найти(Выражение, "(") > 0 Тогда
				Возврат Результат;
			КонецЕсли; 
			Результат = ПолучитьПолноеИмяПоляВВыражении(Выражение, ЗапросПакета, ЧастьОбъединения);
			Результат = Новый ПолеКомпоновкиДанных(Результат);
			Возврат Результат;
		ИначеЕсли ИмяПравила = "<Brackets>" Тогда
			Результат = ПолучитьТерминОтбораКомпоновкиИзДанныхТокена(ДанныеТокена.Tokens(1), ЗапросПакета, ЧастьОбъединения);
			Возврат Результат;
		ИначеЕсли ИмяПравила = "<Parameter>" Тогда
			//Результат = ДанныеТокена.Tokens(1).Data.Tokens(0).Data;
			Результат = ДанныеТокена.Tokens(0).Data;
			ПроверитьДобавитьПараметр(Результат);
			Результат = Новый ПолеКомпоновкиДанных("ПараметрыДанных." + Результат);
			Возврат Результат;
		ИначеЕсли ИмяПравила = "<Datetime>" Тогда
			Год = ДанныеТокена.Tokens(2).Data;
			Месяц = ДанныеТокена.Tokens(4).Data;
			День = ДанныеТокена.Tokens(6).Data;
			Если ДанныеТокена.TokenCount > 8 Тогда
				Час = ДанныеТокена.Tokens(8).Data;
				Минута = ДанныеТокена.Tokens(10).Data;
				Секунда = ДанныеТокена.Tokens(12).Data;
			Иначе
				Час = 0;
				Минута = 0;
				Секунда = 0;
			КонецЕсли; 
			Результат = Дата(Год, Месяц, День, Час, Минута, Секунда);
			Возврат Результат;
		ИначеЕсли Истина
			И ИмяПравила = "<MonoFunc>"
			И ДанныеТокена.Tokens(0).Data.Tokens(0).Name = "VALUETYPE"
		Тогда
			Результат = ПолучитьТерминОтбораКомпоновкиИзДанныхТокена(ДанныеТокена.Tokens(2), ЗапросПакета, ЧастьОбъединения);
			Если Истина
				И ТипЗнч(Результат) = Тип("ПолеКомпоновкиДанных") 
				И Не ирОбщий.СтрНачинаетсяСЛкс(Результат, "ПараметрыДанных.") 
			Тогда
				Результат = Новый ПолеКомпоновкиДанных("" + Результат + "." + МаркерПоляФункцииТипЗначения());
				Возврат Результат;
			КонецЕсли; 
		ИначеЕсли Истина
			И ИмяПравила = "<Meaning>"
		Тогда
			ПолноеИмяПредопределенного = СобратьВыражениеЗапроса(ДанныеТокена.Tokens(2),, ЗапросПакета, ЧастьОбъединения);
			Попытка
				Результат = ПредопределенноеЗначение(ПолноеИмяПредопределенного);
				Возврат Результат;
			Исключение
			КонецПопытки; 
		КонецЕсли; 
	Иначе
		ИмяТокена = Токен.Name;
		Если ирОбщий.СтрокиРавныЛкс(ИмяТокена, "numLiteral") Тогда
			Попытка
				Результат = Вычислить(ДанныеТокена);
			Исключение
				// hex
			КонецПопытки; 
		ИначеЕсли ирОбщий.СтрокиРавныЛкс(ИмяТокена, "strLiteral") Тогда
			Результат = Токен.Data;
			ПозицияНачала = 2;
			Если Лев(Результат, 1) = "N" Тогда
				ПозицияНачала = ПозицияНачала + 1;
			КонецЕсли; 
			Результат = Сред(Результат, ПозицияНачала, СтрДлина(Результат) - ПозицияНачала);
			Результат = СтрЗаменить(Результат, """""", """");
		ИначеЕсли ирОбщий.СтрокиРавныЛкс(ИмяТокена, "TRUE") Тогда
			Результат = Истина;
		ИначеЕсли ирОбщий.СтрокиРавныЛкс(ИмяТокена, "FALSE") Тогда
			Результат = Ложь;
		ИначеЕсли ирОбщий.СтрокиРавныЛкс(ИмяТокена, "UNDEFINED") Тогда
			Результат = Неопределено;
		КонецЕсли; 
		Возврат Результат;
	КонецЕсли; 
	Если ДанныеТокена.TokenCount = 1 Тогда
		Результат = ПолучитьТерминОтбораКомпоновкиИзДанныхТокена(ДанныеТокена.Tokens(0), ЗапросПакета, ЧастьОбъединения);
	КонецЕсли; 
	Возврат Результат;
	
КонецФункции

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Процедура ПриПолученииДанныхДоступныхПолей(Элемент, ОформленияСтрок)

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

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

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

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

Процедура ПереключитьРежимРедактированияТекста()
	
	ЭтаФорма.мРежимРедактированияТекста = Не мРежимРедактированияТекста;
	НастроитьЭлементыСтраницыТекст();
	
КонецПроцедуры

Процедура КПТекстРедактировать(Кнопка = Неопределено)

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

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

Процедура ОбновитьВсеВыраженияСПроверкойИИндикацией()
	
	Состояние("Обновление выражений...");
	СтруктураПолей = СтруктураПолейДляРасширеннойПроверки();
	ОбновитьВсеВыраженияПакета(,, СтруктураПолей);
	Состояние("");
	
КонецПроцедуры

Функция СтруктураПолейДляРасширеннойПроверки()
	
	СтруктураПолей = НоваяСтруктураОбработкиПолей(""); 
	СтруктураПолей.РазрешитьПроверкуСуществованияТаблиц = Истина;
	Возврат СтруктураПолей;

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

// Параметры:
//   РежимОбновленияВыражений - Число
//		1 - пересобрать
//		2 - очистить токен
Функция ОбновитьВсеВыраженияПакета(Пакет = Неопределено, Знач РежимОбновленияВыражений = 1, СтруктураПолей = Неопределено)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Функция ЛиЛитералЗначения(Знач ИмяПоля)
	
	ИмяПоля = ВРег(ИмяПоля);
	Результат = Ложь
		Или ИмяПоля = СловоЯзыкаЗапросовВФорме("NULL")
		Или ИмяПоля = СловоЯзыкаЗапросовВФорме("UNDEFINED")
		Или ИмяПоля = СловоЯзыкаЗапросовВФорме("FALSE")
		Или ИмяПоля = СловоЯзыкаЗапросовВФорме("TRUE")
		;
	Возврат Результат;

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

Функция ПолучитьИмяВыбраннойТаблицы(СтрокаВыбраннойТаблицы = Неопределено)

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

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

Функция _ПолучитьТекстОператораТокена(Данные, НачальныйИндекс, КонечныйИндекс)

	ТекстОператора = "";
	Для Индекс = НачальныйИндекс По КонечныйИндекс Цикл
		Если ТекстОператора <> "" Тогда
			ТекстОператора = ТекстОператора + " " + ТекстОператора;
		КонецЕсли; 
		ИмяТерминала = Данные.Tokens(Индекс).ParentRule.RuleNonterminal.Name;
		ТекстОператора = ТекстОператора + " " + СловоЯзыкаЗапросовВФорме(ИмяТерминала);
	КонецЦикла;

	Возврат Неопределено;

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

// .
// Параметры:
//  СтрокаТаблицыВыражений		 - 		 - 
//  ТабличноеПоле				 - 		 - 
//  ЗапросПакета				 - 		 - 
//  ЧастьОбъединения			 - 		 - 
//  СтароеИмяТаблицы			 - 		 - 
//  НовоеИмяТаблицы				 - 		 - 
//  РазрешитьПустое				 - 		 - 
//  выхЕстьАгрегаты				 - 		 - 
//  РазрешитьНормализациюИмен	 - Булево	 - используется только когда СтруктураПолей = Неопределено
//  РежимОбновленияВыражения - Число - 
//  	0 - собрать из готового токена
//  	1 - сформировать токен заново и собрать из него
//  	2 - очистить токен
//  РежимОбновленияВыражений	 - 			 - 
//  СтруктураПолей				 -  - 
// 
// Возвращаемое значение:
//   - Строка - собранное выражение
//
Функция ОбновитьВыражениеЗапроса(СтрокаТаблицыВыражений, ТабличноеПоле = Неопределено, Знач ЗапросПакета = Неопределено, Знач ЧастьОбъединения = Неопределено,
	СтароеИмяТаблицы = "", НовоеИмяТаблицы = "", РазрешитьПустое = Ложь, выхЕстьАгрегаты = Ложь, РазрешитьНормализациюИмен = Истина, РежимОбновленияВыражений = 1, Знач СтруктураПолей = Неопределено)

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

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

Процедура ВключитьРежимПоказаОшибки()
	мРежимПоказаОшибки = Истина;
	ПодключитьОбработчикОжидания("ОтключитьРежимПоказаОшибки", 0.1, Истина);
КонецПроцедуры

Процедура ОтключитьРежимПоказаОшибки()
	мРежимПоказаОшибки = Ложь;
КонецПроцедуры

Процедура ДописатьКВыражениюЕгоЗначение(Результат, Знач СтруктураПолей)
	
	СтрокаПоля = СтруктураПолей.Поля.Найти(Результат, "Определение");
	Если СтрокаПоля <> Неопределено Тогда
		Результат = Результат + "{" + СтрокаПоля.Расшифровка + "}";
	КонецЕсли;

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

Процедура АктивироватьТабличноеПоле(Знач ТабличноеПоле)
	
	// Антибаг платформы 8.3.12+ Не выполняется установка текущим элемента обычной формы на неактивной странице https://partners.v8.1c.ru/forum/t/1757924/m/1757924
	Если ТабличноеПоле = ЭлементыФормы.ВыбранныеПоля Тогда
		ирОбщий.ПрисвоитьЕслиНеРавноЛкс(ЭтаФорма.ЭлементыФормы.ПанельЧасти.ТекущаяСтраница, ЭтаФорма.ЭлементыФормы.ПанельЧасти.Страницы.ВыбранныеПоля);
	ИначеЕсли ТабличноеПоле = ЭлементыФормы.ДеревоУсловия Тогда
		ирОбщий.ПрисвоитьЕслиНеРавноЛкс(ЭтаФорма.ЭлементыФормы.ПанельЧасти.ТекущаяСтраница, ЭтаФорма.ЭлементыФормы.ПанельЧасти.Страницы.ДеревоУсловия);
	ИначеЕсли ТабличноеПоле = ЭлементыФормы.Группировки Тогда
		ирОбщий.ПрисвоитьЕслиНеРавноЛкс(ЭтаФорма.ЭлементыФормы.ПанельЧасти.ТекущаяСтраница, ЭтаФорма.ЭлементыФормы.ПанельЧасти.Страницы.Группировки);
	ИначеЕсли ТабличноеПоле = ЭлементыФормы.ВыбранныеТаблицы Тогда
		ирОбщий.ПрисвоитьЕслиНеРавноЛкс(ЭтаФорма.ЭлементыФормы.ПанельЧасти.ТекущаяСтраница, ЭтаФорма.ЭлементыФормы.ПанельЧасти.Страницы.ВыбранныеТаблицы);
	ИначеЕсли ТабличноеПоле = ЭлементыФормы.ПоляПорядка Тогда
		ирОбщий.ПрисвоитьЕслиНеРавноЛкс(ЭтаФорма.ЭлементыФормы.ПанельОсновная.ТекущаяСтраница, ЭтаФорма.ЭлементыФормы.ПанельОсновная.Страницы.ПоляПорядка);
	КонецЕсли; 
	ЭтаФорма.ТекущийЭлемент = ТабличноеПоле;
	ТабличноеПоле.ОбновитьСтроки(); // Иначе будет отображаться пустым пока не закроешь окна переднего плана

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

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

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

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

Процедура УстановитьДиалектSQL(НовыйДиалектSQL = Неопределено, ИменованныеПараметры = Неопределено) Экспорт
	
	Если НовыйДиалектSQL <> Неопределено Тогда
		ЭтаФорма.ДиалектSQL = НовыйДиалектSQL;
	КонецЕсли; 
	Если Не ЗначениеЗаполнено(ДиалектSQL) Тогда
		ЭтаФорма.ДиалектSQL = мДиалектSQL;
	КонецЕсли; 
	Если ДиалектSQL = Неопределено Тогда
		//ДиалектSQL = "MSSQL";
		ВызватьИсключение "Не указан диалект SQL";
	КонецЕсли; 
	ПараметрыДиалектаSQL = мДиалектыSQL.Найти(ДиалектSQL, "Диалект");
	Если ПараметрыДиалектаSQL = Неопределено Тогда
		Сообщить("Неизвестный диалект " + ДиалектSQL + " заменен на MSSQL");
		ПараметрыДиалектаSQL = мДиалектыSQL.Найти("MSSQL", "Диалект");
	КонецЕсли; 
	Если ИменованныеПараметры <> Неопределено Тогда
		ЭтаФорма.ИменованныеПараметры = ИменованныеПараметры;
	Иначе
		ЭтаФорма.ИменованныеПараметры = ПараметрыДиалектаSQL.ИменованныеПараметры;
	КонецЕсли; 
	Если НЕ ПараметрыДиалектаSQL.ВременныеТаблицы Тогда
		ЭтаФорма.ТипЗапроса = 0;
	КонецЕсли; 
	ЭлементыФормы.ПанельОсновная.Страницы.Итоги.Видимость = ПараметрыДиалектаSQL.Это1С;
	ЭлементыФормы.ПанельОсновная.Страницы.Параметры.Видимость = ПараметрыДиалектаSQL.Параметры;
	ЭлементыФормы.ПанельОсновная.Страницы.ПоляОбъединения.Видимость = ПараметрыДиалектаSQL.Объединения;
	ЭлементыФормы.ПанельЧасти.Страницы.СвязиТаблиц.Видимость = ПараметрыДиалектаSQL.МногоТаблиц;
	ЭлементыФормы.ВыбранныеПоля.Колонки.Имя.Видимость = ПараметрыДиалектаSQL.МногоТаблиц;
	ЭлементыФормы.ПанельЧасти.Страницы.Группировки.Видимость = ПараметрыДиалектаSQL.Группировки;
	ЭлементыФормы.ВыбранныеПоля.Колонки.АгрегатнаяФункция.Видимость = ПараметрыДиалектаSQL.Группировки;
	ЭлементыФормы.ВыбранныеПоля.Колонки.АгрегатнаяФункция.ИзменятьНастройку = ПараметрыДиалектаSQL.Группировки;
	ЭлементыФормы.ВыбранныеПоля.Колонки.Группировка.Видимость = ПараметрыДиалектаSQL.Группировки;
	ЭлементыФормы.ВыбранныеПоля.Колонки.Группировка.ИзменятьНастройку = ПараметрыДиалектаSQL.Группировки;
	ЭлементыФормы.ТипЗапроса.Доступность = ПараметрыДиалектаSQL.ВременныеТаблицы;
	РазрешеныКомментарии = ЗначениеЗаполнено(ПараметрыДиалектаSQL.СтрочныйКомментарий);
	ЭлементыФормы.ПанельЧасти.Страницы.КомментарийЧасти.Видимость = РазрешеныКомментарии;
	ЭлементыФормы.ВыбранныеТаблицы.Колонки.Комментарий.Видимость = РазрешеныКомментарии;
	ЭлементыФормы.ВыбранныеПоля.Колонки.Комментарий.Видимость = РазрешеныКомментарии;
	ЭлементыФормы.Группировки.Колонки.Комментарий.Видимость = РазрешеныКомментарии;
	ЭлементыФормы.ПоляИндекса.Колонки.Комментарий.Видимость = РазрешеныКомментарии;
	ЭлементыФормы.ГруппируемыеПоляИтогов.Колонки.Комментарий.Видимость = РазрешеныКомментарии;
	ЭлементыФормы.ГруппирующиеПоляИтогов.Колонки.Комментарий.Видимость = РазрешеныКомментарии;
	ЭлементыФормы.ОпцияАвтоупорядочивание.Доступность = ПараметрыДиалектаSQL.Это1С;
	ЭлементыФормы.ОпцияАвтоупорядочиваниеОтладки.Доступность = ПараметрыДиалектаSQL.Это1С;
	ЭлементыФормы.ВыбранныеТаблицы.Колонки.УровеньИзоляции.Видимость = ПараметрыДиалектаSQL.УровниИзоляции;
	ЭлементыФормы.УровеньИзоляции.Видимость = ПараметрыДиалектаSQL.УровниИзоляции;
	ЭлементыФормы.ВыбранныеТаблицы.Колонки.ДляИзменения.Видимость = Не ПараметрыДиалектаSQL.УровниИзоляции;
	ЭлементыФормы.ДляИзменения.Видимость = Не ПараметрыДиалектаSQL.УровниИзоляции;
	ЭлементыФормы.ВыбранныеТаблицы.Колонки.Обязательная.Видимость = ПараметрыДиалектаSQL.Это1С;
	ЭлементыФормы.ВыбранныеТаблицы.Колонки.НомерГруппы.Видимость = ПараметрыДиалектаSQL.Это1С;
	ЭлементыФормы.НадписьИсточникДанных1С.Видимость = ПараметрыДиалектаSQL.Это1С;
	ЭлементыФормы.ИсточникДанных1С.Видимость = ПараметрыДиалектаSQL.Это1С;
	ЭлементыФормы.КПВыбранныеТаблицы.Кнопки.ДобавитьСпециальныйПодзапрос.Кнопки.ДобавитьКолонкуБД.Доступность = ПараметрыДиалектаSQL.Это1С;
	
	АгрегатныеФункции = Новый СписокЗначений();
	АгрегатныеФункции.Добавить("SUM(", СловоЯзыкаЗапросовВФорме("SUM"));
	АгрегатныеФункции.Добавить("MAX(", СловоЯзыкаЗапросовВФорме("MAX"));
	АгрегатныеФункции.Добавить("MIN(", СловоЯзыкаЗапросовВФорме("MIN"));
	АгрегатныеФункции.Добавить("AVG(", СловоЯзыкаЗапросовВФорме("AVG"));
	АгрегатныеФункции.Добавить("COUNT(", СловоЯзыкаЗапросовВФорме("COUNT"));
	АгрегатныеФункции.Добавить("COUNT(DISTINCT ", СловоЯзыкаЗапросовВФорме("COUNT") + " " + СловоЯзыкаЗапросовВФорме("DISTINCT"));
	ПоляВвводаАгрегатныхФункций = Новый Массив();
	ПоляВвводаАгрегатныхФункций.Добавить(ЭлементыФормы.ВыбранныеПоля.Колонки.АгрегатнаяФункция.ЭлементУправления);
	ПоляВвводаАгрегатныхФункций.Добавить(ЭлементыФормы.ГруппируемыеПоляИтогов.Колонки.АгрегатнаяФункция.ЭлементУправления);
	Для Каждого ПолеВвводаАгрегатнойФункции Из ПоляВвводаАгрегатныхФункций Цикл
		СписокВыбора = ПолеВвводаАгрегатнойФункции.СписокВыбора;
		СписокВыбора.Очистить();
		Для Каждого АгрегатнаяФункция Из АгрегатныеФункции Цикл
			СписокВыбора.Добавить(АгрегатнаяФункция.Значение, АгрегатнаяФункция.Представление);
		КонецЦикла;
	КонецЦикла;
	
	СписокВыбораТипаЗапроса = ЭлементыФормы.ТипЗапроса.СписокВыбора;
	СписокВыбораТипаЗапроса.Очистить();
	СписокВыбораТипаЗапроса.Добавить(0, "Выборка");
	СписокВыбораТипаЗапроса.Добавить(1, "Создание таблицы");
	СписокВыбораТипаЗапроса.Добавить(2, "Уничтожение таблицы");
	Если Не ПараметрыДиалектаSQL.Это1С Тогда
		СписокВыбораТипаЗапроса.Добавить(3, "Добавление данных");
		СписокВыбораТипаЗапроса.Добавить(4, "Изменение данных");
		СписокВыбораТипаЗапроса.Добавить(5, "Удаление данных");
		СписокВыбораТипаЗапроса.Добавить(6, "Очистка");
	КонецЕсли; 
		
КонецПроцедуры

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

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

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

Процедура ПанельОсновнаяОбновитьТекущуюСтраницу(ПолныйТекстМогИзмениться = Истина)

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

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

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

Функция ОбновитьТабличноеПолеПоляОбъединения()

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

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

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

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

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

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

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

Процедура ЗагрузитьВыражениеУсловия()

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

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

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

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

Процедура ОбъединениеПриИзменении(Элемент)
	
	ИзменитьСвернутостьПанельЧастей(РежимОбъединения);
	
КонецПроцедуры

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

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

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

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

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

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

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

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

Процедура ЧастиОбъединенияПриАктивизацииСтроки(Элемент = Неопределено)
	
	ЗапретитьОформлениеТабличныхПолей();
	СохранитьЧастьОбъединения(); 
	ЗагрузитьЧастьОбъединения();
	
КонецПроцедуры

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

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

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

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

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

Процедура ЧастиОбъединенияПередУдалением(Элемент, Отказ)
	
	Если Элемент.Значение.Количество() = 1 Тогда
		Отказ = Истина;
	КонецЕсли; 
	
КонецПроцедуры

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

Процедура ДоступныеПоляИтоговВыбор(Элемент, ВыбраннаяСтрока, Колонка, СтандартнаяОбработка)
	
	СтандартнаяОбработка = Ложь;
	ДобавитьПолеЧастиОбъединенияВГруппирующиеПоля(ВыбраннаяСтрока);

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

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

Процедура ЛиПакетныйЗапросПриИзменении(Элемент = Неопределено) Экспорт
	
	ИзменитьСвернутостьПанельПакета(ЛиПакетныйЗапрос);

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

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

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

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

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

Процедура ЗапросыПакетаПриАктивизацииСтроки(Элемент = Неопределено)
	
	ЗапретитьОформлениеТабличныхПолей();
	СохранитьЗапросПакета();
	ЗагрузитьЗапросПакета();

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

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

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

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

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

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

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

Функция ТабличныеПоляЧастиОбъединения()
	
	СписокТаблиц = Новый Массив;
	СписокТаблиц.Добавить("ВыбранныеТаблицы");
	СписокТаблиц.Добавить("СвязиТаблиц");
	СписокТаблиц.Добавить("ДеревоУсловияСвязи");
	СписокТаблиц.Добавить("ВыбранныеПоля");
	СписокТаблиц.Добавить("ДеревоУсловия");
	СписокТаблиц.Добавить("Группировки");
	СписокТаблиц.Добавить("ПоляВыбораПостроителя");
	СписокТаблиц.Добавить("ПоляОтбораПостроителя");
	СписокТаблиц.Добавить("ДоступныеПоляВыбора");
	СписокТаблиц.Добавить("ДоступныеПоляУсловия");
	СписокТаблиц.Добавить("ДоступныеПоляГруппировок");
	Возврат СписокТаблиц;

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

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

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

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

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

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

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

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

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

Процедура ОбновитьНаименованиеЗапроса(ЗапросПакета = Неопределено) Экспорт
	
	Если ЗапросПакета = Неопределено Тогда
		//ЗапросПакета = ЭлементыФормы.ЗапросыПакета.ТекущаяСтрока;
		ЗапросПакета = мТекущийЗапросПакета;
	КонецЕсли;
	Если ЗапросПакета.РучноеИмя И ЗначениеЗаполнено(ЗапросПакета.Имя) Тогда
		Возврат;
	КонецЕсли; 
	Если ЗапросПакета.ТипЗапроса = 0 Тогда
		Если ЗначениеЗаполнено(ЗапросПакета.ИмяОсновнойТаблицы) И ЗапросПакета.ИмяОсновнойТаблицы <> "_" Тогда
			ЗапросПакета.Имя = ЗапросПакета.ИмяОсновнойТаблицы;
			ЗапросПакета.РучноеИмя = Истина;
		Иначе
			ЗапросПакета.Имя = XMLСтрока(ЗапросПакета.Индекс);
			Если ЗапросПакета.ЧастиОбъединения.Количество() > 0 Тогда
				ИмяЧастиОбъединения = Сред(ЗапросПакета.ЧастиОбъединения[0].Имя, СтрДлина("" + ЗапросПакета.ЧастиОбъединения[0].Номер + ",") + 1);
				Если Не ПустаяСтрока(ИмяЧастиОбъединения) Тогда
					ЗапросПакета.Имя = ЗапросПакета.Имя + ", " + ИмяЧастиОбъединения;
				КонецЕсли; 
			КонецЕсли; 
		КонецЕсли; 
	ИначеЕсли ЗапросПакета.ТипЗапроса = 1 Тогда
		ЗапросПакета.Имя = "+," + ЗапросПакета.ИмяОсновнойТаблицы;
		ЗапросПакета.РучноеИмя = Ложь;
	ИначеЕсли ЗапросПакета.ТипЗапроса = 2 Тогда
		ЗапросПакета.Имя = "-," + ЗапросПакета.ИмяОсновнойТаблицы;
		ЗапросПакета.РучноеИмя = Ложь;
	ИначеЕсли ЗапросПакета.ТипЗапроса = 3 Тогда
		ЗапросПакета.Имя = "^," + ЗапросПакета.ИмяОсновнойТаблицы;
		ЗапросПакета.РучноеИмя = Ложь;
	ИначеЕсли ЗапросПакета.ТипЗапроса = 4 Тогда
		ЗапросПакета.Имя = "*," + ЗапросПакета.ИмяОсновнойТаблицы;
		ЗапросПакета.РучноеИмя = Ложь;
	ИначеЕсли ЗапросПакета.ТипЗапроса = 5 Тогда
		ЗапросПакета.Имя = "x," + ЗапросПакета.ИмяОсновнойТаблицы;
		ЗапросПакета.РучноеИмя = Ложь;
	ИначеЕсли ЗапросПакета.ТипЗапроса = 6 Тогда
		ЗапросПакета.Имя = "&," + ЗапросПакета.ИмяОсновнойТаблицы;
		ЗапросПакета.РучноеИмя = Ложь;
	Иначе
		ЗапросПакета.Имя = XMLСтрока(ЗапросПакета.Индекс);
	КонецЕсли;
	
КонецПроцедуры

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

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

Функция _СкопироватьТаблицуВыражений(ТаблицаВыражений)

	КопияТаблицы = ирОбщий.КопияОбъектаЛкс(ТаблицаВыражений);
	Для Индекс = 0 По КопияТаблицы.Количество() - 1 Цикл
		ЗаполнитьЗначенияСвойств(КопияТаблицы[Индекс], ТаблицаВыражений[Индекс], "Токен"); 
	КонецЦикла;
	Возврат КопияТаблицы;

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

Функция СкопироватьВложенныйПакетДляРедактирования(Пакет)

	СтараяРасширеннаяПроверка = РасширеннаяПроверка;
	ЭтаФорма.РасширеннаяПроверка = Ложь;
	// Удаляем все токены, т.к. для настроек компоновки сериализация всегда выполняется через сериализаторXDTO, который ругается на COM объекты
	ОбновитьВсеВыраженияПакета(Пакет, 2); 
	ПакетКопия = ирОбщий.КопияОбъектаЛкс(Пакет);
	ЗапросИсточник = Пакет[0];
	ЗапросПриемник = ПакетКопия[0];
	Для Индекс = 0 По ЗапросИсточник.ЧастиОбъединения.Количество() - 1 Цикл
		ЧастьОбъединенияКопия = ЗапросПриемник.ЧастиОбъединения[Индекс];
		// Копируем отбор
		ЧастьОбъединенияКопия.Компоновщик.ЗагрузитьНастройки(ЗапросИсточник.ЧастиОбъединения[Индекс].Компоновщик.Настройки); // https://www.hostedredmine.com/issues/890470
		//ЧастьОбъединенияКопия.Условие = ЧастьОбъединенияКопия.Компоновщик.Настройки;
		ОбновитьКомпоновщикЧастиОбъединения(ЧастьОбъединенияКопия);
	КонецЦикла;
	ОбновитьВсеВыраженияЗапроса(ЗапросПриемник);
	//ОбновитьВсеВыраженияПакета(ПакетКопия);
	ЭтаФорма.РасширеннаяПроверка = СтараяРасширеннаяПроверка;
	Возврат ПакетКопия;
	// Доделать копирования токенов
	//ПараметрыТаблицы.Колонки.Добавить("Токен");
	//ВыбранныеПоля.Колонки.Добавить("Токен");
	//Группировки.Колонки.Добавить("Токен");
	//ПоляПорядка.Колонки.Добавить("Токен");
	//ПоляВыбораПостроителя.Колонки.Добавить("Токен");
	//ПоляОтбораПостроителя.Колонки.Добавить("Токен");
	//ПоляПорядкаПостроителя.Колонки.Добавить("Токен");
	//ПоляИтоговПостроителя.Колонки.Добавить("Токен");
	//ГруппируемыеПоляИтогов.Колонки.Добавить("Токен");
	//ГруппирующиеПоляИтогов.Колонки.Добавить("Токен");

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

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

КонецФункции // СкопироватьПакетДляРедактирования()

Функция СкопироватьЧастьОбъединения(ЗапросПакета, ЧастьОбъединения = Неопределено, Позиция = Неопределено)

	Если ЧастьОбъединения = Неопределено Тогда
		ЧастьОбъединения = мТекущаяЧастьОбъединения;
	КонецЕсли; 
	// Удаляем все токены, т.к. для настроек компоновки сериализация всегда выполняется через сериализаторXDTO, который ругается на COM объекты
	ОбновитьВсеВыраженияЧастиОбъединения(ЗапросПакета, ЧастьОбъединения, 2); 
	МассивСтрок = Новый Массив;
	МассивСтрок.Добавить(ЧастьОбъединения);
	ЧастьОбъединенияКопия = ДобавитьЧастьОбъединения(ЗапросПакета, Позиция);
	ЗаполнитьЗначенияСвойств(ЧастьОбъединенияКопия, ирОбщий.КопияОбъектаЛкс(ЧастьОбъединения.Владелец().Скопировать(МассивСтрок))[0],, "Номер");
	ЧастьОбъединенияКопия.Компоновщик.ЗагрузитьНастройки(ЧастьОбъединения.Компоновщик.Настройки); // Закомментировано 06.06.2020. Раскомментировано 12.02.2022
	ОбновитьКомпоновщикЧастиОбъединения(ЧастьОбъединенияКопия);
	ОбновитьВсеВыраженияЧастиОбъединения(ЗапросПакета, ЧастьОбъединенияКопия);
	ОбновитьНаименованиеЧасти(ЧастьОбъединенияКопия);  
	Возврат ЧастьОбъединенияКопия;
	// Доделать копирования токенов
	//ПараметрыТаблицы.Колонки.Добавить("Токен");
	//ВыбранныеПоля.Колонки.Добавить("Токен");
	//Группировки.Колонки.Добавить("Токен");
	//ПоляПорядка.Колонки.Добавить("Токен");
	//ПоляВыбораПостроителя.Колонки.Добавить("Токен");
	//ПоляОтбораПостроителя.Колонки.Добавить("Токен");
	//ПоляПорядкаПостроителя.Колонки.Добавить("Токен");
	//ПоляИтоговПостроителя.Колонки.Добавить("Токен");
	//ГруппируемыеПоляИтогов.Колонки.Добавить("Токен");
	//ГруппирующиеПоляИтогов.Колонки.Добавить("Токен");

КонецФункции // СкопироватьПакетДляРедактирования()

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

Процедура ИмяОсновнойТаблицыПриИзменении(Элемент)

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

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

Процедура ОбновитьНомераЧастейОбъединения()
	
	Для Каждого ЧастьОбъединения Из ЧастиОбъединения Цикл
		ЧастьОбъединения.Номер = ЧастиОбъединения.Индекс(ЧастьОбъединения) + 1; 
		ОбновитьНаименованиеЧасти(ЧастьОбъединения);
	КонецЦикла;
	
КонецПроцедуры

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

Процедура СохранитьВыбраннуюТаблицу()
	
	Если мТекущаяСтрокаВыбранныеТаблицы = Неопределено Тогда
		Возврат;
	КонецЕсли;
	Если ВыбранныеТаблицы.Индекс(мТекущаяСтрокаВыбранныеТаблицы) = -1 Тогда
		// Строка была удалена
		Возврат;
	КонецЕсли; 
	СохранитьПараметрТаблицы();
	
КонецПроцедуры

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

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

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

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

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

Функция ОбновитьТекущееИмяТаблицы()

	мТекущееИмяВыбраннойТаблицы = мТекущаяСтрокаВыбранныеТаблицы.Имя;
	Возврат Неопределено;

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

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

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

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

Функция ЭтоПараметрОтбор1С(Знач СтрокаПараметраТаблицы = Неопределено)

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

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

Функция ЭтоПараметрПериод1С(СтрокаПараметраТаблицы)

	Результат = Истина
		И Найти(НРег(СтрокаПараметраТаблицы.Имя), "period)") > 0
		И ирОбщий.СтрокиРавныЛкс(ДиалектSQL, "1С");
	Возврат Результат;

КонецФункции // ЭтоПараметр1СПериодичность()

Функция ЭтоПараметрМетодДополненияПериодов1С(СтрокаПараметраТаблицы)

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

КонецФункции // ЭтоПараметр1СПериодичность()

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

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

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

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

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

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

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

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

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

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

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

Процедура ПсевдонимыПолейИмяПриИзменении(Элемент)
	
	ПриИзмененииИмениПоляОбъединения();
	
КонецПроцедуры

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

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

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

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

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

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

Процедура ПереключитьРежимПроизвольногоВыраженияОтбора(ЭлементОтбора)

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

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

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

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

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

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

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

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

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

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

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

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

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

Процедура ПолеТекстаОтображаетПакетПриИзменении(Элемент)
	
	ПересобратьВременныйПолныйТекст();
	НастроитьЭлементыСтраницыТекст();
	
КонецПроцедуры

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

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

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

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

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

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

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

Процедура ВыбранныеТаблицыПередУдалением(Элемент, Отказ)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Процедура ВыбранныеПоляПередНачаломИзменения(Элемент, Отказ)
	
	Отказ = Элемент.ТекущаяСтрока.Автополе;

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

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

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

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

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

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

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

Процедура ГруппировкиПриВыводеСтроки(Элемент, ОформлениеСтроки, ДанныеСтроки) Экспорт
	
	ТабличноеПолеТаблицыВыраженийПриВыводеСтроки1(Элемент, ОформлениеСтроки, ДанныеСтроки);

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

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

Процедура ГруппируемыеПоляИтоговПриВыводеСтроки(Элемент, ОформлениеСтроки, ДанныеСтроки) Экспорт
	
	ТабличноеПолеТаблицыВыраженийПриВыводеСтроки1(Элемент, ОформлениеСтроки, ДанныеСтроки);

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

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

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

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

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

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

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

Процедура ВыбранныеПоляАгрегатнаяФункцияПриИзменении(Элемент)
	
	УстановитьАгрегатнуюФункциюВыбранногоПоля(, Элемент.Значение);
	
КонецПроцедуры

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

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

Процедура ВыбранныеПоляОпределениеПриИзменении(Элемент = Неопределено)
	
	ПриИзмененииВыраженияВыбранногоПоля();
	
КонецПроцедуры

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

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

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

Процедура ГруппируемыеПоляИтоговОпределениеПриИзменении(Элемент)
	
	ПриИзмененииВыраженияГруппируемогоПоля();

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

Процедура ПриИзмененииВыраженияГруппируемогоПоля(ГруппируемоеПоле = Неопределено, ЗапросПакета = Неопределено)

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

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

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

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

Процедура ГруппируемыеПоляИтоговПеретаскивание(Элемент, ПараметрыПеретаскивания, СтандартнаяОбработка, Строка, Колонка)

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

Процедура ДобавитьДоступноеПолеВГруппируемыеПоля(ПолеОбъединения)

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

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

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

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

Процедура ГруппирующиеПоляИтоговПослеУдаления(Элемент)
	
	ОбновитьРолиИтогов();
	
КонецПроцедуры

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

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

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

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

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

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

Процедура ДобавитьДоступноеПолеВГруппировки(ДоступноеПоле)
	
	Если Автогруппировки Тогда
		Возврат;
	КонецЕсли; 
	ДобавитьДоступноеПолеВТаблицуВыражений(ДоступноеПоле, ЭлементыФормы.Группировки);

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

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

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

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

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

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

Процедура ГруппируемыеПоляИтоговПриНачалеРедактирования(Элемент, НоваяСтрока, Копирование)
	
	Если Не НоваяСтрока Тогда
		СохранитьГруппируемоеПоле();
	КонецЕсли; 

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

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

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

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

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

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

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

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

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

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

Процедура СвязиТаблицПослеУдаления(Элемент)
	
	ЗагрузитьСвязьТаблиц();
	
КонецПроцедуры

// Параметры:
//  Тип - Число -
//           0 - Элемент
//           1 - Выражение
//           2 - Группа-И
//           3 - Группа-Или
//           4 - Группа-Не
//
Процедура ДобавитьСтрокуВТабличноеПолеОтбора(ТабличноеПолеОтбора, Тип = 0)

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

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

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

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

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

Процедура КПДеревоУсловияСвязиДобавитьГруппуИли(Кнопка)

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

Процедура КПДеревоУсловияДобавитьЭлемент(Кнопка)

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

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

Процедура КПДеревоУсловияДобавитьВыражение(Кнопка)

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

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

Процедура КПДеревоУсловияДобавитьГруппуИ(Кнопка)

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

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

Процедура КПДеревоУсловияДобавитьГруппуИли(Кнопка)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Процедура ПараметрыПриНачалеРедактирования(Элемент, НоваяСтрока, Копирование)
	
	мТекущееИмяПараметра = Элемент.ТекущиеДанные.Имя;
	
КонецПроцедуры

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	ЭлементыФормы.ВыбранныеТаблицы.Колонки.ДляИзменения.Видимость = ОпцияДляИзменения;

КонецПроцедуры // ОбновитьВидимостьКолонкиДляИзмененияВыбранныхТаблиц()

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

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

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

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

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

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

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

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

Функция ПолучитьТекстЗапросаСВыбромМетаданных(ЛиТаблицыИзменения = Ложь) Экспорт

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

КонецФункции // ПолучитьТекстЗапросаСВыбромМетаданных()

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

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

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

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

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

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

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

Процедура ЧастиОбъединенияПриВыводеСтроки(Элемент, ОформлениеСтроки, ДанныеСтроки) Экспорт
	
	Если ДанныеСтроки.РучноеИмя Тогда
		ОформлениеСтроки.Ячейки.Имя.ЦветТекста = Новый Цвет(0, 0, 255);
	КонецЕсли; 

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

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

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

Процедура ПринимающиеПоляПриВыводеСтроки(Элемент, ОформлениеСтроки, ДанныеСтроки) Экспорт
	
	ТабличноеПолеТаблицыВыраженийПриВыводеСтроки1(Элемент, ОформлениеСтроки, ДанныеСтроки);

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

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

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

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

Процедура КПТекстНайтиВКонструкторе(Кнопка)
	
	КПТекстРедактировать();
	КПТекстРедактировать();
	
КонецПроцедуры

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Процедура МенюДоступныхПолейПерейтиКОпределениюТаблицы(Кнопка)

	МенюДоступныхПолейПерейтиКВыбраннойТаблице(, Истина);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Процедура ЗагрузитьПоследнийЗапрос() Экспорт 
	
	ЭлементыФормы.ЗапросыПакета.ТекущаяСтрока = ЗапросыПакета[ЗапросыПакета.Количество() - 1];
	
КонецПроцедуры

Процедура ЗагрузитьЗапросПоИндексу(ИндексЗапроса) Экспорт 
	
	ЭлементыФормы.ЗапросыПакета.ТекущаяСтрока = ЗапросыПакета[ИндексЗапроса];
	
КонецПроцедуры

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

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

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

// Функция - Добавить отборы по строке результата
//
// Параметры:
//  СтрокаРезультата	 - 	 - 
//  ЗапросДоГруппировки	 - Булево - 
//  ИменаПолей			 - Массив - регистрочувствителен
// 
// Возвращаемое значение:
//   - 
//
Функция ДобавитьОтборыПоСтрокеРезультата(СтрокаРезультата, ЗапросДоГруппировки = Ложь, ИменаПолей = Неопределено, Знач РасшифровкиПолей = Неопределено) Экспорт 
	
	РезультатЗапроса = СтрокаРезультата.Владелец();
	#Если Сервер И Не Сервер Тогда
		_ = Новый Запрос;
		РезультатЗапроса = _.Выполнить();
	#КонецЕсли
	ЧастьОбъединения = мТекущаяЧастьОбъединения;
	ЭлементыФормы.ЧастиОбъединения.ТекущаяСтрока = ЧастьОбъединения;
	Результат = КомпоновщикЧасти.Настройки.Отбор.Элементы.Количество();
	РазделительДобавлен = Ложь;
	Для Каждого КолонкаРезультата Из РезультатЗапроса.Колонки Цикл
		Если ИменаПолей <> Неопределено И ИменаПолей.Найти(КолонкаРезультата.Имя) = Неопределено Тогда
			Продолжить;
		КонецЕсли; 
		ЗначениеКолонки = СтрокаРезультата[КолонкаРезультата.Имя];
		ТипЗначения = ТипЗнч(ЗначениеКолонки);
		Если Ложь
			Или ТипЗначения = Тип("ХранилищеЗначения")
			Или ТипЗначения = Тип("ТаблицаЗначений")
		Тогда
			Продолжить;
		КонецЕсли;
		ПолеОбъединения = ПоляОбъединения.Найти(НРег(КолонкаРезультата.Имя), "НИмя");
		Если ПолеОбъединения = Неопределено Тогда
			Продолжить;
		КонецЕсли; 
		ВыбранноеПоле = ВыбранныеПоля.Найти(ПолеОбъединения._1, "ИД");
		Если Ложь
			Или (Истина 
				И ЛиВыражениеЯвляетсяПолемИлиТерминалом(ВыбранноеПоле.Определение) // https://www.hostedredmine.com/issues/907560
				И НайтиДоступноеПоле(КомпоновщикЧасти.Настройки.ДоступныеПоляОтбора, ВыбранноеПоле.Определение) = Неопределено // https://www.hostedredmine.com/issues/897767
				)
			Или ЗапросДоГруппировки И ВыбранноеПоле.ЕстьАгрегаты = Истина
			Или ВыбранноеПоле.ТипЗначения.СодержитТип(Тип("ХранилищеЗначения")) // Представление
		Тогда
			Продолжить;
		КонецЕсли; 
		Если ТипЗначения = Тип("Null") Тогда
			ВыражениеОтбора = "(" + ВыбранноеПоле.Определение + ") ЕСТЬ NULL";
		ИначеЕсли Ложь
			Или ТипЗнч(ЗначениеКолонки) = Тип("Неопределено") 
			Или ТипЗнч(ЗначениеКолонки) = Тип("Булево") 
			Или ТипЗнч(ЗначениеКолонки) = Тип("Число")
			Или (Истина
				И ТипЗнч(ЗначениеКолонки) = Тип("Строка") 
				И КолонкаРезультата.ТипЗначения.КвалификаторыСтроки.Длина > 0
				И СтрЧислоСтрок(ЗначениеКолонки) = 1)
		Тогда
			ВыражениеОтбора = "(" + ВыбранноеПоле.Определение + ") = " + ЗначениеОтбораНаЯзыкеЗапросов(ЗначениеКолонки);
		Иначе
			ИмяПараметра = ДобавитьЗначениеВПараметры(ЗначениеКолонки);
			Если ТипЗнч(ЗначениеКолонки) = Тип("Строка") И КолонкаРезультата.ТипЗначения.КвалификаторыСтроки.Длина = 0 Тогда
				ВыражениеОтбора = "ПОДСТРОКА(" + ВыбранноеПоле.Определение + ", 1, 1000) = ПОДСТРОКА(&" + ИмяПараметра + ", 1, 1000)";
			Иначе
				ВыражениеОтбора = "(" + ВыбранноеПоле.Определение + ") = &" + ИмяПараметра;
			КонецЕсли; 
		КонецЕсли; 
		Если РасшифровкиПолей <> Неопределено Тогда
			СтрокаРасшифровки = РасшифровкиПолей.Найти(ВыбранноеПоле.Определение, "Определение");
			Если СтрокаРасшифровки <> Неопределено Тогда
				СтрокаРасшифровки.РасшифровкаЗначение = ЗначениеКолонки;
			КонецЕсли;
		КонецЕсли;
		ВыражениеОтбораСуществует = Ложь;
		Для Каждого ЭлементОтбора Из КомпоновщикЧасти.Настройки.Отбор.Элементы Цикл
			Если ЭлементОтбора.Представление = ВыражениеОтбора Тогда
				ВыражениеОтбораСуществует = Истина;
				Прервать;
			КонецЕсли; 
		КонецЦикла;
		Если Не ВыражениеОтбораСуществует Тогда
			Если Не РазделительДобавлен Тогда
				ЭлементОтбора = КомпоновщикЧасти.Настройки.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
				ЭлементОтбора.Представление = ПараметрыДиалектаSQL.Кавычка + ТекстРазделительСлужебныхСекцийЗапроса() + ПараметрыДиалектаSQL.Кавычка + " = " 
					+ ПараметрыДиалектаSQL.Кавычка + ТекстРазделительСлужебныхСекцийЗапроса() + ПараметрыДиалектаSQL.Кавычка;
				РазделительДобавлен = Истина;
			КонецЕсли; 
			ЭлементОтбора = КомпоновщикЧасти.Настройки.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
			ЭлементОтбора.Представление = ВыражениеОтбора;
		КонецЕсли; 
	КонецЦикла;
	Возврат Результат;
	
КонецФункции

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

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

Процедура СброситьПризнакЕстьАгрегатыУВыбранныхПолей() Экспорт 
	ВыбранныеПоля.ЗаполнитьЗначения(Ложь, "ЕстьАгрегаты");
КонецПроцедуры

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

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

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

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

Функция ТекстРазделительСлужебныхСекцийЗапроса()
	
	Возврат "------";

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

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

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

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

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

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

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

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

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

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

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

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

Процедура ДеревоУсловияСвязиНачалоПеретаскивания(Элемент, ПараметрыПеретаскивания, Выполнение)
	
	СохранитьСвязьТаблиц();
	
КонецПроцедуры

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

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

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

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

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

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

Процедура ЧастиОбъединенияПослеУдаления(Элемент)
	
	ОбновитьНомераЧастейОбъединения();
	
КонецПроцедуры

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

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

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

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

Процедура ДоступныеПоляИтоговЧастиОбъединенияВыбор(Элемент, ВыбраннаяСтрока, Колонка, СтандартнаяОбработка)
	
	СтандартнаяОбработка = Ложь;
	ДобавитьПолеЧастиОбъединенияВГруппирующиеПоля(ВыбраннаяСтрока);

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

Процедура ДобавитьПолеЧастиОбъединенияВГруппирующиеПоля(Знач ВыбраннаяСтрока)
	
	ДобавитьДоступноеПолеВТаблицуВыражений(ВыбраннаяСтрока, ЭлементыФормы.ГруппирующиеПоляИтогов,,,,,,,, "");
	ОбновитьРолиИтогов();

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

//Процедура ДеревоУсловияЛевоеЗначениеДляКраткогоОтображенияЭлементаОкончаниеВводаТекста(Элемент, Текст, Значение, СтандартнаяОбработка)
//	ПолеВводаЗначенияОтбораОкончаниеВводаТекста(Элемент, Текст, Значение, СтандартнаяОбработка, КомпоновщикЧасти);
//КонецПроцедуры

//Процедура ДеревоУсловияПравоеЗначениеДляКраткогоОтображенияЭлементаОкончаниеВводаТекста(Элемент, Текст, Значение, СтандартнаяОбработка)
//	ПолеВводаЗначенияОтбораОкончаниеВводаТекста(Элемент, Текст, Значение, СтандартнаяОбработка, КомпоновщикЧасти);
//КонецПроцедуры

Процедура КПЗапросыПакетаЗаполнитьНастройкиКомпоновки(Кнопка)
	
	СохранитьЗапросПакета();
	СтруктураОбработки = НоваяСтруктураОбработкиПолей("ОчисткаНастроекКомпоновки");
	ОбновитьВсеВыраженияПакета(,, СтруктураОбработки);
	ЗагрузитьЗапросПакета();
	Ответ = Вопрос("Настройки построителя/компоновки очищены. Хотите заполнить их?", РежимДиалогаВопрос.ДаНет);
	Если Ответ = КодВозвратаДиалога.Да Тогда
		// Алгоритм заполнения https://its.1c.ru/db/metod8dev/content/1577/hdoc/_top/%D0%B0%D0%B2%D1%82%D0%BE%D0%B7%D0%B0%D0%BF%D0%BE%D0%BB%D0%BD%D0%B5%D0%BD%D0%B8%D0%B5%20%D0%BD%D0%B0%D0%B1%D0%BE%D1%80%20%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85%20%D1%81%D1%85%D0%B5%D0%BC%D0%B0%20%D0%BA%D0%BE%D0%BC%D0%BF%D0%BE%D0%BD%D0%BE%D0%B2%D0%BA%D0%B8
		СтруктураОбработки = НоваяСтруктураОбработкиПолей("ЗаполнениеНастроекКомпоновки");
		ОбновитьВсеВыраженияПакета(,, СтруктураОбработки);
		ЗагрузитьЗапросПакета();
	КонецЕсли;
	
КонецПроцедуры

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

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

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

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

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

Процедура ЧастиОбъединенияОкончаниеПеретаскивания(Элемент, ПараметрыПеретаскивания, СтандартнаяОбработка)
	
	ОбновитьНомераЧастейОбъединения();

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

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

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

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

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

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

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

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

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

Процедура ИсточникДанных1СПриИзменении(Элемент)
	
	ЗаполнитьДоступныеТаблицы1С();
	ПанельЧастиПриСменеСтраницы();
	
КонецПроцедуры

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

Процедура ИсточникДанных1СОчистка(Элемент, СтандартнаяОбработка)
	
	ИсточникДанных1СОбработкаВыбора(Элемент, "", СтандартнаяОбработка);
	
КонецПроцедуры

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

// Если в обработчике события может выполняться несколько активаций текущих строк в табличных полях, то используем отложенное оформление для избежания его многократного выполнения
Процедура ЗапретитьОформлениеТабличныхПолей()
	ЗапрещеноОформлениеТабличныхПолей = Истина;
	ПодключитьОбработчикОжидания("ОформитьТабличныеПоля", 0.1, Истина);
КонецПроцедуры

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

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

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

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

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

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

Процедура ВыбранныеПоляНачалоПеретаскивания(Элемент, ПараметрыПеретаскивания, Выполнение)
	
	ПараметрыПеретаскивания.Значение = ирКлиент.ВыделенныеСтрокиТабличногоПоляЛкс(Элемент); // Так платформа будет делать копию таблицы
	//ПараметрыПеретаскивания.Значение = Элемент.ВыделенныеСтроки; // Так при переходе на другие запросы пакета и части объедиения массив будет терять содержимое
	
КонецПроцедуры

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

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

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

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

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

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

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

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

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

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

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

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

Процедура МенюДоступныхПолейКолонкаБД(Кнопка)
	// Вставить содержимое обработчика.
КонецПроцедуры

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

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

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

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

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

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

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

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

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

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

Процедура ЧастиОбъединенияНачалоПеретаскивания(Элемент, ПараметрыПеретаскивания, Выполнение)
	// Устранено аварийное завершение приложения при перетаскивании https://www.hostedredmine.com/issues/966596
	Для Каждого ЧастьОбъединения Из Элемент.ВыделенныеСтроки Цикл
		Для Каждого СвязьТаблиц Из ирОбщий.ВсеСтрокиДереваЗначенийЛкс(ЧастьОбъединения.СвязиТаблиц) Цикл
			ОчиститьТокеныВНастройкахКомпоновки(СвязьТаблиц.Условие);
		КонецЦикла;
	КонецЦикла;
КонецПроцедуры

Процедура ЗапросыПакетаНачалоПеретаскивания(Элемент, ПараметрыПеретаскивания, Выполнение)
	// Устранено аварийное завершение приложения при перетаскивании https://www.hostedredmine.com/issues/966596
	Для Каждого ВыделеннаяСтрока Из Элемент.ВыделенныеСтроки Цикл
		Для Каждого ЧастьОбъединения Из ВыделеннаяСтрока.ЧастиОбъединения Цикл
			Для Каждого СвязьТаблиц Из ирОбщий.ВсеСтрокиДереваЗначенийЛкс(ЧастьОбъединения.СвязиТаблиц) Цикл
				ОчиститьТокеныВНастройкахКомпоновки(СвязьТаблиц.Условие);
			КонецЦикла;
		КонецЦикла;
	КонецЦикла;
КонецПроцедуры

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

Процедура ДеревоУсловияПриНачалеРедактирования(Элемент, НоваяСтрока, Копирование)

	// Не сработает при выполении системной команды "В группу"
	Если НоваяСтрока И Не Копирование Тогда
	КонецЕсли;
	
КонецПроцедуры

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

СписокВыбораДиалектов = ЭлементыФормы.ДиалектSQL.СписокВыбора;
СписокВыбораДиалектов.Добавить("1С");
СписокВыбораДиалектов.Добавить("WQL");
СписокВыбораДиалектов.Добавить("Oracle");
СписокВыбораДиалектов.Добавить("MSSQL");
СписокВыбораДиалектов.Добавить("DB2");
СписокВыбораДиалектов.Добавить("MSVisualFoxPro");
СписокВыбораДиалектов.Добавить("MSJet");
СписокВыбораДиалектов.Добавить("MySQL");
СписокВыбораДиалектов.Добавить("PostgreSQL");
СписокВыбораДиалектов.Добавить("SQLite");
СписокВыбораДиалектов.СортироватьПоЗначению();

СписокВыбораИсточникаДанных = ЭлементыФормы.ИсточникДанных1С.СписокВыбора;
Для Каждого ОбъектМД Из Метаданные.ВнешниеИсточникиДанных Цикл
	СписокВыбораИсточникаДанных.Добавить(ОбъектМД.Имя);
КонецЦикла;
СписокВыбораИсточникаДанных.СортироватьПоЗначению();

СписокВыбораПервые = ЭлементыФормы.ПервыеКоличество.СписокВыбора;
СписокВыбораПервые.Добавить(1);
СписокВыбораПервые.Добавить(10);
СписокВыбораПервые.Добавить(100);
СписокВыбораПервые.Добавить(1000);
СписокВыбораПервые.Добавить(10000);
СписокВыбораПервые.Добавить(100000);
СписокВыбораПервые.Добавить(1000000);
СписокВыбораПервые.СортироватьПоЗначению();        

СписокВыбораТипИтогов = ЭлементыФормы.ГруппирующиеПоляИтогов.Колонки.ТипИтогов.ЭлементУправления.СписокВыбора;
СписокВыбораТипИтогов.Добавить("Иерархия");
СписокВыбораТипИтогов.Добавить("ТолькоИерархия");

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