//ирПортативный Перем ирПортативный Экспорт;
//ирПортативный Перем ирОбщий Экспорт;
//ирПортативный Перем ирСервер Экспорт;
//ирПортативный Перем ирКэш Экспорт;
//ирПортативный Перем ирПривилегированный Экспорт;

////////////////////////////////////////////////////////////////////////////////
// КОНТЕКСНАЯ ПОДСКАЗКА ПОЛЯ ТЕКСТОВОГО ДОКУМЕНТА

#Если Клиент Тогда

Перем ИмяКласса Экспорт;
Перем СсылочнаяФормаКласса Экспорт;
Перем ДопКнопкиКомандныхПанелей Экспорт;
Перем СоответствиеЭУ Экспорт;
Перем ФормаПодсказки Экспорт;

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

Перем шЧисло;
Перем шБуква;
Перем шСтрокаПрограммы Экспорт;
Перем шСтрокаЗапроса;
Перем шИндекс;
Перем шСкобки;
Перем шНачалоСкобок;
Перем шИмя;
Перем шПараметрЗапроса;
Перем шНачалоИдентификатора;
Перем шИЗ;
Перем шРазделитель;
Перем шВыражениеПрограммы;
Перем шВыражениеЗапроса;
Перем шВызовМетодаПрограммы;
Перем шВызовМетодаЗапроса;
Перем шПока;
Перем шЕсли;
Перем шВызватьИсключение;
Перем шНачалоТокена;  
Перем шКонецТокена;
Перем шКомментарий;
Перем шПрисваивание;
Перем шПоискОписанияТаблицы;

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

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

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

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

Процедура ИнициализироватьСсылочно(пФорма, мСвойстваФормы, пПолеТекстовогоДокумента, пКоманднаяПанель = Неопределено,
	пЯзыкПрограммы = 0, пМетодВыполнения = "", пКонтекстВыполнения = Неопределено, пТипТекста = "Алгоритм",
	пКонфигурация = Неопределено) Экспорт

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

Процедура УстановитьФормуВладельца(пФорма) Экспорт

	ФормаВладелец = пФорма;
	мСообщенияЧерезПредупреждения = ФормаВладелец.МодальныйРежим;

КонецПроцедуры // УстановитьВладельца()

// Освобождает ресурсы занятые экземпляром класса.
// Самое главное - очистить ссылки на формы и объекты БД.
//
// Параметры:
//  Нет.
//
Процедура Уничтожить() Экспорт

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

КонецПроцедуры // Уничтожить()


////////////////////////////////////////////////////////////////////////////////
// ПРОГРАММНЫЙ ИНТЕРФЕЙС

// Получает номер текущей строки в тексте (по конечной границе выделения).
//
// Параметры:
//  Нет.
//
// Возвращаемое значение:
//  Число.
//
Функция ПолучитьНомерТекущейСтроки() Экспорт

	ПолеТекстовогоДокумента.ПолучитьГраницыВыделения(мНачальнаяСтрока, мНачальнаяКолонка, мКонечнаяСтрока, мКонечнаяКолонка);
	Возврат мКонечнаяСтрока;

КонецФункции // ПолучитьНомерТекущейСтроки()

// Получает текущее объектное выражение (на котором установлен курсор).
//
// Параметры:
//  Нет.
//
// Возвращаемое значение:
//  Строка - объектное выражение, в котором находится курсов.
//
Функция ПолучитьТекущееОбъектноеВыражение() Экспорт

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

КонецФункции // ПолучитьТекущееОбъектноеВыражение()

// Получает текущее контекст параметра. 
//
// Параметры:
//  Нет.
//
// Возвращаемое значение:
//  Структура -
//    "ОбъектноеВыражение"
//    "НомерПараметра"
//
Функция ПолучитьТекущийКонтекстПараметра() Экспорт

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

КонецФункции // ПолучитьТекущийКонтектПараметра()

// Разбирает контекст метода.
//
// Параметры:
//  Нет.
//
Функция ПолучитьТекущийКонтекстМетода() Экспорт

	мПлатформа.ИнициализацияОписанияМетодовИСвойств();
	ПолеТекстовогоДокумента.ПолучитьГраницыВыделения(мНачальнаяСтрока, мНачальнаяКолонка, мКонечнаяСтрока, мКонечнаяКолонка);
	RegExp.Global = Истина;
	
	ВыделитьНачалоИКонецТекущейСтроки();
	мКонтекст = "";
	
	ОригинальныйТекст = ПолеТекстовогоДокумента.ПолучитьТекст();
	СлужебноеПолеТекстовогоДокумента.УстановитьТекст(ОригинальныйТекст);
	мПредшествующийТекст = "";
	СледующийТекст = "";
	
	Если мКонечнаяСтрока > 1 Тогда
		СлужебноеПолеТекстовогоДокумента.УстановитьГраницыВыделения(1, 1, мКонечнаяСтрока - 1, 333);
		мПредшествующийТекст = СлужебноеПолеТекстовогоДокумента.ВыделенныйТекст;
	КонецЕсли; 
	
	МаксНомерСтроки = Мин(СлужебноеПолеТекстовогоДокумента.КоличествоСтрок(), мКонечнаяСтрока + 100);
	Если Истина
		И МаксНомерСтроки > 0
		И МаксНомерСтроки <= СлужебноеПолеТекстовогоДокумента.КоличествоСтрок() 
	Тогда
		СлужебноеПолеТекстовогоДокумента.УстановитьГраницыВыделения(мКонечнаяСтрока + 1, 1, МаксНомерСтроки, 333);
		СледующийТекст = СлужебноеПолеТекстовогоДокумента.ВыделенныйТекст;
	КонецЕсли;
	
	ТекстДоКурсора = мПредшествующийТекст + ТекущееНачалоСтроки; // Так почему то иногда возникало смещение на 1 символ
	ТекстПослеКурсора = ТекущийКонецСтроки + Символы.ПС + СледующийТекст;
	
	Если ЯзыкПрограммы = 0 Тогда
		ШаблонПараметра = "(?:" + шВыражениеПрограммы + ")?" + шРазделитель + "*";
	Иначе
		ШаблонПараметра = "(?:" + шВыражениеЗапроса   + ")?" + шРазделитель + "*";
	КонецЕсли;
	RegExp.Global = Ложь;
	RegExp.MultiLine = Ложь;
	RegExp.Pattern = "^(?:" + ШаблонПараметра + ",)*" + ШаблонПараметра + "\)";
	Результат = RegExp.Execute(ТекстПослеКурсора);
	Если Результат.Count > 0 Тогда
		//КонецВыражения = Лев(ТекстПослеКурсора, Результат.Item(0).Length);
		КонецВыражения = Результат.Item(0).Value;
	КонецЕсли;
	
	RegExp.Global = Ложь;
	RegExp.MultiLine = Ложь;
	RegExp.Pattern = шВызовМетодаПрограммы + "$";
	//Результат = RegExp.Execute(ТекстДоКурсора + Лев(КонецВыражения, СтрДлина(КонецВыражения) - 1) + ",");
	Результат = RegExp.Execute(Лев(ОригинальныйТекст, СтрДлина(ТекстДоКурсора)+ СтрДлина(КонецВыражения) - 1) + ",");
	МассивПараметров = Новый Массив;
	Если Результат.Count > 0 Тогда
		ПоследнееВхождение = Результат.Item(Результат.Count - 1);
		Попытка
			СлужебноеПолеТекстовогоДокумента.УстановитьГраницыВыделения(ПоследнееВхождение.FirstIndex + 1, 
				ПоследнееВхождение.FirstIndex + 1 + ПоследнееВхождение.Length);
		Исключение
			СлужебноеПолеТекстовогоДокумента.УстановитьГраницыВыделения(ПоследнееВхождение.FirstIndex + 1, 
				ПоследнееВхождение.FirstIndex + 1 + ПоследнееВхождение.Length - 1); // -1 надо делать из-за бага платформы (она не дает выделить последний символ в тексте)
		КонецПопытки;
		СлужебноеПолеТекстовогоДокумента.ПолучитьГраницыВыделения(мНачальнаяСтрока, мНачальнаяКолонка, мКонечнаяСтрока, мКонечнаяКолонка);
		мКонтекст = ПоследнееВхождение.SubMatches(0) + "(";
		ТекстПараметров = ПоследнееВхождение.SubMatches(4);
		RegExp.Global = Истина;
		Если ЯзыкПрограммы = 0 Тогда
			ШаблонПараметра = "(" + шВыражениеПрограммы + ")?" + шРазделитель + "*";
		Иначе
			ШаблонПараметра = "(" + шВыражениеЗапроса   + ")?" + шРазделитель + "*";
		КонецЕсли;
		RegExp.Pattern = ШаблонПараметра + ",";
		Результат = RegExp.Execute(ТекстПараметров);
		ЛокальнаяПозицияКурсора = СтрДлина(ТекстПараметров) - СтрДлина(КонецВыражения);
		Счетчик = 0;
		Для Каждого Вхождение Из Результат Цикл
			Счетчик = Счетчик + 1;
			Если Истина
				И (Вхождение.FirstIndex + 1) <= ЛокальнаяПозицияКурсора 
				И (Вхождение.FirstIndex + Вхождение.Length + 1) >= ЛокальнаяПозицияКурсора 
			Тогда
				мНомерПараметра = Счетчик;
			КонецЕсли;
			МассивПараметров.Добавить(СокрЛП(Вхождение.SubMatches(0)));
		КонецЦикла;
		СтруктураРезультата = Новый Структура;
		СтруктураРезультата.Вставить("ОбъектноеВыражение", мКонтекст);
		СтруктураРезультата.Вставить("ОригинальныйТекст", Лев(ПоследнееВхождение.Value, СтрДлина(ПоследнееВхождение.Value) - 1) + ")");
		СтруктураРезультата.Вставить("МассивПараметров", МассивПараметров);
		СтруктураРезультата.Вставить("НомерПараметра", мНомерПараметра);
		Возврат СтруктураРезультата;
	Иначе
		Возврат Неопределено;
	КонецЕсли;

КонецФункции // ПолучитьТекущийКонтекстМетода()

// Разбирает контекст метода.
//
// Параметры:
//  Нет.
//
Функция УстановитьТекущийКонтекстМетода(НовыйТекст) Экспорт

	ПолеТекстовогоДокумента.УстановитьГраницыВыделения(мНачальнаяСтрока, мНачальнаяКолонка, мКонечнаяСтрока, мКонечнаяКолонка);
	ПолеТекстовогоДокумента.ВыделенныйТекст = НовыйТекст;
	ПолеТекстовогоДокумента.УстановитьГраницыВыделения(мНачальнаяСтрока, мНачальнаяКолонка, мНачальнаяСтрока, мНачальнаяКолонка);

КонецФункции // УстановитьТекущийКонтекстМетода()

// Разбирает контекст УК.
//
// Параметры:
//  Нет.
//
Функция ПолучитьТекущийКонтекстУК() Экспорт

	мПлатформа.ИнициализацияОписанияМетодовИСвойств();
	ПолеТекстовогоДокумента.ПолучитьГраницыВыделения(мНачальнаяСтрока, мНачальнаяКолонка, мКонечнаяСтрока, мКонечнаяКолонка);
	RegExp.Global = Истина;
	ВыделитьНачалоИКонецТекущейСтроки();
	ИмяСтруктурыПараметров = "";
	
	ОригинальныйТекст = ПолеТекстовогоДокумента.ПолучитьТекст();
	СлужебноеПолеТекстовогоДокумента.УстановитьТекст(ОригинальныйТекст);
	мПредшествующийТекст = "";
	СледующийТекст = "";
	Если мКонечнаяСтрока > 1 Тогда
		СлужебноеПолеТекстовогоДокумента.УстановитьГраницыВыделения(1, 1, мКонечнаяСтрока - 1, 333);
		мПредшествующийТекст = СлужебноеПолеТекстовогоДокумента.ВыделенныйТекст;
	КонецЕсли; 
	МаксНомерСтроки = Мин(СлужебноеПолеТекстовогоДокумента.КоличествоСтрок(), мКонечнаяСтрока + 100);
	Если Истина
		И МаксНомерСтроки > 0
		И МаксНомерСтроки <= СлужебноеПолеТекстовогоДокумента.КоличествоСтрок() 
	Тогда
		СлужебноеПолеТекстовогоДокумента.УстановитьГраницыВыделения(мКонечнаяСтрока + 1, 1, МаксНомерСтроки, 333);
		СледующийТекст = СлужебноеПолеТекстовогоДокумента.ВыделенныйТекст;
	КонецЕсли;
	ТекстДоКурсора = мПредшествующийТекст + Символы.ПС + ТекущееНачалоСтроки;
	ТекстПослеКурсора = ТекущийКонецСтроки + Символы.ПС + СледующийТекст;
	
	ШаблонУК = "(" + шИмя + ")" + шРазделитель + "*=" + шРазделитель + "*УК\((" + шИмя + ")\)";
	RegExp.Global = Ложь;
	RegExp.MultiLine = Ложь;
	RegExp.Pattern = "^" + "(" + шРазделитель + "*)" + ШаблонУК;
	Результат = RegExp.Execute(ТекущееНачалоСтроки + ТекстПослеКурсора);
	Если Результат.Count > 0 Тогда
		Смещение = Результат.Item(0).SubMatches(0);
		ИмяСтруктурыПараметров = Результат.Item(0).SubMatches(1);
		МассивПараметров = Новый Массив;
		МассивПараметров.Добавить(Результат.Item(0).SubMatches(2));
	Иначе
		Возврат Неопределено;
	КонецЕсли;
	
	ШаблонПараметра = шРазделитель + "*" + ИмяСтруктурыПараметров + "\.(" + шИмя + ")" + шРазделитель + "*=" 
		+ шРазделитель + "*(" + шВыражениеПрограммы + ")?" + шРазделитель + "*" + ";";
	RegExp.Pattern = "^" + "(" + шРазделитель + "*)" + ШаблонУК + ";" + "((?:" + ШаблонПараметра  + шРазделитель + "*" + ")*)";
	Результат = RegExp.Execute(ТекущееНачалоСтроки + ТекстПослеКурсора);
	Если Результат.Count > 0 Тогда
		ПолныйТекстВыражения = Результат.Item(0).Value;
	Иначе
		Возврат Неопределено;
	КонецЕсли;
	
	//RegExp.Global = Ложь;
	RegExp.MultiLine = Ложь;
	//RegExp.Pattern = "(" + шРазделитель + "*)("+ шИмя + ")" + шРазделитель + "*=s*" + шВызовМетодаПрограммы + "$";
	RegExp.Pattern = ШаблонУК + ";" + "((?:" + ШаблонПараметра  + шРазделитель + "*" + ")*)$";
	Результат = RegExp.Execute(мПредшествующийТекст + ПолныйТекстВыражения);
	СтруктураПараметров = Новый Структура;
	Если Результат.Count > 0 Тогда
		ПоследнееВхождение = Результат.Item(Результат.Count - 1);
		Попытка
			СлужебноеПолеТекстовогоДокумента.УстановитьГраницыВыделения(ПоследнееВхождение.FirstIndex + 1, 
				ПоследнееВхождение.FirstIndex + 1 + ПоследнееВхождение.Length);
		Исключение
			СлужебноеПолеТекстовогоДокумента.УстановитьГраницыВыделения(ПоследнееВхождение.FirstIndex + 1, 
				ПоследнееВхождение.FirstIndex + 1 + ПоследнееВхождение.Length - 1); // -1 надо делать из-за бага платформы (она не дает выделить последний символ в тексте)
		КонецПопытки;
		СлужебноеПолеТекстовогоДокумента.ПолучитьГраницыВыделения(мНачальнаяСтрока, мНачальнаяКолонка, мКонечнаяСтрока, мКонечнаяКолонка);
		//ИмяСтруктурыПараметров = Результат.Item(0).SubMatches(0);
		ТекстПараметров = ПоследнееВхождение.SubMatches(2);
		RegExp.Global = Истина;
		RegExp.Pattern = ШаблонПараметра;
		Результат = RegExp.Execute(ТекстПараметров);
		//ЛокальнаяПозицияКурсора = СтрДлина(ТекстПараметров) - СтрДлина(ПолныйТекстВыражения);
		Счетчик = 0;
		Для Каждого Вхождение Из Результат Цикл
			Счетчик = Счетчик + 1;
			//Если Истина
			//	И (Вхождение.FirstIndex + 1) <= ЛокальнаяПозицияКурсора 
			//	И (Вхождение.FirstIndex + Вхождение.Length + 1) >= ЛокальнаяПозицияКурсора 
			//Тогда
			//	мНомерПараметра = Счетчик;
			//КонецЕсли;
			СтруктураПараметров.Вставить(СокрЛП(Вхождение.SubMatches(0)), СокрЛП(Вхождение.SubMatches(1)));
		КонецЦикла;
		СтруктураРезультата = Новый Структура;
		СтруктураРезультата.Вставить("ИмяСтруктурыПараметров", ИмяСтруктурыПараметров);
		СтруктураРезультата.Вставить("МассивПараметров", МассивПараметров);
		СтруктураРезультата.Вставить("ОригинальныйТекст", ПоследнееВхождение.Value);
		СтруктураРезультата.Вставить("Смещение", Смещение);
		СтруктураРезультата.Вставить("СтруктураПараметров", СтруктураПараметров);
		СтруктураРезультата.Вставить("НомерПараметра", мНомерПараметра);
		Возврат СтруктураРезультата;
	Иначе
		Возврат Неопределено;
	КонецЕсли;

КонецФункции // ПолучитьТекущийКонтекстМетода()


// Вызывается в конце обработки команды.
//
// Параметры:
//  Нет.
//
Процедура ЗнакончитьОбработкуКоманды() Экспорт

	мРазбиратьКонтекст = Истина;

КонецПроцедуры // ЗнакончитьОбработкуКоманды()

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

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

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

КонецФункции // ВставитьСсылкуНаОбъектБД()

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

	ЗнакончитьОбработкуКоманды();
	Возврат Результат;
	
КонецФункции // Нажатие()

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

Функция ПолучитьВыделенныйИлиВесьТекст() Экспорт 

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

КонецФункции // ПолучитьВыделенныйИлиВесьТекст()

// <Описание процедуры>
//
// Параметры:
//  <Параметр1>  – <Тип.Вид> – <описание параметра>
//                 <продолжение описания параметра>;
//  <Параметр2>  – <Тип.Вид> – <описание параметра>
//                 <продолжение описания параметра>.
//
Процедура КопироватьВБуферОбменаТекстВВидеКода() Экспорт

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

КонецПроцедуры // КопироватьВБуферОбменаТекстВВидеКода()

Процедура Закомментировать() Экспорт

	#Если Сервер И Не Сервер Тогда
	    ПолеТекстовогоДокумента = Новый ТекстовыйДокумент;
	#КонецЕсли
	//Для Счетчик = мНачальнаяСтрока По мКонечнаяСтрока Цикл
	//	ПолеТекстовогоДокумента.УстановитьГраницыВыделения(Счетчик, 1, Счетчик, 1);
	//	ПолеТекстовогоДокумента.ВыделенныйТекст = "//";
	//КонецЦикла;
	//ПолеТекстовогоДокумента.УстановитьГраницыВыделения(мНачальнаяСтрока, мНачальнаяКолонка, мКонечнаяСтрока, мКонечнаяКолонка);
	//
	ПерваяСтрока = мНачальнаяСтрока;
	ПерваяКолонка = мНачальнаяКолонка;
	ПоследняяСтрока = мКонечнаяСтрока;
	ПоследняяКолонка = мКонечнаяКолонка;
	КоличествоСтрок = ПолеТекстовогоДокумента.КоличествоСтрок();
	ВыделенныйФрагмент = "";
	ДлинаПоследнейСтроки = 0;
	
	Если ПоследняяКолонка = 1 Тогда 
		ПоследняяСтрока = ПоследняяСтрока - 1;
	КонецЕсли;
	Если ПерваяСтрока >= ПоследняяСтрока И ПоследняяКолонка = 1 Тогда 
		ПоследняяКолонка = Макс(1, СтрДлина(ПолеТекстовогоДокумента.ПолучитьСтроку(ПерваяСтрока)));
		ПоследняяСтрока = ПерваяСтрока;
	КонецЕсли;
	Для НомерСтроки = 1 По КоличествоСтрок Цикл
		Фрагмент = ПолеТекстовогоДокумента.ПолучитьСтроку(НомерСтроки);
		Если НомерСтроки >= ПерваяСтрока И НомерСтроки <= ПоследняяСтрока Тогда
			Если НомерСтроки = ПерваяСтрока Тогда 
				ВыделенныйФрагмент = ВыделенныйФрагмент + "//" + Фрагмент;
			Иначе
				ВыделенныйФрагмент = ВыделенныйФрагмент + Символы.ПС + "//" +Фрагмент;
			КонецЕсли;
			Если НомерСтроки = ПоследняяСтрока Тогда 
				ДлинаПоследнейСтроки = СтрДлина(Фрагмент) + 3;
			КонецЕсли;
		КонецЕсли;
	КонецЦикла;
	
	Если ПоследняяКолонка = 1 Тогда 
		ПоследняяСтрока = ПоследняяСтрока + 1;
		ДлинаПоследнейСтроки = 1;
		ВыделенныйФрагмент =  ВыделенныйФрагмент + Символы.ПС;
	КонецЕсли;

	Элемент = ПолеТекстовогоДокумента;
	Элемент.УстановитьГраницыВыделения(ПерваяСтрока, 1, ПоследняяСтрока, ДлинаПоследнейСтроки);
	Элемент.ВыделенныйТекст = ВыделенныйФрагмент;
	Элемент.УстановитьГраницыВыделения(ПерваяСтрока, 1, ПоследняяСтрока, ДлинаПоследнейСтроки);

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

Процедура Раскомментировать() Экспорт

	#Если Сервер И Не Сервер Тогда
	    ПолеТекстовогоДокумента = Новый ТекстовыйДокумент;
	#КонецЕсли
	//Для Счетчик = мНачальнаяСтрока По мКонечнаяСтрока Цикл
	//	СтрокаТекста = СтрПолучитьСтроку(ТекстДоИзменения, Счетчик);
	//	Если Лев(СокрЛ(СтрокаТекста), 2) = "//" Тогда
	//		ПозицияМаркера = Найти(СтрокаТекста, "//");
	//		ПолеТекстовогоДокумента.УстановитьГраницыВыделения(Счетчик, 1, Счетчик, 10000);
	//		ПолеТекстовогоДокумента.ВыделенныйТекст = Сред(СтрокаТекста, 1, ПозицияМаркера - 1) + Сред(СтрокаТекста, ПозицияМаркера + 2);
	//	КонецЕсли; 
	//КонецЦикла;
	//ПолеТекстовогоДокумента.УстановитьГраницыВыделения(мНачальнаяСтрока, мНачальнаяКолонка, мКонечнаяСтрока, мКонечнаяКолонка);
	//
	ПерваяСтрока = мНачальнаяСтрока;
	ПерваяКолонка = мНачальнаяКолонка;
	ПоследняяСтрока = мКонечнаяСтрока;
	ПоследняяКолонка = мКонечнаяКолонка;
	КоличествоСтрок = ПолеТекстовогоДокумента.КоличествоСтрок();
	ВыделенныйФрагмент = "";
	ДлинаПоследнейСтроки = ПоследняяКолонка;
	Если ПоследняяКолонка = 1 Тогда 
		ПоследняяСтрока = ПоследняяСтрока - 1;
	КонецЕсли;
	Если ПерваяСтрока >= ПоследняяСтрока И ПоследняяКолонка = 1 Тогда 
		ПоследняяКолонка = СтрДлина(ПолеТекстовогоДокумента.ПолучитьСтроку(ПерваяСтрока));
		ПоследняяСтрока = ПерваяСтрока;
	КонецЕсли;

	Для НомерСтроки = 1 По КоличествоСтрок Цикл
		Фрагмент = ПолеТекстовогоДокумента.ПолучитьСтроку(НомерСтроки);
		Если НомерСтроки >= ПерваяСтрока И НомерСтроки <= ПоследняяСтрока Тогда
			Если Лев(СокрЛ(Фрагмент), 2) = "//" Тогда
				Позиция = Найти(Фрагмент, "//");
				Фрагмент = Лев(Фрагмент, Позиция - 1) + Сред(Фрагмент, Позиция + 2);
			КонецЕсли;
			Если НомерСтроки = ПерваяСтрока Тогда 
				ВыделенныйФрагмент = ВыделенныйФрагмент + Фрагмент;
			Иначе
				ВыделенныйФрагмент = ВыделенныйФрагмент + Символы.ПС + Фрагмент;
			КонецЕсли;
			Если НомерСтроки = ПоследняяСтрока Тогда 
				ДлинаПоследнейСтроки = СтрДлина(Фрагмент) + 3;
			КонецЕсли;
		КонецЕсли;
	КонецЦикла;
	
	Если ПоследняяКолонка = 1 Тогда 
		ПоследняяСтрока = ПоследняяСтрока + 1;
		ДлинаПоследнейСтроки = 1;
		ВыделенныйФрагмент =  ВыделенныйФрагмент + Символы.ПС;
	КонецЕсли;

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

// Устанавливает фокус на поле текстового документа.
//
// Параметры:
//  Нет.
//
Процедура УстановитьФокус() Экспорт 

	ФормаВладелец.ТекущийЭлемент = ПолеТекстовогоДокумента;

КонецПроцедуры // УстановитьФокус()

Процедура ВыделитьНачалоИКонецТекущейСтроки()

	//ОригинальнаяСтрока = СокрП(ПолеТекстовогоДокумента.ПолучитьСтроку(мКонечнаяСтрока));
	ОригинальнаяСтрока = ПолеТекстовогоДокумента.ПолучитьСтроку(мКонечнаяСтрока);
	Для Счетчик = 0 По мКонечнаяКолонка - СтрДлина(ОригинальнаяСтрока) - 2 Цикл
		ОригинальнаяСтрока = ОригинальнаяСтрока + " ";
	КонецЦикла;
	ТекущееНачалоСтроки = Лев(ОригинальнаяСтрока, мКонечнаяКолонка - 1);
	ТекущийКонецСтроки = Сред(ОригинальнаяСтрока, мКонечнаяКолонка);

КонецПроцедуры // ВыделитьНачалоИКонецТекущейСтроки()

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

	ТекстИнициализации = "";
	Если ЯзыкПрограммы = 0 Тогда
		Для Каждого ЛокальноеСлово Из ТаблицаЛокальногоКонтекста Цикл
			Если Истина
				//И Не ЛокальноеСлово.Глобальное // Закомментировано 06.12.2011
				И ТипТекста = "Алгоритм"
				И ЛокальноеСлово.ТипСлова = "Свойство" 
			Тогда
				ТекстИнициализации = ЛокальноеСлово.Слово + " = 0; " + ТекстИнициализации;
			КонецЕсли;
		КонецЦикла;
		Для Каждого СтрокаПараметра Из Параметры Цикл
			Если ТипТекста = "Алгоритм" Тогда
				ТекстИнициализации = СтрокаПараметра.Имя + " = 0; " + ТекстИнициализации;
			КонецЕсли;
		КонецЦикла;
	КонецЕсли; 

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

КонецФункции // ПолучитьИнформациюОбОшибке()

Процедура ВыделитьТекущееСлово() Экспорт 

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

КонецПроцедуры // ВыделитьТекущееСлово()

Процедура ВыделитьТекущееОбъектноеВыражение() Экспорт 

	ПолучитьТекущееОбъектноеВыражение();
	мНачальнаяКолонка = мКонечнаяКолонка - СтрДлина(НачалоКонтекста);
	мКонечнаяКолонка = мКонечнаяКолонка + СтрДлина(КонецКонтекста);
	Если Прав(КонецКонтекста, 1) = "(" Тогда
		мКонечнаяКолонка = мКонечнаяКолонка - 1;
	КонецЕсли;
	ПолеТекстовогоДокумента.УстановитьГраницыВыделения(мНачальнаяСтрока, мНачальнаяКолонка, мКонечнаяСтрока, мКонечнаяКолонка);

КонецПроцедуры // ВыделитьТекущееСлово()

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

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

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

КонецФункции // ОткрытьПоискВСинтаксПомощнике()

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

// <Описание процедуры>
//
// Параметры:
//  <Параметр1>  – <Тип.Вид> – <описание параметра>
//                 <продолжение описания параметра>;
//  <Параметр2>  – <Тип.Вид> – <описание параметра>
//                 <продолжение описания параметра>.
//
Процедура ОткрытьСправкуПоЯзыкуПрограммы() Экспорт 

	Если ЯзыкПрограммы = 0 Тогда
		Книга = "shcntx_ru";
	ИначеЕсли ЯзыкПрограммы = 1 Тогда
		Книга = "shquery_ru";
	ИначеЕсли ЯзыкПрограммы = 2 Тогда
		Книга = "dcsui_ru";
	КонецЕсли;
	ФормаСправка = ирОбщий.ПолучитьФормуЛкс("Обработка.ирСинтаксПомощник.Форма", , ФормаВладелец);
	ФормаСправка.ОткрытьАдрес("//" + Книга);

КонецПроцедуры // ОткрытьСправкуПоЯзыкуПрограммы()

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

Функция УдалитьКомментарии(Текст) Экспорт 
	
	RegExp.Global = Истина;
	RegExp.Multiline = Ложь;
	
	Если Ложь
		Или ЯзыкПрограммы = 1
		Или ЯзыкПрограммы = 2
	Тогда
		// Не проверено
		RegExp.Pattern = "(?:(?://[^\n]*" + ")|(" + шСтрокаЗапроса + ")|([\s\S])";
		ШаблонЗамены = "$1$2$3$4";
	ИначеЕсли ЯзыкПрограммы = 0 Тогда
		шОднострочнаяСтрокаПрограммыСКавычки = """(?:(?:"""")|[^""\n$])*""?"; 
		шОднострочнаяСтрокаПрограммыСЧерты = "\n\s*\|(?:(?:"""")|[^""\n$])*""?";
		RegExp.Pattern = "//[^\n]*|" + "(" + "#[^\n]*" + ")|(" + шОднострочнаяСтрокаПрограммыСКавычки + ")|(" + шОднострочнаяСтрокаПрограммыСЧерты + ")|([\s\S])";
		ШаблонЗамены = "$1$2$3$4";
	КонецЕсли;
	Результат = RegExp.Replace(Текст, ШаблонЗамены);
	Возврат Результат;
	
КонецФункции

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

	RegExp.Global = Истина;
	RegExp.Multiline = Ложь;
	
	//// Старый вариант - 
	//Если Ложь
	//	Или ЯзыкПрограммы = 1
	//	Или ЯзыкПрограммы = 2
	//Тогда
	//	RegExp.Pattern = "(""" + шИмя+ "(?:\." + шИмя + ")*"")|(" + "//(:)?[^\n]*(?:\n|$)" + ")|(" + шСтрокаЗапроса + ")|(.|\n|\r)";
	//ИначеЕсли ЯзыкПрограммы = 0 Тогда
	//	RegExp.Pattern = "(""" + шИмя+ "(?:\." + шИмя + ")*"")|(" + "//(:)?[^\n]*(?:\n|$)" + ")|(" + шСтрокаПрограммы + ")|(.|\n|\r)";
	//КонецЕсли;
	//Результат = RegExp.Execute(Текст);
	//RegExp.Pattern = "(\S)";
	//ЗалитыйТекст = "";
	//Для Каждого Match Из Результат Цикл
	//	НайденныйТекст = Неопределено;
	//	ТекстДляЗаливки = Неопределено;
	//	Если Match.SubMatches(1) <> Неопределено Тогда
	//		Если Истина
	//			И ЯзыкПрограммы = 0
	//			И Match.SubMatches(2) <> Неопределено
	//		Тогда
	//			НовыйТекстСтроки = Сред(Match.SubMatches(1), СтрДлина("//:") + 1) + Символы.ПС;
	//		Иначе
	//			ТекстДляЗаливки = Match.SubMatches(1);
	//		КонецЕсли;
	//	ИначеЕсли Match.SubMatches(3) <> Неопределено Тогда
	//		ТекстДляЗаливки = Match.SubMatches(3);
	//	ИначеЕсли Match.SubMatches(0) <> Неопределено Тогда 
	//		НовыйТекстСтроки = Match.SubMatches(0);
	//	ИначеЕсли Match.SubMatches(4) <> Неопределено Тогда 
	//		НовыйТекстСтроки = Match.SubMatches(4);
	//	КонецЕсли;
	//	Если ТекстДляЗаливки <> Неопределено Тогда
	//		ЗалитыйТекст = ЗалитыйТекст + RegExp.Replace(ТекстДляЗаливки, СимволЗамена);
	//	Иначе
	//		ЗалитыйТекст = ЗалитыйТекст + НовыйТекстСтроки;
	//	КонецЕсли;
	//КонецЦикла;
	
	// Новый вариант. Значительно быстрее старого.
	// Количество символов в тексте меняется, но позиции строк сохраняются
	Если Ложь
		Или ЯзыкПрограммы = 1
		Или ЯзыкПрограммы = 2
	Тогда
		////RegExp.Pattern = "(""" + шИмя+ "(?:\." + шИмя + ")*"")|(" + "//(:)?[^\n]*" + ")|(" + шСтрокаЗапроса   + ")|(.|\n|\r)";
		//RegExp.Pattern = "(""" + шИмя+ "(?:\." + шИмя + ")*"")|(?:" + "//:([^\n]*)" + ")|(?:" + "//[^\n]*" + ")|(" + шСтрокаЗапроса + ")|(.|\n|\r)";
		RegExp.Pattern = "(""" + шИмя+ "(?:\." + шИмя + ")*"")|(?:" + "//:([^\n]*)" + ")|(?:" + "//[^\n]*" + ")|(" + шСтрокаЗапроса + ")|([\s\S])";
		ШаблонЗамены = "$1$2$3$4";
	ИначеЕсли ЯзыкПрограммы = 0 Тогда
		//RegExp.Pattern = "(""" + шИмя+ "(?:\." + шИмя + ")*"")|(" + "//(:)?[^\n]*" + ")|(" + шСтрокаПрограммы + ")|(.|\n|\r)";
		шОднострочнаяСтрокаПрограммыСКавычки = """(?:(?:"""")|[^""\n$])*""?"; 
		шОднострочнаяСтрокаПрограммыСЧерты = "(?:(\n)\s*\|(?:(?:"""")|[^""\n$])*""?)";
		//RegExp.Pattern = "(""" + шИмя+ "(?:\." + шИмя + ")*"")|" + "//:([^\n]*)" + "|" + "//[^\n]*" + "|"
		//RegExp.Pattern = "(""" + шИмя+ "(?:\." + шИмя + ")*"")|" + "//:([^\n]*)" + "|" + "//[^\n]*" + "|(?:" + "#[^\n]*" + ")|" // Директивы препроцессора пропускаем. Изменено 28.01.2012
		//RegExp.Pattern = "(""" + шИмя+ "(?:\." + шИмя + ")*"")|" + "//:([^\n]*)" + "|" + "//[^\n]*|" + "(?:" + "#[^\n]*" + ")|" + "(?:" + "~" + шИмя + ")|"  // Метки пропускаем. Изменено 01.02.2012
		//	+ шОднострочнаяСтрокаПрограммыСКавычки + "|" + шОднострочнаяСтрокаПрограммыСЧерты + "|(.|\n|\r)";
		RegExp.Pattern = "(""" + шИмя+ "(?:\.[А-Яа-я_A-Za-z\d]+)*"")|" + "//:([^\n]*)" + "|" + "//[^\n]*|" + "(?:" + "#[^\n]*" + ")|" + "(?:" + "~" + шИмя + ")|" // имена ProgId от COM объектов бывают "Forms.TextBox.1"
			//+ шОднострочнаяСтрокаПрограммыСКавычки + "|" + шОднострочнаяСтрокаПрограммыСЧерты + "|(.|\n|\r)";
			+ шОднострочнаяСтрокаПрограммыСКавычки + "|" + шОднострочнаяСтрокаПрограммыСЧерты + "|([\s\S])";
		ШаблонЗамены = "$1$2$3$4";
	КонецЕсли;
	ЗалитыйТекст = RegExp.Replace(Текст, ШаблонЗамены);
	
	Если СтрДлина(ОригинальныйТекст) < 10000 Тогда // Долго на больших текстах!
		// Заливаем условия, чтобы проверка равенства в них не считалась присвоением
		// В будущем можно отказаться от этого блока и собирать все возможные типы, а потом давать юзеру выбирать.
		Если ЯзыкПрограммы = 0 Тогда
			//RegExp.Pattern = "(" + шЕсли + ")|(" + шПока + ")|(" + шВызватьИсключение + ")|(.|\n|\r)";
			RegExp.Pattern = "(" + шЕсли + ")|(" + шПока + ")|(" + шВызватьИсключение + ")|([\s\S])";
			Результат = RegExp.Execute(ЗалитыйТекст);
			RegExp.Pattern = "(\S)";
			ЗалитыйТекст = "";
			Для Каждого Match Из Результат Цикл
				НайденныйТекст = Неопределено;
				//Если Не ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(Match.SubMatches(0)) Тогда
				Если Match.SubMatches(0) <> Неопределено Тогда
					НайденныйТекст = Match.SubMatches(0);
				//ИначеЕсли Не ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(Match.SubMatches(4)) Тогда
				ИначеЕсли Match.SubMatches(4) <> Неопределено Тогда
					НайденныйТекст = Match.SubMatches(4);
				//ИначеЕсли Не ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(Match.SubMatches(8)) Тогда
				ИначеЕсли Match.SubMatches(8) <> Неопределено Тогда
					НайденныйТекст = Match.SubMatches(8);
				КонецЕсли;
				Если ЗначениеЗаполнено(НайденныйТекст) Тогда
					ЗалитыйТекст = ЗалитыйТекст + Лев(НайденныйТекст, 1) + RegExp.Replace(Сред(НайденныйТекст, 2, СтрДлина(НайденныйТекст) - 2), СимволЗамена)
						+ Прав(НайденныйТекст, 1);
				Иначе
					ЗалитыйТекст = ЗалитыйТекст + Match.SubMatches(11);
				КонецЕсли;
			КонецЦикла;
		КонецЕсли; 
	КонецЕсли; 
	Возврат ЗалитыйТекст;

КонецФункции // ЗалитьКомментарииИСтроковыеЛитералы()

// Меняет RegExp!
Функция ЭтоРусскийВариантТекстаЗапроса(Текст) Экспорт 
	
	ТекстБезКомментариев = СокрЛП(ЗалитьКомментарииИСтроковыеЛитералы(Текст));
	RegExp.Pattern = "[А-ЯЁ]";
	ЭтоРусскийЯзык = RegExp.Test(Лев(ТекстБезКомментариев, 1));
	Возврат ЭтоРусскийЯзык;

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

// Добавляет/заменяет/удаляет оператор ПОМЕСТИТЬ в запросе.
// Это неточный метод, основанный на regexp.
//
// Параметры:
//  ТекстЗапроса – Строка;
//  *ИмяВременнойТаблицы – Строка - если пустое, то оператор удаляется.
//
// Возвращаемое значение:
//  Строка - исправленный текст запроса.
//
Функция ИзменитьОператорПоместитьЗапроса(ТекстЗапроса, ИмяВременнойТаблицы = "") Экспорт 

	ЭтоРусскийЯзык = ЭтоРусскийВариантТекстаЗапроса(ТекстЗапроса); // Меняет RegExp!
	RegExp.Global = Истина;
	шСтрокаЗапроса = """(?:(?:"""")|[^""\n$])*(?:" + шРазделитель + "*(?:(?:"""")|[^""\n$])*)*(?:""|$)";
	ШаблонПОМЕСТИТЬИЗ = "(" + шСтрокаЗапроса + ")|(?:(" + шРазделитель + ")+(" + "(?:ПОМЕСТИТЬ|INTO(?:" + шРазделитель + "+TABLE)?)" + шРазделитель + "+" + шИмя + шРазделитель + "+)"
		+ "|((?:ИЗ|FROM|ГДЕ|WHERE|СГРУППИРОВАТЬ|GROUP|УПОРЯДОЧИТЬ|ORDER|ИМЕЮЩИЕ|HAVING|ОБЪЕДИНИТЬ|UNION)" + шРазделитель + "+))|(.|\r|\n)";
	RegExp.Pattern = ШаблонПОМЕСТИТЬИЗ;
	Если ЗначениеЗаполнено(ИмяВременнойТаблицы) Тогда
		Если ЭтоРусскийЯзык Тогда
			ТерминПоместить = "ПОМЕСТИТЬ";
		Иначе
			ТерминПоместить = "INTO";
		КонецЕсли; 
		Результат = RegExp.Execute(ТекстЗапроса);
		Текст = "";
		ПредложениеДобавлено = Ложь;
		Для Каждого Match Из Результат Цикл
			Если Ложь
				Или ПредложениеДобавлено
				Или Не ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(Match.SubMatches(0))
				Или Не ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(Match.SubMatches(4))
			Тогда
				Текст = Текст + Match.Value;
			Иначе
				Текст = Текст + "
				|" + ТерминПоместить + "
				|	" + ИмяВременнойТаблицы;
				Если Match.SubMatches(3) <> 0 Тогда // Видимо здесь ошибка
					Текст = Текст + Символы.ПС + Match.SubMatches(3);
				КонецЕсли;
				ПредложениеДобавлено = Истина;
			КонецЕсли;
		КонецЦикла;
		Если Не ПредложениеДобавлено Тогда
			Текст = Текст + "
			|" + ТерминПоместить + "
			|	" + ИмяВременнойТаблицы;
		КонецЕсли;
	Иначе
		Текст = RegExp.Replace(ТекстЗапроса, "$1$2$4$5");
	КонецЕсли; 
	Возврат Текст;

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

Функция ШаблонЗапросаДопускаетВстройкуВРодительскийЗапрос(Текст) Экспорт 
	
	RegExp.Global = Ложь;
	RegExp.Pattern = шРазделитель + "*(?:ВЫБРАТЬ|SELECT)(?:" + шРазделитель + "+)\*(?:" + шРазделитель + "+)(?:ИЗ|FROM)(?:" + шРазделитель + "+(?:КАК|AS)?(?:" + шРазделитель + "+" + шИмя + "))" + шРазделитель + "*";
	Результат = RegExp.Test(Текст);
	Возврат Результат;

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

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

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

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

// <Описание функции>
//
// Параметры:
//  <Параметр1>  – <Тип.Вид> – <описание параметра>
//                 <продолжение описания параметра>;
//  <Параметр2>  – <Тип.Вид> – <описание параметра>
//                 <продолжение описания параметра>.
//
// Возвращаемое значение:
//               – <Тип.Вид> – <описание значения>
//                 <продолжение описания значения>;
//  <Значение2>  – <Тип.Вид> – <описание значения>
//                 <продолжение описания значения>.
//
Процедура _РазобратьКонтекстРавенства() Экспорт

	Если Не мРазбиратьКонтекст Тогда 
		Возврат;
	КонецЕсли;
	RegExp.Global = Истина;
	ВыделитьНачалоИКонецТекущейСтроки();
	мКонтекст = "";
	
	ОригинальныйТекст = ПолеТекстовогоДокумента.ПолучитьТекст();
	мПредшествующийТекст = "";
	Если мКонечнаяСтрока > 1 Тогда
		СлужебноеПолеТекстовогоДокумента.УстановитьТекст(ОригинальныйТекст);
		СлужебноеПолеТекстовогоДокумента.УстановитьГраницыВыделения(1, 1, мКонечнаяСтрока - 1, 333);
		мПредшествующийТекст = СлужебноеПолеТекстовогоДокумента.ВыделенныйТекст;
	КонецЕсли;
	ТекстДоКурсора = мПредшествующийТекст + ТекущееНачалоСтроки;
	Если ЯзыкПрограммы = 0 Тогда
		мТекстДляПоискаОпределения = мПредшествующийТекст;
	Иначе
		мТекстДляПоискаОпределения = ОригинальныйТекст;
	КонецЕсли;
	мТекстДляПоискаОпределения = ЗалитьКомментарииИСтроковыеЛитералы(мТекстДляПоискаОпределения);
	
	RegExp.Global = Ложь;
	Если ЯзыкПрограммы = 0 Тогда
		RegExp.Pattern = "(" + шВыражениеПрограммы + ")" + шРазделитель + "*=" + шРазделитель + "*$";
	Иначе
		RegExp.Pattern = "(" + шВыражениеЗапроса   + ")" + шРазделитель + "*=" + шРазделитель + "*$";
	КонецЕсли;
	Результат = RegExp.Execute(ТекстДоКурсора);
	Если Результат.Count > 0 Тогда
		мКонтекст = Результат.Item(0).SubMatches(0);
	КонецЕсли;
	мРазбиратьКонтекст = Ложь;

КонецПроцедуры // ПолучитьЛевоеВыражениеОтРавно()

// Разбирает текущий контекст по составляющим.
//
// Параметры:
//  *ДеструктивныйАнализ - Булево, *Истина - текст для поиска определения оптимизировать.
//
Процедура РазобратьТекущийКонтекст(ЛиСправаОтРавенства = Ложь)

	Если Не мРазбиратьКонтекст Тогда 
		Возврат;
	КонецЕсли;
	мНомерПараметра = 0;
	RegExp.Global = Истина;
	ВыделитьНачалоИКонецТекущейСтроки();
	НачалоКонтекста = "";
	НачалоСлова = "";
	КонецКонтекста = "";
	мРодительскийКонтекст = "";
	мКонтекст = "";
	мАргументы = "";
	
	RegExp.Global = Ложь;
	ШаблонПрефиксаПараметра = "(?:&|\?|@)?";
		
	// Начало контекста
	СтрокаШаблона = шНачалоИдентификатора + "(";
	Если Ложь
		Или ЯзыкПрограммы = 1
		Или ЯзыкПрограммы = 2
	Тогда
		СтрокаШаблона = СтрокаШаблона + ШаблонПрефиксаПараметра + "(?:" + шИмя + ")?";
	Иначе
		СтрокаШаблона = СтрокаШаблона + шИмя; 
	КонецЕсли;
	СтрокаШаблона = СтрокаШаблона + шСкобки + "?"
		+ "((\.(" + шИмя + ")" + шСкобки + "?)|" + шИндекс + ")*\.?)";
	Если ЛиСправаОтРавенства Тогда
		СтрокаШаблона = СтрокаШаблона + шРазделитель + "*=" + шРазделитель + "*";
	КонецЕсли;
	СтрокаШаблона = СтрокаШаблона + "$";
	RegExp.Pattern = СтрокаШаблона;
	Результат = RegExp.Execute(ТекущееНачалоСтроки);
	Если Результат.Count > 0 Тогда
		НачалоКонтекста = Результат.Item(0).SubMatches(0);
	КонецЕсли;
	
	// Конец контекста
	Если Не ЛиСправаОтРавенства Тогда
		RegExp.Pattern = "([" + шБуква + "\d]*\(?)";
		Результат = RegExp.Execute(ТекущийКонецСтроки);
		Если Результат.Count > 0 Тогда
			КонецКонтекста = Результат.Item(0).SubMatches(0);
		КонецЕсли;
	КонецЕсли; 
	
	Если Ложь
		Или ЯзыкПрограммы = 1
		Или ЯзыкПрограммы = 2
	Тогда
		СтрокаШаблона = ШаблонПрефиксаПараметра + "(?:" + шИмя + ")?"; 
	Иначе
		СтрокаШаблона = шИмя;
	КонецЕсли;
	СтрокаШаблона = "(((" + шИмя + шСкобки + "?"
		+ "((\." + шИмя + шСкобки + "?)|" + шИндекс + ")*))\.)?(" + СтрокаШаблона + ")?$";
	// Родительский контекст по позиции курсора
	RegExp.Pattern = СтрокаШаблона;
	Результат = RegExp.Execute(НачалоКонтекста);
	Если Результат.Count > 0 Тогда
		ПервоеВхождение = Результат.Item(0);
		Если Не ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(ПервоеВхождение.SubMatches(1)) Тогда 
			мРодительскийКонтекст = ПервоеВхождение.SubMatches(1);
		КонецЕсли;
		Если Не ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(ПервоеВхождение.SubMatches(8)) Тогда 
			НачалоСлова = ПервоеВхождение.SubMatches(8);
		КонецЕсли;
	КонецЕсли;
	мТекущееСлово = НачалоСлова + ирОбщий.ПолучитьПервыйФрагментЛкс(КонецКонтекста);
	мКонтекст = НачалоКонтекста + КонецКонтекста;
	
	ОригинальныйТекст = ПолеТекстовогоДокумента.ПолучитьТекст();
	ТекстБезКомментариевИОпасныхСтрок = ЗалитьКомментарииИСтроковыеЛитералы(ОригинальныйТекст);
	мПредшествующийТекст = "";
	// Старый вариант
	//Для Счетчик = 1 По мКонечнаяСтрока - 1 Цикл
	//	мПредшествующийТекст = мПредшествующийТекст + ПолеТекстовогоДокумента.ПолучитьСтроку(Счетчик);
	//КонецЦикла;
	Если мКонечнаяСтрока > 1 Тогда
		СлужебноеПолеТекстовогоДокумента.УстановитьТекст(ОригинальныйТекст);
		СлужебноеПолеТекстовогоДокумента.УстановитьГраницыВыделения(1, 1, мКонечнаяСтрока - 1, 333);
		мПредшествующийТекст = СлужебноеПолеТекстовогоДокумента.ВыделенныйТекст;
	КонецЕсли;
	мПредшествующийТекст = мПредшествующийТекст + Лев(ТекущееНачалоСтроки, СтрДлина(ТекущееНачалоСтроки)
		- СтрДлина(НачалоКонтекста));
	СлужебноеПолеТекстовогоДокумента.УстановитьТекст(ТекстБезКомментариевИОпасныхСтрок);
	Если ЯзыкПрограммы = 0 Тогда
		мТекстДляПоискаОпределения = "";
		Если мКонечнаяСтрока > 1 Тогда
			СлужебноеПолеТекстовогоДокумента.УстановитьГраницыВыделения(1, 1, мКонечнаяСтрока - 1, 333);
			мТекстДляПоискаОпределения = СлужебноеПолеТекстовогоДокумента.ВыделенныйТекст;
		КонецЕсли;
		// Здесь не учтена возможность наличия комментария слева от текущей позиции
		мТекстДляПоискаОпределения = мТекстДляПоискаОпределения + Лев(ТекущееНачалоСтроки, СтрДлина(ТекущееНачалоСтроки)
			- СтрДлина(НачалоКонтекста));
	Иначе
		// мПредшествующийТекст не должен использоваться потом
		мТекстДляПоискаОпределения = ТекстБезКомментариевИОпасныхСтрок;
	КонецЕсли;
	мРазбиратьКонтекст = Ложь;

КонецПроцедуры // РазобратьТекущийКонтекст()

// Разбирает контекст параметра метода.
//
// Параметры:
//  Нет.
//
Процедура РазобратьКонтекстПараметра()

	Если Не мРазбиратьКонтекст Тогда 
		Возврат;
	КонецЕсли;
	мНомерПараметра = 0;
	RegExp.Global = Истина;
	ВыделитьНачалоИКонецТекущейСтроки();
	мКонтекст = "";
	
	ОригинальныйТекст = ПолеТекстовогоДокумента.ПолучитьТекст();
	мПредшествующийТекст = "";
	Если мКонечнаяСтрока > 1 Тогда
		СлужебноеПолеТекстовогоДокумента.УстановитьТекст(ОригинальныйТекст);
		СлужебноеПолеТекстовогоДокумента.УстановитьГраницыВыделения(1, 1, мКонечнаяСтрока - 1, 333);
		мПредшествующийТекст = СлужебноеПолеТекстовогоДокумента.ВыделенныйТекст;
	КонецЕсли;
	ТекстДоКурсора = мПредшествующийТекст + ТекущееНачалоСтроки;
	Если ЯзыкПрограммы = 0 Тогда
		мТекстДляПоискаОпределения = мПредшествующийТекст;
	Иначе
		мТекстДляПоискаОпределения = ОригинальныйТекст;
	КонецЕсли;
	мТекстДляПоискаОпределения = ЗалитьКомментарииИСтроковыеЛитералы(мТекстДляПоискаОпределения);
	
	RegExp.Global = Ложь;
	
	Если ЯзыкПрограммы = 1 Тогда
		RegExp.Pattern = шВызовМетодаЗапроса + "$";
	Иначе 
		RegExp.Pattern = шВызовМетодаПрограммы + "$";
	КонецЕсли;
	Результат = RegExp.Execute(ТекстДоКурсора);
	Если Результат.Count > 0 Тогда
		мКонтекст = Результат.Item(0).SubMatches(0) + "(";
		ТекстПараметров = Результат.Item(0).SubMatches(4);
		RegExp.Global = Истина;
		Если ЯзыкПрограммы = 0 Тогда
			RegExp.Pattern = "(" + шВыражениеПрограммы + ")?" + шРазделитель + "*,";
		Иначе
			RegExp.Pattern = "(" + шВыражениеЗапроса   + ")?" + шРазделитель + "*,";
		КонецЕсли;
		Результат = RegExp.Execute(ТекстПараметров);
		мНомерПараметра = Результат.Count + 1;
		Если Результат.Count > 0 Тогда 
			мПервыйПараметр = Результат.Item(0).SubMatches(0);
		Иначе
			мПервыйПараметр = "";
		КонецЕсли;
	КонецЕсли;
	мРазбиратьКонтекст = Ложь;

КонецПроцедуры // РазобратьКонтекстПараметра()

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

КонецФункции // ВыполнитьПрограммныйКод()

Процедура УстановитьКонфигурациюМетаданных(пКонфигурация = Неопределено, пКонтекстВыполнения = Неопределено, ДиалектSQL = Неопределено, РасширенноеПолучениеМетаданныхADO = Ложь) Экспорт

	//Если ЯзыкПрограммы = 1 Тогда
		Если ДиалектSQL = Неопределено Тогда
			Если пКонфигурация <> Неопределено Тогда
				ЭтотОбъект.Конфигурация = пКонфигурация;
			Иначе
				ЭтотОбъект.Конфигурация = мПлатформа.мМетаданные;
			КонецЕсли; 
			Если ТипЗнч(Конфигурация) = Тип("ОбъектМетаданныхКонфигурация") Тогда
				ЭтотОбъект.мДиалектSQL = "1С";
			Иначе
				Попытка
					Пустышка = Конфигурация.Provider;
				Исключение
					Пустышка = Неопределено;
				КонецПопытки;
				Если Пустышка <> Неопределено Тогда
					// Это ADODB.Connection
					Если Конфигурация.State = 1 Тогда
						ЭтотОбъект.мДиалектSQL = Конфигурация.Properties("DBMS Name").Value;
					Иначе
						// Не меняем мДиалектSQL!
					КонецЕсли; 
				Иначе
					ЭтотОбъект.мДиалектSQL = "WQL";
				КонецЕсли; 
			КонецЕсли; 
		Иначе
			Если ирОбщий.СтрокиРавныЛкс(ДиалектSQL, "1С") Тогда
				ЭтотОбъект.Конфигурация = мПлатформа.мМетаданные;
			Иначе
				ЭтотОбъект.Конфигурация = пКонфигурация;
			КонецЕсли; 
			ЭтотОбъект.мДиалектSQL = ДиалектSQL;
		КонецЕсли;
		Если мДиалектыSQL = Неопределено Тогда
			ЭтотОбъект.мДиалектыSQL = ирОбщий.ПолучитьТаблицуИзТабличногоДокументаЛкс(ПолучитьМакет("ДиалектыSQL"),,, Ложь, Истина);
		КонецЕсли; 
		ЭтотОбъект.мПараметрыДиалектаSQL = мДиалектыSQL.Найти(мДиалектSQL, "Диалект");
		ЭтотОбъект.мРасширенноеПолучениеМетаданныхADO = РасширенноеПолучениеМетаданныхADO = Истина;
	//Иначе
	//	Если пКонфигурация <> Неопределено Тогда
	//		ЭтотОбъект.Конфигурация = пКонфигурация;
	//	Иначе
	//		ЭтотОбъект.Конфигурация = мПлатформа.мМетаданные;
	//	КонецЕсли; 
	//КонецЕсли;
	
	//Если ирОбщий.СтрокиРавныЛкс(мДиалектSQL, "1С") Тогда
	//	мДоступныеТаблицыПолучены = Истина;
	//ИначеЕсли ирОбщий.СтрокиРавныЛкс(мДиалектSQL, "WQL") Тогда
	//	//ЗаполнитьДоступныеТаблицыWQL(); // Слишком долго
	//	мДоступныеТаблицыПолучены = Истина;
	//Иначе
	//	мДоступныеТаблицыПолучены = Ложь;
	//КонецЕсли; 
	ЭтотОбъект.КонтекстВыполнения = пКонтекстВыполнения;

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

Функция ЗаполнитьДоступныеТаблицыWQL() Экспорт

	////Если мДоступныеТаблицыПолучены Тогда
	////	Возврат Неопределено;
	////КонецЕсли; 
	////ЭтотОбъект.мДоступныеТаблицыПолучены = Истина;
	//ДоступныеТаблицы.Очистить();
	ОчиститьДоступныеНеВременныеТаблицы();
	Если Конфигурация = Неопределено Тогда
		Возврат Неопределено;
	КонецЕсли; 
	Состояние("Подготовка метаданных...");
	wbemFlagUseAmendedQualifiers = 131072; //&H20000
	КоллекцияКлассов = Конфигурация.SubclassesOf(, wbemFlagUseAmendedQualifiers);
	ВидимостьКолонкиСхема = Ложь;
	ВидимостьКолонкиОписание = Ложь;
	Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(КоллекцияКлассов.Count, "Получаем метаданные");
	Для Каждого ЭлементКоллекции Из КоллекцияКлассов Цикл
		ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
		СтрокаТаблицы = ДоступныеТаблицы.Добавить();
		СтрокаТаблицы.Имя = ЭлементКоллекции.Path_.Class;
		//СтрокаТаблицы.Схема = СтрокаТЗ.TABLE_SCHEMA;
		//СтрокаТаблицы.Тип = СтрокаТЗ.TABLE_TYPE;
		СтрокаТаблицы.Описание = ирОбщий.ПолучитьОписаниеЭлементаWMIЛкс(ЭлементКоллекции);
		ПолноИмя = СтрокаТаблицы.Имя;
		Если ЗначениеЗаполнено(СтрокаТаблицы.Схема) Тогда
			ПолноИмя = СтрокаТаблицы.Схема + "." + ПолноИмя;
		КонецЕсли;
		СтрокаТаблицы.ПолноеИмя = ПолноИмя;
		СтрокаТаблицы.НПолноеИмя = НРег(СтрокаТаблицы.ПолноеИмя);
		ВидимостьКолонкиСхема = ВидимостьКолонкиСхема Или ЗначениеЗаполнено(СтрокаТаблицы.Схема);
		ВидимостьКолонкиОписание = ВидимостьКолонкиСхема Или ЗначениеЗаполнено(СтрокаТаблицы.Описание);
	КонецЦикла;
	ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
	Возврат Неопределено;

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

Функция ЗаполнитьДоступныеТаблицыADO() Экспорт

	////Если мДоступныеТаблицыПолучены Тогда
	////	Возврат Неопределено;
	////КонецЕсли; 
	////мДоступныеТаблицыПолучены = Истина;
	//ДоступныеТаблицы.Очистить();
	ОчиститьДоступныеНеВременныеТаблицы();
	Если Ложь
		Или Конфигурация = Неопределено 
		Или Конфигурация.State = 0
	Тогда
		Возврат Неопределено;
	КонецЕсли; 
	Состояние("Подготовка метаданных...");
	Если Не мРасширенноеПолучениеМетаданныхADO Тогда
		Фильтры = Новый Массив();
		Фильтры.Добавить(); // TABLE_CATALOG
		Фильтры.Добавить(); // TABLE_SCHEMA
		Фильтры.Добавить(); // TABLE_NAME
		Если Не мРасширенноеПолучениеМетаданныхADO Тогда
			Фильтры.Добавить("TABLE"); // TABLE_TYPE
		КонецЕсли; 
		Фильтры = Новый COMSafeArray(Фильтры, "VT_VARIANT");
		ОписаниеТаблицRecordSet = Конфигурация.OpenSchema(20, Фильтры); //adSchemaTables // Может выполняться долго (oracle)
	Иначе
		ОписаниеТаблицRecordSet = Конфигурация.OpenSchema(20); //adSchemaTables // Может выполняться долго (oracle)
	КонецЕсли; 
	ADOUtils = мПлатформа.ПолучитьADOUtils();
	Если ADOUtils <> Неопределено Тогда
		ОписаниеТаблицТЗ = ADOUtils.ADORecordsetToValueTable(ОписаниеТаблицRecordSet);
		Для Каждого СтрокаТЗ Из ОписаниеТаблицТЗ Цикл
			ТипТаблицы = СтрокаТЗ.TABLE_TYPE;
			Если Не ЭтоПолезныйТипТаблицыADO(ТипТаблицы) Тогда
				Продолжить;
			КонецЕсли; 
			СтрокаТаблицы = ДоступныеТаблицы.Добавить();
			СтрокаТаблицы.Имя = СтрокаТЗ.TABLE_NAME;
			СтрокаТаблицы.Схема = СтрокаТЗ.TABLE_SCHEMA;
			СтрокаТаблицы.Тип = ТипТаблицы;
			СтрокаТаблицы.Описание = СтрокаТЗ.DESCRIPTION;
			ПолноеИмяДоступнойТаблицы = ПолноеИмяДоступнойТаблицы(СтрокаТаблицы.Имя, СтрокаТаблицы.Схема);
			СтрокаТаблицы.ПолноеИмя = ПолноеИмяДоступнойТаблицы;
			СтрокаТаблицы.НПолноеИмя = НРег(ПолноеИмяДоступнойТаблицы);
		КонецЦикла;
	Иначе
		Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(ОписаниеТаблицRecordSet.RecordCount, "Получаем метаданные");
		Пока Не ОписаниеТаблицRecordSet.EOF() Цикл
			ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
			ТипТаблицы = ОписаниеТаблицRecordSet.Fields("TABLE_TYPE").Value;
			Если Не ЭтоПолезныйТипТаблицыADO(ТипТаблицы) Тогда
				Продолжить;
			КонецЕсли; 
			СтрокаТаблицы = ДоступныеТаблицы.Добавить();
			СтрокаТаблицы.Имя = ОписаниеТаблицRecordSet.Fields("TABLE_NAME").Value;
			СтрокаТаблицы.Схема = ОписаниеТаблицRecordSet.Fields("TABLE_SCHEMA").Value;
			СтрокаТаблицы.Тип = ТипТаблицы;
			СтрокаТаблицы.Описание = ОписаниеТаблицRecordSet.Fields("DESCRIPTION").Value;
			ПолноеИмяДоступнойТаблицы = ПолноеИмяДоступнойТаблицы(СтрокаТаблицы.Имя, СтрокаТаблицы.Схема);
			СтрокаТаблицы.ПолноеИмя = ПолноеИмяДоступнойТаблицы;
			СтрокаТаблицы.НПолноеИмя = НРег(ПолноеИмяДоступнойТаблицы);
			ОписаниеТаблицRecordSet.MoveNext();
		КонецЦикла;
		ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
	КонецЕсли; 
	
	//Const adSchemaProviderSpecific = -1
	//Const adSchemaAsserts = 0
	//Const adSchemaCatalogs = 1
	//Const adSchemaCharacterSets = 2
	//Const adSchemaCollations = 3
	//Const adSchemaColumns = 4
	//Const adSchemaCheckConstraints = 5
	//Const adSchemaConstraintColumnUsage = 6
	//Const adSchemaConstraintTableUsage = 7
	//Const adSchemaKeyColumnUsage = 8
	//Const adSchemaReferentialConstraints = 9
	//Const adSchemaTableConstraints = 10
	//Const adSchemaColumnsDomainUsage = 11
	//Const adSchemaIndexes = 12
	//Const adSchemaColumnPrivileges = 13
	//Const adSchemaTablePrivileges = 14
	//Const adSchemaUsagePrivileges = 15
	//Const adSchemaProcedures = 16
	//Const adSchemaSchemata = 17
	//Const adSchemaSQLLanguages = 18
	//Const adSchemaStatistics = 19
	//Const adSchemaTables = 20
	//Const adSchemaTranslations = 21
	//Const adSchemaProviderTypes = 22
	//Const adSchemaViews = 23
	//Const adSchemaViewColumnUsage = 24
	//Const adSchemaViewTableUsage = 25
	//Const adSchemaProcedureParameters = 26
	//Const adSchemaForeignKeys = 27
	//Const adSchemaPrimaryKeys = 28
	//Const adSchemaProcedureColumns = 29
	//Const adSchemaDBInfoKeywords = 30
	//Const adSchemaDBInfoLiterals = 31
	//Const adSchemaCubes = 32
	//Const adSchemaDimensions = 33
	//Const adSchemaHierarchies = 34
	//Const adSchemaLevels = 35
	//Const adSchemaMeasures = 36
	//Const adSchemaProperties = 37
	//Const adSchemaMembers = 38
	//Const adSchemaTrustees = 39
	//Const adSchemaFunctions = 40
	//Const adSchemaActions = 41
	//Const adSchemaCommands = 42
	//Const adSchemaSets = 43 

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

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

Функция ПолучитьИмяТаблицыADO(Знач ИмяИсходное)  
	
     Если Лев(ИмяИсходное, 1) <> "[" Тогда
         ИмяИсходное = "[" + ИмяИсходное + "]";  
     КонецЕсли;  
     Возврат ИмяИсходное;
	 
 КонецФункции
 
Функция ЭтоПолезныйТипТаблицыADO(ТипТаблицы)

	Результат = Ложь
		Или ирОбщий.СтрокиРавныЛкс(ТипТаблицы, "table")
		Или ирОбщий.СтрокиРавныЛкс(ТипТаблицы, "view");
	Возврат Результат;

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

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

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

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

Процедура ОчиститьДоступныеВременныеТаблицы(ТаблицаДоступныхТаблиц = Неопределено) Экспорт

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

Процедура ОчиститьДоступныеНеВременныеТаблицы() Экспорт

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

Функция ПолучитьПрефиксПараметра() Экспорт
	
	Возврат мПараметрыДиалектаSQL.ПрефиксПараметра;
	
КонецФункции

// Вызывает конструктор запросов и передает ему текст из текстового поля.
//
// Параметры:
//  Нет.
//
Функция ВызватьКонструкторЗапросов(ИспользуемСобственныйКонструктор = Неопределено) Экспорт

	РежимТолькоПросмотр = Ложь
		Или ПолеТекстовогоДокумента.ТолькоПросмотр
		Или ФормаВладелец.ТолькоПросмотр;
	Если РежимТолькоПросмотр Тогда
		Ответ = Вопрос("Текст запроса не может быть изменен. Открыть конструктор без возможности сохранения измений?",
			РежимДиалогаВопрос.ОКОтмена);
		Если Ответ = КодВозвратаДиалога.Отмена Тогда
			Возврат Ложь;
		КонецЕсли;
	КонецЕсли;
	
	ПредпочитаюСобственныйКонструкторЗапроса = Ложь;
	Если ИспользуемСобственныйКонструктор = Неопределено Тогда
		ПредпочитаюСобственныйКонструкторЗапроса = ирОбщий.ВосстановитьЗначениеЛкс(ИмяКласса + ".ПредпочитаюСобственныйКонструкторЗапроса");
		Если ПредпочитаюСобственныйКонструкторЗапроса = Неопределено Тогда
			Ответ = Вопрос("Подсистема имеет собственный конструктор запроса. Приоритет его использования задается в настройках компоненты ""Контекстная подсказка"".
			|Хотите установить приоритет его использования?", РежимДиалогаВопрос.ДаНет);
			ПредпочитаюСобственныйКонструкторЗапроса = Ответ = КодВозвратаДиалога.Да;
		КонецЕсли; 
	КонецЕсли; 
	ИспользуемСобственныйКонструктор = Ложь
		Или ИспользуемСобственныйКонструктор = Истина
		Или мДиалектSQL <> "1С"
		Или ПредпочитаюСобственныйКонструкторЗапроса;
	Если ИспользуемСобственныйКонструктор Тогда
		КонструкторЗапроса = ПолучитьФорму("КонструкторЗапроса");
		КонструкторЗапроса.Конфигурация = Конфигурация;
	Иначе
		КонструкторЗапроса = Новый КонструкторЗапроса;
	КонецЕсли; 
	Если ЯзыкПрограммы = 1 Тогда
		Если ПустаяСтрока(ПолеТекстовогоДокумента.ВыделенныйТекст) Тогда 
			ТекстЗапроса = ПолеТекстовогоДокумента.ПолучитьТекст();
			НачальнаяСтрокаЗапроса = 0; 
			НачальнаяКолонкаЗапроса = 0;
		Иначе
			ТекстЗапроса = ПолеТекстовогоДокумента.ВыделенныйТекст;
			НачальнаяСтрокаЗапроса = мНачальнаяСтрока - 1; 
			НачальнаяКолонкаЗапроса = мНачальнаяКолонка - 1;
		КонецЕсли;
		КонструкторЗапроса.РежимКомпоновкиДанных = РежимКомпоновкиДанных;
		//КонструкторЗапроса.АвтодобавлениеПредставлений = Истина;
		МассивВременныхТаблиц = Новый Массив;
		Если Не ПустаяСтрока(ТекстЗапроса) Тогда
			Если Истина
				И ТипЗнч(КонтекстВыполнения) = Тип("Запрос") 
				И Не ИспользуемСобственныйКонструктор
			Тогда
				СтарыйТекстЗапроса = ТекстЗапроса;
				ИнформацияОбОшибке = ПолучитьИнформациюОбОшибке(ТекстЗапроса);
				Попытка
					ТекстЗапроса = мПлатформа.ЗамаскироватьВременныеТаблицы(КонтекстВыполнения, ТекстЗапроса, МассивВременныхТаблиц);
				Исключение
					ФормаВладелец.ТекущийЭлемент = ПолеТекстовогоДокумента;
					ирОбщий.ПоказатьОшибкуВЗапросеИлиПрограммномКодеЛкс(ПолеТекстовогоДокумента, , , Истина, мСообщенияЧерезПредупреждения,
						ИнформацияОбОшибке());
					Возврат Ложь;
				КонецПопытки;
				НоваяИнформацияОбОшибке = ПолучитьИнформациюОбОшибке(ТекстЗапроса);
				Если Истина
					И НоваяИнформацияОбОшибке <> Неопределено
					И ИнформацияОбОшибке = Неопределено
					И Найти(ПодробноеПредставлениеОшибки(НоваяИнформацияОбОшибке), "Ожидается псевдоним запроса") > 0 
				Тогда
					// Сюда попадаем, когда у временной таблицы нет псевдонима
					ирОбщий.СообщитьСУчетомМодальностиЛкс("В запросе присутствуют временные таблицы без псевдонимов. "
						+ "Для максимальной функциональности рекомендуется задать каждой временной таблице псевдоним",
						мСообщенияЧерезПредупреждения, СтатусСообщения.Внимание);
					МассивВременныхТаблиц = Новый Массив;
					ТекстЗапроса = СтарыйТекстЗапроса;
                КонецЕсли; 
			КонецЕсли;
		КонецЕсли;
	Иначе
		РазобратьТекущийКонтекст();
		ТекстПоля = ПолеТекстовогоДокумента.ПолучитьТекст();
		RegExp.Global = Истина;
		RegExp.MultiLine = Истина;
		RegExp.Pattern = шСтрокаПрограммы;
		Результат = RegExp.Execute(ТекстПоля);
		Успех = Ложь;
		ДлинаТекстаДо = СтрДлина(мПредшествующийТекст);
		Для Каждого Вхождение Из Результат Цикл
			Если Истина
				И (Вхождение.FirstIndex + 1) <= ДлинаТекстаДо 
				И (Вхождение.FirstIndex + Вхождение.Length + 1) >= ДлинаТекстаДо 
			Тогда
				ПолеТекстовогоДокумента.УстановитьГраницыВыделения(Вхождение.FirstIndex + 1, Вхождение.FirstIndex + Вхождение.Length + 1);
				Успех = Истина;
				Прервать;
			КонецЕсли;
		КонецЦикла;
		ПолеТекстовогоДокумента.ПолучитьГраницыВыделения(НачальнаяСтрокаЗапроса, НачальнаяКолонкаЗапроса, , );
		НачальнаяСтрокаЗапроса = НачальнаяСтрокаЗапроса - 1; 
		НачальнаяКолонкаЗапроса = НачальнаяСтрокаЗапроса - 1;
		Если Успех Тогда
			ТекстЗапроса = ПолеТекстовогоДокумента.ВыделенныйТекст;
			Если Прав(ТекстЗапроса, 1) <> """" Тогда
				ТекстЗапроса = ТекстЗапроса + """";
			КонецЕсли; 
			ТекстЗапроса = Вычислить(ТекстЗапроса);
			ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "|", "");
		Иначе
			ТекстЗапроса = "";
		КонецЕсли;
	КонецЕсли;
	Если Не ПустаяСтрока(ТекстЗапроса) Тогда
		Если ИспользуемСобственныйКонструктор Тогда
			РезультатРазбора = ЗагрузитьТекстВКонструктор(ТекстЗапроса, КонструкторЗапроса,, мДиалектSQL);
			Если РезультатРазбора = Неопределено Тогда
				ирОбщий.СообщитьСУчетомМодальностиЛкс("Компонента анализа текста запроса не подключена", мСообщенияЧерезПредупреждения);
			КонецЕсли; 
			Если РезультатРазбора = Ложь Тогда
				Возврат Ложь;
			КонецЕсли; 
		Иначе
			СтруктуруРезультатаПакетногоЗапроса = мПлатформа.ПолучитьСтруктуруРезультатаПакетногоЗапроса(ТекстЗапроса);
			Если СтруктуруРезультатаПакетногоЗапроса.Количество() > 0 Тогда
				Ответ = Вопрос("В комментариях обнаружены имена запросов. Стандартный конструктор запросов их удалит. Продолжить?", РежимДиалогаВопрос.ОКОтмена);
				Если Ответ <> КодВозвратаДиалога.ОК Тогда
					Возврат Ложь;
				КонецЕсли;
			КонецЕсли; 
			Попытка
				КонструкторЗапроса.Текст = ТекстЗапроса;
			Исключение
				ФормаВладелец.ТекущийЭлемент = ПолеТекстовогоДокумента;
				ирОбщий.ПоказатьОшибкуВЗапросеИлиПрограммномКодеЛкс(ПолеТекстовогоДокумента, НачальнаяСтрокаЗапроса, НачальнаяКолонкаЗапроса, Истина,
					мСообщенияЧерезПредупреждения, ИнформацияОбОшибке());
				Возврат Ложь;
			КонецПопытки;
		КонецЕсли; 
	Иначе
		Если ИспользуемСобственныйКонструктор Тогда
			//КонструкторЗапроса.УстановитьДиалектSQL(мДиалектSQL);
			КонструкторЗапроса.УстановитьДанные();
		КонецЕсли; 
	КонецЕсли;
	ирОбщий.СохранитьЗначениеЛкс(ИмяКласса + ".ПредпочитаюСобственныйКонструкторЗапроса", ПредпочитаюСобственныйКонструкторЗапроса);
	Если КонструкторЗапроса.ОткрытьМодально() = Истина Тогда
		Если Не РежимТолькоПросмотр Тогда
			НовыйТекстЗапроса = КонструкторЗапроса.Текст;
			Если Истина
				И ТипЗнч(Конфигурация) = Тип("ОбъектМетаданныхКонфигурация")
				И ТипЗнч(КонтекстВыполнения) = Тип("Запрос") 
			Тогда
				//RegExp.Global = Истина;
				//RegExp.MultiLine = Истина;
				//RegExp.IgnoreCase = Истина;
				//// Допустим 1 уровень скобок.
				//шОдинарныеСкобки = "\([^\)\(]*?\)";
				//шИмяВременнойТаблицы = "";
				//Для Каждого ПодмененнаяВременнаяТаблица Из МассивВременныхТаблиц Цикл
				//	шИмяВременнойТаблицы = шИмяВременнойТаблицы + "|" + ПодмененнаяВременнаяТаблица;
				//КонецЦикла;
				//шИмяВременнойТаблицы = Сред(шИмяВременнойТаблицы, 2);
				//RegExp.Pattern = "\(ВЫБРАТЬ(?:" + шОдинарныеСкобки + "|[^$\(\)])*?""ВременнаяТаблица"" = ""(" + шИмяВременнойТаблицы + ")""\)";
				//НовыйТекстЗапроса = RegExp.Replace(НовыйТекстЗапроса, "$1");
				НовыйТекстЗапроса = мПлатформа.РазмаскироватьВременныеТаблицы(НовыйТекстЗапроса, МассивВременныхТаблиц);
			КонецЕсли;
			Если ЯзыкПрограммы = 1 Тогда
				Если ПустаяСтрока(ПолеТекстовогоДокумента.ВыделенныйТекст) Тогда 
					ПолеТекстовогоДокумента.УстановитьТекст(НовыйТекстЗапроса);
				Иначе
					ПолеТекстовогоДокумента.ВыделенныйТекст = НовыйТекстЗапроса;
				КонецЕсли;
			Иначе
				НовыйТекстЗапроса = Символы.ПС + НовыйТекстЗапроса;
				НовыйТекстЗапроса = СтрЗаменить(НовыйТекстЗапроса, Символы.ПС, Символы.ПС + "|");
				НовыйТекстЗапроса = СтрЗаменить(НовыйТекстЗапроса, """", """""");
				НовыйТекстЗапроса = """" + НовыйТекстЗапроса + """";
				ЧислоСтрокЗамены = СтрЧислоСтрок(НовыйТекстЗапроса);
				ТекстовыйДокумент = Новый ТекстовыйДокумент;
				ТекстовыйДокумент.УстановитьТекст(НовыйТекстЗапроса);
				СдвинутыйТекст = ТекстовыйДокумент.ПолучитьСтроку(1);
				ЗаменаТабуляции = ирОбщий.ПолучитьСтрокуПовторомЛкс(" ", ШиринаТабуляции);
				ТекстНачальнойСтроки = ПолеТекстовогоДокумента.ПолучитьСтроку(мНачальнаяСтрока);
				ДлинаНачалаСтроки = СтрДлина(ТекстНачальнойСтроки) - СтрДлина(СокрЛ(ТекстНачальнойСтроки));
				НачалоСтроки = Лев(ТекстНачальнойСтроки, ДлинаНачалаСтроки);
				ДлинаРазвернутогоНачалаСтроки = СтрДлина(СтрЗаменить(НачалоСтроки, Символы.Таб, ЗаменаТабуляции));
				ЧислоТабуляций = ДлинаРазвернутогоНачалаСтроки / ШиринаТабуляции;
				ЧислоПробелов  = ДлинаРазвернутогоНачалаСтроки % ШиринаТабуляции;
				НачалоНовойСтроки = ирОбщий.ПолучитьСтрокуПовторомЛкс(Символы.Таб, ЧислоТабуляций);
				НачалоНовойСтроки = НачалоНовойСтроки + ирОбщий.ПолучитьСтрокуПовторомЛкс(" ", ЧислоПробелов);
				Для Счетчик = 2 По ЧислоСтрокЗамены Цикл
					ТекущаяСтрокаВставки = ТекстовыйДокумент.ПолучитьСтроку(Счетчик);
					СдвинутыйТекст = СдвинутыйТекст + Символы.ПС + НачалоНовойСтроки + ТекущаяСтрокаВставки;
				КонецЦикла;
				ПолеТекстовогоДокумента.ВыделенныйТекст = СдвинутыйТекст;
				
			КонецЕсли;
			
			// Баг платформы. 8.1.10.50
			Если ирКэш.НомерВерсииПлатформыЛкс() < 801012 Тогда
				ПолеТекстовогоДокумента.УстановитьТекст(ПолеТекстовогоДокумента.ПолучитьТекст());
			КонецЕсли;
			
			УстановитьПризнакМодифицированностиФормы();
			Возврат Истина;
		КонецЕсли;
	КонецЕсли;
	Возврат Ложь;

КонецФункции // ВызватьКонструкторЗапросов()

Процедура ПоказатьТекущиеКоординаты(ПолеТекстовогоДокумента, СтартоваяСтрокаДляОтображенияОшибок = 0)

	// Антибаг платформы 8.1 . Терялся фокус
	ФормаВладелец.ТекущийЭлемент = ПолеТекстовогоДокумента;
	
	ПолеТекстовогоДокумента.УстановитьГраницыВыделения(мПарсер.CurrentLineNumber() + СтартоваяСтрокаДляОтображенияОшибок, 1,
		мПарсер.CurrentLineNumber() + СтартоваяСтрокаДляОтображенияОшибок, 200);

КонецПроцедуры // ПоказатьКоординаты()

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

Функция ПолучитьСтрокуОжидаемыхТокенов()

	СтрокаОжидаемыхТокенов = "";
	Для й = 0 по мПарсер.TokenCount() - 1 Цикл
		Токен = мПарсер.Tokens(й);
		СтрокаОжидаемыхТокенов = СтрокаОжидаемыхТокенов + ", " + Токен.Text;
	КонецЦикла;
	Возврат Сред(СтрокаОжидаемыхТокенов, 3);

КонецФункции // ПолучитьСтрокуОжидаемыхТокенов()

Функция _ПолучитьГраничныйТерминалПравила(Данные, ИндексГраницы = 0, ЗахватыватьКрайниеКомментарии = Ложь) Экспорт

	КоличествоТокенов = Данные.TokenCount;
	Для Сч1 = 1 По КоличествоТокенов Цикл
		Если ИндексГраницы = 1 Тогда
			УзелКандидат = Данные.Tokens(КоличествоТокенов - Сч1);
		Иначе
			УзелКандидат = Данные.Tokens(Сч1 - 1);
		КонецЕсли; 
		Если ТипЗнч(УзелКандидат.Data) = Тип("Строка") Тогда
			Если ЗахватыватьКрайниеКомментарии И ИндексГраницы = 1 И УзелКандидат.EndNoise <> Неопределено Тогда
				Возврат УзелКандидат.EndNoise;
			ИначеЕсли ЗахватыватьКрайниеКомментарии И ИндексГраницы = 0 И УзелКандидат.BeginNoise <> Неопределено Тогда
				Возврат УзелКандидат.BeginNoise;
			Иначе
				Возврат УзелКандидат;
			КонецЕсли; 
		ИначеЕсли ТипЗнч(УзелКандидат.Data) = Тип("COMОбъект") Тогда
			Если УзелКандидат.Data.TokenCount > 0 Тогда
				УзелСнизу = _ПолучитьГраничныйТерминалПравила(УзелКандидат.Data, ИндексГраницы, ЗахватыватьКрайниеКомментарии);
				Если УзелСнизу <> Неопределено Тогда
					Возврат УзелСнизу;
				КонецЕсли; 
			КонецЕсли;
		КонецЕсли;
	КонецЦикла;
	Возврат Неопределено;

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

Функция ПолучитьТекстИзТокена(Токен, выхНачальнаяСтрока = 0, выхНачальнаяКолонка = 0, выхКонечнаяСтрока = 0, выхКонечнаяКолонка = 0) Экспорт

	Если Токен = Неопределено Тогда
		Возврат "";
	КонецЕсли; 
	НачальныйТокен = Токен.GetBorderToken(0);
	Если НачальныйТокен = Неопределено Тогда
		Возврат "";
	КонецЕсли; 
	выхНачальнаяКолонка = НачальныйТокен.ColumnNumber;
	выхНачальнаяСтрока = НачальныйТокен.LineNumber;
	КонечныйТокен = Токен.GetBorderToken(1);
	Если КонечныйТокен = Неопределено Тогда
		Возврат "";
	КонецЕсли; 
	выхКонечнаяКолонка = КонечныйТокен.ColumnNumber + СтрДлина(КонечныйТокен.Data);
	выхКонечнаяСтрока = КонечныйТокен.LineNumber + СтрЧислоСтрок(КонечныйТокен.Data) - 1;
	СлужебноеПолеТекстовогоДокумента.УстановитьГраницыВыделения(выхНачальнаяСтрока, выхНачальнаяКолонка, выхКонечнаяСтрока, выхКонечнаяКолонка);
	ТекстОпределения = СлужебноеПолеТекстовогоДокумента.ВыделенныйТекст;
	ТекстОпределения = СокрЛП(ТекстОпределения);
	Возврат ТекстОпределения;

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

Функция _ПолучитьТекстИзДанныхТокена(ДанныеТокена, выхНачальнаяСтрока = 0, выхНачальнаяКолонка = 0, выхКонечнаяСтрока = 0, выхКонечнаяКолонка = 0) Экспорт

	НачальныйТокен = _ПолучитьГраничныйТерминалПравила(ДанныеТокена, 0);
	Если НачальныйТокен = Неопределено Тогда
		Возврат "";
	КонецЕсли; 
	выхНачальнаяКолонка = НачальныйТокен.ColumnNumber;
	выхНачальнаяСтрока = НачальныйТокен.LineNumber;
	КонечныйТокен = _ПолучитьГраничныйТерминалПравила(ДанныеТокена, 1);
	Если КонечныйТокен = Неопределено Тогда
		Возврат "";
	КонецЕсли; 
	выхКонечнаяКолонка = КонечныйТокен.ColumnNumber + СтрДлина(КонечныйТокен.Data);
	выхКонечнаяСтрока = КонечныйТокен.LineNumber + СтрЧислоСтрок(КонечныйТокен.Data) - 1;
	СлужебноеПолеТекстовогоДокумента.УстановитьГраницыВыделения(выхНачальнаяСтрока, выхНачальнаяКолонка, выхКонечнаяСтрока, выхКонечнаяКолонка);
	ТекстОпределения = СлужебноеПолеТекстовогоДокумента.ВыделенныйТекст;
	ТекстОпределения = СокрЛП(ТекстОпределения);
	Возврат ТекстОпределения;

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

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

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

	#Если Сервер И Не Сервер Тогда
	    мПлатформа = Обработки.ирПлатформа.Создать();
	#КонецЕсли
	мПарсер = мПлатформа.мПолучитьПарсер("ГрамматикаЯзыкаЗапросов");
	Если мПарсер = Неопределено Тогда
		Возврат Неопределено;
	КонецЕсли;
	Если пПолеТекстовогоДокумента = Неопределено Тогда
		пПолеТекстовогоДокумента = ПолеТекстовогоДокумента;
	КонецЕсли; 
	Если ОбновлятьСостояние Тогда
		Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(, "Синтаксическое дерево");
	КонецЕсли; 
	выхТаблицаКомментариев = Новый ТаблицаЗначений;
	выхТаблицаКомментариев.Колонки.Добавить("Позиция", Новый ОписаниеТипов("Число"));
	выхТаблицаКомментариев.Колонки.Добавить("Текст", Новый ОписаниеТипов("Строка"));
	выхТаблицаКомментариев.Колонки.Добавить("ЭтоРасширение", Новый ОписаниеТипов("Булево"));
	gpMsgTokenRead			= 1;
	gpMsgReduction			= 2;
	gpMsgAccept				= 3;
	gpMsgNotLoadedError		= 4;
	gpMsgLexicalError		= 5;
	gpMsgSyntaxError 		= 6;
	gpMsgCommentError		= 7;
	gpMsgInternalError		= 8;
	gpMsgCommentBlockRead	= 9;
	gpMsgCommentLineRead	= 10;
	мПарсер.OpenTextString(ТекстЗапроса + Символы.ПС);
	Закончили = Ложь;
	//ПоследниеТокены = Новый Массив();
	ПоследнееПравилоНеКомментарий = Неопределено;
	TrimReductions = СокращенноеДерево;
	мПарсер.TrimReductions = СокращенноеДерево; // Была Истина
	Пока Не Закончили Цикл 
		Если ОбновлятьСостояние Тогда
			ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
		КонецЕсли; 
		Ответ = мПарсер.Parse();
		Если Истина
			И СокращенноеДерево
			И TrimReductions <> Истина 
		Тогда
			мПарсер.TrimReductions = Истина;
			TrimReductions = Истина;
		КонецЕсли; 
		Если Ложь
			Или Ответ = gpMsgLexicalError 
			Или (Истина // Хотя Builder в этом случае диагностирует лексическую ошибку, этот парсер почему то бесконечно выдает статус 7
				И Ответ = 7 
				И мПарсер.CurrentReduction = Неопределено)
		Тогда
			мПарсер.PopInputToken();
			Закончили = Истина;
			КоординатыВТекстеЗапроса = ПолучитьКоординатыВТекстеЗапроса(пПолеТекстовогоДокумента, СтартоваяСтрокаДляОтображенияОшибок);
			ирОбщий.СообщитьСУчетомМодальностиЛкс(КоординатыВТекстеЗапроса + "Лексическая ошибка!",
				мСообщенияЧерезПредупреждения, СтатусСообщения.Важное);
			Если ТипЗнч(пПолеТекстовогоДокумента) = Тип("ПолеТекстовогоДокумента") Тогда
				ПоказатьТекущиеКоординаты(пПолеТекстовогоДокумента, СтартоваяСтрокаДляОтображенияОшибок);
			КонецЕсли; 
		ИначеЕсли Ответ = gpMsgSyntaxError Тогда
			ТекущийТокен = мПарсер.CurrentToken();
			Если Истина
				И ТекущийТокен.Kind = 1 
				И (Ложь
					Или ТекущийТокен.Name = "MultiCommentLine"
					//Или ТекущийТокен.Name = "ExtensionBlock"
					Или ТекущийТокен.Name = "CommentBlock")
			Тогда
				Если СообщатьОПропущенныхТерминалах Тогда
					КоординатыВТекстеЗапроса = ПолучитьКоординатыВТекстеЗапроса(пПолеТекстовогоДокумента, СтартоваяСтрокаДляОтображенияОшибок);
					ирОбщий.СообщитьСУчетомМодальностиЛкс(КоординатыВТекстеЗапроса + "Проигнорирован комментарий """ 
						+ СокрЛП(ТекущийТокен.Data) + """"
						//+ ", ожидается: " + ПолучитьСтрокуОжидаемыхТокенов()
						, , СтатусСообщения.Внимание);
				КонецЕсли; 
				мПарсер.PopInputToken();
			Иначе
				КоординатыВТекстеЗапроса = ПолучитьКоординатыВТекстеЗапроса(пПолеТекстовогоДокумента, СтартоваяСтрокаДляОтображенияОшибок);
				ТекстОшибки = КоординатыВТекстеЗапроса + "Синтаксическая ошибка """ 
					+ ТекущийТокен.Data + """"
					+ ", ожидается: " + ПолучитьСтрокуОжидаемыхТокенов();
				//Если ПоследниеТокены.Количество() > 1 Тогда 
				//	ТокенКомментария = ПоследниеТокены[ПоследниеТокены.Количество() - 1];
				//	Если Ложь
				//		Или ТокенКомментария.Name = "MultiCommentLine"
				//		//Или ТокенКомментария.Name = "ExtensionBlock"
				//		Или ТокенКомментария.Name = "CommentBlock"
				//	Тогда 
				//		//СлужебноеПолеТекстовогоДокумента.УстановитьТекст(ТекстЗапроса); // Нужно дл использования функции ПолучитьТекстИзТокена
				//		ТекстОшибки = ТекстОшибки + Символы.ПС + "Возможно следует перенести предшествующий комментарий """ + СокрЛП(ТокенКомментария.Data) + """";
				//		//ТекущийТокен = мПарсер.PopInputToken();
				//		//мПарсер.PushInputToken(ТекущийТокен);
				//		//мПарсер.CurrentReduction = ПоследнееПравилоНеКомментарий;
				//		////мПарсер.PushInputToken(ТекущийТокен);
				//	КонецЕсли; 
				//КонецЕсли; 
				ирОбщий.СообщитьСУчетомМодальностиЛкс(ТекстОшибки, мСообщенияЧерезПредупреждения, СтатусСообщения.Важное);
				Если ТипЗнч(пПолеТекстовогоДокумента) = Тип("ПолеТекстовогоДокумента") Тогда
					ПоказатьТекущиеКоординаты(пПолеТекстовогоДокумента, СтартоваяСтрокаДляОтображенияОшибок);
				КонецЕсли; 
				Закончили = Истина;
			КонецЕсли; 
		ИначеЕсли Ответ = gpMsgReduction Тогда
			Если СокращенноеДерево Тогда
				//ИмяПравила = мПарсер.CurrentReduction.ParentRule.RuleNonterminal.Name;
				ИмяПравила = мПарсер.CurrentRuleName();
				Если Ложь // Есть сомнения, что это работает как задумано
					Или ИмяПравила = "Table" 
					Или ИмяПравила = "TableName"
				Тогда
					мПарсер.TrimReductions = Ложь;
					TrimReductions = Ложь;
				КонецЕсли; 
			КонецЕсли; 
		ИначеЕсли Ответ = gpMsgAccept Тогда
			Закончили = Истина;
		ИначеЕсли Ответ = gpMsgCommentError Тогда
		ИначеЕсли Ответ = gpMsgTokenRead Тогда
			Если мПарсер.IsCurrentTokenComment() Тогда
				// Храним 2 последних токена
				ТекущийТокен = мПарсер.CurrentToken();
				//Если Ложь
				//	Или ирОбщий.СтрокиРавныЛкс(ТекущийТокен.Name, "whitespace") 
				//	Или ирОбщий.СтрокиРавныЛкс(ТекущийТокен.Name, "NewLine")
				//Тогда
				//ИначеЕсли Ложь
				//	Или ирОбщий.СтрокиРавныЛкс(ТекущийТокен.Name, "CommentLine1")
				//	Или ирОбщий.СтрокиРавныЛкс(ТекущийТокен.Name, "CommentLine2")
				//	Или ирОбщий.СтрокиРавныЛкс(ТекущийТокен.Name, "CommentBlock")
				//Тогда 
				//	ПрочитатьКомментарий(выхТаблицаКомментариев, ТекущийТокен, пПолеТекстовогоДокумента, СообщатьОПропущенныхТерминалах, СтартоваяСтрокаДляОтображенияОшибок);
				//ИначеЕсли ирОбщий.СтрокиРавныЛкс(ТекущийТокен.Name, "ExtensionBlock") Тогда
					ПрочитатьКомментарий(выхТаблицаКомментариев, ТекущийТокен, пПолеТекстовогоДокумента, СообщатьОПропущенныхТерминалах, СтартоваяСтрокаДляОтображенияОшибок);
				//КонецЕсли; 
			КонецЕсли; 
		ИначеЕсли Ответ = gpMsgInternalError Тогда
			Закончили = Истина;
		ИначеЕсли Ответ = gpMsgNotLoadedError Тогда
			Закончили = Истина;
		//ИначеЕсли Ложь // Для старого движка
		//	Или Ответ = gpMsgCommentBlockRead 
		//	Или Ответ = gpMsgCommentLineRead 
		//Тогда
		//	ТекстКомментария = СокрЛП(мПарсер.CurrentComment);
		//	ПрочитатьКомментарий(выхТаблицаКомментариев, ПоследниеТокены, пПолеТекстовогоДокумента, СообщатьОПропущенныхТерминалах, СтартоваяСтрокаДляОтображенияОшибок, ТекстКомментария);
		КонецЕсли;
	КонецЦикла;
	Если ОбновлятьСостояние Тогда
		ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
	КонецЕсли; 
	Если Ответ = gpMsgAccept Тогда
		НачальныйТокен = Новый Структура("Data, LineNumber, ColumnNumber, Name, Kind", мПарсер.CurrentReduction, 0, 0, "", 0);
		Возврат НачальныйТокен;
	Иначе
		Возврат Неопределено;
	КонецЕсли; 

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

Процедура ПрочитатьКомментарий(Знач выхТаблицаКомментариев, Знач ТекущийТокен, Знач пПолеТекстовогоДокумента, Знач СообщатьОПропущенныхТерминалах, Знач СтартоваяСтрокаДляОтображенияОшибок)
	
	ТекстКомментария = СокрЛП(ТекущийТокен.Data);
	МаркерХАРАКТЕРИСТИКИ = "ХАРАКТЕРИСТИКИ";
	ЭтоРасширение = Ложь;
	Если Лев(ТекстКомментария, 1) = "{" Тогда
		ТекстКомментария = Сред(ТекстКомментария, 2, СтрДлина(ТекстКомментария) - 2);
		ЭтоРасширение = мПараметрыДиалектаSQL.Это1С;
	ИначеЕсли Лев(ТекстКомментария, 2) = "//" Тогда
		ТекстКомментария = Сред(ТекстКомментария, 3);
	ИначеЕсли Лев(ТекстКомментария, 2) = "/*" Тогда
		ТекстКомментария = Сред(ТекстКомментария, 3, СтрДлина(ТекстКомментария) - 4);
	КонецЕсли; 
	Если ЭтоРасширение И Лев(ТекстКомментария, СтрДлина(МаркерХАРАКТЕРИСТИКИ)) = МаркерХАРАКТЕРИСТИКИ Тогда
		выхБылиПотери = Истина;
		Если СообщатьОПропущенныхТерминалах Тогда
			КоординатыВТекстеЗапроса = ПолучитьКоординатыВТекстеЗапроса(пПолеТекстовогоДокумента, СтартоваяСтрокаДляОтображенияОшибок);
			ирОбщий.СообщитьСУчетомМодальностиЛкс(КоординатыВТекстеЗапроса + "Проигнорирован комментарий """ 
			+ СокрЛП(ТекущийТокен.Data) + """"
			//+ ", ожидается: " + ПолучитьСтрокуОжидаемыхТокенов()
			, , СтатусСообщения.Внимание);
		КонецЕсли; 
	ИначеЕсли ЗначениеЗаполнено(ТекстКомментария) Тогда 
		СтрокаРасширения = выхТаблицаКомментариев.Добавить();
		СтрокаРасширения.ЭтоРасширение = ЭтоРасширение;
		СтрокаРасширения.Позиция = ПолучитьОтносительнуюПозициюТокена(ТекущийТокен);
		СтрокаРасширения.Текст = ТекстКомментария; // Убираем крайние фигурные скобки
	КонецЕсли;

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

Функция ПолучитьОтносительнуюПозициюТокена(Токен) Экспорт 
	
	Результат = Токен.LineNumber * 1000 + Токен.ColumnNumber;
	Возврат Результат;
	
КонецФункции

// Вызывает конструктор запросов и передает ему текст из текстового поля.
//
// Параметры:
//  Нет.
//
Функция ВызватьРедакторСтроковогоЛитерала()

	РежимТолькоПросмотр = Ложь
		Или ПолеТекстовогоДокумента.ТолькоПросмотр
		Или ФормаВладелец.ТолькоПросмотр;
	Если РежимТолькоПросмотр Тогда
		Ответ = Вопрос("Текст не может быть изменен. Открыть редактор без возможности сохранения измений?",
			РежимДиалогаВопрос.ОКОтмена);
		Если Ответ = КодВозвратаДиалога.Отмена Тогда
			Возврат Ложь;
		КонецЕсли;
	КонецЕсли;
	
	РазобратьТекущийКонтекст();
	ТекстПоля = ПолеТекстовогоДокумента.ПолучитьТекст();
	RegExp.Global = Истина;
	RegExp.MultiLine = Истина;
	RegExp.IgnoreCase = Истина;
	RegExp.Pattern = шСтрокаПрограммы;
	Результат = RegExp.Execute(ТекстПоля);
	Успех = Ложь;
	ДлинаТекстаДо = СтрДлина(мПредшествующийТекст);
	Для Каждого Match Из Результат Цикл
		Если Истина
			И (Match.FirstIndex + 1) <= ДлинаТекстаДо 
			И (Match.FirstIndex + Match.Length + 1) >= ДлинаТекстаДо 
		Тогда
			ПолеТекстовогоДокумента.УстановитьГраницыВыделения(Match.FirstIndex + 1, Match.FirstIndex + Match.Length + 1);
			Успех = Истина;
			Прервать;
		КонецЕсли;
	КонецЦикла;
	НачальнаяСтрокаЗапроса = 0;
	НачальнаяКолонкаЗапроса = 0;
	ПолеТекстовогоДокумента.ПолучитьГраницыВыделения(НачальнаяСтрокаЗапроса, НачальнаяКолонкаЗапроса, , );
	НачальнаяСтрокаЗапроса = НачальнаяСтрокаЗапроса - 1; 
	НачальнаяКолонкаЗапроса = НачальнаяСтрокаЗапроса - 1;
	Если Успех Тогда
		ТекстСтроковогоЛитерала = ПолеТекстовогоДокумента.ВыделенныйТекст;
		Если Прав(ТекстСтроковогоЛитерала, 1) <> """" Тогда
			ТекстСтроковогоЛитерала = ТекстСтроковогоЛитерала + """";
		КонецЕсли; 
		ТекстСтроковогоЛитерала = Вычислить(ТекстСтроковогоЛитерала);
		////ТекстСтроковогоЛитерала = СтрЗаменить(ТекстСтроковогоЛитерала, "|", "");
		//RegExp.Pattern = "(\s*)\|((.|"""")*(\n|\r|""))";
		//ТекстСтроковогоЛитерала = RegExp.Replace(ТекстСтроковогоЛитерала, "$1 $2");
	Иначе
		ТекстСтроковогоЛитерала = "";
	КонецЕсли;
	ФормаРедактора = мПлатформа.ПолучитьФорму("Текст", , Новый УникальныйИдентификатор);
	ФормаРедактора.НачальноеЗначениеВыбора = ТекстСтроковогоЛитерала;
	Если ФормаРедактора.ОткрытьМодально() <> Неопределено Тогда
		Если Не РежимТолькоПросмотр Тогда
			НовыйТекстЗапроса = ФормаРедактора.Текст;
			НовыйТекстЗапроса = СтрЗаменить(НовыйТекстЗапроса, Символы.ПС, Символы.ПС + "|");
			НовыйТекстЗапроса = СтрЗаменить(НовыйТекстЗапроса, """", """""");
			НовыйТекстЗапроса = """" + НовыйТекстЗапроса + """";
			ЧислоСтрокЗамены = СтрЧислоСтрок(НовыйТекстЗапроса);
			ТекстовыйДокумент = Новый ТекстовыйДокумент;
			ТекстовыйДокумент.УстановитьТекст(НовыйТекстЗапроса);
			СдвинутыйТекст = ТекстовыйДокумент.ПолучитьСтроку(1);
			ЗаменаТабуляции = ирОбщий.ПолучитьСтрокуПовторомЛкс(" ", ШиринаТабуляции);
			ТекстНачальнойСтроки = ПолеТекстовогоДокумента.ПолучитьСтроку(мНачальнаяСтрока);
			ДлинаНачалаСтроки = СтрДлина(ТекстНачальнойСтроки) - СтрДлина(СокрЛ(ТекстНачальнойСтроки));
			НачалоСтроки = Лев(ТекстНачальнойСтроки, ДлинаНачалаСтроки);
			ДлинаРазвернутогоНачалаСтроки = СтрДлина(СтрЗаменить(НачалоСтроки, Символы.Таб, ЗаменаТабуляции));
			ЧислоТабуляций = ДлинаРазвернутогоНачалаСтроки / ШиринаТабуляции;
			ЧислоПробелов  = ДлинаРазвернутогоНачалаСтроки % ШиринаТабуляции;
			НачалоНовойСтроки = ирОбщий.ПолучитьСтрокуПовторомЛкс(Символы.Таб, ЧислоТабуляций);
			НачалоНовойСтроки = НачалоНовойСтроки + ирОбщий.ПолучитьСтрокуПовторомЛкс(" ", ЧислоПробелов);
			Для Счетчик = 2 По ЧислоСтрокЗамены Цикл
				ТекущаяСтрокаВставки = ТекстовыйДокумент.ПолучитьСтроку(Счетчик);
				СдвинутыйТекст = СдвинутыйТекст + Символы.ПС + НачалоНовойСтроки + ТекущаяСтрокаВставки;
			КонецЦикла;
			ПолеТекстовогоДокумента.ВыделенныйТекст = СдвинутыйТекст;
			
			// Баг платформы. 8.1.10.50
			Если ирКэш.НомерВерсииПлатформыЛкс() < 801012 Тогда
				ПолеТекстовогоДокумента.УстановитьТекст(ПолеТекстовогоДокумента.ПолучитьТекст());
			КонецЕсли;
			
			УстановитьПризнакМодифицированностиФормы();
			Возврат Истина;
		КонецЕсли;
	КонецЕсли;
	Возврат Ложь;

КонецФункции // ВызватьРедакторСтроковогоЛитерала()

// Осуществляет переход к определению контекста.
//
// Параметры:
//  Нет.
//
Процедура ПерейтиКОпределению()
	
	РазобратьТекущийКонтекст();
	Если ПустаяСтрока(мКонтекст) Тогда
		Возврат;
	КонецЕсли;
	ПоследнееОпределение = Неопределено;
	Если ЯзыкПрограммы = 1 Тогда
		RegExp.Global = Ложь;
		RegExp.Pattern = СтрЗаменить(шПоискОписанияТаблицы, "#Идентификатор#", ирОбщий.ПреобразоватьТекстДляРегулярныхВыраженийЛкс(мКонтекст));
		РезультатТекста = RegExp.Execute(мТекстДляПоискаОпределения);
		Если РезультатТекста.Count > 0 Тогда
			ПоследнееВхождение = РезультатТекста.Item(0);
			ПоследнееОпределение = ПоследнееВхождение.SubMatches(3);
		Иначе
			МаркерЗначение = "ЗНАЧЕНИЕ(";
			Если Прав(мПредшествующийТекст, СтрДлина(МаркерЗначение)) = МаркерЗначение Тогда
				RegExp.Global = Ложь;
				RegExp.Pattern = шИмя;
				Если RegExp.Test(мКонтекст) Тогда 
					Попытка
						ПредопределенноеЗначение = ПредопределенноеЗначение(мКонтекст);
					Исключение
						ПредопределенноеЗначение = Неопределено;
					КонецПопытки; 
					Если ПредопределенноеЗначение <> Неопределено Тогда
						ОткрытьЗначение(ПредопределенноеЗначение);
					КонецЕсли; 
				КонецЕсли; 
			КонецЕсли; 
		КонецЕсли;
	Иначе
		RegExp.Global = Истина;
		//шПрисваивание = "(" + шРазделитель + "*=" + шРазделитель + "*((Новый)" + шРазделитель 
		//	+ "+(" + шИмя + ")|(" + шИмя + шСкобки + "?" + шИндекс 
		//	+ "?(\." + шИмя + шСкобки + "?" + шИндекс + "?)*)" + "|(" + шЧисло + ")|(" + шСтрокаПрограммы + ")))";
		ШаблонКоллекции = "(" + шРазделитель + "+Из" + шРазделитель + "+(" + шИмя + шСкобки + "?"
			+ шИндекс + "?" + "(\." + шИмя + шСкобки + "?" + шИндекс + "?)*))";
		RegExp.Pattern = шНачалоИдентификатора + ирОбщий.ПреобразоватьТекстДляРегулярныхВыраженийЛкс(мКонтекст) 
			+ "(" + шПрисваивание + "|" + ШаблонКоллекции + ")";
		РезультатТекста = RegExp.Execute(мТекстДляПоискаОпределения);
		Если РезультатТекста.Count > 0 Тогда
			ПоследнееВхождение = РезультатТекста.Item(РезультатТекста.Count - 1);
			ПоследнееОпределение = ПоследнееВхождение.SubMatches(0);
			//Если ПоследнееВхождение.SubMatches(1) <> Неопределено Тогда
			//	// Это присвоение
			//	ПоследнееОпределение = ПоследнееВхождение.SubMatches(1);
			//Иначе
			//	// Это обход коллекции
			//	ПоследнееОпределение = ПоследнееВхождение.SubMatches(20);
			//КонецЕсли;
		КонецЕсли;
	КонецЕсли;
	
	Если ПоследнееВхождение <> Неопределено Тогда
		НачальнаяПозицияОпределения = ПоследнееВхождение.FirstIndex + Найти(ПоследнееВхождение.Value, ПоследнееОпределение);
		КонечнаяПозицияОпределения = НачальнаяПозицияОпределения + СтрДлина(ПоследнееОпределение);
		СлужебноеПолеТекстовогоДокумента.УстановитьГраницыВыделения(НачальнаяПозицияОпределения, КонечнаяПозицияОпределения);
		СлужебноеПолеТекстовогоДокумента.ПолучитьГраницыВыделения(мНачальнаяСтрока, мНачальнаяКолонка, мКонечнаяСтрока, мКонечнаяКолонка);
		ПолеТекстовогоДокумента.УстановитьГраницыВыделения(НачальнаяПозицияОпределения, КонечнаяПозицияОпределения);
		//ПолеТекстовогоДокумента.ПолучитьГраницыВыделения(мНачальнаяСтрока, мНачальнаяКолонка, мКонечнаяСтрока, мКонечнаяКолонка);
	Иначе
		ТаблицаСлов.Найти(НРег(мКонтекст), "НСлово");
		ТаблицаСтруктурТипов = ОпределитьТипЗначенияКонтекста(мКонтекст);
		Если ТаблицаСтруктурТипов.Количество() = 1 Тогда
			Для Каждого СтруктураТипа Из ТаблицаСтруктурТипов Цикл
				Если Истина
					И СтруктураТипа.СтрокаОписания <> Неопределено 
					И СтруктураТипа.СтрокаОписания.Владелец().Колонки.Найти("Значение") <> Неопределено 
					И ирОбщий.ЛиСсылкаНаОбъектБДЛкс(СтруктураТипа.СтрокаОписания.Значение)
					И ЗначениеЗаполнено(СтруктураТипа.СтрокаОписания.Значение) 
				Тогда
					//ирОбщий.ОткрытьСсылкуВРедактореОбъектаБДЛкс(СтруктураТипа.СтрокаОписания.Значение);
					ОткрытьЗначение(СтруктураТипа.СтрокаОписания.Значение);
					Прервать;
				КонецЕсли; 
				Если ТипЗнч(СтруктураТипа.Метаданные) = Тип("ОбъектМетаданных") Тогда
					ПолноеИмяМД = СтруктураТипа.Метаданные.ПолноеИмя();
					ирОбщий.ОткрытьОбъектМетаданныхЛкс(СтруктураТипа.Метаданные);
					Прервать;
				КонецЕсли; 
			КонецЦикла;
		КонецЕсли; 
	КонецЕсли;

КонецПроцедуры // ПерейтиКОпределению()

// <Описание процедуры>
//
// Параметры:
//  <Параметр1>  – <Тип.Вид> – <описание параметра>
//                 <продолжение описания параметра>;
//  <Параметр2>  – <Тип.Вид> – <описание параметра>
//                 <продолжение описания параметра>.
//
Процедура ДобавитьТипЭлементаКоллекцииВТаблицуСтруктурТипов(СтруктураТипаКоллекции, СтруктураТипаЭлементаКоллекции,
	ТаблицаСтруктурТипов)

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

КонецПроцедуры // ДобавитьТипЭлементаКоллекцииВТаблицуСтруктурТипов()

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

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

КонецФункции // ОпределитьТипДочернегоКонтекста()

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

	СтруктураТипа = мПлатформа.ПолучитьНовуюСтруктуруТипа();
	//Если ЗначениеЗаполнено(Конфигурация) Тогда
		СтруктураТипа.Метаданные = Конфигурация;
	//Иначе
	//	СтруктураТипа.Метаданные = мПлатформа.мМетаданные;
	//КонецЕсли; 
	ТаблицаСтруктурТипов = мПлатформа.ПолучитьНовуюТаблицуСтруктурТипа();
	ЛиКонструктор = Ложь;
	Если ЯзыкПрограммы = 1 Тогда
		RegExp.Global = Истина;
		RegExp.Pattern = шНачалоИдентификатора + "(?:ССЫЛКА|REFS)" + шРазделитель + "+$";
		Результат = RegExp.Execute(ПредшествующийТекст);
		Если Результат.Count > 0 Тогда
			СтруктураТипа.ТипЯзыка = "ИмяТипа";
		КонецЕсли;
		RegExp.Pattern = шНачалоИдентификатора + "(?:ВЫРАЗИТЬ|CAST)" + шРазделитель + "*\(" 
			+ шВыражениеЗапроса + шРазделитель + "+(?:КАК|AS)" + шРазделитель + "+$";
		Результат = RegExp.Execute(ПредшествующийТекст);
		Если Результат.Count > 0 Тогда
			СтруктураТипа.ТипЯзыка = "ИмяТипа";
		КонецЕсли;
		RegExp.Pattern = шНачалоИдентификатора + "(?:ЗНАЧЕНИЕ|VALUE)" + шРазделитель + "*\(" + шРазделитель + "*$";
		Результат = RegExp.Execute(ПредшествующийТекст);
		Если Результат.Count > 0 Тогда
			СтруктураТипа.ТипЯзыка = "ЗначениеВЗапросе";
		КонецЕсли;
	Иначе
		RegExp.Global = Истина;
		RegExp.Pattern = шНачалоИдентификатора + "Новый" + шРазделитель + "+$";
		Результат = RegExp.Execute(ПредшествующийТекст);
		Если Результат.Count > 0 Тогда
			СтруктураТипа.Вставить("Конструктор", Истина);
			СтруктураТипа.ТипЯзыка = "ИмяТипа";
		КонецЕсли;
		RegExp.Pattern = шНачалоИдентификатора + "Новый" + шРазделитель + "*\(" + шРазделитель + "*""$";
		Результат = RegExp.Execute(ПредшествующийТекст);
		Если Результат.Count > 0 Тогда
			// Активная следующая строка блокирует недокументированные возможности.
			//СтруктураТипа.Вставить("Конструктор", Истина);
			СтруктураТипа.ТипЯзыка = "ИмяТипа";
		КонецЕсли;
		RegExp.Pattern = шНачалоИдентификатора + "Тип" + шРазделитель + "*\(" + шРазделитель + "*""$";
		Результат = RegExp.Execute(ПредшествующийТекст);
		Если Результат.Count > 0 Тогда
			СтруктураТипа.ТипЯзыка = "ИмяТипа";
		КонецЕсли;
		RegExp.Pattern = шНачалоИдентификатора + "Новый" + шРазделитель + "*ОписаниеТипов\(" + шРазделитель + "*""[^""]*$";
		Результат = RegExp.Execute(ПредшествующийТекст);
		Если Результат.Count > 0 Тогда
			СтруктураТипа.ТипЯзыка = "ИмяТипа";
		КонецЕсли;
	КонецЕсли;
	Если Ложь
		Или СтруктураТипа.ТипЯзыка = "ИмяТипа"
		Или СтруктураТипа.ТипЯзыка = "ЗначениеВЗапросе"
	Тогда
		СтруктураТипа.ИмяОбщегоТипа = "";
	КонецЕсли;
	RegExp.Global = Ложь;
	RegExp.Pattern = "(((\.(" + шИмя + ")" + шСкобки + "?)|" + шИндекс + ")*)" +
		"((\.(" + шИмя + ")" + шНачалоСкобок + "?)|" + шИндекс + ")$";
	Результат = RegExp.Execute("." + Контекст);
	Если Ложь
		Или Контекст = Неопределено
		Или Контекст = ""
	Тогда
		Если СтруктураТипа.ИмяОбщегоТипа = "Неизвестный контекст" Тогда
			СтруктураТипа.ИмяОбщегоТипа = "Локальный контекст";
		КонецЕсли;
	ИначеЕсли Результат.Count > 0 Тогда 
		МассивРодительскихСтрутурТипа = Новый Массив;
		РодительскийКонтекст = Сред(Результат.Item(0).SubMatches(0), 2);
		ТекущееСлово = Результат.Item(0).SubMatches(8);
		ТекущийИндекс = Результат.Item(0).SubMatches(10);
		ТекущиеАргументы = Результат.Item(0).SubMatches(9);
		ТипСлова = "Свойство";
		Если Не ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(ТекущийИндекс) Тогда
			ТекущееСлово = Сред(ТекущийИндекс, 2, СтрДлина(ТекущийИндекс) - 2);
		КонецЕсли;
		Если ЯзыкПрограммы = 1 Тогда
			ТипСлова = Неопределено;
			Если РодительскийКонтекст = "" Тогда
				RegExp.Global = Ложь;
				RegExp.Pattern = СтрЗаменить(шПоискОписанияТаблицы, "#Идентификатор#",
					ирОбщий.ПреобразоватьТекстДляРегулярныхВыраженийЛкс(ТекущееСлово));
				РезультатТекста = RegExp.Execute(ТекстДляПоискаОпределения);
				Если РезультатТекста.Count > 0 Тогда
					ПоследнееВхождение = РезультатТекста.Item(0);
					СледРекурсии = МассивЗащитыОтРекурсии.Найти(ПоследнееВхождение.FirstIndex);
					Если СледРекурсии = Неопределено Тогда
						МассивЗащитыОтРекурсии.Добавить(ПоследнееВхождение.FirstIndex);
						ПрисвоенныйКонтекст = ПоследнееВхождение.SubMatches(3);
						Если ПрисвоенныйКонтекст <> Контекст Тогда
							МассивСтруктурПрисвоенныхТипов = ОпределитьТипЗначенияКонтекста(ПрисвоенныйКонтекст, ТекстДляПоискаОпределения,
								Лев(ТекстДляПоискаОпределения, ПоследнееВхождение.FirstIndex - 1));
							ирОбщий.ЗагрузитьВТаблицуЗначенийЛкс(МассивСтруктурПрисвоенныхТипов, ТаблицаСтруктурТипов); 
						КонецЕсли; 
					КонецЕсли;
				КонецЕсли;
			КонецЕсли;
		Иначе
			ТипСлова = "Свойство";
			Если Истина
				И Не ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(ТекущиеАргументы) 
				И Не СтруктураТипа.ТипЯзыка = "ИмяТипа"
			Тогда
				// Это метод или функция
				ТипСлова = "Метод";
			КонецЕсли;
			RegExp.Global = Истина;
			ШаблонКоллекции = "(" + шРазделитель + "+Из" + шРазделитель + "+(" + шИмя 
				+ шСкобки + "?" + шИндекс + "?" + "(\." + шИмя + шСкобки + "?" + шИндекс + "?)*))";
			RegExp.Pattern = шНачалоИдентификатора + ирОбщий.ПреобразоватьТекстДляРегулярныхВыраженийЛкс(Контекст) 
				+ "(" + шПрисваивание + "|" + ШаблонКоллекции + ")";
			РезультатТекста = RegExp.Execute(ТекстДляПоискаОпределения);
			Если РезультатТекста.Count > 0 Тогда
				СтруктураТипа = мПлатформа.ПолучитьНовуюСтруктуруТипа();
				ПоследнееВхождение = РезультатТекста.Item(РезультатТекста.Count - 1);
				Если Не ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(ПоследнееВхождение.SubMatches(1)) Тогда
					// Это присвоение
					ПрисвоенныйКонтекст = ПоследнееВхождение.SubMatches(2);
					Если НРег(ПоследнееВхождение.SubMatches(3)) = Нрег("Новый") Тогда
						//СтруктураТипа = мПлатформа.ПолучитьНовуюСтруктуруТипа();
						
						//Если ПоследнееВхождение.SubMatches(4) <> Неопределено Тогда 
						//	Попытка
						//		ТипНового = Тип(ПоследнееВхождение.SubMatches(4));
						//		СтруктураТипа = мПлатформа.ПолучитьСтруктуруТипаИзКонкретногоТипа(ТипНового, ЯзыкПрограммы);
						//	Исключение
						//		СтруктураТипа.ИмяОбщегоТипа = ПоследнееВхождение.SubMatches(4);
						//	КонецПопытки;
						//КонецЕсли;
						//Если ПоследнееВхождение.SubMatches(5) <> Неопределено Тогда
						//	Если ТипНового = Тип("COMОбъект") Тогда
						//		СтруктураТипа.ИмяОбщегоТипа = СтруктураТипа.ИмяОбщегоТипа + "." + ПоследнееВхождение.SubMatches(5);
						//	Иначе
						//		СтруктураТипа.ИмяОбщегоТипа = ПоследнееВхождение.SubMatches(5);
						//	КонецЕсли;
						//КонецЕсли;
						
						Если Не ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(ПоследнееВхождение.SubMatches(4)) Тогда 
							ИмяТипа = ПоследнееВхождение.SubMatches(4);
						ИначеЕсли Не ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(ПоследнееВхождение.SubMatches(5)) Тогда 
							ИмяТипа = ПоследнееВхождение.SubMatches(5);
						Иначе
							ИмяТипа = Неопределено;
						КонецЕсли;
						Если ЗначениеЗаполнено(ИмяТипа) Тогда
							Попытка
								ТипНового = Тип(ИмяТипа);
							Исключение
								ТипНового = Неопределено;
								СтруктураТипа.ИмяОбщегоТипа = ИмяТипа;
							КонецПопытки;
							Если Истина
								И ТипНового = Тип("COMОбъект")
								И Не ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(ПоследнееВхождение.SubMatches(5)) 
							Тогда
								ПолноеИмяОсновногоКлассаCOM = ПоследнееВхождение.SubMatches(5);
								ИмяОбщегоТипа = мИменаОбщихТиповПоИменамКлассовCOM[ПолноеИмяОсновногоКлассаCOM];
								Если ИмяОбщегоТипа = Неопределено Тогда
									МетаданныеСлова = мПлатформа.ПолучитьОбразецCOMОбъекта(ПолноеИмяОсновногоКлассаCOM);
									Если МетаданныеСлова = Неопределено Тогда
										ИмяОсновногоКлассаCOM = ирОбщий.ПолучитьПоследнийФрагментЛкс(ПолноеИмяОсновногоКлассаCOM);
										ИмяОбщегоТипа = "COMОбъект.{" + ПолноеИмяОсновногоКлассаCOM + "}." + ИмяОсновногоКлассаCOM;
									Иначе
										ИмяОбщегоТипа = мПлатформа.ПолучитьПолноеИмяТипаCOMОбъекта(МетаданныеСлова, ПолноеИмяОсновногоКлассаCOM);
										Если ирОбщий.СтрокиРавныЛкс(ИмяОбщегоТипа, "COMОбъект") Тогда
											ИмяОсновногоКлассаCOM = ирОбщий.ПолучитьПоследнийФрагментЛкс(ПолноеИмяОсновногоКлассаCOM);
											ИмяОбщегоТипа = "COMОбъект.{" + ПолноеИмяОсновногоКлассаCOM + "}." + ИмяОсновногоКлассаCOM;
										КонецЕсли; 
									КонецЕсли; 
									мИменаОбщихТиповПоИменамКлассовCOM[ПолноеИмяОсновногоКлассаCOM] = ИмяОбщегоТипа;
								КонецЕсли; 
								СтруктураТипа.ИмяОбщегоТипа = ИмяОбщегоТипа;
							ИначеЕсли ТипНового <> Неопределено Тогда
								СтруктураТипа = мПлатформа.ПолучитьСтруктуруТипаИзКонкретногоТипа(ТипНового, ЯзыкПрограммы);
							КонецЕсли;
						КонецЕсли; 
						
						мПлатформа.ДобавитьВТаблицуСтруктурТипов(ТаблицаСтруктурТипов, СтруктураТипа);
					ИначеЕсли Не ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(ПоследнееВхождение.SubMatches(6)) Тогда 
				        ТаблицаСтруктурТипов = ОпределитьТипЗначенияКонтекста(ПрисвоенныйКонтекст, Лев(ТекстДляПоискаОпределения,
							ПоследнееВхождение.FirstIndex - 1) , Лев(ТекстДляПоискаОпределения, ПоследнееВхождение.FirstIndex - 1));
						Для Каждого СтруктураТипа Из ТаблицаСтруктурТипов Цикл
							СтруктураКлюча = Новый Структура("Слово, ЯзыкПрограммы",
								СтруктураТипа.ИмяОбщегоТипа, ЯзыкПрограммы);
							СтруктураТипа.СтрокаОписания = Неопределено;
							
							// Было закомментировано
							//НайденныеСтроки = мПлатформа.ТаблицаОбщихТипов.НайтиСтроки(СтруктураКлюча);
							//Если НайденныеСтроки.Количество() > 0 Тогда
							//	СтруктураТипа.СтрокаОписания = НайденныеСтроки[0];
							//КонецЕсли;
						КонецЦикла;
					// **** Сделать определение примитивного типа
					Иначе
						СтруктураТипа.ИмяОбщегоТипа = "Примитивный";
						мПлатформа.ДобавитьВТаблицуСтруктурТипов(ТаблицаСтруктурТипов, СтруктураТипа);
					КонецЕсли;
				Иначе
					// Это обход коллекции
					ПрисвоенныйКонтекст = ПоследнееВхождение.SubMatches(15);
					// **** Раньше текст для поиска определения передавался неизменным. Тестовый режим
					ТаблицаСтруктурТиповКоллекции = ОпределитьТипЗначенияКонтекста(ПрисвоенныйКонтекст, Лев(ТекстДляПоискаОпределения,
							ПоследнееВхождение.FirstIndex - 1) , Лев(ТекстДляПоискаОпределения, ПоследнееВхождение.FirstIndex - 1));
							
							// Структура типов коллекции всегда имеет ровно один элемент
					//СтруктураКлюча = Новый Структура("Слово, ЯзыкПрограммы", СтруктураТипаКоллекции.ИмяОбщегоТипа, ЯзыкПрограммы);
					//НайденныеСтроки = мПлатформа.ТаблицаОбщихТипов.НайтиСтроки(СтруктураКлюча);
					//Если НайденныеСтроки.Количество() > 0 Тогда
					//	БазовыеТипы = ирОбщий.ПолучитьМассивИзСтрокиСРазделителемЛкс(НайденныеСтроки[0].ТипЭлементаКоллекции, ",", Истина);
					//	Для Каждого БазовыйТип Из БазовыеТипы Цикл
					//		СтруктураКлюча = Новый Структура("БазовыйТип, ЯзыкПрограммы", БазовыйТип, ЯзыкПрограммы);
					//		НайденныеСтроки = мПлатформа.ТаблицаОбщихТипов.НайтиСтроки(СтруктураКлюча);
					//		Если НайденныеСтроки.Количество() > 0 Тогда
					//			СтруктураТипа.СтрокаОписания = НайденныеСтроки[0];
					//			СтруктураТипа.ИмяОбщегоТипа  = НайденныеСтроки[0].Слово;
					//			СтруктураТипа.Метаданные = СтруктураТипаКоллекции.Метаданные;
					//		КонецЕсли;
					//		мПлатформа.ДобавитьВТаблицуСтруктурТипов(ТаблицаСтруктурТипов, СтруктураТипа);
					//	КонецЦикла;
					//Иначе
					//	мПлатформа.ДобавитьВТаблицуСтруктурТипов(ТаблицаСтруктурТипов, СтруктураТипа);
					//КонецЕсли;
					ДобавитьТипЭлементаКоллекцииВТаблицуСтруктурТипов(ТаблицаСтруктурТиповКоллекции[0], СтруктураТипа, ТаблицаСтруктурТипов);
				КонецЕсли;
				Если Не ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(ТекущийИндекс) Тогда
					МассивРодительскихСтрутурТипа = ТаблицаСтруктурТипов;
					ТаблицаСтруктурТипов = мПлатформа.ПолучитьНовуюТаблицуСтруктурТипа();
				КонецЕсли;
			КонецЕсли;
		КонецЕсли;
		Если МассивРодительскихСтрутурТипа.Количество() = 0 Тогда
			МассивРодительскихСтрутурТипа = ОпределитьТипЗначенияКонтекста(РодительскийКонтекст, ТекстДляПоискаОпределения,
				ПредшествующийТекст);
		КонецЕсли;
		МассивДочернихСтруктурТипа = ОпределитьТипДочернегоКонтекста(МассивРодительскихСтрутурТипа, ТекущееСлово, ТипСлова, 
			ТекущийИндекс, ТекущиеАргументы, ПредшествующийТекст);
		ирОбщий.ЗагрузитьВТаблицуЗначенийЛкс(МассивДочернихСтруктурТипа, ТаблицаСтруктурТипов); 
		Если Истина 
			И ЯзыкПрограммы = 1
			И РодительскийКонтекст = ""
			И СтруктураТипа.ИмяОбщегоТипа = "Неизвестный контекст"
			И ТипЗнч(КонтекстВыполнения) = Тип("Запрос")
		Тогда
			ВременныйЗапрос = Новый Запрос;
			ВременныйЗапрос.МенеджерВременныхТаблиц = КонтекстВыполнения.МенеджерВременныхТаблиц;
			ВременныйЗапрос.Текст = "ВЫБРАТЬ ПЕРВЫЕ 1 * ИЗ " + ТекущееСлово;
			Попытка
				// Активное вычисление!
				СтруктураТипа.Метаданные = ВременныйЗапрос.Выполнить();
				СтруктураТипа.ИмяОбщегоТипа = "ВременнаяТаблица";
			Исключение
			КонецПопытки;
		КонецЕсли;
	КонецЕсли;
	Если ТаблицаСтруктурТипов.Количество() = 0 Тогда
		мПлатформа.ДобавитьВТаблицуСтруктурТипов(ТаблицаСтруктурТипов, СтруктураТипа);
	КонецЕсли;
	Возврат ТаблицаСтруктурТипов;

КонецФункции // ОпределитьТипЗначенияКонтекста()

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

	Если Не ЗначениеЗаполнено(ТекстДляАнализа) Тогда
		Если ОбновитьТекстДляАнализа Тогда
			ТекстДляАнализа = ПолеТекстовогоДокумента.ПолучитьТекст();
		КонецЕсли; 
	КонецЕсли; 
	Если ЗначениеЗаполнено(ТекстДляАнализа) Тогда
		ТекстБезКомментариевИОпасныхСтрок = ЗалитьКомментарииИСтроковыеЛитералы(ТекстДляАнализа);
	КонецЕсли; 
	Если ОчиститьТаблицуСлов Тогда
		ТаблицаСлов.Очистить();
	КонецЕсли;
	
	Если ВключатьКонструкции Тогда
		Если ЯзыкПрограммы = 0 Тогда
			СписокСловЯзыка = мПлатформа.ПолучитьСписокКлючевыхСловВстроенногоЯзыка();
		ИначеЕсли ЯзыкПрограммы = 1 Тогда
			ВключаяРусские = ТипЗнч(Конфигурация) = Тип("ОбъектМетаданныхКонфигурация");
			СписокСловЯзыка = мПлатформа.ПолучитьСписокКлючевыхСловЯзыкаЗапросов(РежимКомпоновкиДанных, ВключаяРусские, Истина);
		ИначеЕсли ЯзыкПрограммы = 2 Тогда
			//СписокСловЯзыка = мПлатформа.ПолучитьСписокКлючевыхСловЯзыкаЗапросов();
			СписокСловЯзыка = Новый СписокЗначений;
		КонецЕсли;
		Для Каждого ЭлементСписка Из СписокСловЯзыка Цикл
			НоваяСтрока = ТаблицаСлов.Добавить();
			НоваяСтрока.Слово = ЭлементСписка.Значение;
			НоваяСтрока.НСлово = НРег(НоваяСтрока.Слово);
			НоваяСтрока.ТипСлова = "Конструкция";
			НоваяСтрока.Определение = "Предопределенный";
		КонецЦикла;
	КонецЕсли;
	Если ВключатьГлобальныйКонтекст Тогда
		СтруктураТипа = мПлатформа.ПолучитьНовуюСтруктуруТипа();
		СтруктураТипа.ИмяОбщегоТипа = "Глобальный контекст";
		СтруктураТипа.Метаданные = Метаданные;
		ТаблицаГлобальногоКонтекста = мПлатформа.ПолучитьТаблицуСловСтруктурыТипа(СтруктураТипа);
		Для Каждого СтрокаСлова Из ТаблицаГлобальногоКонтекста Цикл
			НоваяСтрока = ТаблицаСлов.Добавить();
			ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаСлова); 
			НоваяСтрока.НСлово = НРег(НоваяСтрока.Слово);
			//НоваяСтрока.Слово = ЭлементСписка.Значение;
			//НоваяСтрока.ТипСлова = "Конструкция";
			//НоваяСтрока.Определение = "Предопределенный";
		КонецЦикла;
	КонецЕсли;
	
	//Поиск использованных свойств и методов данного контекста.
	//Из-за отсутствия поддержки в VBScript RegExp lookahead & lookbehind пришлось применять неизящный подход.
	ТаблицаЦикла = Новый ТаблицаЗначений;
	ТаблицаЦикла.Колонки.Добавить("Шаблон");
	ТаблицаЦикла.Колонки.Добавить("ТипСлова");
	
	// Свойства
	СтрокаТаблицыЦикла = ТаблицаЦикла.Добавить();
	СтрокаТаблицыЦикла.ТипСлова = "Свойство";
	Если Ложь
		Или Не УчитыватьРодительскийКонтекст
		Или мРодительскийКонтекст = ""
	Тогда
		СтрокаТаблицыЦикла.Шаблон = "(?:(" + шПараметрЗапроса + ")"
			+ "|(" + шИмя + ")(?:(?:\.(?:" + шИмя + ")?)+" 
			+ "|[^\(?:\._А-Яа-яA-Za-z\d]|$))|(?:[_А-Яа-яA-Za-z\d\.]*)";
	Иначе
		СтрокаТаблицыЦикла.Шаблон = "(?:" + ирОбщий.ПреобразоватьТекстДляРегулярныхВыраженийЛкс(мРодительскийКонтекст) 
			+ "\.(" + шИмя + ")(?:[^\(?:_А-Яа-яA-Za-z\d]|$))|(?:[_А-Яа-яA-Za-z\d\.]*)";
	КонецЕсли;
		
	// Методы
	СтрокаТаблицыЦикла = ТаблицаЦикла.Добавить();
	СтрокаТаблицыЦикла.ТипСлова = "Метод";
	Если Ложь
		Или Не УчитыватьРодительскийКонтекст
		Или мРодительскийКонтекст = ""
	Тогда
		СтрокаТаблицыЦикла.Шаблон = "(?:(" + шИмя + ")\()|(?:[_А-Яа-яA-Za-z\d\.]*)";
	Иначе
		СтрокаТаблицыЦикла.Шаблон = "(?:" + ирОбщий.ПреобразоватьТекстДляРегулярныхВыраженийЛкс(мРодительскийКонтекст) 
			+ "\.(" + шИмя + ")\()|(?:[_А-Яа-яA-Za-z\d\.]*)";
	КонецЕсли;
		
	RegExp.Global = Истина;
	Для Каждого СтрокаТаблицыЦикла Из ТаблицаЦикла Цикл
		RegExp.Pattern = "(?:" + шСтрокаПрограммы + "|" + шРазделитель + "|Новый\s+" + шИмя + "|" + СтрокаТаблицыЦикла.Шаблон + ")";
		Результат = RegExp.Execute(" " + ТекстБезКомментариевИОпасныхСтрок);
		Для Каждого Match Из Результат Цикл
			//Если Не ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(Match.SubMatches(0)) Тогда 
			Если Match.SubMatches(0) <> Неопределено Тогда
				Слово = Match.SubMatches(0);
			ИначеЕсли Истина
				И Match.SubMatches.Count > 1
				//И Не ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(Match.SubMatches(1))
				И Match.SubMatches(1) <> Неопределено
			Тогда 
				Слово = Match.SubMatches(1);
			Иначе 
				Продолжить;
			КонецЕсли;
			СтруктураКлюча = Новый Структура("НСлово", НРег(Слово));
			НайденныеСтроки = ТаблицаСлов.НайтиСтроки(СтруктураКлюча);
			НоваяСтрока = Неопределено;
			Для Каждого НайденнаяСтрока Из НайденныеСтроки Цикл
				Если Ложь
					Или ЯзыкПрограммы = 1
					Или (Истина
						И СтрокаТаблицыЦикла.ТипСлова = "Метод" 
						И НайденнаяСтрока.ТипСлова = "Метод")
					Или (Истина
						И СтрокаТаблицыЦикла.ТипСлова <> "Метод" 
						И НайденнаяСтрока.ТипСлова <> "Метод")
				Тогда
					НоваяСтрока = НайденнаяСтрока;
					Прервать;
				КонецЕсли;
			КонецЦикла;
			Если НоваяСтрока = Неопределено Тогда 
				НоваяСтрока = ТаблицаСлов.Добавить();
				НоваяСтрока.Определение = "Статистический";
				НоваяСтрока.Слово = Слово;
				НоваяСтрока.НСлово = НРег(НоваяСтрока.Слово);
				НоваяСтрока.ТипСлова = СтрокаТаблицыЦикла.ТипСлова;
			КонецЕсли;
			ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураКлюча);
			НоваяСтрока.Частота = НоваяСтрока.Частота + 1;
		КонецЦикла;
	КонецЦикла;

КонецПроцедуры // ЗаполнитьЛокальныеСвойстваИМетодыПоТексту()

Процедура УстановитьПризнакМодифицированностиФормы()

	Если ПолеТекстовогоДокумента.ИзменяетДанные Тогда
		ФормаВладелец.Модифицированность = Истина;
	КонецЕсли; 

КонецПроцедуры // УстановитьПризнакМодифицированностиФормы()

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

КонецФункции//ПолучитьСтруктуруТипаСправоОтРавно

Функция ПолучитьТаблицуСтруктурТиповТекущегоВыражения(ЛиСправаОтРавенства = Ложь) Экспорт

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

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

КонецПроцедуры // ВызватьКонтекстнуюПодсказку()

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

// Заменяет все символы табуляции в каждой строке текста после первого печатного символа эквивалентным
// количеством пробелов.
//
// Параметры:
//  Нет.
//
Процедура ЗаменитьТабуляции()

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

КонецПроцедуры // ЗаменитьТабуляции()

// Управляет режимом вывода сообщений (через предупреждение/в окно сообщений).
//
// Параметры:
//  *НовыйРежим - Булево, *Неопределено - новый режим (Истина - через предупреждения).
//
Процедура УстановитьСообщенияЧерезПредупреждения(НовыйРежим = Неопределено)

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

КонецПроцедуры // УстановитьСообщенияЧерезПредупреждения()

Процедура УстановитьАвтоКонтекстнаяПомощь(НовыйРежим)

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

КонецПроцедуры // УстановитьСообщенияЧерезПредупреждения()

// Удаляет все символы переноса строки из текста.
//
// Параметры:
//  Нет.
//
Процедура УдалитьПереносы()

	Если Ложь
		Или ПолеТекстовогоДокумента.ТолькоПросмотр
		Или ФормаВладелец.ТолькоПросмотр
	Тогда
		Возврат;
	КонецЕсли;
	Текст = ПолеТекстовогоДокумента.ПолучитьТекст();
	Текст = СокрЛП(Текст);
	Если Истина
		И Лев(Текст, 1) = """"
		И Лев(Текст, 2) <> """"""
	Тогда
		Текст = Сред(Текст, 2);
	КонецЕсли; 
	Если Истина
		И Прав(Текст, 1) = """"
		И Прав(Текст, 2) <> """"""
	Тогда
		Текст = Лев(Текст, СтрДлина(Текст) - 1);
	КонецЕсли; 
	Если Истина
		И Прав(Текст, 2) = """;"
		И Прав(Текст, 3) <> """"";"
	Тогда
		Текст = Лев(Текст, СтрДлина(Текст) - 2);
	КонецЕсли; 
	Текст = СтрЗаменить(Текст, "|", "");
	Текст = СтрЗаменить(Текст, """""", """");
	ПолеТекстовогоДокумента.УстановитьТекст(Текст);
	УстановитьПризнакМодифицированностиФормы();
	
КонецПроцедуры // УдалитьПереносы()

// Добавляет слово локального контекста.
//
// Параметры:
//  Слово        – Строка;
//  ТипСлова     – Строка - "Метод", "Свойство";
//  *ТипЗначения - ОписаниеТипов, *Неопределено;
//  *Метаданные  - Произвольный, *Неопределено - используется, если ТипЗначения задан;
//  *Глобальное  - Булево, *Ложь - это слово глобального контекста;
//  *ТаблицаСтруктурТипа - ТаблицаЗначений, *Неопределено;
//
Процедура ДобавитьСловоЛокальногоКонтекста(Слово, ТипСлова = "Свойство", ТипЗначения = Неопределено,
	пМетаданные = Неопределено, Глобальное = Ложь, Значение = Неопределено, ТаблицаСтруктурТипов = Неопределено, ИмяОбщегоТипа = "") Экспорт

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

КонецПроцедуры // ДобавитьСловоЛокальногоКонтекста()

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

КонецПроцедуры // ДобавитьСловоЛокальногоКонтекста()

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

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

КонецПроцедуры // ДобавитьПеременнуюЛокальногоКонтекста()

// Очишает таблицу слов локального контекста.
//
// Параметры:
//  Нет.
//
Процедура ОчиститьТаблицуСловЛокальногоКонтекста() Экспорт

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

КонецПроцедуры // ОчиститьТаблицуСловЛокальногоКонтекста()

// Удаляет слово локального контекста.
//
// Параметры:
//  Слово        – Строка;
//  ТипСлова     – Строка.
//
Процедура УдалитьСловоЛокальногоКонтекста(Слово, ТипСлова) Экспорт

	КлючСтроки = Новый Структура;
	КлючСтроки.Вставить("нСлово", НРег(Слово));
	КлючСтроки.Вставить("ТипСлова", ТипСлова);
	СтрокиСлова = ТаблицаЛокальногоКонтекста.НайтиСтроки(КлючСтроки);
	Если СтрокиСлова.Количество() > 0 Тогда
		ТаблицаЛокальногоКонтекста.Удалить(СтрокиСлова[0]);
	КонецЕсли;

КонецПроцедуры // УдалитьСловоЛокальногоКонтекста()

// Устанавливает доступность действий, изменяющих данные.
//
// Параметры:
//  НовыйТолькоПросмотр – Булево.
//
Процедура УстановитьТолькоПросмотр(НовыйТолькоПросмотр) Экспорт 

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

// Получает представление массива типов.
//
// Параметры:
//  ТаблицаСтруктурТиповКонтекста – Массив.
//
// Возвращаемое значение:
//   Строка - представление массива типов.
//
Функция ПолучитьПредставлениеМассиваСтруктурТипов(ТаблицаСтруктурТиповКонтекста)

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

КонецФункции // ПолучитьПредставлениеМассиваСтруктурТипов()

/////////////////////////////////////////////////////////////////////////////////
// Шаблоны текста

// Выполняет шаблон текста.
//
// Параметры:
//  Нет.
//
Процедура ВыполнитьШаблонТекста()

	ЗаменаТабуляции = ирОбщий.ПолучитьСтрокуПовторомЛкс(" ", ШиринаТабуляции);
	ВыделитьНачалоИКонецТекущейСтроки();
	RegExp.Global = Ложь;
	СтрокаРазделителейШаблоновТекста = ";.,:()[]";
	RegExp.Pattern = "([^\s" + ирОбщий.ПреобразоватьТекстДляРегулярныхВыраженийЛкс(СтрокаРазделителейШаблоновТекста) + "]*)$";
	Результат = RegExp.Execute(ТекущееНачалоСтроки);
	Если Результат.Count > 0 Тогда
		НачалоКонтекста = Результат.Item(0).SubMatches(0);
		ТаблицаШаблоновТекста = мПлатформа.ПолучитьТаблицуШаблоновТекста(ИмяКласса, мСообщенияЧерезПредупреждения);
		Если ТаблицаШаблоновТекста = Неопределено Тогда
			Возврат;
		КонецЕсли;
		//СтрокаШаблона = ТаблицаШаблоновТекста.Найти(НРег(НачалоКонтекста), "ШаблонБезКвадратныхСкобок");
		СтрокаШаблона = Неопределено;
		Для каждого ТекСтрокаШаблона Из ТаблицаШаблоновТекста Цикл
			Если ТекСтрокаШаблона.Шаблон = НРег(НачалоКонтекста) Тогда
				СтрокаШаблона = ТекСтрокаШаблона;
				Прервать;
			КонецЕсли;
			МинимальнаяДлинаСовпадения = Найти(ТекСтрокаШаблона.Шаблон, "[");
			Если МинимальнаяДлинаСовпадения > 0 Тогда
				Если СтрДлина(НачалоКонтекста) < МинимальнаяДлинаСовпадения - 1 Тогда
					Продолжить;
				КонецЕсли; 
				ШаблонБезСкобок = СтрЗаменить(ТекСтрокаШаблона.Шаблон, "[", "");
				ШаблонБезСкобок = СтрЗаменить(ШаблонБезСкобок, "]", "");
				Если Найти(ШаблонБезСкобок, НРег(НачалоКонтекста)) = 1 Тогда
					СтрокаШаблона = ТекСтрокаШаблона;
					Прервать;
				КонецЕсли;
			КонецЕсли; 
		КонецЦикла;
		Если СтрокаШаблона <> Неопределено Тогда
			RegExp.Global = Истина;
			RegExp.MultiLine = Истина;
			RegExp.Pattern = "(<\?\s*(""[^""\^]*"")?(?:.|\r|\n)*?>)|(.|\r|\n)";
			Результат = RegExp.Execute(СтрокаШаблона.Замена);
			КонечныйТекстЗамены = "";
			ПоследняяПозицияКурсора = 0;
			КешПараметров = Новый ТаблицаЗначений;
			КешПараметров.Колонки.Добавить("ИмяПараметра");
			КешПараметров.Колонки.Добавить("ЗначениеПараметра");
			Для Каждого Match Из Результат Цикл
				УправляющаяКонструкция = Match.SubMatches(0);
				Если ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(УправляющаяКонструкция) Тогда
					КонечныйТекстЗамены = КонечныйТекстЗамены + Match.SubMatches(2);
				Иначе
					ИмяПараметраШаблона = Match.SubMatches(1);
					Если Не ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(ИмяПараметраШаблона) Тогда
						ИмяПараметраШаблона = Сред(ИмяПараметраШаблона, 2, СтрДлина(ИмяПараметраШаблона) - 2);
						ВведеннаяСтрока = "";
						Если ИмяПараметраШаблона <> "" Тогда
							СтрокаКэша = КешПараметров.Найти(ИмяПараметраШаблона, "ИмяПараметра");
							Если СтрокаКэша <> Неопределено Тогда
								ВведеннаяСтрока = СтрокаКэша.ЗначениеПараметра;
							Иначе
								СтрокаКэша = КешПараметров.Добавить();
								СтрокаКэша.ИмяПараметра = ИмяПараметраШаблона;
								ВвестиЗначение(ВведеннаяСтрока, ИмяПараметраШаблона, Тип("Строка"));
								СтрокаКэша.ЗначениеПараметра = ВведеннаяСтрока;
							КонецЕсли;
						КонецЕсли; 
						КонечныйТекстЗамены = КонечныйТекстЗамены + ВведеннаяСтрока;
					Иначе
						ПоследняяПозицияКурсора = СтрДлина(КонечныйТекстЗамены) + 1;
					КонецЕсли;
				КонецЕсли;
			КонецЦикла;
			КонечныйТекстЗаменыТД = Новый ТекстовыйДокумент;
			КонечныйТекстЗаменыТД.УстановитьТекст(КонечныйТекстЗамены);
			лКонечнаяСтрока = 0;
			лКонечнаяКолонка = 0;
			Если ПоследняяПозицияКурсора > 0 Тогда
				СлужебноеПолеТекстовогоДокумента.УстановитьТекст(КонечныйТекстЗамены);
				Если ПоследняяПозицияКурсора <= СтрДлина(КонечныйТекстЗамены) Тогда
					СлужебноеПолеТекстовогоДокумента.УстановитьГраницыВыделения(ПоследняяПозицияКурсора, ПоследняяПозицияКурсора);
					СлужебноеПолеТекстовогоДокумента.ПолучитьГраницыВыделения(лКонечнаяСтрока, лКонечнаяКолонка, лКонечнаяСтрока, лКонечнаяКолонка);
				Иначе
					лКонечнаяСтрока = КонечныйТекстЗаменыТД.КоличествоСтрок();
					лКонечнаяКолонка = СтрДлина(КонечныйТекстЗаменыТД.ПолучитьСтроку(КонечныйТекстЗаменыТД.КоличествоСтрок())) + 1;
				КонецЕсли;
			КонецЕсли;
			ЧислоСтрокЗамены = КонечныйТекстЗаменыТД.КоличествоСтрок();
			СтрокаДобавка = КонечныйТекстЗаменыТД.ПолучитьСтроку(1);
			ДлинаНачалаСтроки = мКонечнаяКолонка - СтрДлина(НачалоКонтекста) - 1;
			НачалоСтроки = Лев(ТекущееНачалоСтроки, ДлинаНачалаСтроки);
			ТекущееНачалоСтроки = НачалоСтроки + СтрокаДобавка;
			ТекущаяСтрока = ТекущееНачалоСтроки;
			Если ЧислоСтрокЗамены = 1 Тогда
				ТекущаяСтрока = ТекущаяСтрока + ТекущийКонецСтроки;
			КонецЕсли;
			ПолеТекстовогоДокумента.ЗаменитьСтроку(мКонечнаяСтрока, "" + ТекущаяСтрока);
			ДлинаРазвернутогоНачалаСтроки = СтрДлина(СтрЗаменить(НачалоСтроки, Символы.Таб, ЗаменаТабуляции));
			ЧислоТабуляций = ДлинаРазвернутогоНачалаСтроки / ШиринаТабуляции;
			ЧислоПробелов  = ДлинаРазвернутогоНачалаСтроки % ШиринаТабуляции;
			НачалоНовойСтроки = ирОбщий.ПолучитьСтрокуПовторомЛкс(Символы.Таб, ЧислоТабуляций);
			НачалоНовойСтроки = НачалоНовойСтроки + ирОбщий.ПолучитьСтрокуПовторомЛкс(" ", ЧислоПробелов);
			Для Счетчик = 2 По ЧислоСтрокЗамены - 1 Цикл
				ТекущаяСтрокаВставки = КонечныйТекстЗаменыТД.ПолучитьСтроку(Счетчик);
				ПолеТекстовогоДокумента.ВставитьСтроку(мКонечнаяСтрока + Счетчик - 1, НачалоНовойСтроки + ТекущаяСтрокаВставки);
			КонецЦикла;
			Если ЧислоСтрокЗамены > 1 Тогда
				ТекущаяСтрокаВставки = КонечныйТекстЗаменыТД.ПолучитьСтроку(ЧислоСтрокЗамены);
				ПолеТекстовогоДокумента.ВставитьСтроку(мКонечнаяСтрока + ЧислоСтрокЗамены - 1,
					НачалоНовойСтроки + ТекущаяСтрокаВставки + ТекущийКонецСтроки);
			КонецЕсли;
			Если лКонечнаяСтрока > 0 Тогда
				Если лКонечнаяСтрока = 1 Тогда
					лКонечнаяКолонка = лКонечнаяКолонка + СтрДлина(НачалоСтроки);
				Иначе
					лКонечнаяКолонка = лКонечнаяКолонка + СтрДлина(НачалоНовойСтроки);
				КонецЕсли;
				лКонечнаяСтрока = лКонечнаяСтрока + мКонечнаяСтрока - 1;
				мКонечнаяКолонка = лКонечнаяКолонка;
				мКонечнаяСтрока = лКонечнаяСтрока;
			Иначе
				мКонечнаяСтрока = мКонечнаяСтрока + ЧислоСтрокЗамены - 1;
				Если ЧислоСтрокЗамены > 1 Тогда
					мКонечнаяКолонка = СтрДлина(НачалоСтроки + ТекущаяСтрокаВставки) + 1;
				Иначе
					мКонечнаяКолонка = мКонечнаяКолонка + СтрДлина(КонечныйТекстЗамены) - СтрДлина(НачалоКонтекста);
				КонецЕсли;
			КонецЕсли;
			мНачальнаяСтрока = мКонечнаяСтрока;
			мНачальнаяКолонка = мКонечнаяКолонка;
		КонецЕсли;
	КонецЕсли;

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

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

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

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

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

ШиринаТабуляции = 4;

RegExp = мПлатформа.ПолучитьНовыйВычислительРегулярныхВыражений();
RegExp.IgnoreCase = Истина;
RegExp.MultiLine = Ложь;

шБуква       = мПлатформа.шБуква;
шИмя         = мПлатформа.шИмя;
шЧисло       = мПлатформа.шЧисло;
шИндекс      = мПлатформа.шИндекс;
шСкобки      = мПлатформа.шСкобки;
шРазделитель = мПлатформа.шРазделитель;
шКомментарий = мПлатформа.шКомментарий;

шНачалоЧисла = "\d+(?:\.)?\d*";
шНачалоСкобок = "(\((?:[^\)\(]*?(?:(?:\([^\)]*?\)[^\)\(]*?)*)*\))?)";

// Шаблоны программы

шДирективаПрепроцессора = "#[^\n]*\n";
шСтрокаПрограммы       = """(?:(?:"""")|[^""\n$])*(?:" + шРазделитель + "*\|(?:(?:"""")|[^""\n$])*)*(?:""|$)";
шНачалоСтрокиПрограммы = """(?:(?:"""")|[^""\n$])*(?:" + шРазделитель + "*\|(?:(?:"""")|[^""\n$])*)*(?:""|$)?";
шОператорПрограммы = "(?:(?:=|>|<|<>|<=|>=|\*|\/|\+|\-)|" + шРазделитель + "(?:И|ИЛИ|НЕ)" + шРазделитель + ")+";

шНачалоТокена = "([" + шБуква + "\d]" + шРазделитель + "+|(?:\]|\)|" + шСтрокаПрограммы + "|;|^)" + шРазделитель + "*)";
шКонецТокена = "(" + шРазделитель + "+[" + шБуква + "\d]|" + шРазделитель + "*(?:\[|\(|" + шСтрокаПрограммы + "|;|$))";
шЕсли = шНачалоТокена + "(?:Если|ИначеЕсли)"  
	+ шКонецТокена + "(?:" + шСтрокаПрограммы + "|\." + шРазделитель + "*Тогда|\r|\n|.)*?" + "[^" + шБуква + "\d\.]"
	+ "Тогда" + шКонецТокена;
шПока = шНачалоТокена + "Пока" 
	+ шКонецТокена + "(?:" + шСтрокаПрограммы + "|\r|\n|.)*?" + "[^" + шБуква + "\d\.]"
	+ "Цикл" + шКонецТокена;
шВызватьИсключение = шНачалоТокена + "ВызватьИсключение" 
	+ шКонецТокена + "(?:" + шСтрокаПрограммы + "|\." + шРазделитель + "*;|\r|\n|.)*?;";

шОписаниеФункции = "Функция" + шРазделитель + "*(" + шИмя + ")" + шРазделитель + "*\(([^\)]*)\)(" + шРазделитель + "*Экспорт)?"
	+ "((?:(?:" + шСтрокаПрограммы + "|\." + шРазделитель + "*КонецФункции|\r|\n|.)*?))"
	+ "[^" + шБуква + "\d\.""]КонецФункции[^" + шБуква + "\d\.""]";

шОписаниеПроцедуры = "Процедура" + шРазделитель + "*(" + шИмя + ")" + шРазделитель + "*\(([^\)]*)\)(" + шРазделитель + "*Экспорт)?"
	+ "((?:(?:" + шСтрокаПрограммы + "|\." + шРазделитель + "*КонецПроцедуры|\r|\n|.)*?))"
	+ "[^" + шБуква + "\d\.""]КонецПроцедуры[^" + шБуква + "\d\.""]";
	
шОписаниеПеременной = "Перем" + шРазделитель + "*(" + шИмя + ")(" + шРазделитель + "+Экспорт)?" + шРазделитель + "*;";

шМодуль = "^((?:" + шОписаниеПеременной + "|" + шРазделитель + "|" + шДирективаПрепроцессора + ")*)"
	+ "((?:" + шОписаниеФункции + "|" + шОписаниеПроцедуры + "|" + шДирективаПрепроцессора + "|" + шРазделитель + ")*)((?:\r|\n|.)*)$";

//шВыражениеПрограммы       = "(?:" + шРазделитель + "*(?:(?:" + шИмя + шСкобки + "?" + "(?:(?:\.(?:" + шИмя + ")" + шСкобки + "?)|" + шИндекс + ")*)|"
//	+ шЧисло + "|" + шСтрокаПрограммы + ")" + шРазделитель + "*" + шОператорПрограммы + ")*" 
//	+ шРазделитель + "*(?:(?:" + шИмя + шСкобки + "?" + "(?:(?:\.(?:" + шИмя + ")" + шСкобки + "?)|" + шИндекс + ")*)|"
//	+ шЧисло + "|" + шСтрокаПрограммы + ")";
//шВыражениеПрограммы       = "(?:" + шРазделитель + "*" + шОператорПрограммы + шРазделитель + "*"
//	+ "(?:(?:" + шИмя + шСкобки + "?" + "(?:(?:\.(?:" + шИмя + ")" + шСкобки + "?)|" + шИндекс + ")*)|"
//	+ шЧисло + "|" + шСтрокаПрограммы + ")*)*";
//шВыражениеПрограммы       = "(?:" + шРазделитель + "*"
//	+ "(?:новый)" + "(?:" + шРазделитель + "(?:" + шИмя + "))?" + шРазделитель + "*" + "(?:\(""(?:" + шИмя+ "(?:\." + шИмя + ")*))?|(?:"
//	+ "(?:*" + шОператорПрограммы + шИмя + шСкобки + "?" + "(?:(?:\.(?:" + шИмя + ")" + шСкобки + "?)|" + шИндекс + ")*)|"
//	+ шЧисло + "|" + шСтрокаПрограммы + ")" + шРазделитель + ")*" 
//	+ шРазделитель + "*(?:(?:" + шИмя + шСкобки + "?" + "(?:(?:\.(?:" + шИмя + ")" + шСкобки + "?)|" + шИндекс + ")*)|"
//	+ шЧисло + "|" + шСтрокаПрограммы + ")";

шВыражениеПрограммы1 = "(?:(?:новый)" + "(?:" + шРазделитель + "(?:" + шИмя + "))?" + шРазделитель + "*" + "(?:\(""(?:" + шИмя+ "(?:\." + шИмя + ")*)""\))?"
	+ "|(?:не" + шРазделитель + "+)?(?:" + шИмя + шСкобки + "?" + "(?:(?:\.(?:" + шИмя + ")" + шСкобки + "?)|" + шИндекс + ")*)|"
	+ шЧисло + "|" + шСтрокаПрограммы + ")";
шВыражениеПрограммы = шРазделитель + "*" + шВыражениеПрограммы1 + "(?:" + шРазделитель + "*" + шОператорПрограммы + шРазделитель + "*"
	+ шВыражениеПрограммы1 + ")*";
	
шНачалоВыраженияПрограммы = "(?:" + шРазделитель + "*(?:(?:" 
	+ шИмя + шСкобки + "?" + "(?:(?:\.(?:" + шИмя + ")" + шСкобки + "?)|" + шИндекс + ")*)|"
	+ шЧисло + "|" + шСтрокаПрограммы + ")" + шРазделитель + "*" + шОператорПрограммы + ")*" 
	+ шРазделитель + "*(?:(?:" + шИмя + шСкобки + "?" + "(?:(?:\.(?:" + шИмя + ")" + шСкобки + "?)|" + шИндекс + ")*)|"
	+ шНачалоЧисла + "|" + шНачалоСтрокиПрограммы + ")?";

шВызовМетодаПрограммы = "(" + шИмя + шСкобки + "?" + "(?:(?:\.(?:" + шИмя + ")" + шСкобки + "?)|" + шИндекс + ")*?)"
	+ "\(((?:(?:" + шВыражениеПрограммы + ")?" + шРазделитель + "*,)*)" + "(?:" + шНачалоВыраженияПрограммы + ")?" + шРазделитель + "*";

//шПрисваивание = "(" + шРазделитель + "*=" + шРазделитель + "*((новый)" 
//	+ "(?:" + шРазделитель + "(" + шИмя + "))?" + шРазделитель + "*" + "(?:\(""(" + шИмя+ "(?:\." + шИмя + ")*)""\))?|"
//	+ "(" + шИмя + шСкобки + "?" + шИндекс + "?(?:\." + шИмя + шСкобки + "?" + шИндекс + "?)*)" + "|"
//	+ "(" + шЧисло + ")|(" + шСтрокаПрограммы + ")))";
//шПрисваивание = "(" + шРазделитель + "*=" + шРазделитель + "*((новый)" 
//	+ "(?:(?:" + шРазделитель + "+(" + шИмя + ")" + шРазделитель + "*(?:;|\())|(?:" + шРазделитель + "*\(""(" + шИмя+ "(?:\." + шИмя + ")*)""\)))|"
//	+ "(" + шИмя + шСкобки + "?" + шИндекс + "?(?:\." + шИмя + шСкобки + "?" + шИндекс + "?)*)" + "|"
//	+ "(" + шЧисло + ")|(" + шСтрокаПрограммы + ")))";
//шПрисваивание = "(" + шРазделитель + "*=" + шРазделитель + "*((новый)" 
//	+ "(?:" + шРазделитель + "+(" + шИмя + "))?" + шРазделитель + "*(?:\(""(" + шИмя+ "(?:\." + шИмя + ")*)""\))?|"
//	+ "(" + шИмя + шСкобки + "?" + шИндекс + "?(?:\." + шИмя + шСкобки + "?" + шИндекс + "?)*)" + "|"
//	+ "(" + шЧисло + ")|(" + шСтрокаПрограммы + ")))";
//шПрисваивание = "(" + шРазделитель + "*=" + шРазделитель + "*((новый)" // Изменение для поддержки ProgID типа Forms.TextBox.1
//	+ "(?:" + шРазделитель + "+(" + шИмя + "))?" + шРазделитель + "*(?:\(""(" + шИмя+ "(?:\.[А-Яа-я_A-Za-z\d]+)*)""\))?(?:" + шРазделитель + "|;)|"
//	+ "(" + шИмя + шСкобки + "?" + шИндекс + "?(?:\." + шИмя + шСкобки + "?" + шИндекс + "?)*)" + "|"
//	+ "(" + шЧисло + ")|(" + шСтрокаПрограммы + ")))";
шПрисваивание = "(" + шРазделитель + "*=" + шРазделитель + "*((новый)" // Изменение для поддержки ProgID типа Forms.TextBox.1
	+ "(?:" + шРазделитель + "+(" + шИмя + "))?" + шРазделитель + "*(?:\(""(" + шИмя+ "(?:\.[А-Я_A-Z\d]+)*)""\)(?:" + шРазделитель + "|;))?|"
	+ "(" + шИмя + шСкобки + "?" + шИндекс + "?(?:\." + шИмя + шСкобки + "?" + шИндекс + "?)*)" + "|"
	+ "(" + шЧисло + ")|(" + шСтрокаПрограммы + ")))";

// Шаблоны запроса
шПараметрЗапроса = "(?:&|\?|@)[" + шБуква + "][" + шБуква + "\d]*";
шСтрокаЗапроса       = """(?:(?:"""")|[^""\n$])*(?:" + шРазделитель + "*(?:(?:"""")|[^""\n$])*)*(?:""|$)";
шНачалоСтрокиЗапроса = """(?:(?:"""")|[^""\n$])*(?:" + шРазделитель + "*(?:(?:"""")|[^""\n$])*)*(?:""|$)?";
шОператорЗапроса = "(?:(?:=|>|<|<>|<=|>=|\*|\/|\+|\-)|" + шРазделитель 
	+ "(?:И|AND|ИЛИ|OR|НЕ|NOT|МЕЖДУ|BETWEEN|ПОДОБНО|LIKE|ССЫЛКА|REFS|(?:ЕСТЬ|IS)" + шРазделитель + "+NULL|В|IN"
	+ "|В" + шРазделитель + "+ИЕРАРХИИ|IN" + шРазделитель + "+HIERARCHY)" + шРазделитель + ")+";
ШаблонВыбора = "(?:ВЫБОР|CASE).+?(?:КОГДА|WHEN).+?(?:ТОГДА|THEN).+?(?:ИНАЧЕ|ELSE).+?(?:КОНЕЦ|END)";
ШаблонНачалаВыбора = "(?:ВЫБОР|CASE).+?(?:КОНЕЦ|END)?";
шИмяЗапроса = "(?:" + шИмя + "|\[[^\]]+\])";
ШаблонТаблицы = "(" + шИмяЗапроса + "\.)*" + шИмяЗапроса + шСкобки + "?";
ШаблонСоединения = шРазделитель + "+((ПРАВОЕ|RIGHT|ЛЕВОЕ|LEFT|ВНУТРЕННЕЕ|INNER|ПОЛНОЕ|FULL|ВНЕШНЕЕ|OUTER)" + шРазделитель + "+)?(?:СОЕДИНЕНИЕ|JOIN)" 
	+ шРазделитель + "+";
	
ШаблонОписанияТаблицы = "(" + шСкобки + "|" + ШаблонТаблицы + "|&" + шИмя + ")" + шРазделитель
	+ "+(?:КАК|AS)" + шРазделитель + "+" + шИмяЗапроса;
	
шВыражениеЗапроса = "(?:" + шРазделитель + "*(?:" + шСкобки + "|(?:&|\?|@)" + шИмя + "|" + шЧисло + "|" + шСтрокаЗапроса + "|" + ШаблонВыбора
	+ "|" + шИмя + шСкобки + "?" + "(?:\." + шИмя + шСкобки + "?" + ")*)" + шРазделитель + "*" + шОператорЗапроса + ")*"
	+ шРазделитель + "*" + "(?:" + шСкобки + "|(?:&|\?|@)" + шИмя + "|" + шЧисло + "|" + шСтрокаЗапроса + "|" + ШаблонВыбора
	+ "|" + шИмя + шСкобки + "?" + "(?:\." + шИмя + шСкобки + "?" + ")*)";
	
шНачалоВыраженияЗапроса = "(?:" + шРазделитель + "*(?:" + шСкобки + "|(?:&|\?|@)" + шИмя + "|" + шЧисло + "|" + шСтрокаЗапроса + "|" + ШаблонВыбора
	+ "|" + шИмяЗапроса + шСкобки + "?" + "(?:\." + шИмяЗапроса + шСкобки + "?" + ")*)" + шРазделитель + "*" + шОператорЗапроса + ")*"
	+ шРазделитель + "*" + "(?:" + шСкобки + "|(?:&|\?|@)" + шИмя + "|" + шЧисло + "|" + шНачалоСтрокиЗапроса + "|" + ШаблонНачалаВыбора
	+ "|" + шИмяЗапроса + шСкобки + "?" + "(?:\." + шИмяЗапроса + шСкобки + "?" + ")*)?";
	
шВызовМетодаЗапроса = "(" + шИмяЗапроса + шСкобки + "?" + "(?:(?:\.(?:" + шИмяЗапроса + ")" + шСкобки + "?)|" + шИндекс + ")*)"
	+ "\(((?:(?:" + шВыражениеЗапроса + ")?" + шРазделитель + "*,)*)" + "(?:" + шНачалоВыраженияЗапроса + ")?" + шРазделитель + "*";
	
ШаблонОписанияПоля = шВыражениеЗапроса + шРазделитель + "+КАК" + шРазделитель + "+" + шИмяЗапроса;
ШаблонВЫБРАТЬ = "(?:ВЫБРАТЬ|SELECT)(" + шРазделитель + "+(?:РАЗРЕШЕННЫЕ|ALLOWED))?(" + ШаблонОписанияПоля + ",)*" + ШаблонОписанияПоля;
шИЗ = "(?:ИЗ|FROM)" + шРазделитель + "+" + ШаблонОписанияТаблицы + "(" + ШаблонСоединения + ШаблонОписанияТаблицы 
	+ шРазделитель + "+(?:ПО|ON)" + шРазделитель + "+" + шВыражениеЗапроса + "|" + шРазделитель + "*," 
	+ шРазделитель + "*" + ШаблонОписанияТаблицы + ")*";
шПоискОписанияТаблицы = "(" + ШаблонСоединения + ")?(" + шСкобки + "|" + ШаблонТаблицы + "|&" + шИмя 
	+ ")" + шРазделитель + "+(?:КАК|AS)" + шРазделитель + "+" + "#Идентификатор#(" + шРазделитель 
	+ "+(?:ПО|ON)" + шРазделитель + "+" + шВыражениеЗапроса + "|" + шРазделитель + "|,|\)|$)";
	
// К нему привязаны имена методов-трансляторов событий
ИмяКласса = "ПолеТекстовогоДокументаСКонтекстнойПодсказкой";
мМаркерСлужебногоКомментария = "{: ";
#КонецЕсли

