RDT1C/DataProcessors/ирКлсПолеТекстаПрограммы/Ext/ObjectModule.bsl
Администратор 948dc29a02 .
2021-04-25 20:46:45 +03:00

5394 lines
381 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//ирПортативный Перем ирПортативный Экспорт;
//ирПортативный Перем ирОбщий Экспорт;
//ирПортативный Перем ирСервер Экспорт;
//ирПортативный Перем ирКэш Экспорт;
//ирПортативный Перем ирПривилегированный Экспорт;
////////////////////////////////////////////////////////////////////////////////
// КОНТЕКСНАЯ ПОДСКАЗКА ПОЛЯ ТЕКСТОВОГО ДОКУМЕНТА
#Если Клиент Тогда
Перем ИмяКласса Экспорт;
Перем СсылочнаяФормаКласса Экспорт;
Перем ДопКнопкиКомандныхПанелей Экспорт;
Перем СоответствиеЭУ Экспорт;
Перем мФормаАвтодополнение Экспорт;
Перем мФормаВызовМетода Экспорт;
Перем RegExp;
Перем СлужебноеПолеТекстовогоДокумента Экспорт;
Перем Парсер;
Перем ШиринаТабуляции;
Перем мПлатформа Экспорт;
Перем ТаблицаЛокальногоКонтекста;
Перем мНачальнаяСтрока Экспорт; // снаружи только для чтения
Перем мНачальнаяКолонка Экспорт; // снаружи только для чтения
Перем мКонечнаяСтрока Экспорт; // снаружи только для чтения
Перем мКонечнаяКолонка Экспорт; // снаружи только для чтения
Перем ТекущееНачалоСтроки;
Перем ОригинальнаяСтрока;
Перем ТекущийКонецСтроки;
Перем НачалоКонтекста;
Перем НачалоСлова;
Перем КонецКонтекста;
Перем ОригинальныйТекст;
Перем ТекстБезКомментариевИОпасныхСтрок;
Перем мТекстДляПоискаОпределения Экспорт;
Перем мРодительскийКонтекст;
Перем мКонтекст;
Перем мВызовМетода Экспорт;
Перем мЭтоСтроковыйЛитерал;
Перем мТекущееСлово;
Перем мПредшествующийТекст Экспорт;
Перем мНомерПараметра Экспорт;
Перем мИмяМетода Экспорт;
Перем мЭтоКонструктор Экспорт;
Перем мФактическиеПараметры Экспорт;
Перем мПервыйПараметр;
Перем мРазбиратьКонтекст;
Перем МассивЗащитыОтРекурсии;
Перем мСообщенияЧерезПредупреждения Экспорт;
Перем мАвтоКонтекстнаяПомощь Экспорт;
Перем мРасширенноеПолучениеМетаданныхADO Экспорт;
Перем ПравилаВычисленияФункций;
Перем мПоследнийРежимВызоваСправки;
Перем мИменаОбщихТиповПоИменамКлассовCOM;
Перем мПарсер;
Перем мДиалектSQL Экспорт;
Перем мДиалектыSQL Экспорт;
Перем мПараметрыДиалектаSQL Экспорт;
Перем мПрефиксыПараметров Экспорт;
Перем мМаркерСлужебногоКомментария Экспорт;
Перем мОткрытьСправкуПоПараметру;
Перем мМодульМетаданных Экспорт;
Перем МассивКомКлассов;
Перем шЧисло;
Перем шБуква;
Перем шСтрокаПрограммы Экспорт;
Перем шНачалоСтрокиПрограммы;
Перем шСтрокаЗапроса;
Перем шИндекс;
Перем шСкобки;
Перем шНачалоСкобок;
Перем шИмя;
Перем шИмяСкобки;
Перем шПараметрЗапроса;
Перем шПредИмя;
Перем шИЗ;
Перем шРазделитель;
Перем шВыражениеПрограммы;
Перем шВыражениеЗапроса;
Перем шВызовМетодаПрограммы;
Перем шВызовМетодаЗапроса;
Перем шПока;
Перем шЕсли;
Перем шВызватьИсключение;
Перем шНачалоТокена;
Перем шКонецТокена;
Перем шКомментарий;
Перем шПрисваивание;
Перем шПоискОписанияТаблицы;
// Инициализирует экземпляр класса.
//
// Параметры:
// *СтруктураЭкземляров - Структура, *Неопределено - содержит все объекты данного класса для данной формы;
// пФорма - Форма - владелец элементов управления;
// пПолеТекстовогоДокумента ПолеТекстовогоДокумента;
// *пКоманднаяПанель КоманднаяПанель, *Неопределено в конце которой будут размещены кнопки;
// *пЛиЯзыкЗапросов - Булево, *Ложь - режим языка запросов, иначе внутренний язык;
// *пМетодВыполнения - Строка, *"" - имя метода выполнения программного кода;
// *пКонтекстВыполнения - Тип, Запрос, Произвольный, *Неопределено - контекст выполнения программного кода или текста запроса;
// *пТипТекста - Строка, *"Алгоритм" - "Алгоритм" или "Выражение".
//
Процедура ИнициализироватьНеинтерактивно(пЯзыкПрограммы = 0, пМетодВыполнения = "", пКонтекстВыполнения = Неопределено, пТипТекста = "Алгоритм",
пКонфигурация = Неопределено, пПолеТекстовогоДокумента= Неопределено) Экспорт
ЭтотОбъект.ЯзыкПрограммы = пЯзыкПрограммы;
ЭтотОбъект.МетодВыполнения = пМетодВыполнения;
ЭтотОбъект.ТипТекста = пТипТекста;
ЭтотОбъект.ПолеТекстовогоДокумента = пПолеТекстовогоДокумента;
УстановитьКонфигурациюМетаданных(пКонфигурация, пКонтекстВыполнения);
ОчиститьТаблицуСловЛокальногоКонтекста();
мПрефиксыПараметров = мДиалектыSQL.Скопировать(, "ПрефиксПараметра");
мПрефиксыПараметров.Свернуть("ПрефиксПараметра");
мПрефиксыПараметров.ВыгрузитьКолонку(0);
Если ЯзыкПрограммы = 1 Тогда
Если КонтекстВыполнения = Неопределено Тогда
КонтекстВыполнения = Новый ПостроительЗапроса;
КонецЕсли;
шПредИмя = "(?:[^&#?" + шБуква + "\d\.]|^)";
Иначе
шПредИмя = "(?:[^" + шБуква + "\d\.]|^)";
КонецЕсли;
Если МетодВыполнения = "" Тогда
ЭтотОбъект.МетодВыполнения = "ВыполнитьЛокально";
КонецЕсли;
Попытка
ПроверитьПрограммныйКод(, "");
Исключение
ирОбщий.СообщитьСУчетомМодальностиЛкс(ОписаниеОшибки());
ирОбщий.СообщитьСУчетомМодальностиЛкс("Задан неверный контекст выполнения программы. Будет использован общий контекст выполнения",
мСообщенияЧерезПредупреждения);
ЭтотОбъект.КонтекстВыполнения = ЭтотОбъект;
ЭтотОбъект.МетодВыполнения = "ВыполнитьПрограмму";
КонецПопытки;
КонецПроцедуры
// Инициализирует экземпляр класса.
//
// Параметры:
// *СтруктураЭкземляров - Структура, *Неопределено - содержит все объекты данного класса для данной формы;
// пФорма - Форма - владелец элементов управления;
// пПолеТекстовогоДокумента ПолеТекстовогоДокумента;
// *пКоманднаяПанель КоманднаяПанель, *Неопределено в конце которой будут размещены кнопки;
// *пЛиЯзыкЗапросов - Булево, *Ложь - режим языка запросов, иначе внутренний язык;
// *пМетодВыполнения - Строка, *"" - имя метода выполнения программного кода;
// *пКонтекстВыполнения - Тип, Запрос, Произвольный, *Неопределено - контекст выполнения программного кода или текста запроса;
// *пТипТекста - Строка, *"Алгоритм" - "Алгоритм" или "Выражение".
//
Процедура Инициализировать(СтруктураЭкземляров = Неопределено, пФорма, пПолеТекстовогоДокумента, пКоманднаяПанель = Неопределено,
пЯзыкПрограммы = 0, пМетодВыполнения = "", пКонтекстВыполнения = Неопределено, пТипТекста = "Алгоритм", пКонфигурация = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
мПлатформа.ПодключитьПерехватКлавиатуры();
СсылочнаяФормаКласса = Ложь;
КоманднаяПанель = пКоманднаяПанель;
УстановитьФормуВладельца(пФорма);
ИнициализироватьНеинтерактивно(пЯзыкПрограммы, пМетодВыполнения, пКонтекстВыполнения, пТипТекста, пКонфигурация, пПолеТекстовогоДокумента);
Имя = ПолеТекстовогоДокумента.Имя;
Если КоманднаяПанель = Неопределено Тогда
КоманднаяПанель = ФормаВладелец.ЭлементыФормы.Добавить(Тип("КоманднаяПанель"), "КоманднаяПанель" + Имя, Ложь);
ПолеТекстовогоДокумента.КонтекстноеМеню = КоманднаяПанель;
КонецЕсли;
ФормаКласса = мПлатформа.ПолучитьМакетКомпоненты(ЭтотОбъект);
КнопкиМакета = ФормаКласса.ЭлементыФормы["КоманднаяПанель" + Формат(ЯзыкПрограммы, "ЧН=")].Кнопки;
ирОбщий.ДобавитьКнопкиКоманднойПанелиКомпонентыЛкс(ЭтотОбъект, КнопкиМакета, КоманднаяПанель);
КнопкиМакета = ФормаКласса.ЭлементыФормы.КоманднаяПанельОбщая.Кнопки;
ирОбщий.ДобавитьКнопкиКоманднойПанелиКомпонентыЛкс(ЭтотОбъект, КнопкиМакета, КоманднаяПанель);
Попытка
ФормаВладелец.ПодключитьОбработчикОжидания("КлсПолеТекстаПрограммыАвтоОбновитьСправку", 100);;
ФормаВладелец.ОтключитьОбработчикОжидания("КлсПолеТекстаПрограммыАвтоОбновитьСправку");
Исключение
//КоманднаяПанель.Кнопки.Удалить(ирОбщий.КнопкаКоманднойПанелиЭкземпляраКомпонентыЛкс(ЭтотОбъект, "АвтоКонтекстнаяПомощь"));
Кнопка = ирОбщий.КнопкаКоманднойПанелиЭкземпляраКомпонентыЛкс(ЭтотОбъект, "АвтоКонтекстнаяПомощь");
Кнопка.Доступность = Ложь;
КонецПопытки;
//ФайлШаблоновТекста = ирОбщий.ВосстановитьЗначениеЛкс(ИмяКласса + ".ФайлШаблоновТекста");
//Если Ложь
// Или ТипЗнч(ФайлШаблоновТекста) <> Тип("Строка")
// Или ФайлШаблоновТекста = ""
//Тогда
// КнопкаВыполнитьШаблон = ирОбщий.КнопкаКоманднойПанелиЭкземпляраКомпонентыЛкс(ЭтотОбъект, "ВыполнитьШаблон");
// КнопкаВыполнитьШаблон.Доступность = Ложь;
// КнопкаВыполнитьШаблон.СочетаниеКлавиш = Новый СочетаниеКлавиш(Клавиша.Нет); // Чтобы освободить сочетание клавиш
//КонецЕсли;
Если СтруктураЭкземляров <> Неопределено Тогда
СтруктураЭкземляров.Вставить(Имя, ЭтотОбъект);
КонецЕсли;
КонецПроцедуры
Процедура ИнициализироватьСсылочно(пФорма, мСвойстваФормы, пПолеТекстовогоДокумента, пКоманднаяПанель = Неопределено,
пЯзыкПрограммы = 0, пМетодВыполнения = "", пКонтекстВыполнения = Неопределено, пТипТекста = "Алгоритм",
пКонфигурация = Неопределено) Экспорт
ИнициализироватьНеинтерактивно(пЯзыкПрограммы, пМетодВыполнения, пКонтекстВыполнения, пТипТекста);
СсылочнаяФормаКласса = Истина;
ПолеТекстовогоДокумента = пПолеТекстовогоДокумента;
КоманднаяПанель = пКоманднаяПанель;
Имя = ПолеТекстовогоДокумента.Имя;
УстановитьФормуВладельца(пФорма);
Если КоманднаяПанель = Неопределено Тогда
КоманднаяПанель = ФормаВладелец.ЭлементыФормы.Добавить(Тип("КоманднаяПанель"), "КоманднаяПанель" + Имя, Ложь);
ПолеТекстовогоДокумента.КонтекстноеМеню = КоманднаяПанель;
КонецЕсли;
мСвойстваФормы.Компоненты.Добавить(ЭтотОбъект);
ФормаКласса = Вычислить("глПолучитьФормуКомпоненты(ЭтотОбъект)");
СоответствиеЭУ = Новый Соответствие;
СоответствиеЭУ.Вставить(ПолеТекстовогоДокумента, ФормаКласса.ЭлементыФормы.ПолеТекстовогоДокумента);
СоответствиеЭУ.Вставить(КоманднаяПанель, ФормаКласса.ЭлементыФормы.КП_Компонента);
КонецПроцедуры // Инициализировать()
Процедура УстановитьФормуВладельца(пФорма) Экспорт
ФормаВладелец = пФорма;
КонецПроцедуры // УстановитьВладельца()
// Освобождает ресурсы занятые экземпляром класса.
// Самое главное - очистить ссылки на формы и объекты БД.
//
// Параметры:
// Нет.
//
Процедура Уничтожить() Экспорт
Для Каждого Реквизит Из Метаданные().Реквизиты Цикл
ЭтотОбъект[Реквизит.Имя] = Неопределено;
КонецЦикла;
Если мФормаВызовМетода <> Неопределено Тогда
ЭтотОбъект.мФормаВызовМетода.ВладелецФормы = Неопределено;
КонецЕсли;
ЭтотОбъект.мФормаВызовМетода = Неопределено;
Если ЭтотОбъект.мФормаАвтодополнение <> Неопределено Тогда
ЭтотОбъект.мФормаАвтодополнение.ВладелецФормы = Неопределено;
КонецЕсли;
ЭтотОбъект.мФормаАвтодополнение = Неопределено;
ОчиститьТаблицуСловЛокальногоКонтекста();
СохранитьСтатистикуВыбораПодсказки();
КонецПроцедуры
Процедура СохранитьСтатистикуВыбораПодсказки() Экспорт
ирОбщий.СохранитьЗначениеЛкс("ирПлатформа.ТаблицаСтатистикиВыбора", мПлатформа.ТаблицаСтатистикиВыбора);
КонецПроцедуры
Процедура ВнешнееСобытиеОбъекта(Источник, Событие, Данные) Экспорт
Если Источник <> "KeyboardHook" Тогда
Возврат;
КонецЕсли;
Если ФормаВладелец = Неопределено Или Не ФормаВладелец.ВводДоступен() Тогда
Возврат;
КонецЕсли;
ирОбщий.Форма_ВнешнееСобытиеЛкс(ФормаВладелец, Источник, Событие, Данные);
//Формат строки данные:
//Первые 5 символов десятичное число в котором закодированы двоичные данные
//биты 0-7 - виртуальный код клавиши (http://msdn.microsoft.com/en-us/library/dd375731%28v=VS.85%29.aspx)
//бит 08 - 1 = нажата расширенная клавиша
//бит 09 - 1 = Правый alt
//бит 10 - 1 = Левый alt
//бит 11 - 1 = Правый ctrl
//бит 12 - 1 = Левый ctrl
//бит 13 - 1 = Правый shift
//бит 14 - 1 = Левый shift
//
//6 символ и возможно следующие символы могут быть или не быть (максимальное количество 10)
//Это результат интерпретации клавиши с учетом языковой раскладки. (http://msdn.microsoft.com/en-us/library/ms646320%28v=VS.85%29.aspx)
//
ПолученноеЧисло = Лев(Данные,5);
ПолученноеЧисло = Число(ПолученноеЧисло);
ВиртуальнаяКлавиша = ПолученноеЧисло % 256;
ПолученноеЧисло = ПолученноеЧисло - ВиртуальнаяКлавиша;
РасширеннаяКлавиша = ПолученноеЧисло % 512;
ПолученноеЧисло = ПолученноеЧисло - РасширеннаяКлавиша;
ПравыйАльт = ПолученноеЧисло % 1024;
ПолученноеЧисло = ПолученноеЧисло - ПравыйАльт;
ЛевыйАльт = ПолученноеЧисло % 2048;
ПолученноеЧисло = ПолученноеЧисло - ЛевыйАльт;
ПравыйСонтрол = ПолученноеЧисло % 4096;
ПолученноеЧисло = ПолученноеЧисло - ПравыйСонтрол;
ЛевыйСонтрол = ПолученноеЧисло % 8192;
ПолученноеЧисло = ПолученноеЧисло - ЛевыйСонтрол;
ПравыйШифт = ПолученноеЧисло % 16384;
ПолученноеЧисло = ПолученноеЧисло - ПравыйШифт;
ЛевыйШифт = ПолученноеЧисло;
Если СтрДлина(Данные) > 5 Тогда
Символ = Сред(Данные,6);
Иначе
Символ = "";
КонецЕсли;
Если ФормаВладелец.ТекущийЭлемент = ПолеТекстовогоДокумента Тогда
Форма = ФормаВызовМетода();
БылаОткрыта = Форма.Открыта();
Если Истина
И Не БылаОткрыта
И (Ложь
Или Символ = "("
Или Символ = ",")
Тогда
АвтоматическаяПодсказкаПоВызовуМетода = ирОбщий.ВосстановитьЗначениеЛкс(ИмяКласса + ".АвтоматическаяПодсказкаПоВызовуМетода");
Если АвтоматическаяПодсказкаПоВызовуМетода = Истина Тогда
ВыполнитьКоманду("ПодсказатьПараметрАвто");
КонецЕсли;
КонецЕсли;
Если БылаОткрыта Тогда
Форма.ПараметрСтруктураТипаКонтекста = Неопределено;
//Если Форма.Открыта() Тогда
Форма.ОбновитьИлиЗакрытьФорму(, Истина);
//КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Функция ФормаВызовМетода()
Если мФормаВызовМетода = Неопределено Тогда
мФормаВызовМетода = ПолучитьФорму("ВызовМетода", ФормаВладелец);
КонецЕсли;
Возврат мФормаВызовМетода;
КонецФункции
// Получает номер текущей строки в тексте (по конечной границе выделения).
//
// Параметры:
// Нет.
//
// Возвращаемое значение:
// Число.
//
Функция ПолучитьНомерТекущейСтроки() Экспорт
Если ПолеТекстовогоДокумента <> Неопределено Тогда
ПолеТекстовогоДокумента.ПолучитьГраницыВыделения(мНачальнаяСтрока, мНачальнаяКолонка, мКонечнаяСтрока, мКонечнаяКолонка);
Возврат мКонечнаяСтрока;
Иначе
Возврат Неопределено;
КонецЕсли;
КонецФункции // ПолучитьНомерТекущейСтроки()
// Получает текущее объектное выражение (на котором установлен курсор).
//
// Параметры:
// Нет.
//
// Возвращаемое значение:
// Строка - объектное выражение, в котором находится курсов.
//
Функция ПолучитьТекущееОбъектноеВыражение(выхЕстьТочкаСправа = Ложь) Экспорт
Если ирОбщий.ПроверитьПлатформаНеWindowsЛкс() Тогда
Возврат Неопределено;
КонецЕсли;
мПлатформа.ИнициализацияОписанияМетодовИСвойств();
ПолеТекстовогоДокумента.ПолучитьГраницыВыделения(мНачальнаяСтрока, мНачальнаяКолонка, мКонечнаяСтрока, мКонечнаяКолонка);
КончитьОбработкуКоманды();
РазобратьТекущийКонтекст(, выхЕстьТочкаСправа);
КончитьОбработкуКоманды();
Возврат мКонтекст;
КонецФункции // ПолучитьТекущееОбъектноеВыражение()
// Получает текущее контекст параметра.
//
// Параметры:
// Нет.
//
// Возвращаемое значение:
// Структура -
// "ОбъектноеВыражение"
// "НомерПараметра"
//
Функция ПолучитьТекущийКонтекстПараметра() Экспорт
мПлатформа.ИнициализацияОписанияМетодовИСвойств();
ПолеТекстовогоДокумента.ПолучитьГраницыВыделения(мНачальнаяСтрока, мНачальнаяКолонка, мКонечнаяСтрока, мКонечнаяКолонка);
КончитьОбработкуКоманды();
РазобратьТекущийКонтекст(,, Истина);
КончитьОбработкуКоманды();
СтруктураРезультата = Новый Структура;
СтруктураРезультата.Вставить("ОбъектноеВыражение", мВызовМетода);
СтруктураРезультата.Вставить("ПервыйПараметр", мПервыйПараметр);
СтруктураРезультата.Вставить("НомерПараметра", мНомерПараметра);
Возврат СтруктураРезультата;
КонецФункции // ПолучитьТекущийКонтектПараметра()
// Разбирает контекст метода.
//
// Параметры:
// Нет.
//
Функция ТекущийКонтекстМетода()
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 = Ложь;
Если ЯзыкПрограммы = 1 Тогда
RegExp.Pattern = шВызовМетодаЗапроса + "$";
Иначе
RegExp.Pattern = шВызовМетодаПрограммы + "$";
КонецЕсли;
Результат = RegExp.Execute(ТекстДоКурсора + Лев(КонецВыражения, СтрДлина(КонецВыражения) - 1) + ",");
//Результат = RegExp.Execute(Лев(ОригинальныйТекст, СтрДлина(ТекстДоКурсора)+ СтрДлина(КонецВыражения) - 1) + ","); // Отрезаем последний символ зачем то
мФактическиеПараметры = Новый Массив;
Если Результат.Count > 0 Тогда
//ПоследнееВхождение = Результат.Item(Результат.Count - 1);
ПоследнееВхождение = Результат.Item(0);
//ДлинаТекста = СтрДлина(ОригинальныйТекст);
//Попытка
// СлужебноеПолеТекстовогоДокумента.УстановитьГраницыВыделения(ПоследнееВхождение.FirstIndex + 1,
// Мин(ДлинаТекста, ПоследнееВхождение.FirstIndex + 1 + ПоследнееВхождение.Length));
//Исключение
// СлужебноеПолеТекстовогоДокумента.УстановитьГраницыВыделения(ПоследнееВхождение.FirstIndex + 1,
// Мин(ДлинаТекста, ПоследнееВхождение.FirstIndex + 1 + ПоследнееВхождение.Length - 1)); // -1 надо делать из-за бага платформы (она не дает выделить последний символ в тексте)
//КонецПопытки;
//СлужебноеПолеТекстовогоДокумента.ПолучитьГраницыВыделения(мНачальнаяСтрока, мНачальнаяКолонка, мКонечнаяСтрока, мКонечнаяКолонка);
мВызовМетода = ПоследнееВхождение.SubMatches(1) + "(";
ТекстПараметров = ПоследнееВхождение.SubMatches(5) + ПоследнееВхождение.SubMatches(14);
мЭтоКонструктор = ЗначениеЗаполнено(ПоследнееВхождение.SubMatches(0));
RegExp.Global = Истина;
Если ЯзыкПрограммы = 0 Тогда
ШаблонПараметра = "(" + шВыражениеПрограммы + ")?" ;
Иначе
ШаблонПараметра = "(" + шВыражениеЗапроса + ")?";
КонецЕсли;
RegExp.Pattern = ШаблонПараметра + шРазделитель + "*,";
Результат = RegExp.Execute(ТекстПараметров);
ЛокальнаяПозицияКурсора = СтрДлина(ТекстПараметров) + 1 - СтрДлина(КонецВыражения);
Счетчик = 0;
Для Каждого Вхождение Из Результат Цикл
Счетчик = Счетчик + 1;
ПозицияВхождения = Вхождение.FirstIndex;
Если Истина
И (ПозицияВхождения + 1) <= ЛокальнаяПозицияКурсора
И (ПозицияВхождения + Вхождение.Length + 1) >= ЛокальнаяПозицияКурсора
Тогда
мНомерПараметра = Счетчик;
КонецЕсли;
мФактическиеПараметры.Добавить(СокрЛП(Вхождение.SubMatches(0)));
КонецЦикла;
Если мФактическиеПараметры.Количество() > 0 Тогда
мПервыйПараметр = мФактическиеПараметры[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 = ШаблонУК + ";" + "((?:" + ШаблонПараметра + шРазделитель + "*" + ")*)$";
Результат = 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
И Команда = "Выполнить"
Тогда
ВыполнитьПрограммныйКод();
ИначеЕсли Команда = "КонтекстныйСинтаксПомощник" Тогда
мПоследнийРежимВызоваСправки = Команда;
ОткрытьКонтекстнуюСправку(, ФормаВладелец);
ИначеЕсли Команда = "СинтаксПомощник" Тогда
ОткрытьСправкуПоЯзыкуПрограммы();
ИначеЕсли Команда = "ПодсказатьПараметр" Тогда
мПоследнийРежимВызоваСправки = Команда;
ОткрытьСправкуПоПараметру();
ИначеЕсли Команда = "ПодсказатьПараметрАвто" Тогда
#Если ТолстыйКлиентОбычноеПриложение Тогда
Если ФормаВладелец.ТекущийЭлемент = ПолеТекстовогоДокумента Тогда
ОткрытьСправкуПоПараметру(, Ложь);
КонецЕсли;
#КонецЕсли
ИначеЕсли Команда = "Настройка" Тогда
ПолучитьФорму("ФормаНастройки", ФормаВладелец).Открыть();
ИначеЕсли Команда = "ВыполнитьШаблон" Тогда
ВыполнитьШаблонТекста();
КонецЕсли;
Если Ложь
Или Команда = "ВыделитьСлово"
Или Команда = "Форматировать"
Или Команда = "ВыполнитьШаблон"
Или Команда = "ВызватьКонтекстнуюПодсказку"
Или Команда = "ЗаменитьТабуляции"
Или Команда = "УдалитьПереносы"
Или Команда = "ПерейтиКОпределению"
Или Команда = "КонструкторЗапросов1С"
Или Команда = "КонструкторЗапросовИР"
Или Команда = "КонструкторЗапросов"
Или Команда = "РедакторСтроковогоЛитерала"
Тогда
Если Результат <> Ложь Тогда
ПолеТекстовогоДокумента.УстановитьГраницыВыделения(мНачальнаяСтрока, мНачальнаяКолонка, мКонечнаяСтрока, мКонечнаяКолонка);
Если мОткрытьСправкуПоПараметру Тогда
#Если ТолстыйКлиентОбычноеПриложение Тогда
ОткрытьСправкуПоПараметру(, Ложь);
#КонецЕсли
КонецЕсли;
КонецЕсли;
КонецЕсли;
Исключение
КончитьОбработкуКоманды();
ВызватьИсключение;
КонецПопытки;
КончитьОбработкуКоманды();
Возврат Результат;
КонецФункции
Процедура ФорматироватьТекст()
ТекстЗапроса = ПолеТекстовогоДокумента.ПолучитьТекст();
КонструкторЗапроса = ПолучитьФорму("КонструкторЗапроса");
КонструкторЗапроса.ВосстановитьНастройкиФормы();
Попытка
Если ЗагрузитьТекстВКонструктор(ТекстЗапроса, КонструкторЗапроса) Тогда
НовыйТекст = КонструкторЗапроса.СобратьПолныйТекст(, Истина);
ВыделитьВесьТекст();
УстановитьВыделенныйТекст(НовыйТекст);
КонецЕсли;
Исключение
Сообщить(КраткоеПредставлениеОшибки(ИнформацияОбОшибке()));
Возврат;
КонецПопытки;
КонецПроцедуры
Процедура УстановитьВыделенныйТекст(Знач НовыйТекст) Экспорт
ПолеТекстовогоДокумента.ВыделенныйТекст = НовыйТекст;
ПослеУстановкиВыделенногоМногострочногоТекста();
КонецПроцедуры
Процедура ДобавитьВТекстЗапросаОтборыПоСтрокеРезультата(ТекущаяСтрокаРезультата, ИменаПолей = Неопределено) Экспорт
ТекстЗапроса = ПолеТекстовогоДокумента.ПолучитьТекст();
КонструкторЗапроса = ПолучитьФорму("КонструкторЗапроса");
КонструкторЗапроса.ВосстановитьНастройкиФормы();
Если КонструкторЗапроса.ЗагрузитьТекстВКонструктор(ТекстЗапроса, КонструкторЗапроса) Тогда
КонструкторЗапроса.ЗагрузитьПоследнийЗапрос();
КонструкторЗапроса.ДобавитьОтборыПоСтрокеРезультата(ТекущаяСтрокаРезультата,, ИменаПолей);
ВыделитьВесьТекст();
ПолеТекстовогоДокумента.ВыделенныйТекст = КонструкторЗапроса.СобратьПолныйТекст(, Истина);
КонструкторЗапроса.ЗагрузитьПараметрыВОбъект();
ПослеУстановкиВыделенногоМногострочногоТекста();
КонецЕсли;
КонецПроцедуры
Процедура ВыделитьВесьТекст(ПолеТекстовогоДокумента = Неопределено) Экспорт
Если ПолеТекстовогоДокумента = Неопределено Тогда
ПолеТекстовогоДокумента = ЭтотОбъект.ПолеТекстовогоДокумента;
КонецЕсли;
КоличествоСтрок = ПолеТекстовогоДокумента.КоличествоСтрок();
ПолеТекстовогоДокумента.УстановитьГраницыВыделения(1, 1, Макс(1, КоличествоСтрок), СтрДлина(ПолеТекстовогоДокумента.ПолучитьСтроку(КоличествоСтрок) + 1));
КонецПроцедуры
Процедура ПослеУстановкиВыделенногоМногострочногоТекста()
Перем НачСтрока, НачКолонка, КонСтрока, КонКолонка;
Если ФормаВладелец = Неопределено Тогда
Возврат;
КонецЕсли;
// Антибаг платформы https://partners.v8.1c.ru/forum/t/1860281, http://www.hostedredmine.com/issues/840411
ПолеТекстовогоДокумента.ПолучитьГраницыВыделения(НачСтрока, НачКолонка, КонСтрока, КонКолонка);
ПолеТекстовогоДокумента.УстановитьГраницыВыделения(1, 1, 1, 1);
//ПолеТекстовогоДокумента.ВыделенныйТекст = "";
ПолеТекстовогоДокумента.УстановитьГраницыВыделения(НачСтрока, НачКолонка, КонСтрока, КонКолонка);
// Антибаг платформы. 8.1.10.50
Если ирКэш.НомерВерсииПлатформыЛкс() < 801012 Тогда
ПолеТекстовогоДокумента.УстановитьТекст(ПолеТекстовогоДокумента.ПолучитьТекст());
КонецЕсли;
УстановитьПризнакМодифицированностиФормы();
КонецПроцедуры
Процедура АвтоОбновитьСправку() Экспорт
Если Ложь
Или Не ФормаВладелец.ВводДоступен()
Или ФормаВладелец.ТекущийЭлемент <> ПолеТекстовогоДокумента
Тогда
Возврат;
КонецЕсли;
Если мПоследнийРежимВызоваСправки = Неопределено Тогда
Возврат;
КонецЕсли;
Кнопка = ирОбщий.КнопкаКоманднойПанелиЭкземпляраКомпонентыЛкс(ЭтотОбъект, мПоследнийРежимВызоваСправки);
Нажатие(Кнопка);
КонецПроцедуры
Функция ПолучитьВыделенныйИлиВесьТекст() Экспорт
НовыйТекстЗапроса = ПолеТекстовогоДокумента.ВыделенныйТекст;
Если ПустаяСтрока(НовыйТекстЗапроса) Тогда
НовыйТекстЗапроса = ПолеТекстовогоДокумента.ПолучитьТекст();
КонецЕсли;
Возврат НовыйТекстЗапроса;
КонецФункции // ПолучитьВыделенныйИлиВесьТекст()
// <Описание процедуры>
//
// Параметры:
// <Параметр1> <Тип.Вид> <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> <Тип.Вид> <описание параметра>
// <продолжение описания параметра>.
//
Процедура КопироватьВБуферОбменаТекстВВидеКода() Экспорт
НовыйТекстЗапроса = ПолучитьВыделенныйИлиВесьТекст();
ИменованныеЗапросы = мПлатформа.ПолучитьСтруктуруРезультатаПакетногоЗапроса(НовыйТекстЗапроса);
Если Прав(НовыйТекстЗапроса, 1) <> Символы.ПС Тогда
НовыйТекстЗапроса = НовыйТекстЗапроса + Символы.ПС;
КонецЕсли;
НовыйТекстЗапроса = ирОбщий.ПолучитьСтроковыйЛитералИзМногострочногоТекстаЛкс(НовыйТекстЗапроса);
НовыйТекстЗапроса = НовыйТекстЗапроса + ";" + Символы.ПС;
Для Каждого КлючИЗначение Из ИменованныеЗапросы Цикл
НовыйТекстЗапроса = НовыйТекстЗапроса + "Индекс_" + КлючИЗначение.Ключ + " = " + XMLСтрока(КлючИЗначение.Значение) + ";" + Символы.ПС;
КонецЦикла;
ирОбщий.ПоместитьТекстВБуферОбменаОСЛкс(НовыйТекстЗапроса, "ВстроенныйЯзык");
КонецПроцедуры
Процедура Закомментировать() Экспорт
#Если Сервер И Не Сервер Тогда
ПолеТекстовогоДокумента = Новый ТекстовыйДокумент;
#КонецЕсли
//Для Счетчик = мНачальнаяСтрока По мКонечнаяСтрока Цикл
// ПолеТекстовогоДокумента.УстановитьГраницыВыделения(Счетчик, 1, Счетчик, 1);
// ПолеТекстовогоДокумента.ВыделенныйТекст = "//";
//КонецЦикла;
//ПолеТекстовогоДокумента.УстановитьГраницыВыделения(мНачальнаяСтрока, мНачальнаяКолонка, мКонечнаяСтрока, мКонечнаяКолонка);
//
ПерваяСтрока = мНачальнаяСтрока;
ПерваяКолонка = мНачальнаяКолонка;
ПоследняяСтрока = мКонечнаяСтрока;
ПоследняяКолонка = мКонечнаяКолонка;
КоличествоСтрок = ПолеТекстовогоДокумента.КоличествоСтрок();
ВыделенныйФрагмент = "";
ДлинаПоследнейСтроки = 0;
Если ПоследняяКолонка = 1 Тогда
ПоследняяСтрока = ПоследняяСтрока - 1;
КонецЕсли;
Если ПерваяСтрока >= ПоследняяСтрока И ПоследняяКолонка = 1 Тогда
ПоследняяКолонка = Макс(1, СтрДлина(ПолеТекстовогоДокумента.ПолучитьСтроку(ПерваяСтрока)));
ПоследняяСтрока = ПерваяСтрока;
КонецЕсли;
Для НомерСтроки = 1 По КоличествоСтрок Цикл
Фрагмент = ПолеТекстовогоДокумента.ПолучитьСтроку(НомерСтроки);
Если НомерСтроки >= ПерваяСтрока И НомерСтроки <= ПоследняяСтрока Тогда
Если НомерСтроки = ПерваяСтрока Тогда
ВыделенныйФрагмент = ВыделенныйФрагмент + "//" + Фрагмент;
Иначе
ВыделенныйФрагмент = ВыделенныйФрагмент + Символы.ПС + "//" +Фрагмент;
КонецЕсли;
Если НомерСтроки = ПоследняяСтрока Тогда
ДлинаПоследнейСтроки = СтрДлина(Фрагмент) + 3;
КонецЕсли;
КонецЕсли;
КонецЦикла;
ЗаменитьФрагментТекстаВПоле(ПолеТекстовогоДокумента, ВыделенныйФрагмент, ДлинаПоследнейСтроки, ПерваяСтрока, ПоследняяСтрока, ПоследняяКолонка);
КонецПроцедуры
Процедура Раскомментировать() Экспорт
#Если Сервер И Не Сервер Тогда
ПолеТекстовогоДокумента = Новый ТекстовыйДокумент;
#КонецЕсли
//Для Счетчик = мНачальнаяСтрока По мКонечнаяСтрока Цикл
// СтрокаТекста = СтрПолучитьСтроку(ТекстДоИзменения, Счетчик);
// Если Лев(СокрЛ(СтрокаТекста), 2) = "//" Тогда
// ПозицияМаркера = Найти(СтрокаТекста, "//");
// ПолеТекстовогоДокумента.УстановитьГраницыВыделения(Счетчик, 1, Счетчик, 10000);
// ПолеТекстовогоДокумента.ВыделенныйТекст = Сред(СтрокаТекста, 1, ПозицияМаркера - 1) + Сред(СтрокаТекста, ПозицияМаркера + 2);
// КонецЕсли;
//КонецЦикла;
//ПолеТекстовогоДокумента.УстановитьГраницыВыделения(мНачальнаяСтрока, мНачальнаяКолонка, мКонечнаяСтрока, мКонечнаяКолонка);
//
ПерваяСтрока = мНачальнаяСтрока;
ПерваяКолонка = мНачальнаяКолонка;
ПоследняяСтрока = мКонечнаяСтрока;
ПоследняяКолонка = мКонечнаяКолонка;
КоличествоСтрок = ПолеТекстовогоДокумента.КоличествоСтрок();
ВыделенныйФрагмент = "";
ДлинаПоследнейСтроки = ПоследняяКолонка;
Если ПоследняяКолонка = 1 Тогда
ПоследняяСтрока = ПоследняяСтрока - 1;
КонецЕсли;
Если ПерваяСтрока >= ПоследняяСтрока И ПоследняяКолонка = 1 Тогда
ПоследняяКолонка = СтрДлина(ПолеТекстовогоДокумента.ПолучитьСтроку(ПерваяСтрока));
ПоследняяСтрока = ПерваяСтрока;
КонецЕсли;
Для НомерСтроки = 1 По КоличествоСтрок Цикл
Фрагмент = ПолеТекстовогоДокумента.ПолучитьСтроку(НомерСтроки);
Если НомерСтроки >= ПерваяСтрока И НомерСтроки <= ПоследняяСтрока Тогда
Если Лев(СокрЛ(Фрагмент), 2) = "//" Тогда
Позиция = Найти(Фрагмент, "//");
Фрагмент = Лев(Фрагмент, Позиция - 1) + Сред(Фрагмент, Позиция + 2);
КонецЕсли;
Если НомерСтроки = ПерваяСтрока Тогда
ВыделенныйФрагмент = ВыделенныйФрагмент + Фрагмент;
Иначе
ВыделенныйФрагмент = ВыделенныйФрагмент + Символы.ПС + Фрагмент;
КонецЕсли;
Если НомерСтроки = ПоследняяСтрока Тогда
ДлинаПоследнейСтроки = СтрДлина(Фрагмент) + 3;
КонецЕсли;
КонецЕсли;
КонецЦикла;
ЗаменитьФрагментТекстаВПоле(ПолеТекстовогоДокумента, ВыделенныйФрагмент, ДлинаПоследнейСтроки, ПерваяСтрока, ПоследняяСтрока, ПоследняяКолонка);
КонецПроцедуры
Процедура ЗаменитьФрагментТекстаВПоле(Знач Элемент, Знач ВыделенныйФрагмент, Знач ДлинаПоследнейСтроки, Знач ПерваяСтрока, Знач ПоследняяСтрока, Знач ПоследняяКолонка)
Если ПоследняяКолонка = 1 Тогда
ПоследняяСтрока = ПоследняяСтрока + 1;
ДлинаПоследнейСтроки = 1;
ВыделенныйФрагмент = ВыделенныйФрагмент + Символы.ПС;
КонецЕсли;
Элемент.УстановитьГраницыВыделения(ПерваяСтрока, 1, ПоследняяСтрока, ДлинаПоследнейСтроки);
ЧислоПереносовСтрокНачальное = СтрЧислоВхождений(Элемент.ВыделенныйТекст, Символы.ПС);
Если ЧислоПереносовСтрокНачальное > ПоследняяСтрока - ПерваяСтрока Тогда
// https://www.hostedredmine.com/issues/925662
Для Счетчик = 1 По Мин(2, ДлинаПоследнейСтроки - 1) Цикл
ДлинаПоследнейСтрокиБезПереноса = ДлинаПоследнейСтроки - Счетчик;
Элемент.УстановитьГраницыВыделения(ПерваяСтрока, 1, ПоследняяСтрока, ДлинаПоследнейСтрокиБезПереноса);
Если СтрЧислоВхождений(Элемент.ВыделенныйТекст, Символы.ПС) < ЧислоПереносовСтрокНачальное Тогда
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Элемент.ВыделенныйТекст = ВыделенныйФрагмент;
Элемент.УстановитьГраницыВыделения(ПерваяСтрока, 1, ПоследняяСтрока, ДлинаПоследнейСтроки);
УстановитьПризнакМодифицированностиФормы();
КонецПроцедуры
// Устанавливает фокус на поле текстового документа.
//
// Параметры:
// Нет.
//
Процедура УстановитьФокус() Экспорт
ФормаВладелец.ТекущийЭлемент = ПолеТекстовогоДокумента;
КонецПроцедуры // УстановитьФокус()
Процедура ВыделитьНачалоИКонецТекущейСтроки() Экспорт
СброситьРезультатРазбораПозицииВТексте();
//ОригинальнаяСтрока = СокрП(ПолеТекстовогоДокумента.ПолучитьСтроку(мКонечнаяСтрока));
ОригинальнаяСтрока = ПолеТекстовогоДокумента.ПолучитьСтроку(мКонечнаяСтрока);
Для Счетчик = 0 По мКонечнаяКолонка - СтрДлина(ОригинальнаяСтрока) - 2 Цикл
ОригинальнаяСтрока = ОригинальнаяСтрока + " ";
КонецЦикла;
ТекущееНачалоСтроки = Лев(ОригинальнаяСтрока, мКонечнаяКолонка - 1);
ТекущийКонецСтроки = Сред(ОригинальнаяСтрока, мКонечнаяКолонка);
КонецПроцедуры
Процедура СброситьРезультатРазбораПозицииВТексте()
мНомерПараметра = 0;
НачалоКонтекста = "";
НачалоСлова = "";
КонецКонтекста = "";
выхЕстьТочкаСправа = Ложь;
мРодительскийКонтекст = "";
мКонтекст = "";
мЭтоСтроковыйЛитерал = Ложь;
мЭтоКонструктор = Ложь;
мАргументы = "";
мПервыйПараметр = "";
мФактическиеПараметры = Новый Массив;
КонецПроцедуры
// <Описание функции>
//
// Параметры:
// <Параметр1> <Тип.Вид> <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> <Тип.Вид> <описание параметра>
// <продолжение описания параметра>.
//
// Возвращаемое значение:
// <Тип.Вид> <описание значения>
// <продолжение описания значения>;
// <Значение2> <Тип.Вид> <описание значения>
// <продолжение описания значения>.
//
Функция ПолучитьИнформациюОбОшибке(ТекстДляПроверки = Неопределено, СтартоваяСтрока = 0, СтартоваяКолонка = 0, Контекст = "", СамаяВложеннаяПричина = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ТекстИнициализации = "";
Если ЯзыкПрограммы = 0 Тогда
Для Каждого ЛокальноеСлово Из ТаблицаЛокальногоКонтекста Цикл
Если Истина
И ТипТекста = "Алгоритм"
И ЛокальноеСлово.ТипСлова = "Свойство"
Тогда
ТекстИнициализации = ЛокальноеСлово.Слово + " = 0; " + ТекстИнициализации;
КонецЕсли;
КонецЦикла;
Для Каждого СтрокаПараметра Из Параметры Цикл
Если ТипТекста = "Алгоритм"
И СтрокаПараметра.Вход // Добавил 14.09.2019
Тогда
ТекстИнициализации = СтрокаПараметра.Имя + " = 0; " + ТекстИнициализации;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если ТекстДляПроверки = Неопределено Тогда
ТекстДляПроверки = ПолеТекстовогоДокумента.ПолучитьТекст();
КонецЕсли;
СтартоваяСтрока = 0;
СтартоваяКолонка = 0;
Если ЯзыкПрограммы = 1 Тогда
ТекстЗапроса = ТекстДляПроверки;
Если ТекстЗапроса <> "" Тогда
Если ТипТекста = "Выражение" Тогда
лКонтекстВыполнения = КонтекстВыполнения;
лМетодВыполнения = МетодВыполнения;
Попытка
ИнформацияОбОшибке = мПлатформа.ВыполнитьПрограммныйКодВКонтексте(лКонтекстВыполнения, лМетодВыполнения, ТекстЗапроса, Истина);
Исключение
ИнформацияОбОшибке = ИнформацияОбОшибке();
КонецПопытки;
СтартоваяСтрока = -1;
Иначе
Если мДиалектSQL <> "1С" Тогда
РезультатРазбора = ЗагрузитьТекстВКонструктор(ТекстЗапроса);
Если Не РезультатРазбора Тогда
ИнформацияОбОшибке = 1;
КонецЕсли;
Иначе
Если ТипЗнч(КонтекстВыполнения) = Тип("Запрос") Тогда
ПроверочныйЗапрос = Новый Запрос;
ПроверочныйЗапрос.МенеджерВременныхТаблиц = КонтекстВыполнения.МенеджерВременныхТаблиц;
ПроверочныйЗапрос.Текст = ТекстЗапроса;
Попытка
ПроверочныйЗапрос.НайтиПараметры();
Исключение
ИнформацияОбОшибке = ИнформацияОбОшибке();
КонецПопытки;
Иначе
КонструкторЗапроса = Новый КонструкторЗапроса;
КонструкторЗапроса.РежимКомпоновкиДанных = РежимКомпоновкиДанных;
Попытка
КонструкторЗапроса.Текст = ТекстЗапроса;
Исключение
ИнформацияОбОшибке = ИнформацияОбОшибке();
КонецПопытки;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
ИначеЕсли ЯзыкПрограммы = 0 Тогда
ТекстДляВыполнения = ТекстИнициализации;
Если ТипТекста = "Выражение" Тогда
Если ТекстДляПроверки = "" Тогда
ТекстДляПроверки = 0;
КонецЕсли;
ТекстДляВыполнения = ТекстДляВыполнения + "?(Истина, 0, " + Символы.ПС + ТекстДляПроверки + Символы.ПС + ")";
Иначе
//ТекстДляВыполнения = ТекстДляВыполнения + "Если Ложь Тогда " + Символы.ПС + ТекстДляПроверки + Символы.ПС + " КонецЕсли"; // Заменено 06.12.2011
ТекстДляВыполнения = "Если Ложь Тогда " + ТекстДляВыполнения + Символы.ПС + ТекстДляПроверки + Символы.ПС + " КонецЕсли";
КонецЕсли;
Если Нрег(Контекст) = Нрег("Сервер") Тогда
лКонтекстВыполнения = ирСервер;
лМетодВыполнения = "ВыполнитьАлгоритм";
Иначе
лКонтекстВыполнения = КонтекстВыполнения;
лМетодВыполнения = МетодВыполнения;
КонецЕсли;
Попытка
ИнформацияОбОшибке = мПлатформа.ВыполнитьПрограммныйКодВКонтексте(лКонтекстВыполнения, лМетодВыполнения, ТекстДляВыполнения, Истина);
Исключение
ИнформацияОбОшибке = ИнформацияОбОшибке();
КонецПопытки;
СтартоваяСтрока = - 1;
ИначеЕсли ЯзыкПрограммы = 2 Тогда
лКонтекстВыполнения = КонтекстВыполнения;
лМетодВыполнения = МетодВыполнения;
Попытка
ИнформацияОбОшибке = мПлатформа.ВыполнитьПрограммныйКодВКонтексте(лКонтекстВыполнения, лМетодВыполнения, ТекстДляПроверки, Истина);
Исключение
ИнформацияОбОшибке = ИнформацияОбОшибке();
КонецПопытки;
КонецЕсли;
Если СамаяВложеннаяПричина И ИнформацияОбОшибке <> Неопределено Тогда
#Если Сервер И Не Сервер Тогда
ИнформацияОбОшибке = ИнформацияОбОшибке();
#КонецЕсли
Пока ИнформацияОбОшибке.Причина <> Неопределено Цикл
ИнформацияОбОшибке = ИнформацияОбОшибке.Причина;
КонецЦикла;
КонецЕсли;
Возврат ИнформацияОбОшибке;
КонецФункции
// Замена операторов внешнего перехода https://partners.v8.1c.ru/forum/t/1849050/m/1849050
Функция ЗаменитьОператорыВнешнегоПерехода(Знач Текст = Неопределено, выхТипыВнешнихПереходов, выхЗаглушкаВозврата = "", выхИмяПараметраТипаВыхода = "") Экспорт
Перем ИмяМетода;
УникальнаяСтрока = "1092383289";
Если Не ЗначениеЗаполнено(выхЗаглушкаВозврата) Тогда
выхЗаглушкаВозврата = "Возврат" + УникальнаяСтрока + "=0";
КонецЕсли;
Если Не ЗначениеЗаполнено(выхИмяПараметраТипаВыхода) Тогда
выхИмяПараметраТипаВыхода = "ТипВыхода";
КонецЕсли;
Если Текст <> Неопределено Тогда
ПолеТекстовогоДокумента.УстановитьТекст(Текст);
КонецЕсли;
Если выхТипыВнешнихПереходов = Неопределено Тогда
выхТипыВнешнихПереходов = Новый Структура;
КонецЕсли;
СтартоваяСтрока = 0;
Пока Истина Цикл
ИнформацияОбОшибке = ПолучитьИнформациюОбОшибке(, СтартоваяСтрока,,, Истина);
Если ИнформацияОбОшибке = Неопределено Тогда
Прервать;
КонецЕсли;
#Если Сервер И Не Сервер Тогда
ИнформацияОбОшибке = ИнформацияОбОшибке();
#КонецЕсли
ОписаниеОшибки = ИнформацияОбОшибке.Описание;
Если Найти(ОписаниеОшибки, "Оператор Прервать") > 0 Тогда
ИмяОператора = "Прервать";
ИначеЕсли Найти(ОписаниеОшибки, "Оператор Продолжить") > 0 Тогда
ИмяОператора = "Продолжить";
ИначеЕсли Найти(ОписаниеОшибки, "Оператор Возврат") > 0 Тогда
ИмяОператора = "Возврат";
//ИначеЕсли Найти(ОписаниеОшибки, "Оператор Перейти") > 0 Тогда
// ИмяОператора = "Перейти"; // TODO
Иначе
Прервать;
КонецЕсли;
КоординатыОшибки = КоординатыОшибки(ИнформацияОбОшибке, СтартоваяСтрока);
выхТипыВнешнихПереходов.Вставить(ИмяОператора);
// Выделяем вхождение имени оператора в ПолеТекстовогоДокумента
ПолеТекстовогоДокумента.УстановитьГраницыВыделения(1, 1, КоординатыОшибки.НомерСтроки, КоординатыОшибки.НомерКолонки);
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.УстановитьТекст(СокрП(ПолеТекстовогоДокумента.ВыделенныйТекст));
КоличествоСтрок = ТекстовыйДокумент.КоличествоСтрок();
ДлинаПоследнейСтроки = СтрДлина(ТекстовыйДокумент.ПолучитьСтроку(КоличествоСтрок) + 1);
ПолеТекстовогоДокумента.УстановитьГраницыВыделения(Макс(1, КоличествоСтрок), ДлинаПоследнейСтроки - СтрДлина(ИмяОператора), Макс(1, КоличествоСтрок), ДлинаПоследнейСтроки);
ПолеТекстовогоДокумента.ВыделенныйТекст = выхИмяПараметраТипаВыхода + " = """ + ИмяОператора + """; " + выхЗаглушкаВозврата;
Если ИмяОператора = "Возврат" Тогда
ИнформацияОбОшибке = ПолучитьИнформациюОбОшибке(, СтартоваяСтрока,,, Истина);
Если ИнформацияОбОшибке <> Неопределено Тогда
#Если Сервер И Не Сервер Тогда
ИнформацияОбОшибке = ИнформацияОбОшибке();
#КонецЕсли
ОписаниеОшибки = ИнформацияОбОшибке.Описание;
КоординатыОшибкиПосле = КоординатыОшибки(ИнформацияОбОшибке, СтартоваяСтрока);
Если КоординатыОшибкиПосле.НомерСтроки = КоординатыОшибки.НомерСтроки Тогда
ПолеТекстовогоДокумента.ВыделенныйТекст = "=";
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Текст = ПолеТекстовогоДокумента.ПолучитьТекст();
Возврат Текст;
КонецФункции
Функция КоординатыОшибки(Знач ИнформацияОбОшибке, Знач СтартоваяСтрока = 0) Экспорт
КоординатыОшибки = Новый Структура("НомерСтроки, НомерКолонки");
RegExp.Pattern = "{[^\(]*\(([^\)]+)\)}";
ТекстКоординат = RegExp.Execute(ИнформацияОбОшибке.Описание).Item(0).Submatches(0);
Фрагменты = ирОбщий.СтрРазделитьЛкс(ТекстКоординат, ",", Истина);
КоординатыОшибки.НомерСтроки = Число(Фрагменты[0]) + СтартоваяСтрока;
КоординатыОшибки.НомерКолонки = Число(Фрагменты[1]);
Возврат КоординатыОшибки;
КонецФункции
Процедура ВыделитьТекущееСлово() Экспорт
ПолучитьТекущееОбъектноеВыражение();
мНачальнаяКолонка = мКонечнаяКолонка - СтрДлина(НачалоКонтекста);
Если Не ПустаяСтрока(мРодительскийКонтекст) Тогда
мНачальнаяКолонка = мНачальнаяКолонка + СтрДлина(мРодительскийКонтекст) + 1;
КонецЕсли;
мКонечнаяКолонка = мКонечнаяКолонка + СтрДлина(КонецКонтекста);
Если Прав(КонецКонтекста, 1) = "(" Тогда
мКонечнаяКолонка = мКонечнаяКолонка - 1;
КонецЕсли;
ПолеТекстовогоДокумента.УстановитьГраницыВыделения(мНачальнаяСтрока, мНачальнаяКолонка, мКонечнаяСтрока, мКонечнаяКолонка);
КонецПроцедуры
Процедура ВыделитьТекущееОбъектноеВыражение() Экспорт
ПолучитьТекущееОбъектноеВыражение();
мНачальнаяКолонка = мКонечнаяКолонка - СтрДлина(НачалоКонтекста);
мКонечнаяКолонка = мКонечнаяКолонка + СтрДлина(КонецКонтекста);
Если Прав(КонецКонтекста, 1) = "(" Тогда
мКонечнаяКолонка = мКонечнаяКолонка - 1;
КонецЕсли;
ПолеТекстовогоДокумента.УстановитьГраницыВыделения(мНачальнаяСтрока, мНачальнаяКолонка, мКонечнаяСтрока, мКонечнаяКолонка);
КонецПроцедуры
// Выполняет проверку синтаксиса программного кода или текста запроса.
//
// Параметры:
// *СообщатьОбУспешнойПроверке - Булево, *Ложь;
// *ТекстДляПроверки - Строка, *Неопределено - проверяемый текст (используется весь текст или этот).
//
// Возвращаемое значение:
// Булево результат проверки.
//
Функция ПроверитьПрограммныйКод(СообщатьОбУспешнойПроверке = Ложь, ТекстДляПроверки = Неопределено, Контекст = "") Экспорт
СтартоваяСтрока = 0;
СтартоваяКолонка = 0;
ИнформацияОбОшибке = ПолучитьИнформациюОбОшибке(ТекстДляПроверки, СтартоваяСтрока, СтартоваяКолонка, Контекст);
Если ЗначениеЗаполнено(Контекст) Тогда
ПредставлениеКонтекста = " (Проверка " + Контекст + ")";
КонецЕсли;
Если ИнформацияОбОшибке <> Неопределено Тогда
Если ТипЗнч(ИнформацияОбОшибке) = Тип("ИнформацияОбОшибке") Тогда
Если ФормаВладелец <> Неопределено Тогда
ФормаВладелец.ТекущийЭлемент = ПолеТекстовогоДокумента;
КонецЕсли;
ирОбщий.ПоказатьОшибкуВЗапросеИлиПрограммномКодеЛкс(ПолеТекстовогоДокумента, СтартоваяСтрока, СтартоваяКолонка, ЯзыкПрограммы, , ИнформацияОбОшибке, , ПредставлениеКонтекста);
Иначе
// Ошибка обработана и отображена ранее
КонецЕсли;
Иначе
Если СообщатьОбУспешнойПроверке Тогда
ирОбщий.СообщитьСУчетомМодальностиЛкс(ирОбщий.ПолучитьПредставлениеИзИдентификатораЛкс(ПолеТекстовогоДокумента.Имя)
+ ПредставлениеКонтекста + ": Синтаксических ошибок не обнаружено!");
КонецЕсли;
КонецЕсли;
Возврат ИнформацияОбОшибке = Неопределено;
КонецФункции
// Получает путь к описанию заданного контекста.
//
// Параметры:
// ПутьКСлову Строка;
// *СтрокаОписания - СтрокаТаблицыЗначений - возвращаемая строка описания;
// *ВключатьПутьКОписаниюТипаЗначения - Булево, *Неопределено - признак добавления в список выбора тип значения слова.
//
Функция НайтиПоказатьСправкуПоСлову(ПутьКСлову, СтрокаОписания = Неопределено, ВключатьПутьКОписаниюТипаЗначения = Ложь, выхФормаВыбора = Неопределено, РазрешитьАнализИмениТипа = Истина,
ВладелецФормы = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
МассивЗащитыОтРекурсии.Очистить();
ТаблицаСтруктурТиповКонтекста = ОпределитьТипЗначенияКонтекста(ПутьКСлову, " " + мТекстДляПоискаОпределения, мПредшествующийТекст, РазрешитьАнализИмениТипа, мЭтоКонструктор);
ОтносительныйПутьКОписанию = "";
СтруктураТипаКонтекста = ТаблицаСтруктурТиповКонтекста[0];
Если Истина
И ТипЗнч(СтруктураТипаКонтекста.СтрокаОписания) <> Тип("СтрокаТаблицыЗначений")
И ТипЗнч(СтруктураТипаКонтекста.Метаданные) = Тип("COMОбъект")
Тогда
Если мНомерПараметра > 0 Тогда
Возврат Неопределено;
КонецЕсли;
МетаданныеСлова = СтруктураТипаКонтекста.Метаданные;
ИмяТипа = мПлатформа.ПолноеИмяТипаCOMОбъекта(МетаданныеСлова);
Попытка
Пустышка = МетаданныеСлова.Path_;
Исключение
Пустышка = Неопределено;
КонецПопытки;
Слово = ирОбщий.ПоследнийФрагментЛкс(ПутьКСлову, ".", Ложь);
Если Прав(ПутьКСлову, 1) = "(" Тогда
Слово = СтрЗаменить(Слово, "(", "");
КонецЕсли;
Если Пустышка <> Неопределено Тогда
// WMI
ИмяКлассаWMI = МетаданныеСлова.Path_.Class;
Если ЗначениеЗаполнено(Слово) Тогда
ОписаниеСлова = ирОбщий.ПолучитьДокументациюСвойстваWMIЛкс(ИмяКлассаWMI, Слово);
Если ЗначениеЗаполнено(ОписаниеСлова) Тогда
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.УстановитьТекст(ОписаниеСлова);
ТекстовыйДокумент.Показать(ИмяКласса + "." + Слово);
КонецЕсли;
КонецЕсли;
Иначе
ЗапуститьПриложение("http://google.com/search?q=" + ирОбщий.ПервыйФрагментЛкс(ИмяТипа, " ") + "+" + Слово);
КонецЕсли;
Иначе
Если ВладелецФормы <> Неопределено И СтруктураТипаКонтекста.СтрокаОписания <> Неопределено Тогда
ТаблицаВладелец = СтруктураТипаКонтекста.СтрокаОписания.Владелец();
#Если Сервер И Не Сервер Тогда
ТаблицаВладелец = Новый ТаблицаЗначений;
#КонецЕсли
Если ТаблицаВладелец.Колонки.Найти("ЛиЭкспорт") <> Неопределено Тогда
ФормаВызовМетода = ФормаВызовМетода();
ФормаВызовМетода.ПараметрСтруктураТипаКонтекста = СтруктураТипаКонтекста;
БылаОткрыта = ФормаВызовМетода.Открыта();
#Если ТолстыйКлиентОбычноеПриложение Тогда
ОткрытьПодсказкуПоВызовуМетодаПассивно(ФормаВызовМетода);
Если Не БылаОткрыта Тогда
ирОбщий.Форма_АктивироватьОткрытьЛкс(ФормаВладелец);
КонецЕсли;
#Иначе
ФормаВызовМетода.ОткрытьМодально();
#КонецЕсли
Возврат ФормаВызовМетода;
КонецЕсли;
КонецЕсли;
Если СтруктураТипаКонтекста.ТипЯзыка = "ИмяТипа" Тогда
ВключатьПутьКОписаниюТипаЗначения = Истина;
КонецЕсли;
Слово = ирОбщий.ПоследнийФрагментЛкс(ПутьКСлову);
// Возможные роли слова без учета вычисленного контекста
ТаблицаСтруктурВозможныхТиповКонтекста = ирОбщий.НайтиВозможныеСтрокиОписанияСловаВСинтаксПомощникеЛкс(Слово, ЯзыкПрограммы);
СтруктураЦикла = Новый Соответствие;
СтруктураЦикла.Вставить("1.Предсказанные:", ТаблицаСтруктурТиповКонтекста);
СтруктураЦикла.Вставить("2.Возможные:", ТаблицаСтруктурВозможныхТиповКонтекста);
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
Если ВладелецФормы = Неопределено Тогда
ВладелецФормы = ФормаВладелец;
КонецЕсли;
мПлатформа.ВыбратьСтрокуОписанияИзМассиваСтруктурТипов(СтруктураЦикла, ВключатьПутьКОписаниюТипаЗначения, ВладелецФормы, Слово, мНомерПараметра,, выхФормаВыбора, мФактическиеПараметры.Количество());
КонецЕсли;
КонецФункции
// Открывает контекстную справку по текущему слову или его типу.
//
// Параметры:
// *ПутьКСлову - Строка, *"" - используется для получения дочерних слов относительно текущего контекста.
//
Процедура ОткрытьКонтекстнуюСправку(ПутьКСлову = "", ВладелецФормы = Неопределено) Экспорт
Если ирОбщий.ПроверитьПлатформаНеWindowsЛкс() Тогда
Возврат;
КонецЕсли;
РазобратьТекущийКонтекст = Не ЗначениеЗаполнено(ПутьКСлову);
Если РазобратьТекущийКонтекст Тогда
мРазобратьТекущийКонтекст = Истина;
КонецЕсли;
РазобратьТекущийКонтекст();
Если РазобратьТекущийКонтекст Тогда
ПутьКСлову = мТекущееСлово;
КонецЕсли;
Если мРодительскийКонтекст <> "" Тогда
ПутьКСлову = мРодительскийКонтекст + "." + ПутьКСлову;
КонецЕсли;
НайтиПоказатьСправкуПоСлову(ПутьКСлову,,,, РазобратьТекущийКонтекст, ВладелецФормы);
КонецПроцедуры
// <Описание процедуры>
//
// Параметры:
// <Параметр1> <Тип.Вид> <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> <Тип.Вид> <описание параметра>
// <продолжение описания параметра>.
//
Процедура ОткрытьСправкуПоЯзыкуПрограммы() Экспорт
Если ЯзыкПрограммы = 0 Тогда
Книга = "shcntx_ru";
ИначеЕсли ЯзыкПрограммы = 1 Тогда
Книга = "shquery_ru";
ИначеЕсли ЯзыкПрограммы = 2 Тогда
Книга = "dcsui_ru";
КонецЕсли;
ФормаСправка = ирОбщий.ПолучитьФормуЛкс("Обработка.ирСинтаксПомощник.Форма", , ФормаВладелец);
ФормаСправка.ОткрытьАдрес("//" + Книга);
КонецПроцедуры // ОткрытьСправкуПоЯзыкуПрограммы()
// Открывает контекстную справку по текущему параметру метода.
//
// Параметры:
// *ПутьКСлову - Строка, *"" - используется для получения дочерних слов относительно текущего контекста.
//
Процедура ОткрытьСправкуПоПараметру(ПутьКСлову = "", ОткрыватьСинтаксПомощник = Истина) Экспорт
Если ирОбщий.ПроверитьПлатформаНеWindowsЛкс() Тогда
Возврат;
КонецЕсли;
РазобратьТекущийКонтекст(,, Истина);
Если ПутьКСлову = "" Тогда
ПутьКСлову = мВызовМетода;
КонецЕсли;
Если ОткрыватьСинтаксПомощник Тогда
#Если ТолстыйКлиентОбычноеПриложение Тогда
#Иначе
ФормаСинтаксПомощникаДо = ирОбщий.ПолучитьФормуЛкс("Обработка.ирСинтаксПомощник.Форма");
#КонецЕсли
ФормаСинтаксПомощникаПосле = Неопределено;
НайтиПоказатьСправкуПоСлову(ПутьКСлову,,, ФормаСинтаксПомощникаПосле);
КонецЕсли;
ФормаПодсказкаПоПараметрам = ФормаВызовМетода();
ФормаПодсказкаПоПараметрам.ПараметрСтруктураТипаКонтекста = Неопределено;
Если Не ФормаПодсказкаПоПараметрам.Открыта() Тогда
ФормаПодсказкаПоПараметрам.ЗапомнитьПозициюКаретки();
КонецЕсли;
#Если ТолстыйКлиентОбычноеПриложение Тогда
Если Ложь
Или ОткрыватьСинтаксПомощник
Или Не ФормаПодсказкаПоПараметрам.Открыта()
Тогда
ОткрытьПодсказкуПоВызовуМетодаПассивно(ФормаПодсказкаПоПараметрам);
КонецЕсли;
#Иначе
Если Ложь
Или Не ОткрыватьСинтаксПомощник
Или ФормаСинтаксПомощникаДо.Открыта() = ФормаСинтаксПомощникаПосле.Открыта()
Тогда
ФормаПодсказкаПоПараметрам.ОткрытьМодально();
КонецЕсли;
#КонецЕсли
КонецПроцедуры
Процедура ОткрытьПодсказкуПоВызовуМетодаПассивно(Знач ФормаПодсказкаПоПараметрам)
ФормаПодсказкаПоПараметрам.Открыть();
ФормаПодсказкаПоПараметрам.Обновить(); // Нужно для 8.2, т.к. там форма форкус получает после завершения ПриОткрытии и только после этого сработает установка позиции окна
КонецПроцедуры
Функция УдалитьКомментарии(Текст) Экспорт
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])*""?)";
// + шОднострочнаяСтрокаПрограммыСКавычки + "|" + шОднострочнаяСтрокаПрограммыСЧерты + "|(.|\n|\r)";
RegExp.Pattern = "(""" + шИмя+ "(?:\.[А-Яа-я_A-Za-z\d]+)*"")" // имена ProgId от COM объектов бывают "Forms.TextBox.1"
+ "|(""(?:" + шИмя + "\s*,\s*)*" + шИмя + """)" // создание структуры
+ "|" + "//:([^\n]*)" + "|" + "//[^\n]*|" + "(?:" + "#[^\n]*" + ")|" + "(?:" + "~" + шИмя + ")|"; // Присвоение типа выражению в комментарии
ШаблонЗамены = "$1$2$3$4";
Если ЗалитьСтроковыеЛитералы Тогда
RegExp.Pattern = RegExp.Pattern + шОднострочнаяСтрокаПрограммыСКавычки + "|" + шОднострочнаяСтрокаПрограммыСЧерты + "";
ШаблонЗамены = ШаблонЗамены + "$5";
Иначе
// http://www.hostedredmine.com/issues/885452
КонецЕсли;
RegExp.Pattern = RegExp.Pattern + "|([\s\S])";
КонецЕсли;
ЗалитыйТекст = RegExp.Replace(Текст, ШаблонЗамены);
Если СтрДлина(ОригинальныйТекст) < 10000 Тогда // Долго на больших текстах!
// Заливаем условия, чтобы проверка равенства в них не считалась присвоением
// В будущем можно отказаться от этого блока и собирать все возможные типы, а потом давать юзеру выбирать.
Если ЯзыкПрограммы = 0 Тогда
RegExp.Pattern = "(" + шЕсли + ")|(" + шПока + ")";
ЗалитыйТекстОригинал = ЗалитыйТекст;
Результат = RegExp.Execute(ЗалитыйТекстОригинал);
ЗалитыйТекст = Новый ЗаписьXML;
ЗалитыйТекст.УстановитьСтроку("");
ТекущаяПозицияВОригинале = 1;
Для Каждого Match Из Результат Цикл
НайденныйТекст = Неопределено;
НачалоТокена = "";
КонецТокена = "";
Если Match.SubMatches(0) <> Неопределено Тогда
НайденныйТекст = Match.SubMatches(0);
НачалоТокена = Match.SubMatches(1);
КонецТокена = Match.SubMatches(3);
ИначеЕсли Match.SubMatches(4) <> Неопределено Тогда
НайденныйТекст = Match.SubMatches(4);
НачалоТокена = Match.SubMatches(5);
КонецТокена = Match.SubMatches(7);
КонецЕсли;
ЗалитыйТекст.ЗаписатьБезОбработки(Сред(ЗалитыйТекстОригинал, ТекущаяПозицияВОригинале, Match.FirstIndex + 1 - ТекущаяПозицияВОригинале));
ЗалитыйТекст.ЗаписатьБезОбработки(НачалоТокена + RegExp.Replace(Сред(НайденныйТекст, 1 + СтрДлина(НачалоТокена), СтрДлина(НайденныйТекст) - СтрДлина(НачалоТокена) - СтрДлина(КонецТокена)), СимволЗамена)
+ КонецТокена);
ТекущаяПозицияВОригинале = Match.FirstIndex + 1 + СтрДлина(Match.Value);
КонецЦикла;
ЗалитыйТекст.ЗаписатьБезОбработки(Сред(ЗалитыйТекстОригинал, ТекущаяПозицияВОригинале));
ЗалитыйТекст = ЗалитыйТекст.Закрыть();
КонецЕсли;
КонецЕсли;
Возврат ЗалитыйТекст;
КонецФункции
// Меняет 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);
КонецЕсли;
НачатьОбработкуКоманды();
КонецПроцедуры
// Разбирает текущий контекст по составляющим.
//
// Параметры:
// *ДеструктивныйАнализ - Булево, *Истина - текст для поиска определения оптимизировать.
//
Процедура РазобратьТекущийКонтекст(ЛиСправаОтРавенства = Ложь, выхЕстьТочкаСправа = Ложь, КакВызовМетода = Ложь)
Если Не мРазбиратьКонтекст Тогда
Возврат;
КонецЕсли;
мПлатформа.ИнициализацияОписанияМетодовИСвойств();
ВыделитьНачалоИКонецТекущейСтроки();
мЭтоСтроковыйЛитерал = ирОбщий.ЛиВнутриСтроковогоЛитералаЛкс(ТекущееНачалоСтроки);
Если КакВызовМетода Или мЭтоСтроковыйЛитерал Тогда
ТекущийКонтекстМетода();
КонецЕсли;
RegExp.Global = Ложь;
ШаблонПрефиксаПараметра = "(?:&|#|\?|@)?";
// Начало контекста
СтрокаШаблона = шПредИмя + "(";
Если Ложь
Или ЯзыкПрограммы = 1
Или ЯзыкПрограммы = 2
Тогда
СтрокаШаблона = СтрокаШаблона + ШаблонПрефиксаПараметра + "(?:" + шИмя + ")?";
Иначе
СтрокаШаблона = СтрокаШаблона + шИмя;
КонецЕсли;
СтрокаШаблона = СтрокаШаблона + шСкобки + "?"
//+ "((\.(" + шИмя + ")" + шСкобки + "?)|" + шИндекс + ")*\.?)";
+ "((\.(" + шИмя + ")" + шСкобки + "?)|" + шИндекс + ")*\.?)?"; // 20.08.2020
Если ЛиСправаОтРавенства Тогда
СтрокаШаблона = СтрокаШаблона + шРазделитель + "*=" + шРазделитель + "*";
КонецЕсли;
СтрокаШаблона = СтрокаШаблона + "$";
RegExp.Pattern = СтрокаШаблона;
Результат = RegExp.Execute(ТекущееНачалоСтроки);
Если Результат.Count > 0 Тогда
НачалоКонтекста = "" + Результат.Item(0).SubMatches(0);
КонецЕсли;
ВычислитьПредшествующийТекст();
// Конец контекста
RegExp.Global = Ложь;
Если Не ЛиСправаОтРавенства Тогда
RegExp.Pattern = "([" + шБуква + "\d]*\(?)(\.)?";
Результат = RegExp.Execute(ТекущийКонецСтроки);
Если Результат.Count > 0 Тогда
КонецКонтекста = Результат.Item(0).SubMatches(0);
выхЕстьТочкаСправа = Результат.Item(0).SubMatches(1) <> Неопределено;
КонецЕсли;
КонецЕсли;
Если Ложь
Или ЯзыкПрограммы = 1
Или ЯзыкПрограммы = 2
Тогда
СтрокаШаблона = ШаблонПрефиксаПараметра + "(?:" + шИмя + ")?";
Иначе
СтрокаШаблона = шИмя;
КонецЕсли;
СтрокаШаблона = "(((" + шИмяСкобки + "?" + "((\." + шИмяСкобки + "?)|" + шИндекс + ")*))\.)?(" + СтрокаШаблона + ")?$";
// Родительский контекст по позиции курсора
RegExp.Pattern = СтрокаШаблона;
Результат = RegExp.Execute(НачалоКонтекста);
Если Результат.Count > 0 Тогда
ПервоеВхождение = Результат.Item(0);
Если Не ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(ПервоеВхождение.SubMatches(1)) Тогда
мРодительскийКонтекст = ПервоеВхождение.SubMatches(1);
КонецЕсли;
Если Не ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(ПервоеВхождение.SubMatches(8)) Тогда
НачалоСлова = ПервоеВхождение.SubMatches(8);
КонецЕсли;
КонецЕсли;
мТекущееСлово = НачалоСлова + ирОбщий.ПервыйФрагментЛкс(КонецКонтекста);
мКонтекст = НачалоКонтекста + КонецКонтекста;
ТекстБезКомментариевИОпасныхСтрок = ЗалитьКомментарииИСтроковыеЛитералы(ОригинальныйТекст);
СлужебноеПолеТекстовогоДокумента.УстановитьТекст(ТекстБезКомментариевИОпасныхСтрок);
Если ЯзыкПрограммы = 0 Тогда
мТекстДляПоискаОпределения = "";
Если мКонечнаяСтрока > 1 Тогда
СлужебноеПолеТекстовогоДокумента.УстановитьГраницыВыделения(1, 1, мКонечнаяСтрока - 1, 333);
мТекстДляПоискаОпределения = СлужебноеПолеТекстовогоДокумента.ВыделенныйТекст;
КонецЕсли;
// Здесь не учтена возможность наличия комментария слева от текущей позиции
мТекстДляПоискаОпределения = мТекстДляПоискаОпределения + Лев(ТекущееНачалоСтроки, СтрДлина(ТекущееНачалоСтроки)
- СтрДлина(НачалоКонтекста));
Иначе
// мПредшествующийТекст не должен использоваться потом
мТекстДляПоискаОпределения = ТекстБезКомментариевИОпасныхСтрок;
КонецЕсли;
НачатьОбработкуКоманды();
КонецПроцедуры
Процедура ВычислитьПредшествующийТекст()
ОригинальныйТекст = ПолеТекстовогоДокумента.ПолучитьТекст();
мПредшествующийТекст = "";
// Старый вариант
//Для Счетчик = 1 По мКонечнаяСтрока - 1 Цикл
// мПредшествующийТекст = мПредшествующийТекст + ПолеТекстовогоДокумента.ПолучитьСтроку(Счетчик);
//КонецЦикла;
Если мКонечнаяСтрока > 1 Тогда
СлужебноеПолеТекстовогоДокумента.УстановитьТекст(ОригинальныйТекст);
СлужебноеПолеТекстовогоДокумента.УстановитьГраницыВыделения(1, 1, мКонечнаяСтрока - 1, 333);
мПредшествующийТекст = СлужебноеПолеТекстовогоДокумента.ВыделенныйТекст;
КонецЕсли;
мПредшествующийТекст = мПредшествующийТекст + Лев(ТекущееНачалоСтроки, СтрДлина(ТекущееНачалоСтроки) - СтрДлина(НачалоКонтекста));
КонецПроцедуры
// Выполняет программу на внутреннем языке.
//
// Параметры:
// Нет.
//
// Возвращаемое значение:
// Булево безошибочность выполнения кода.
//
Функция ВыполнитьПрограммныйКод() Экспорт
ТекстДляВыполнения = ПолеТекстовогоДокумента.ПолучитьТекст();
Попытка
мПлатформа.ВыполнитьПрограммныйКодВКонтексте(КонтекстВыполнения, МетодВыполнения, ТекстДляВыполнения);
Возврат Истина;
Исключение
// Баг платформы. Зависает приложение, если пытаемся установить выделение на невидимой странице.
ФормаВладелец.ТекущийЭлемент = ПолеТекстовогоДокумента;
ирОбщий.ПоказатьОшибкуВЗапросеИлиПрограммномКодеЛкс(ПолеТекстовогоДокумента,,,,, ИнформацияОбОшибке());
Возврат Ложь;
КонецПопытки;
КонецФункции // ВыполнитьПрограммныйКод()
Процедура УстановитьКонфигурациюМетаданных(пКонфигурация = Неопределено, пКонтекстВыполнения = Неопределено, Знач ДиалектSQL = Неопределено, РасширенноеПолучениеМетаданныхADO = Ложь) Экспорт
//Если ЯзыкПрограммы = 1 Тогда
Если ДиалектSQL = Неопределено Тогда
Если пКонфигурация <> Неопределено Тогда
ЭтотОбъект.Конфигурация = пКонфигурация;
Иначе
ЭтотОбъект.Конфигурация = мПлатформа.мМетаданные;
КонецЕсли;
Если ТипЗнч(Конфигурация) = Тип("ОбъектМетаданныхКонфигурация") Тогда
ЭтотОбъект.мДиалектSQL = "1С";
Иначе
ЭтотОбъект.мДиалектSQL = "MSSQL";
Попытка
Пустышка = Конфигурация.Provider;
Исключение
Пустышка = Неопределено;
КонецПопытки;
Если Пустышка <> Неопределено Тогда
// Это ADODB.Connection
Если Конфигурация.State = 1 Тогда
ДиалектSQL = Конфигурация.Properties("DBMS Name").Value;
Иначе
// Не меняем мДиалектSQL!
КонецЕсли;
Иначе
ДиалектSQL = "WQL";
КонецЕсли;
КонецЕсли;
Иначе
Если ирОбщий.СтрокиРавныЛкс(ДиалектSQL, "1С") Тогда
ЭтотОбъект.Конфигурация = мПлатформа.мМетаданные;
Иначе
ЭтотОбъект.Конфигурация = пКонфигурация;
КонецЕсли;
КонецЕсли;
Если мДиалектыSQL = Неопределено Тогда
ЭтотОбъект.мДиалектыSQL = ирОбщий.ТаблицаЗначенийИзТабличногоДокументаЛкс(ПолучитьМакет("Диалекты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)
КонецЕсли;
ОписаниеТаблицТЗ = ирОбщий.РезультатЗапросаADOВТаблицуЗначенийОбщийЛкс(ОписаниеТаблицRecordSet);
// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
#Если Сервер И Не Сервер Тогда
Для Каждого СтрокаТЗ Из ОписаниеТаблицТЗ Цикл
ТипТаблицы = СтрокаТЗ.TABLE_TYPE;
Если Истина
И Не ирОбщий.СтрокиРавныЛкс(ТипТаблицы, "table")
И Не ирОбщий.СтрокиРавныЛкс(ТипТаблицы, "view")
Тогда
Продолжить;
КонецЕсли;
СтрокаТаблицы = ДоступныеТаблицы.Добавить();
СтрокаТаблицы.Имя = СтрокаТЗ.TABLE_NAME;
СтрокаТаблицы.Схема = СтрокаТЗ.TABLE_SCHEMA;
СтрокаТаблицы.Тип = ТипТаблицы;
СтрокаТаблицы.Описание = СтрокаТЗ.DESCRIPTION;
ПолноеИмяДоступнойТаблицы = ПолноеИмяДоступнойТаблицы(СтрокаТаблицы.Имя, СтрокаТаблицы.Схема);
СтрокаТаблицы.ПолноеИмя = ПолноеИмяДоступнойТаблицы;
СтрокаТаблицы.НПолноеИмя = НРег(ПолноеИмяДоступнойТаблицы);
КонецЦикла;
#КонецЕсли
// Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru)
Для Каждого СтрокаТЗ Из ОписаниеТаблицТЗ Цикл   ТипТаблицы = СтрокаТЗ.TABLE_TYPE;   Если Истина   И Не ирОбщий.СтрокиРавныЛкс(ТипТаблицы, "table")   И Не ирОбщий.СтрокиРавныЛкс(ТипТаблицы, "view")   Тогда   Продолжить;   КонецЕсли;   СтрокаТаблицы = ДоступныеТаблицы.Добавить();   СтрокаТаблицы.Имя = СтрокаТЗ.TABLE_NAME;   СтрокаТаблицы.Схема = СтрокаТЗ.TABLE_SCHEMA;   СтрокаТаблицы.Тип = ТипТаблицы;   СтрокаТаблицы.Описание = СтрокаТЗ.DESCRIPTION;   ПолноеИмяДоступнойТаблицы = ПолноеИмяДоступнойТаблицы(СтрокаТаблицы.Имя, СтрокаТаблицы.Схема);   СтрокаТаблицы.ПолноеИмя = ПолноеИмяДоступнойТаблицы;   СтрокаТаблицы.НПолноеИмя = НРег(ПолноеИмяДоступнойТаблицы);   КонецЦикла;  
Возврат Неопределено;
КонецФункции
Функция ПолучитьИмяТаблицыADO(Знач ИмяИсходное)
Если Лев(ИмяИсходное, 1) <> "[" Тогда
ИмяИсходное = "[" + ИмяИсходное + "]";
КонецЕсли;
Возврат ИмяИсходное;
КонецФункции
Функция НайтиДобавитьДоступнуюВременнуюТаблицу(Знач ЛюбоеИмяТаблицы, ПородившийЗапрос = Неопределено, выхБылиДобавления = Ложь, ИсточникДанных1С = Неопределено) Экспорт
КраткоеИмяТаблицы = КраткоеИмяВременнойТаблицы(ЛюбоеИмяТаблицы);
ПолноеИмяТаблицы = ПолноеИмяДоступнойТаблицы(ЛюбоеИмяТаблицы);
ПолноеИмяТаблицы = ПолноеИмяВременнойТаблицы(ПолноеИмяТаблицы, ИсточникДанных1С);
СтрокаДоступнойТаблицы = ДоступныеТаблицы.Найти(НРег(ПолноеИмяТаблицы), "НПолноеИмя");
Если СтрокаДоступнойТаблицы = Неопределено Тогда
СтрокаДоступнойТаблицы = ДоступныеТаблицы.Добавить();
СтрокаДоступнойТаблицы.Имя = КраткоеИмяТаблицы;
СтрокаДоступнойТаблицы.ПолноеИмя = ПолноеИмяТаблицы;
СтрокаДоступнойТаблицы.Схема = ИсточникДанных1С;
ирОбщий.ОбновитьКопиюСвойстваВНижнемРегистреЛкс(СтрокаДоступнойТаблицы, "ПолноеИмя");
СтрокаДоступнойТаблицы.Тип = "ВременнаяТаблица";
СтрокаДоступнойТаблицы.ЕстьДоступ = Истина;
выхБылиДобавления = Истина;
КонецЕсли;
Если ПородившийЗапрос <> Неопределено Тогда
Для Каждого СтараяСтрока Из ДоступныеТаблицы.НайтиСтроки(Новый Структура("ПородившийЗапрос", ПородившийЗапрос)) Цикл
Если СтараяСтрока = СтрокаДоступнойТаблицы Тогда
Продолжить;
КонецЕсли;
ДоступныеТаблицы.Удалить(СтараяСтрока);
КонецЦикла;
СтрокаДоступнойТаблицы.ПородившийЗапрос = ПородившийЗапрос;
КонецЕсли;
Возврат СтрокаДоступнойТаблицы;
КонецФункции
Функция ПолноеИмяДоступнойТаблицы(Знач ИмяДоступнойТаблицы, ИмяСхемы = Неопределено) Экспорт
Если Истина
И Найти(ИмяДоступнойТаблицы, ".") = 0
И мПараметрыДиалектаSQL.Диалект <> "1С"
И мПараметрыДиалектаSQL.Диалект <> "WQL"
Тогда
ИмяДоступнойТаблицы = ПолучитьИмяТаблицыADO(ИмяДоступнойТаблицы);
Если ИмяСхемы = Неопределено И ДоступныеТаблицы.Количество() > 0 Тогда
ИмяСхемы = ДоступныеТаблицы[0].Схема;
КонецЕсли;
Если ЗначениеЗаполнено(ИмяСхемы) Тогда
ИмяДоступнойТаблицы = ИмяСхемы + "." + ИмяДоступнойТаблицы;
КонецЕсли;
КонецЕсли;
Возврат ИмяДоступнойТаблицы;
КонецФункции
Функция ПолноеИмяВременнойТаблицы(Знач КраткоеИмяТаблицы, Знач ИсточникДанных1С = Неопределено) Экспорт
Результат = КраткоеИмяТаблицы;
Если Истина
И Найти(КраткоеИмяТаблицы, ".") = 0
И мПараметрыДиалектаSQL.Диалект = "1С"
И ЗначениеЗаполнено(ИсточникДанных1С)
И ИсточникДанных1С <> "<Локальный>"
Тогда
Результат = "ВнешнийИсточникДанных." + ИсточникДанных1С + ".ВременнаяТаблица." + Результат;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция КраткоеИмяВременнойТаблицы(ЛюбоеИмяТаблицы) Экспорт
Результат = ЛюбоеИмяТаблицы;
Если Истина
И мПараметрыДиалектаSQL.Диалект = "1С"
И Найти(Результат, ".") > 0
Тогда
Результат = ирОбщий.ПоследнийФрагментЛкс(Результат);
КонецЕсли;
Возврат Результат;
КонецФункции
Процедура ОчиститьДоступныеВременныеТаблицы(ТаблицаДоступныхТаблиц = Неопределено) Экспорт
Если ТаблицаДоступныхТаблиц = Неопределено Тогда
ТаблицаДоступныхТаблиц = ДоступныеТаблицы;
КонецЕсли;
СтрокиКУдалению = ТаблицаДоступныхТаблиц.НайтиСтроки(Новый Структура("Тип", "ВременнаяТаблица"));
Для Каждого СтрокаКУдалению Из СтрокиКУдалению Цикл
ТаблицаДоступныхТаблиц.Удалить(СтрокаКУдалению);;
КонецЦикла;
КонецПроцедуры
Процедура ОчиститьДоступныеНеВременныеТаблицы() Экспорт
ДоступныеВременныеТаблицы = ДоступныеТаблицы.Выгрузить(Новый Структура("Тип", "ВременнаяТаблица"));
ДоступныеТаблицы.Очистить();
ДоступныеТаблицы.Загрузить(ДоступныеВременныеТаблицы);
КонецПроцедуры
Функция ПолучитьПрефиксПараметра() Экспорт
Возврат мПараметрыДиалектаSQL.ПрефиксПараметра;
КонецФункции
// Вызывает конструктор запросов и передает ему текст из текстового поля.
//
// Параметры:
// Нет.
//
Функция ВызватьКонструкторЗапросов(ИспользуемСобственныйКонструктор = Неопределено) Экспорт
Если ирОбщий.ПроверитьПлатформаНеWindowsЛкс() Тогда
Возврат Ложь;
КонецЕсли;
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
РежимТолькоПросмотр = Ложь
Или ПолеТекстовогоДокумента.ТолькоПросмотр
Или ФормаВладелец.ТолькоПросмотр;
Если РежимТолькоПросмотр Тогда
Ответ = Вопрос("Текст запроса не может быть изменен. Открыть конструктор без возможности сохранения измений?",
РежимДиалогаВопрос.ОКОтмена);
Если Ответ = КодВозвратаДиалога.Отмена Тогда
Возврат Ложь;
КонецЕсли;
КонецЕсли;
ПредпочитаюСобственныйКонструкторЗапроса = Ложь;
Если ИспользуемСобственныйКонструктор = Неопределено Тогда
ПредпочитаюСобственныйКонструкторЗапроса = ирОбщий.ВосстановитьЗначениеЛкс(ИмяКласса + ".ПредпочитаюСобственныйКонструкторЗапроса");
Если ПредпочитаюСобственныйКонструкторЗапроса = Неопределено Тогда
Ответ = Вопрос("Подсистема имеет собственный конструктор запроса. Приоритет его использования задается в настройках компоненты ""Контекстная подсказка"".
|Хотите установить приоритет его использования?", РежимДиалогаВопрос.ДаНет);
ПредпочитаюСобственныйКонструкторЗапроса = Ответ = КодВозвратаДиалога.Да;
КонецЕсли;
КонецЕсли;
ИспользуемСобственныйКонструктор = Ложь
Или ИспользуемСобственныйКонструктор = Истина
Или мДиалектSQL <> "1С"
Или ПредпочитаюСобственныйКонструкторЗапроса;
Если ИспользуемСобственныйКонструктор Тогда
КонструкторЗапроса = ПолучитьФорму("КонструкторЗапроса");
КонструкторЗапроса.Конфигурация = Конфигурация;
Иначе
КонструкторЗапроса = Новый КонструкторЗапроса;
КонецЕсли;
//ОбрамитьСобранныйТекстСкобками = Ложь;
Если ЯзыкПрограммы = 1 Тогда
Если СтрДлина(СокрЛП(ПолеТекстовогоДокумента.ВыделенныйТекст)) < 6 И Не ЭтоЧастичныйЗапрос Тогда
ТекстЗапроса = ПолеТекстовогоДокумента.ПолучитьТекст();
НачальнаяСтрокаЗапроса = 0;
НачальнаяКолонкаЗапроса = 0;
Иначе
ТекстЗапроса = ПолеТекстовогоДокумента.ВыделенныйТекст;
//Если Не ЗначениеЗаполнено(ТекстЗапроса) И ЭтоЧастичныйЗапрос Тогда
// ТекстЗапроса = "ВЫБРАТЬ 1";
// ОбрамитьСобранныйТекстСкобками = Истина;
//КонецЕсли;
НачальнаяСтрокаЗапроса = мНачальнаяСтрока - 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 Тогда
Если Не ЭтоЧастичныйЗапрос И НачальнаяСтрокаЗапроса = 0 Тогда
ВыделитьВесьТекст();
КонецЕсли;
//Если ОбрамитьСобранныйТекстСкобками Тогда
// НовыйТекстЗапроса = "(" + НовыйТекстЗапроса + ")";
//КонецЕсли;
Если ИспользуемСобственныйКонструктор Тогда
ПолучитьНомерТекущейСтроки();
ПолеТекстовогоДокумента.ВыделенныйТекст = НовыйТекстЗапроса;
мНачальнаяСтрока = мНачальнаяСтрока + КонструкторЗапроса.мНомерТекущейСтрокиВСобранномТексте;
мНачальнаяКолонка = 1;
мКонечнаяСтрока = мНачальнаяСтрока;
мКонечнаяКолонка = мНачальнаяКолонка;
Иначе
ПолеТекстовогоДокумента.ВыделенныйТекст = НовыйТекстЗапроса;
КонецЕсли;
ПослеУстановкиВыделенногоМногострочногоТекста();
Иначе
НовыйТекстЗапроса = ирОбщий.ПолучитьСтроковыйЛитералИзМногострочногоТекстаЛкс(НовыйТекстЗапроса);
ЧислоСтрокЗамены = СтрЧислоСтрок(НовыйТекстЗапроса);
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.УстановитьТекст(НовыйТекстЗапроса);
СдвинутыйТекст = ТекстовыйДокумент.ПолучитьСтроку(1);
ЗаменаТабуляции = ирОбщий.СтрокаПовторомЛкс(" ", ШиринаТабуляции);
ТекстНачальнойСтроки = ПолеТекстовогоДокумента.ПолучитьСтроку(мНачальнаяСтрока);
ДлинаНачалаСтроки = СтрДлина(ТекстНачальнойСтроки) - СтрДлина(СокрЛ(ТекстНачальнойСтроки));
НачалоСтроки = Лев(ТекстНачальнойСтроки, ДлинаНачалаСтроки);
ДлинаРазвернутогоНачалаСтроки = СтрДлина(СтрЗаменить(НачалоСтроки, Символы.Таб, ЗаменаТабуляции));
ЧислоТабуляций = ДлинаРазвернутогоНачалаСтроки / ШиринаТабуляции;
ЧислоПробелов = ДлинаРазвернутогоНачалаСтроки % ШиринаТабуляции;
НачалоНовойСтроки = ирОбщий.СтрокаПовторомЛкс(Символы.Таб, ЧислоТабуляций);
НачалоНовойСтроки = НачалоНовойСтроки + ирОбщий.СтрокаПовторомЛкс(" ", ЧислоПробелов);
Для Счетчик = 2 По ЧислоСтрокЗамены Цикл
ТекущаяСтрокаВставки = ТекстовыйДокумент.ПолучитьСтроку(Счетчик);
СдвинутыйТекст = СдвинутыйТекст + Символы.ПС + НачалоНовойСтроки + ТекущаяСтрокаВставки;
КонецЦикла;
ПолеТекстовогоДокумента.ВыделенныйТекст = СдвинутыйТекст;
ПослеУстановкиВыделенногоМногострочногоТекста();
КонецЕсли;
Возврат Истина;
КонецЕсли;
КонецЕсли;
Возврат Ложь;
КонецФункции // ВызватьКонструкторЗапросов()
Процедура ПоказатьТекущиеКоординаты(ПолеТекстовогоДокумента, СтартоваяСтрокаДляОтображенияОшибок = 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;
Возврат Результат;
КонецФункции
// Вызывает конструктор запросов и передает ему текст из текстового поля.
//
// Параметры:
// Нет.
//
Функция ВызватьРедакторСтроковогоЛитерала()
Если ирОбщий.ПроверитьПлатформаНеWindowsЛкс() Тогда
Возврат Ложь;
КонецЕсли;
РежимТолькоПросмотр = Ложь
Или ПолеТекстовогоДокумента.ТолькоПросмотр
Или ФормаВладелец.ТолькоПросмотр;
Если РежимТолькоПросмотр Тогда
Ответ = Вопрос("Текст не может быть изменен. Открыть редактор без возможности сохранения измений?",
РежимДиалогаВопрос.ОКОтмена);
Если Ответ = КодВозвратаДиалога.Отмена Тогда
Возврат Ложь;
КонецЕсли;
КонецЕсли;
РазобратьТекущийКонтекст();
ТекстПоля = ПолеТекстовогоДокумента.ПолучитьТекст();
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 По ЧислоСтрокЗамены Цикл
ТекущаяСтрокаВставки = ТекстовыйДокумент.ПолучитьСтроку(Счетчик);
СдвинутыйТекст = СдвинутыйТекст + Символы.ПС + НачалоНовойСтроки + ТекущаяСтрокаВставки;
КонецЦикла;
ПолеТекстовогоДокумента.ВыделенныйТекст = СдвинутыйТекст;
ПослеУстановкиВыделенногоМногострочногоТекста();
Возврат Истина;
КонецЕсли;
КонецЕсли;
Возврат Ложь;
КонецФункции // ВызватьРедакторСтроковогоЛитерала()
// Осуществляет переход к определению контекста.
//
// Параметры:
// Нет.
//
Процедура ПерейтиКОпределению()
Если ирОбщий.ПроверитьПлатформаНеWindowsЛкс() Тогда
Возврат;
КонецЕсли;
РазобратьТекущийКонтекст();
Если ПустаяСтрока(мКонтекст) Тогда
Возврат;
КонецЕсли;
ПоследнееВхождение = Неопределено;
ПоследнееОпределение = Неопределено;
НайтиОпределениеСлова(мКонтекст, ПоследнееОпределение, ПоследнееВхождение);
Если ПоследнееВхождение <> Неопределено Тогда
НачальнаяПозицияОпределения = ПоследнееВхождение.FirstIndex + Найти(ПоследнееВхождение.Value, ПоследнееОпределение);
КонечнаяПозицияОпределения = НачальнаяПозицияОпределения + СтрДлина(ПоследнееОпределение);
СлужебноеПолеТекстовогоДокумента.УстановитьГраницыВыделения(НачальнаяПозицияОпределения, КонечнаяПозицияОпределения);
СлужебноеПолеТекстовогоДокумента.ПолучитьГраницыВыделения(мНачальнаяСтрока, мНачальнаяКолонка, мКонечнаяСтрока, мКонечнаяКолонка);
ПолеТекстовогоДокумента.УстановитьГраницыВыделения(НачальнаяПозицияОпределения, КонечнаяПозицияОпределения);
//ПолеТекстовогоДокумента.ПолучитьГраницыВыделения(мНачальнаяСтрока, мНачальнаяКолонка, мКонечнаяСтрока, мКонечнаяКолонка);
Иначе
ТаблицаСлов.Найти(НРег(мКонтекст), "НСлово");
ТаблицаСтруктурТипов = ОпределитьТипЗначенияКонтекста(мКонтекст, " " + мТекстДляПоискаОпределения, мПредшествующийТекст, Истина);
// TODO Сделать диалог выбора варианта
Для Каждого СтруктураТипа Из ТаблицаСтруктурТипов Цикл
Если СтруктураТипа.СтрокаОписания <> Неопределено Тогда
ТаблицаВладелец = СтруктураТипа.СтрокаОписания.Владелец();
#Если Сервер И Не Сервер Тогда
ТаблицаВладелец = Новый ТаблицаЗначений;
#КонецЕсли
Если ТаблицаВладелец.Колонки.Найти("ЛиЭкспорт") <> Неопределено Тогда
// Экспортный метод модуля
СтрокаСозданияРодителя = ТаблицаВладелец.Колонки.Имя.Заголовок;
Если ЗначениеЗаполнено(СтрокаСозданияРодителя) Тогда
Ответ = Вопрос("Перейти к определению метода через открытие вспомогательной внешней обработки в открытом конфигураторе?", РежимДиалогаВопрос.ОКОтмена);
Если Ответ = КодВозвратаДиалога.ОК Тогда
ирОбщий.ПерейтиКОпределениюМетодаВКонфигуратореЛкс(СтрокаСозданияРодителя + "." + ирОбщий.СтрокаБезКонцаЛкс(мТекущееСлово, 1));
КонецЕсли;
Прервать;
КонецЕсли;
ИначеЕсли Истина
И ТаблицаВладелец.Колонки.Найти("Значение") <> Неопределено
И ирОбщий.ЛиСсылкаНаОбъектБДЛкс(СтруктураТипа.СтрокаОписания.Значение)
И ЗначениеЗаполнено(СтруктураТипа.СтрокаОписания.Значение)
Тогда
//ирОбщий.ОткрытьСсылкуВРедактореОбъектаБДЛкс(СтруктураТипа.СтрокаОписания.Значение);
ОткрытьЗначение(СтруктураТипа.СтрокаОписания.Значение);
Прервать;
ИначеЕсли Истина
И ТаблицаВладелец.Колонки.Найти("ТипЗначения") <> Неопределено
И СтруктураТипа.СтрокаОписания.ТипЗначения = "Картинка"
И ТипЗнч(СтруктураТипа.Метаданные) = Тип("ОбъектМетаданных")
Тогда
ирОбщий.ОткрытьЗначениеЛкс(БиблиотекаКартинок[СтруктураТипа.Метаданные.Имя]);
Прервать;
КонецЕсли;
КонецЕсли;
Если ТипЗнч(СтруктураТипа.Метаданные) = Тип("ОбъектМетаданных") Тогда
ПолноеИмяМД = СтруктураТипа.Метаданные.ПолноеИмя();
ирОбщий.ОткрытьОбъектМетаданныхЛкс(СтруктураТипа.Метаданные);
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецПроцедуры
// Ищем в мТекстДляПоискаОпределения
Функция НайтиОпределениеСлова(Слово, ПоследнееОпределение = Неопределено, ПоследнееВхождение = Неопределено) Экспорт
ПоследнееОпределение = Неопределено;
Если ЯзыкПрограммы = 1 Тогда
RegExp.Global = Ложь;
RegExp.Pattern = СтрЗаменить(шПоискОписанияТаблицы, "#Идентификатор#", ирОбщий.ПреобразоватьТекстДляРегулярныхВыраженийЛкс(Слово));
РезультатТекста = RegExp.Execute(мТекстДляПоискаОпределения);
Если РезультатТекста.Count > 0 Тогда
ПоследнееВхождение = РезультатТекста.Item(0);
ПоследнееОпределение = ПоследнееВхождение.SubMatches(3);
Иначе
МаркерЗначение = "ЗНАЧЕНИЕ(";
Если Прав(мПредшествующийТекст, СтрДлина(МаркерЗначение)) = МаркерЗначение Тогда
RegExp.Global = Ложь;
RegExp.Pattern = шИмя;
Если RegExp.Test(Слово) Тогда
Попытка
ПредопределенноеЗначение = ПредопределенноеЗначение(Слово);
Исключение
ПредопределенноеЗначение = Неопределено;
КонецПопытки;
Если ПредопределенноеЗначение <> Неопределено Тогда
ОткрытьЗначение(ПредопределенноеЗначение);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Иначе
RegExp.Global = Истина;
//шПрисваивание = "(" + шРазделитель + "*=" + шРазделитель + "*((Новый|New)" + шРазделитель
// + "+(" + шИмя + ")|(" + шИмяСкобки + "?" + шИндекс
// + "?(\." + шИмяСкобки + "?" + шИндекс + "?)*)" + "|(" + шЧисло + ")|(" + шСтрокаПрограммы + ")))";
ШаблонКоллекции = "(" + шРазделитель + "+Из" + шРазделитель + "+(" + шИмяСкобки + "?"
+ шИндекс + "?" + "(\." + шИмяСкобки + "?" + шИндекс + "?)*))";
RegExp.Pattern = шПредИмя + ирОбщий.ПреобразоватьТекстДляРегулярныхВыраженийЛкс(Слово)
+ "(" + шПрисваивание + "|" + ШаблонКоллекции + ")";
РезультатТекста = RegExp.Execute(мТекстДляПоискаОпределения);
Если РезультатТекста.Count > 0 Тогда
ПоследнееВхождение = РезультатТекста.Item(РезультатТекста.Count - 1);
ПоследнееОпределение = ПоследнееВхождение.SubMatches(0);
//Если ПоследнееВхождение.SubMatches(1) <> Неопределено Тогда
// // Это присвоение
// ПоследнееОпределение = ПоследнееВхождение.SubMatches(1);
//Иначе
// // Это обход коллекции
// ПоследнееОпределение = ПоследнееВхождение.SubMatches(20);
//КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат ПоследнееОпределение;
КонецФункции
// <Описание процедуры>
//
// Параметры:
// <Параметр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 Тогда
МаксКоличествоВариантов = 5;
КоличествоВариантов = 0;
Для Каждого СтрокаСлова Из ВнутренняяТаблицаСлов Цикл
ирОбщий.ЗагрузитьВТаблицуЗначенийЛкс(СтрокаСлова.ТаблицаСтруктурТипов, ТаблицаСтруктурТипов);
КоличествоВариантов = КоличествоВариантов + 1;
Если КоличествоВариантов >= МаксКоличествоВариантов Тогда
Прервать;
КонецЕсли;
КонецЦикла;
Если Истина
И РодительскаяСтрутураТипа.ИмяОбщегоТипа = "БлокировкаДанных"
И ТипСлова = "Метод"
И ТекущееСлово = "Добавить"
Тогда
ТаблицаСтруктурТипов.ЗаполнитьЗначения(ирОбщий.СтрокаМеждуМаркерамиЛкс(ТекущиеАргументы, """", """"), "Метаданные");
КонецЕсли;
Продолжить;
ИначеЕсли Истина
И ЗначениеЗаполнено(РодительскаяСтрутураТипа.ТипЯзыка)
И РодительскаяСтрутураТипа.ИмяОбщегоТипа = "Строка"
Тогда
ЗаполнитьЗначенияСвойств(ТаблицаСтруктурТипов.Добавить(), РодительскаяСтрутураТипа);
Продолжить;
КонецЕсли;
Иначе
//Попытка
// Пустышка = Новый Структура(ТекущееСлово);
//Исключение
// Пустышка = Неопределено;
//КонецПопытки;
//Если Ложь
// Или Пустышка = Неопределено
// Или НРег(ТекущийИндекс) <> НРег("""" + ТекущееСлово + """") // Противный случай отработается внутри ПолучитьВнутреннююТаблицуМетаданныхСлов
//Тогда
// // Это - произвольный элемент коллекции
// ДобавитьТипЭлементаКоллекцииВТаблицуСтруктурТипов(РодительскаяСтрутураТипа, СтруктураТипа, ТаблицаСтруктурТипов);
// Продолжить;
//КонецЕсли;
КонецЕсли;
ВнутренняяТаблицаСлов = мПлатформа.ПолучитьВнутреннююТаблицуМетаданныхСлов(РодительскаяСтрутураТипа,
ТекущееСлово, ТипСлова, ВиртуальнаяТаблица, ЯзыкПрограммы, ТекущийИндекс,,, ЛиСерверныйКонтекст, мМодульМетаданных);
Если ВнутренняяТаблицаСлов.Количество() > 0 Тогда
Для Каждого СтрокаСлова Из ВнутренняяТаблицаСлов Цикл
Если СтрокаСлова.ТаблицаСтруктурТипов <> Неопределено Тогда
ирОбщий.ЗагрузитьВТаблицуЗначенийЛкс(СтрокаСлова.ТаблицаСтруктурТипов, ТаблицаСтруктурТипов);
КонецЕсли;
КонецЦикла;
Продолжить;
Иначе
// Возможно это - коллекция, т.к. у нее не обнаружилось метасвойств
Если СтруктураТипа.ИмяОбщегоТипа <> "Неизвестный контекст" Тогда
ДобавитьТипЭлементаКоллекцииВТаблицуСтруктурТипов(РодительскаяСтрутураТипа, СтруктураТипа, ТаблицаСтруктурТипов);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Возврат ТаблицаСтруктурТипов;
КонецФункции
// Определяет тип значения слова в режиме внутреннего языка.
//
// Параметры:
// ТекстДляПоискаОпределения Строка - где ищем определение;
// Контекст Строка - последовательность идентификаторов через "." без круглых и квадратных скобок.
//
// Возвращаемое значение:
// Структура "ИмяОбщегоТипа", "ПерсональныйТип".
//
Функция ОпределитьТипЗначенияКонтекста(Знач Контекст = "", Знач ТекстДляПоискаОпределения = "", Знач ПредшествующийТекст = "", Знач РазрешитьАнализИмениТипа = Ложь,
Знач ЭтоВызовКонструктора = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ТаблицаСтруктурТипов = мПлатформа.НоваяТаблицаСтруктурТипа();
СтруктураТипа = мПлатформа.НоваяСтруктураТипа();
//Если ЗначениеЗаполнено(Конфигурация) Тогда
СтруктураТипа.Метаданные = Конфигурация;
//Иначе
// СтруктураТипа.Метаданные = мПлатформа.мМетаданные;
//КонецЕсли;
Если РазрешитьАнализИмениТипа Тогда
Если ЯзыкПрограммы = 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 = шПредИмя + "(?:Новый|New)" + шРазделитель + "+$";
Результат = RegExp.Execute(ПредшествующийТекст);
Если Результат.Count > 0 Тогда
СтруктураТипа.Вставить("Конструктор", Истина);
СтруктураТипа.ТипЯзыка = "ИмяТипа";
КонецЕсли;
RegExp.Pattern = шПредИмя + "(?:Новый|New)" + шРазделитель + "*\(" + шРазделитель + "*""$";
Результат = RegExp.Execute(ПредшествующийТекст);
Если Результат.Count > 0 Тогда
// Активная следующая строка блокирует недокументированные возможности.
//СтруктураТипа.Вставить("Конструктор", Истина);
СтруктураТипа.ТипЯзыка = "ИмяТипа";
КонецЕсли;
RegExp.Pattern = шПредИмя + "Тип" + шРазделитель + "*\(" + шРазделитель + "*""$";
Результат = RegExp.Execute(ПредшествующийТекст);
Если Результат.Count > 0 Тогда
СтруктураТипа.ТипЯзыка = "ИмяТипа";
КонецЕсли;
RegExp.Pattern = шПредИмя + "(?:Новый|New)" + шРазделитель + "*ОписаниеТипов\(" + шРазделитель + "*""[^""]*$";
Результат = 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));
Если СловоНовый = Нрег("Новый") Или СловоНовый = Нрег("New") Тогда
//СтруктураТипа = мПлатформа.НоваяСтруктураТипа();
//Если ПоследнееВхождение.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] = СтруктураКОМТипа;
КонецЕсли;
ЗаполнитьЗначенияСвойств(СтруктураТипа, СтруктураКОМТипа);
ИначеЕсли ТипНового <> Неопределено Тогда
СтруктураТипа = мПлатформа.СтруктураТипаИзКонкретногоТипа(ТипНового, ЯзыкПрограммы);
КонецЕсли;
КонецЕсли;
мПлатформа.ДобавитьВТаблицуСтруктурТипов(ТаблицаСтруктурТипов, СтруктураТипа);
ИначеЕсли Не ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(ПоследнееВхождение.SubMatches(6)) Тогда
ТаблицаСтруктурТипов = ОпределитьТипЗначенияКонтекста(ПрисвоенныйКонтекст, Лев(ТекстДляПоискаОпределения, ПоследнееВхождение.FirstIndex - 1),
Лев(ТекстДляПоискаОпределения, ПоследнееВхождение.FirstIndex - 1), РазрешитьАнализИмениТипа);
Для Каждого СтруктураТипа Из ТаблицаСтруктурТипов Цикл
СтруктураКлюча = Новый Структура("Слово, ЯзыкПрограммы", СтруктураТипа.ИмяОбщегоТипа, ЯзыкПрограммы);
СтруктураТипа.СтрокаОписания = Неопределено;
// Было закомментировано
//НайденныеСтроки = мПлатформа.ТаблицаОбщихТипов.НайтиСтроки(СтруктураКлюча);
//Если НайденныеСтроки.Количество() > 0 Тогда
// СтруктураТипа.СтрокаОписания = НайденныеСтроки[0];
//КонецЕсли;
КонецЦикла;
// **** Сделать определение примитивного типа
Иначе
СтруктураТипа.ИмяОбщегоТипа = "Примитивный";
мПлатформа.ДобавитьВТаблицуСтруктурТипов(ТаблицаСтруктурТипов, СтруктураТипа);
КонецЕсли;
Иначе
// Это обход коллекции
ПрисвоенныйКонтекст = ПоследнееВхождение.SubMatches(15);
// **** Раньше текст для поиска определения передавался неизменным. Тестовый режим
ТаблицаСтруктурТиповКоллекции = ОпределитьТипЗначенияКонтекста(ПрисвоенныйКонтекст, Лев(ТекстДляПоискаОпределения, ПоследнееВхождение.FirstIndex - 1),
Лев(ТекстДляПоискаОпределения, ПоследнееВхождение.FirstIndex - 1));
//// Структура типов коллекции всегда имеет ровно один элемент
//СтруктураКлюча = Новый Структура("Слово, ЯзыкПрограммы", СтруктураТипаКоллекции.ИмяОбщегоТипа, ЯзыкПрограммы);
//НайденныеСтроки = мПлатформа.ТаблицаОбщихТипов.НайтиСтроки(СтруктураКлюча);
//Если НайденныеСтроки.Количество() > 0 Тогда
// БазовыеТипы = ирОбщий.СтрРазделитьЛкс(НайденныеСтроки[0].ТипЭлементаКоллекции, ",", Истина);
// Для Каждого БазовыйТип Из БазовыеТипы Цикл
// СтруктураКлюча = Новый Структура("БазовыйТип, ЯзыкПрограммы", БазовыйТип, ЯзыкПрограммы);
// НайденныеСтроки = мПлатформа.ТаблицаОбщихТипов.НайтиСтроки(СтруктураКлюча);
// Если НайденныеСтроки.Количество() > 0 Тогда
// СтруктураТипа.СтрокаОписания = НайденныеСтроки[0];
// СтруктураТипа.ИмяОбщегоТипа = НайденныеСтроки[0].Слово;
// СтруктураТипа.Метаданные = СтруктураТипаКоллекции.Метаданные;
// КонецЕсли;
// мПлатформа.ДобавитьВТаблицуСтруктурТипов(ТаблицаСтруктурТипов, СтруктураТипа);
// КонецЦикла;
//Иначе
// мПлатформа.ДобавитьВТаблицуСтруктурТипов(ТаблицаСтруктурТипов, СтруктураТипа);
//КонецЕсли;
ДобавитьТипЭлементаКоллекцииВТаблицуСтруктурТипов(ТаблицаСтруктурТиповКоллекции[0], СтруктураТипа, ТаблицаСтруктурТипов);
КонецЕсли;
Если Не ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(ТекущийИндекс) Тогда
МассивРодительскихСтрутурТипа = ТаблицаСтруктурТипов;
ТаблицаСтруктурТипов = мПлатформа.НоваяТаблицаСтруктурТипа();
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если МассивРодительскихСтрутурТипа.Количество() = 0 Тогда
МассивРодительскихСтрутурТипа = ОпределитьТипЗначенияКонтекста(РодительскийКонтекст, ТекстДляПоискаОпределения, ПредшествующийТекст, РазрешитьАнализИмениТипа);
КонецЕсли;
МассивДочернихСтруктурТипа = ОпределитьТипДочернегоКонтекста(МассивРодительскихСтрутурТипа, ТекущееСлово, ТипСлова, ТекущийИндекс, ТекущиеАргументы, ПредшествующийТекст);
ирОбщий.ЗагрузитьВТаблицуЗначенийЛкс(МассивДочернихСтруктурТипа, ТаблицаСтруктурТипов);
Если ТипСлова = "Свойство" Тогда
ТекстДляЗаполненияМетаданных = ТекстДляПоискаОпределения;
Для Каждого СтруктураТипаЦикл Из ТаблицаСтруктурТипов Цикл
Если Ложь
Или СтруктураТипаЦикл.ИмяОбщегоТипа = "Структура"
Или СтруктураТипаЦикл.ИмяОбщегоТипа = "ФиксированнаяСтруктура"
Тогда
RegExp.Global = Ложь;
ШаблонКонструкторСоСвойствами = Контекст + "\s*=\s*Новый\s+Структура\s*\(\s*""((?:" + шИмя + "\s*,\s*)*" + шИмя + ")""";
RegExp.Pattern = ШаблонКонструкторСоСвойствами;
РезультатСвойств = RegExp.Execute(ТекстДляЗаполненияМетаданных);
Если РезультатСвойств.Count > 0 Тогда
СтруктураТипаЦикл.Метаданные = Новый Структура(РезультатСвойств.Item(0).SubMatches(0));
ИначеЕсли Истина
И ТипЗнч(СтруктураТипаЦикл.Метаданные) <> Тип("Структура")
И ТипЗнч(СтруктураТипаЦикл.Метаданные) <> Тип("ФиксированнаяСтруктура")
Тогда
СтруктураТипаЦикл.Метаданные = Новый Структура;
КонецЕсли;
ШаблонУстановкаТекста = Контекст + "\s*\.\s*Вставить\s*\(\s*""(" + шИмя + ")""";
RegExp.Pattern = ШаблонУстановкаТекста;
RegExp.Global = Истина;
РезультатСвойств = RegExp.Execute(ТекстДляЗаполненияМетаданных);
Для Каждого ВхождениеСвойства Из РезультатСвойств Цикл
СтруктураТипаЦикл.Метаданные.Вставить(ВхождениеСвойства.SubMatches(0));
КонецЦикла;
ИначеЕсли Ложь
Или СтруктураТипаЦикл.ИмяОбщегоТипа = "ТаблицаЗначений"
Или СтруктураТипаЦикл.ИмяОбщегоТипа = "ДеревоЗначений"
Тогда
RegExp.Global = Ложь;
Если Истина
И ТипЗнч(СтруктураТипаЦикл.Метаданные) <> Тип("ДеревоЗначений")
И ТипЗнч(СтруктураТипаЦикл.Метаданные) <> Тип("ТаблицаЗначений")
Тогда
СтруктураТипаЦикл.Метаданные = Новый ТаблицаЗначений;
КонецЕсли;
ШаблонУстановкаТекста = Контекст + "\s*\.\s*Колонки\s*.\s*Добавить\s*\(\s*""(" + шИмя + ")""";
RegExp.Pattern = ШаблонУстановкаТекста;
RegExp.Global = Истина;
РезультатСвойств = RegExp.Execute(ТекстДляЗаполненияМетаданных);
Колонки = СтруктураТипаЦикл.Метаданные.Колонки;
Для Каждого ВхождениеСвойства Из РезультатСвойств Цикл
ИмяКолонки = ВхождениеСвойства.SubMatches(0);
Попытка
Колонки.Добавить(ИмяКолонки);
Исключение
Пустышка = 0;
КонецПопытки;
КонецЦикла;
ИначеЕсли Ложь
Или СтруктураТипаЦикл.ИмяОбщегоТипа = "Запрос"
Или СтруктураТипаЦикл.ИмяОбщегоТипа = "ПостроительЗапроса"
Или СтруктураТипаЦикл.ИмяОбщегоТипа = "ПостроительОтчета"
Тогда
RegExp.Global = Ложь;
ШаблонУстановкаТекста = Контекст + "\s*\.\s*Текст\s*=\s*(" + шСтрокаПрограммы + ")";
RegExp.Pattern = ШаблонУстановкаТекста;
RegExp.Global = Истина;
РезультатСвойств = RegExp.Execute(ТекстДляЗаполненияМетаданных);
Для Каждого ВхождениеСвойства Из РезультатСвойств Цикл
ПрисвоенноеЗначение = ВхождениеСвойства.SubMatches(0);
Если Лев(ПрисвоенноеЗначение, 1) = """" Тогда
Попытка
ТекстЗапроса = Вычислить(ПрисвоенноеЗначение);
Прервать;
Исключение
ТекстЗапроса = "";
КонецПопытки;
КонецЕсли;
КонецЦикла;
Если ЗначениеЗаполнено(ТекстЗапроса) Тогда
СтруктураТипаЦикл.Метаданные = Новый ТаблицаЗначений;
ПостроительЗапроса = Новый ПостроительЗапроса;
Попытка
ПостроительЗапроса.Текст = ТекстЗапроса;
ПостроительЗапроса.ЗаполнитьНастройки();
Исключение
ПостроительЗапроса = Неопределено;
КонецПопытки;
Если ПостроительЗапроса <> Неопределено Тогда
ирОбщий.УстановитьМетаданныеКоллекцииЛкс(ПостроительЗапроса.ДоступныеПоля, СтруктураТипаЦикл.Метаданные);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если Истина
И ЯзыкПрограммы = 1
И РодительскийКонтекст = ""
И СтруктураТипа.ИмяОбщегоТипа = "Неизвестный контекст"
И ТипЗнч(КонтекстВыполнения) = Тип("Запрос")
Тогда
ВременныйЗапрос = Новый Запрос;
ВременныйЗапрос.МенеджерВременныхТаблиц = КонтекстВыполнения.МенеджерВременныхТаблиц;
ВременныйЗапрос.Текст = "ВЫБРАТЬ ПЕРВЫЕ 1 * ИЗ " + ТекущееСлово;
Попытка
// Активное вычисление!
СтруктураТипа.Метаданные = ВременныйЗапрос.Выполнить();
СтруктураТипа.ИмяОбщегоТипа = "ВременнаяТаблица";
Исключение
КонецПопытки;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ТаблицаСтруктурТипов.Количество() = 0 Тогда
мПлатформа.ДобавитьВТаблицуСтруктурТипов(ТаблицаСтруктурТипов, СтруктураТипа);
КонецЕсли;
Возврат ТаблицаСтруктурТипов;
КонецФункции
Процедура ЗаполнитьЛокальныеСвойстваИМетодыПоТексту(ОчиститьТаблицуСлов = Истина, ВключатьКонструкции = Истина,
УчитыватьРодительскийКонтекст = Ложь, ОбновитьТекстДляАнализа = Истина, ВключатьГлобальныйКонтекст = Ложь, Знач ТекстДляАнализа = "") Экспорт
Если ирОбщий.ПроверитьПлатформаНеWindowsЛкс(, "Заполнение параметров") Тогда
Возврат;
КонецЕсли;
Если Не ЗначениеЗаполнено(ТекстДляАнализа) Тогда
Если ОбновитьТекстДляАнализа Тогда
ТекстДляАнализа = ПолеТекстовогоДокумента.ПолучитьТекст();
КонецЕсли;
КонецЕсли;
Если ЗначениеЗаполнено(ТекстДляАнализа) Тогда
ТекстБезКомментариевИОпасныхСтрок = ЗалитьКомментарииИСтроковыеЛитералы(ТекстДляАнализа,, Истина);
КонецЕсли;
Если ОчиститьТаблицуСлов Тогда
ТаблицаСлов.Очистить();
КонецЕсли;
Если ВключатьКонструкции Тогда
Если ЯзыкПрограммы = 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 = "(?:" + шСтрокаПрограммы + "|" + шРазделитель + "|(?:Новый|New)\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;
КонецЦикла;
КонецЦикла;
КонецПроцедуры
Процедура ОбновитьКонтекстВыраженияЗапросаПоНастройкеКомпоновкиЛкс(НастройкаКомпоновки) Экспорт
#Если Сервер И Не Сервер Тогда
НастройкаКомпоновки = Новый НастройкиКомпоновкиДанных;
#КонецЕсли
ОчиститьТаблицуСловЛокальногоКонтекста();
Для Каждого ДоступноеПоле Из НастройкаКомпоновки.ДоступныеПоляОтбора.Элементы Цикл
НрегПервыйФрагмент = ирОбщий.ПервыйФрагментЛкс(НРег(ДоступноеПоле.Поле));
Если НрегПервыйФрагмент = НРег("ПараметрыДанных") Тогда
Для Каждого ДоступныйПараметр Из ДоступноеПоле.Элементы Цикл
ИмяСвойства = мПараметрыДиалектаSQL.ПрефиксПараметра + ирОбщий.ПоследнийФрагментЛкс(ДоступныйПараметр.Поле);
ДобавитьСловоЛокальногоКонтекста(ИмяСвойства, "Свойство", , ДоступныйПараметр,,,, "СтрокаТаблицы");
КонецЦикла;
Иначе
ДобавитьСловоЛокальногоКонтекста("" + ДоступноеПоле.Поле, "Свойство",, ДоступноеПоле,,,, "СтрокаТаблицы");
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Процедура УстановитьПризнакМодифицированностиФормы()
Если ПолеТекстовогоДокумента.ИзменяетДанные Тогда
ФормаВладелец.Модифицированность = Истина;
КонецЕсли;
КонецПроцедуры
Функция ПолучитьСтруктуруТипаСправаОтРавно() Экспорт
КончитьОбработкуКоманды();
ТаблицаСтруктурТипов = ПолучитьТаблицуСтруктурТиповТекущегоВыражения(Истина);
КончитьОбработкуКоманды();
СписокТиповКонтекста = Новый СписокЗначений;
МассивДляПроверкиДублей = Новый Массив;
Для Каждого СтруктураТипаКонтекста Из ТаблицаСтруктурТипов Цикл
ИмяОбщегоТипа = СтруктураТипаКонтекста.ИмяОбщегоТипа;
Если Ложь
Или Не мПлатформа.ЭтоАгрегатныйОбщийТип(ИмяОбщегоТипа, ЯзыкПрограммы)
Или ТипЗнч(СтруктураТипаКонтекста.Метаданные) <> Тип("ОбъектМетаданных")
Или (Истина
И ЯзыкПрограммы = 0
И Найти(ИмяОбщегоТипа, "Ссылка.") = 0)
Тогда
Продолжить;
КонецЕсли;
ПредставлениеКонкретногоТипа = "";
ПредставлениеКонкретногоТипа = ПредставлениеКонкретногоТипа + мПлатформа.ИмяТипаИзСтруктурыТипа(СтруктураТипаКонтекста);
Если МассивДляПроверкиДублей.Найти(ПредставлениеКонкретногоТипа) = Неопределено Тогда
СписокТиповКонтекста.Добавить(СтруктураТипаКонтекста, ПредставлениеКонкретногоТипа);
МассивДляПроверкиДублей.Добавить(ПредставлениеКонкретногоТипа);
КонецЕсли;
КонецЦикла;
Если СписокТиповКонтекста.Количество() > 0 Тогда
Ответ = Вопрос("Хотите использовать предсказанные равенством метаданные?", РежимДиалогаВопрос.ДаНет);
Если Ответ = КодВозвратаДиалога.Нет Тогда
Возврат Неопределено;
КонецЕсли;
КонецЕсли;
Если СписокТиповКонтекста.Количество() = 1 Тогда
ВыбраннаяСтруктураТипа = СписокТиповКонтекста[0].Значение;
КонкретныйТип = СписокТиповКонтекста[0].Представление;
ИначеЕсли СписокТиповКонтекста.Количество() > 1 Тогда
СписокТиповКонтекста.СортироватьПоПредставлению();
ВыбранныйТип = СписокТиповКонтекста.ВыбратьЭлемент("Выберите тип контекста");
Если ВыбранныйТип <> Неопределено Тогда
ВыбраннаяСтруктураТипа = ВыбранныйТип.Значение;
КонкретныйТип = ВыбранныйТип.Представление;
КонецЕсли;
КонецЕсли;
//Если ВыбраннаяСтруктураТипа <> Неопределено Тогда
// СтруктураТипаКонтекста = мПлатформа.НоваяСтруктураТипа();
// ЗаполнитьЗначенияСвойств(СтруктураТипаКонтекста, ВыбраннаяСтруктураТипа);
//КонецЕсли;
Возврат ВыбраннаяСтруктураТипа;
КонецФункции//ПолучитьСтруктуруТипаСправоОтРавно
Функция ПолучитьТаблицуСтруктурТиповТекущегоВыражения(ЛиСправаОтРавенства = Ложь) Экспорт
РазобратьТекущийКонтекст(ЛиСправаОтРавенства,, Ложь);
лКонтекст = ?(ЛиСправаОтРавенства, мКонтекст, мРодительскийКонтекст);
МассивЗащитыОтРекурсии.Очистить();
Попытка
ТаблицаСтруктурТиповКонтекста = ОпределитьТипЗначенияКонтекста(лКонтекст, " " + мТекстДляПоискаОпределения, мПредшествующийТекст, Истина);
Исключение
Ошибка = ИнформацияОбОшибке();
Если Ошибка.Описание = "ОшибкаВычисленияВиртуальнойТаблицы" Тогда
Возврат Новый ТаблицаЗначений;
КонецЕсли;
ВызватьИсключение;
КонецПопытки;
Возврат ТаблицаСтруктурТиповКонтекста;
КонецФункции
Функция ПодготовитьИмяПараметраМетода(ИмяПараметра) Экспорт
//ирОбщий.ДекодироватьТекстИзXMLЛкс(СтрокаПараметра.Параметр);
ИмяПараметра = СтрЗаменить(ИмяПараметра, "&gt;", "");
ИмяПараметра = СтрЗаменить(ИмяПараметра, "&lt;", "");
Возврат ИмяПараметра;
КонецФункции
// Вызывает контекстную подсказку в текстовом поле.
//
// Параметры:
// Нет.
//
Процедура ВызватьКонтекстнуюПодсказку()
Если ирОбщий.ПроверитьПлатформаНеWindowsЛкс() Тогда
Возврат;
КонецЕсли;
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ВычислятьТипыВСписке = ирОбщий.ВосстановитьЗначениеЛкс(ИмяКласса + ".ВычислятьТипыВСписке") = Истина Или ЯзыкПрограммы <> 0;
Если Ложь
Или ПолеТекстовогоДокумента.ТолькоПросмотр
Или ФормаВладелец.ТолькоПросмотр
Тогда
Возврат;
КонецЕсли;
//Если Истина
// И ЯзыкПрограммы = 1
// И Не мДоступныеТаблицыПолучены
//Тогда
// Если ирОбщий.СтрокиРавныЛкс(мДиалектSQL, "1С") Тогда
// ИначеЕсли ирОбщий.СтрокиРавныЛкс(мДиалектSQL, "WQL") Тогда
// Иначе
// ЗаполнитьДоступныеТаблицыADO();
// Для Каждого СтрокаДоступнойТаблицы Из ДоступныеТаблицы Цикл
// ДобавитьСловоЛокальногоКонтекста(СтрокаДоступнойТаблицы.Имя,,,, Истина,,, "ВременнаяТаблица");
// КонецЦикла;
// КонецЕсли;
//КонецЕсли;
RegExp.Global = Истина;
ТаблицаСтатистикиВыбора = мПлатформа.ТаблицаСтатистикиВыбора;
#Если Сервер И Не Сервер Тогда
ТаблицаСтатистикиВыбора = Новый ТаблицаЗначений;
#КонецЕсли
ТаблицаСтруктурТиповКонтекста = ПолучитьТаблицуСтруктурТиповТекущегоВыражения();
Пока ТаблицаСтруктурТиповКонтекста.Количество() > 0 Цикл
ТаблицаСлов.Очистить();
Если мЭтоСтроковыйЛитерал Тогда
ВыбраннаяСтруктураТипа = ТаблицаСтруктурТиповКонтекста[0];
Иначе
СписокТиповКонтекста = Новый СписокЗначений;
СоответствиеСтруктурТипов = Новый Соответствие;
МассивДляПроверкиДублей = Новый Массив;
Для Каждого СтруктураТипаКонтекста Из ТаблицаСтруктурТиповКонтекста Цикл
ИмяОбщегоТипа = СтруктураТипаКонтекста.ИмяОбщегоТипа;
Если Истина
И Не ЗначениеЗаполнено(СтруктураТипаКонтекста.ТипЯзыка)
И Не мПлатформа.ЭтоАгрегатныйОбщийТип(ИмяОбщегоТипа, ЯзыкПрограммы)
Тогда
Продолжить;
КонецЕсли;
ПредставлениеКонкретногоТипа = "";
//Если СтруктураТипаКонтекста.СтрокаОписания <> Неопределено Тогда
// // Наверное логичнее было бы из ОпределитьТипЗначенияКонтекста ее получать
// РодительскаяСтруктураТипа = мПлатформа.НоваяСтруктураТипа();
// Если СтруктураТипаКонтекста.СтрокаОписания.Владелец().Колонки.Найти("ТипКонтекста") <> Неопределено Тогда
// ЗаполнитьЗначенияСвойств(РодительскаяСтруктураТипа, СтруктураТипаКонтекста);
// РодительскаяСтруктураТипа.ИмяОбщегоТипа = СтруктураТипаКонтекста.СтрокаОписания.ТипКонтекста;
// КонецЕсли;
// ПредставлениеКонкретногоТипа = ПредставлениеКонкретногоТипа
// + мПлатформа.ИмяТипаИзСтруктурыТипа(РодительскаяСтруктураТипа) + " / ";
//КонецЕсли;
ПредставлениеКонкретногоТипа = ПредставлениеКонкретногоТипа + мПлатформа.ИмяТипаИзСтруктурыТипа(СтруктураТипаКонтекста);
Если МассивДляПроверкиДублей.Найти(ПредставлениеКонкретногоТипа) = Неопределено Тогда
СписокТиповКонтекста.Добавить(ПредставлениеКонкретногоТипа, ПредставлениеКонкретногоТипа);
МассивДляПроверкиДублей.Добавить(ПредставлениеКонкретногоТипа);
КонецЕсли;
МассивСтруктурТипа = СоответствиеСтруктурТипов[ПредставлениеКонкретногоТипа];
Если МассивСтруктурТипа = Неопределено Тогда
МассивСтруктурТипа = Новый Массив;
КонецЕсли;
МассивСтруктурТипа.Добавить(СтруктураТипаКонтекста);
СоответствиеСтруктурТипов[ПредставлениеКонкретногоТипа] = МассивСтруктурТипа;
КонецЦикла;
Если СписокТиповКонтекста.Количество() = 0 Тогда
ВыбраннаяСтруктураТипа = ТаблицаСтруктурТиповКонтекста[0];
КонкретныйТип = мПлатформа.ИмяТипаИзСтруктурыТипа(СтруктураТипаКонтекста);
Иначе
ВыбраннаяСтруктураТипа = Неопределено;
Если СписокТиповКонтекста.Количество() > 1 Тогда
СписокТиповКонтекста.СортироватьПоПредставлению();
НачальныйВыбор = Неопределено;
КлючПоискаСтатистики = Новый Структура("ЯзыкПрограммы, ТипКонтекста", ЯзыкПрограммы, "<Выбор типа>");
ВыбранныеРанееТипы = ТаблицаСтатистикиВыбора.Скопировать(КлючПоискаСтатистики);
ВыбранныеРанееТипы.Сортировать("Рейтинг Убыв");
Для Каждого СтрокаТипа Из ВыбранныеРанееТипы Цикл
Для Каждого ЭлементСписка Из СписокТиповКонтекста Цикл
Если СтрокаТипа.Слово = ЭлементСписка.Представление Тогда
НачальныйВыбор = ЭлементСписка;
Прервать;
КонецЕсли;
КонецЦикла;
Если НачальныйВыбор <> Неопределено Тогда
Прервать;
КонецЕсли;
КонецЦикла;
ВыбранныйЭлементСписка = СписокТиповКонтекста.ВыбратьЭлемент("Выберите тип контекста", НачальныйВыбор);
Если ВыбранныйЭлементСписка = Неопределено Тогда
Возврат;
КонецЕсли;
КонкретныйТип = ВыбранныйЭлементСписка.Представление;
// Обновим статистику выбора
КлючПоискаСтатистики.Вставить("Слово", КонкретныйТип);
НайденныеСтроки = ТаблицаСтатистикиВыбора.НайтиСтроки(КлючПоискаСтатистики);
Если НайденныеСтроки.Количество() > 0 Тогда
СтрокаСтатистикиВыбора = НайденныеСтроки[0];
Иначе
СтрокаСтатистикиВыбора = ТаблицаСтатистикиВыбора.Добавить();
ЗаполнитьЗначенияСвойств(СтрокаСтатистикиВыбора, КлючПоискаСтатистики);
КонецЕсли;
СтрокаСтатистикиВыбора.Рейтинг = СтрокаСтатистикиВыбора.Рейтинг + 1;
Иначе
ВыбранныйЭлементСписка = СписокТиповКонтекста[0];
КонкретныйТип = ВыбранныйЭлементСписка.Представление;
КонецЕсли;
МассивСтруктурТипа = СоответствиеСтруктурТипов[КонкретныйТип];
Для Каждого СтруктураТипа Из МассивСтруктурТипа Цикл
Если Ложь
Или ВыбраннаяСтруктураТипа = Неопределено
Или ТипЗнч(ВыбраннаяСтруктураТипа.Метаданные) = Тип("ОбъектМетаданныхКонфигурация")
Тогда
ВыбраннаяСтруктураТипа = СтруктураТипа;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЕсли;
СтруктураТипаКонтекста = мПлатформа.НоваяСтруктураТипа();
Если ВыбраннаяСтруктураТипа.ТипЯзыка <> "ИмяТипа" И мЭтоСтроковыйЛитерал Тогда
// Находимся внутри строкового литерала на позиции параметра
КоллекцияЭлементовМД = Новый Массив;
Если Истина
И ВыбраннаяСтруктураТипа.СтрокаОписания <> Неопределено
И ВыбраннаяСтруктураТипа.СтрокаОписания.Владелец().Колонки.Найти("ЛиЭкспорт") = Неопределено
Тогда
ИмяПараметра = "";
Отбор = Новый Структура;
Отбор.Вставить("ТипКонтекста", ВыбраннаяСтруктураТипа.СтрокаОписания.ТипКонтекста);
Отбор.Вставить("Слово", мИмяМетода);
Отбор.Вставить("ЯзыкПрограммы", ЯзыкПрограммы);
СтрокиПараметров = мПлатформа.ТаблицаПараметров.Скопировать(Отбор);
СтрокиПараметров = СтрокиПараметров.НайтиСтроки(Новый Структура("Номер", мНомерПараметра));
Для Каждого СтрокаПараметра Из СтрокиПараметров Цикл
Если Найти(СтрокаПараметра.ТипЗначения, "Строка") > 0 Тогда
ИмяПараметра = ПодготовитьИмяПараметраМетода(СтрокаПараметра.Параметр);
Прервать;
КонецЕсли;
КонецЦикла;
// Имена свойств
Если Ложь
Или ТипЗнч(ВыбраннаяСтруктураТипа.Метаданные) = Тип("ТаблицаЗначений")
Или ТипЗнч(ВыбраннаяСтруктураТипа.Метаданные) = Тип("ДеревоЗначений")
Или ТипЗнч(ВыбраннаяСтруктураТипа.Метаданные) = Тип("РезультатЗапроса")
Тогда
КоллекцияЭлементовМД = ВыбраннаяСтруктураТипа.Метаданные.Колонки;
ИначеЕсли ТипЗнч(ВыбраннаяСтруктураТипа.Метаданные) = Тип("ОбъектМетаданных") Тогда
Если ИмяПараметра = "Макет" Тогда
КоллекцияЭлементовМД = ВыбраннаяСтруктураТипа.Метаданные.Макеты;
ИначеЕсли ИмяПараметра = "Форма" Тогда
КоллекцияЭлементовМД = ВыбраннаяСтруктураТипа.Метаданные.Формы;
Иначе
ИмяТаблицыБД = ирКэш.ИмяТаблицыИзМетаданныхЛкс(ВыбраннаяСтруктураТипа.Метаданные.ПолноеИмя());
Если ЗначениеЗаполнено(ИмяТаблицыБД) Тогда
КоллекцияЭлементовМД = ирОбщий.ПоляТаблицыБДЛкс(ИмяТаблицыБД);
КонецЕсли;
КонецЕсли;
ИначеЕсли ИмяПараметра = "ИмяПользователяИБ" Тогда
Пользователи = ПользователиИнформационнойБазы.ПолучитьПользователей();
Для Каждого Пользователь Из Пользователи Цикл
КоллекцияЭлементовМД.Добавить(Пользователь.Имя);
КонецЦикла;
ИначеЕсли ИмяПараметра = "Роль" Тогда
КоллекцияЭлементовМД = Метаданные.Роли;
ИначеЕсли ИмяПараметра = "ИмяПользователяИБ" Тогда
Пользователи = ПользователиИнформационнойБазы.ПолучитьПользователей();
Для Каждого Пользователь Из Пользователи Цикл
КоллекцияЭлементовМД.Добавить(Пользователь.Имя);
КонецЦикла;
ИначеЕсли ИмяПараметра = "ОбщийМакет" Тогда
КоллекцияЭлементовМД = Метаданные.ОбщиеМакеты;
ИначеЕсли Истина
И ВыбраннаяСтруктураТипа.СтрокаОписания.Слово = "ПолучитьОбщуюФорму"
И ИмяПараметра = "Форма"
Тогда
КоллекцияЭлементовМД = Метаданные.ОбщиеФормы;
ИначеЕсли Истина
И ВыбраннаяСтруктураТипа.СтрокаОписания.Слово = "НайтиПредопределенное"
И ВыбраннаяСтруктураТипа.СтрокаОписания.ТипКонтекста = "МенеджерРегламентныхЗаданий"
И ИмяПараметра = "Метаданные"
Тогда
КоллекцияЭлементовМД = Метаданные.РегламентныеЗадания;
ИначеЕсли Истина
И ВыбраннаяСтруктураТипа.СтрокаОписания.Слово = "ПравоДоступа"
И ИмяПараметра = "Право"
Тогда
КоллекцияЭлементовМД = ирОбщий.ТаблицаЗначенийИзТабличногоДокументаЛкс(мПлатформа.ПолучитьМакет("ВидыПравДоступа"));
ИначеЕсли Истина
И (Ложь
Или ВыбраннаяСтруктураТипа.СтрокаОписания.Слово = "ПолучитьФункциональнуюОпцию"
Или ВыбраннаяСтруктураТипа.СтрокаОписания.Слово = "ПолучитьФункциональнуюОпциюИнтерфейса"
Или ВыбраннаяСтруктураТипа.СтрокаОписания.Слово = "ПолучитьФункциональнуюОпциюФормы")
И ИмяПараметра = "Имя"
Тогда
КоллекцияЭлементовМД = Метаданные.ФункциональныеОпции;
КонецЕсли;
//Если Ложь
// // ФоновыеЗадания.Выполнить("")
// Или (Истина
// И ВыбраннаяСтруктураТипа.СтрокаОписания.Слово = "Выполнить"
// И ВыбраннаяСтруктураТипа.СтрокаОписания.ТипКонтекста = "МенеджерФоновыхЗаданий"
// И ИмяПараметра = "ИмяМетода")
// // БлокировкаДанных.Добавить("")
// Или (Истина
// И ВыбраннаяСтруктураТипа.СтрокаОписания.Слово = "Добавить"
// И ВыбраннаяСтруктураТипа.СтрокаОписания.ТипКонтекста = "БлокировкаДанных"
// И ИмяПараметра = "ПространствоБлокировки")
// Или (Истина
// И ВыбраннаяСтруктураТипа.СтрокаОписания.Слово = "УстановитьЗначение"
// И ВыбраннаяСтруктураТипа.СтрокаОписания.ТипКонтекста = "ЭлементБлокировкиДанных"
// И ИмяПараметра = "ПолеПространстваБлокировок")
//Тогда
ВыбраннаяСтруктураТипа.ТипЯзыка = ИмяПараметра;
СтруктураТипаКонтекста.ТипЯзыка = ИмяПараметра;
//КонецЕсли;
КонецЕсли;
Если ВыбраннаяСтруктураТипа.ТипЯзыка = "ИмяМетода" Тогда
Если ЗначениеЗаполнено(мРодительскийКонтекст) Тогда
СтруктураТипаКонтекста.ИмяОбщегоТипа = "ОбщийМодуль";
СтруктураТипаКонтекста.Метаданные = Метаданные.ОбщиеМодули.Найти(мРодительскийКонтекст);
ВнутренняяТаблицаСлов = мПлатформа.ПолучитьВнутреннююТаблицуМетаданныхСлов(СтруктураТипаКонтекста,, "Метод",,,,,, Истина);
ВнутренняяТаблицаСлов.Колонки.Добавить("Определение");
ВнутренняяТаблицаСлов.ЗаполнитьЗначения("Метаданные", "Определение");
ЗагрузитьВТаблицуСловИзВнутреннейТаблицыСлов(ВнутренняяТаблицаСлов, ТаблицаСлов);
Иначе
КоллекцияЭлементовМД = Новый Массив;
Для Каждого КлючИЗначение Из ирКэш.ДоступныеОбщиеМодулиЛкс(Истина) Цикл
КоллекцияЭлементовМД.Добавить(КлючИЗначение.Значение);
КонецЦикла;
КонецЕсли;
ИначеЕсли ВыбраннаяСтруктураТипа.ТипЯзыка = "ИмяПредопределенногоЗначения" Тогда
КоллекцияЭлементовМД = Новый Массив;
Если ЗначениеЗаполнено(мРодительскийКонтекст) Тогда
ТаблицаТиповМетаОбъектов = ирКэш.ТипыМетаОбъектов(Ложь);
КорневойТип = ирОбщий.ПервыйФрагментЛкс(мРодительскийКонтекст);
КоллекцияЭлементовМД.Добавить("ПустаяСсылка");
Если Найти(мРодительскийКонтекст, ".") > 0 Тогда
Если ирКэш.НомерВерсииПлатформыЛкс() > 803004 Тогда
ОбъектМД = Метаданные.НайтиПоПолномуИмени(мРодительскийКонтекст);
#Если Сервер И Не Сервер Тогда
ОбъектМД = Метаданные.Справочники.Валюты;
#КонецЕсли
Для Каждого ИмяЭлемента Из ОбъектМД.ПолучитьИменаПредопределенных() Цикл
КоллекцияЭлементовМД.Добавить(ИмяЭлемента);
КонецЦикла;
КонецЕсли;
Иначе
МножественноеИмяМД = ирОбщий.МножественноеИмяМДЛкс(КорневойТип);
Если МножественноеИмяМД <> Неопределено Тогда
Для Каждого МетаОбъект Из Метаданные[МножественноеИмяМД] Цикл
КоллекцияЭлементовМД.Добавить(МетаОбъект);
КонецЦикла;
КонецЕсли;
КонецЕсли;
Иначе
Для Каждого СтрокаТипаМетаОбъекта Из ирКэш.ТипыМетаОбъектов(Ложь, Ложь, Ложь) Цикл
Если ирОбщий.ЛиКорневойТипОбъектаСПредопределеннымЛкс(СтрокаТипаМетаОбъекта.Единственное) Тогда
КоллекцияЭлементовМД.Добавить(СтрокаТипаМетаОбъекта.Единственное);
КонецЕсли;
КонецЦикла;
КонецЕсли;
ИначеЕсли Ложь
Или ВыбраннаяСтруктураТипа.ТипЯзыка = "Местоположение"
Или ВыбраннаяСтруктураТипа.ТипЯзыка = "ИмяФормы"
Тогда
Если ВыбраннаяСтруктураТипа.ТипЯзыка = "Местоположение" Тогда
ИмяДочернегоТипаМД = "Макет";
ИмКорневогоТипаМД = "ОбщийМакет";
Иначе
ИмяДочернегоТипаМД = "Форма";
ИмКорневогоТипаМД = "ОбщаяФорма";
КонецЕсли;
КоллекцияЭлементовМД = Новый Массив;
Если ЗначениеЗаполнено(мРодительскийКонтекст) Тогда
Если ирОбщий.СтрокиРавныЛкс(ИмКорневогоТипаМД, ирОбщий.ПервыйФрагментЛкс(мРодительскийКонтекст)) Тогда
Если СтрЧислоВхождений(мРодительскийКонтекст, ".") = 0 Тогда
Для Каждого МетаМакет Из Метаданные[ирОбщий.МножественноеИмяМДЛкс(ИмКорневогоТипаМД)] Цикл
КоллекцияЭлементовМД.Добавить(МетаМакет.Имя);
КонецЦикла;
КонецЕсли;
Иначе
Если СтрЧислоВхождений(мРодительскийКонтекст, ".") = 0 Тогда
КорневойТип = ирОбщий.ПервыйФрагментЛкс(мРодительскийКонтекст);
МножественноеИмяМД = ирОбщий.МножественноеИмяМДЛкс(КорневойТип);
Если МножественноеИмяМД <> Неопределено Тогда
Для Каждого МетаОбъект Из Метаданные[МножественноеИмяМД] Цикл
КоллекцияЭлементовМД.Добавить(МетаОбъект);
КонецЦикла;
КонецЕсли;
ИначеЕсли СтрЧислоВхождений(мРодительскийКонтекст, ".") = 1 Тогда
КоллекцияЭлементовМД.Добавить(ИмяДочернегоТипаМД);
ИначеЕсли СтрЧислоВхождений(мРодительскийКонтекст, ".") = 2 Тогда
ОбъектМД = Метаданные.НайтиПоПолномуИмени(ирОбщий.СтрокаБезПоследнегоФрагментаЛкс(мРодительскийКонтекст, "."));
#Если Сервер И Не Сервер Тогда
ОбъектМД = Метаданные.Справочники.Валюты;
#КонецЕсли
Для Каждого МетаМакет Из ОбъектМД[ирОбщий.МножественноеИмяМДЛкс(ИмяДочернегоТипаМД)] Цикл
КоллекцияЭлементовМД.Добавить(МетаМакет.Имя);
КонецЦикла;
КонецЕсли;
КонецЕсли;
Иначе
Для Каждого СтрокаТипаМетаОбъекта Из ирКэш.ТипыМетаОбъектов(Истина, Ложь) Цикл
НадоДобавить = ирОбщий.СтрокиРавныЛкс(ИмКорневогоТипаМД, СтрокаТипаМетаОбъекта.Единственное);
Если Не НадоДобавить Тогда
ОтборСвойств = Новый Структура("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка, НСлово, ТипСлова",
"ОбъектМетаданных: " + СтрокаТипаМетаОбъекта.Единственное, 0, "", НРег(ирОбщий.МножественноеИмяМДЛкс(ИмяДочернегоТипаМД)), "Свойство");
НадоДобавить = мПлатформа.ТаблицаКонтекстов.НайтиСтроки(ОтборСвойств).Количество() > 0;
КонецЕсли;
Если НадоДобавить Тогда
КоллекцияЭлементовМД.Добавить(СтрокаТипаМетаОбъекта.Единственное);
КонецЕсли;
КонецЦикла;
КонецЕсли;
ИначеЕсли ВыбраннаяСтруктураТипа.ТипЯзыка = "ПространствоБлокировки" Тогда
КоллекцияЭлементовМД = Новый Массив;
Если ЗначениеЗаполнено(мРодительскийКонтекст) Тогда
КорневойТип = ирОбщий.ПервыйФрагментЛкс(мРодительскийКонтекст);
ЭтоТаблицаВнешнейБД = ирОбщий.ЛиКорневойТипВнешнегоИсточникаДанныхЛкс(КорневойТип);
Если Истина
И ЭтоТаблицаВнешнейБД
И СтрЧислоВхождений(мРодительскийКонтекст, ".") = 1
Тогда
КоллекцияЭлементовМД.Добавить("Таблица");
ИначеЕсли Истина
И ЭтоТаблицаВнешнейБД
И СтрЧислоВхождений(мРодительскийКонтекст, ".") = 2
Тогда
Для Каждого МетаОбъект Из ирКэш.ОбъектМДПоПолномуИмениЛкс(ирОбщий.СтрокаБезПоследнегоФрагментаЛкс(мРодительскийКонтекст)).Таблицы Цикл
КоллекцияЭлементовМД.Добавить(МетаОбъект.Имя);
КонецЦикла;
ИначеЕсли Найти(мРодительскийКонтекст, ".") > 0 Тогда
Если ирОбщий.ЛиКорневойТипРегистраБДЛкс(КорневойТип) Тогда
КоллекцияЭлементовМД.Добавить("НаборЗаписей");
КонецЕсли;
Если ирОбщий.ЛиКорневойТипПоследовательностиЛкс(КорневойТип) Тогда
КоллекцияЭлементовМД.Добавить("Записи");
КонецЕсли;
Иначе
МножественноеИмяМД = ирОбщий.МножественноеИмяМДЛкс(КорневойТип);
Если МножественноеИмяМД <> Неопределено Тогда
Для Каждого МетаОбъект Из Метаданные[МножественноеИмяМД] Цикл
КоллекцияЭлементовМД.Добавить(МетаОбъект);
КонецЦикла;
КонецЕсли;
КонецЕсли;
Иначе
Для Каждого СтрокаТипаМетаОбъекта Из ирКэш.ТипыМетаОбъектов(Ложь, Ложь, Ложь) Цикл
КоллекцияЭлементовМД.Добавить(СтрокаТипаМетаОбъекта.Единственное);
КонецЦикла;
КонецЕсли;
ИначеЕсли ВыбраннаяСтруктураТипа.ТипЯзыка = "ПолеПространстваБлокировок" Тогда
ПространствоБлокировки = ВыбраннаяСтруктураТипа.Метаданные;
КорневойТип = ирОбщий.ПервыйФрагментЛкс(ПространствоБлокировки);
ОбъектМД = ирОбщий.ПолучитьМетаданныеЛкс(ПространствоБлокировки);
ЭтоТаблицаВнешнейБД = ирОбщий.ЛиКорневойТипВнешнегоИсточникаДанныхЛкс(КорневойТип);
Если ирОбщий.ЛиМетаданныеСсылочногоОбъектаЛкс(ОбъектМД) Тогда
КоллекцияЭлементовМД.Добавить("Ссылка");
Если ОбъектМД <> Неопределено Тогда
#Если Сервер И Не Сервер Тогда
ОбъектМД = Метаданные.Справочники.Пользователи;
#КонецЕсли
Для Каждого ПолеБлокировки Из ОбъектМД.ПоляБлокировкиДанных Цикл
КоллекцияЭлементовМД.Добавить(ПолеБлокировки.Имя);
КонецЦикла;
КонецЕсли;
Иначе
Если ОбъектМД <> Неопределено Тогда
#Если Сервер И Не Сервер Тогда
ОбъектМД = Метаданные.РегистрыСведений.КурсыВалют;
#КонецЕсли
Если Найти(ПространствоБлокировки, "." + "НаборЗаписей") > 0 Тогда
СтруктураКлюча = ирОбщий.СтруктураКлючаТаблицыБДЛкс(ирКэш.ИмяТаблицыИзМетаданныхЛкс(ОбъектМД.ПолноеИмя()), Ложь);
Иначе
СтруктураКлюча = Новый Структура;
Если ирОбщий.ЛиКорневойТипРегистраСведенийЛкс(КорневойТип) Тогда
Если ОбъектМД.ПериодичностьРегистраСведений <> Метаданные.СвойстваОбъектов.ПериодичностьРегистраСведений.Непериодический Тогда
СтруктураКлюча.Вставить(ирОбщий.ПеревестиСтроку("Период"));
КонецЕсли;
Если ОбъектМД.РежимЗаписи = Метаданные.СвойстваОбъектов.РежимЗаписиРегистра.ПодчинениеРегистратору Тогда
СтруктураКлюча.Вставить(ирОбщий.ПеревестиСтроку("Регистратор"));
КонецЕсли;
КонецЕсли;
Если ирОбщий.ЛиКорневойТипРегистраРасчетаЛкс(КорневойТип) Тогда
СтруктураКлюча.Вставить(ирОбщий.ПеревестиСтроку("ПериодРегистрации"));
СтруктураКлюча.Вставить(ирОбщий.ПеревестиСтроку("ПериодДействия"));
КонецЕсли;
Если ЭтоТаблицаВнешнейБД Тогда
Для Каждого ПолеКлюча Из ОбъектМД.ПоляКлюча Цикл
СтруктураКлюча.Вставить(ПолеКлюча.Имя);
КонецЦикла;
Иначе
Для Каждого Измерение Из ОбъектМД.Измерения Цикл
СтруктураКлюча.Вставить(Измерение.Имя);
КонецЦикла;
КонецЕсли;
КонецЕсли;
Для Каждого КлючИЗначение Из СтруктураКлюча Цикл
КоллекцияЭлементовМД.Добавить(КлючИЗначение.Ключ);
КонецЦикла;
КонецЕсли;
КонецЕсли;
ИначеЕсли Истина
И ирОбщий.СтрокиРавныЛкс(мИмяМетода, "COMОбъект")
И мНомерПараметра = 1
И ВыбраннаяСтруктураТипа.ИмяОбщегоТипа = "Неизвестный контекст"
Тогда
Если МассивКОМКлассов = Неопределено Тогда
Компьютер = "localhost";
МассивКОМКлассов = Новый Массив;
КаталогПриложений = Новый COMОбъект("COMAdmin.COMAdminCatalog");
КаталогПриложений.Connect(Компьютер);
Компоненты = КаталогПриложений.GetCollection("InprocServers");
Компоненты.Populate();
ДобавитьCOMКлассыВСписокСлов(МассивКомКлассов, Компоненты);
Компоненты = КаталогПриложений.GetCollection("WOWLegacyServers");
Компоненты.Populate();
ДобавитьCOMКлассыВСписокСлов(МассивКомКлассов, Компоненты);
Компоненты = КаталогПриложений.GetCollection("LegacyServers");
Компоненты.Populate();
ДобавитьCOMКлассыВСписокСлов(МассивКомКлассов, Компоненты);
КонецЕсли;
КоллекцияЭлементовМД = МассивКОМКлассов;
КонецЕсли;
СтруктураТипаКонтекста.ИмяОбщегоТипа = "Строка";
Для Каждого ЭлементКоллекцииМД Из КоллекцияЭлементовМД Цикл
СтрокаСлова = ТаблицаСлов.Добавить();
Если ТипЗнч(ЭлементКоллекцииМД) = Тип("Строка") Тогда
СтрокаСлова.Слово = ЭлементКоллекцииМД;
Иначе
СтрокаСлова.Слово = ЭлементКоллекцииМД.Имя;
КонецЕсли;
СтрокаСлова.ТипСлова = "Свойство";
СтрокаСлова.Определение = "Метаданные";
СтрокаСлова.ТипЗначения = "Строка";
КонецЦикла;
Иначе
ЗаполнитьЗначенияСвойств(СтруктураТипаКонтекста, ВыбраннаяСтруктураТипа);
КонецЕсли;
ТаблицаСтруктурТиповКонтекста.Очистить();
Попытка
ВнутренняяТаблицаСлов = мПлатформа.ПолучитьТаблицуСловСтруктурыТипа(СтруктураТипаКонтекста, ЯзыкПрограммы, Конфигурация, ВнешниеФункцииКомпоновкиДанных, ВычислятьТипыВСписке,,, ЛиСерверныйКонтекст);
ВыгрузкаТаблицыСлов = ТаблицаСлов.Выгрузить();
ЗагрузитьВТаблицуСловИзВнутреннейТаблицыСлов(ВнутренняяТаблицаСлов, ВыгрузкаТаблицыСлов);
Если СтруктураТипаКонтекста.ИмяОбщегоТипа = "Локальный" Тогда
ВыгрузкаТаблицыСлов.Индексы.Добавить("Слово, ТипСлова");
// Добавим слова из таблицы локального контекста
Для Каждого СтрокаСлова Из ТаблицаЛокальногоКонтекста Цикл
НоваяСтрока = мПлатформа.ДобавитьВТаблицуСлов(ВыгрузкаТаблицыСлов, СтрокаСлова.Слово, СтрокаСлова.ТипСлова);
//НоваяСтрока = ТаблицаСлов.Добавить();
//ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаСлова, "Слово, ТипСлова");
Если Не ЗначениеЗаполнено(НоваяСтрока.Определение) Тогда
НоваяСтрока.Определение = "Локальный";
КонецЕсли;
НоваяСтрока.ТипЗначения = ПредставлениеМассиваСтруктурТипов(СтрокаСлова.ТаблицаСтруктурТипов);
КонецЦикла;
КонецЕсли;
Если СтруктураТипаКонтекста.ИмяОбщегоТипа = "ВнешнийИсточникДанных.<Имя внешнего источника>.ВременнаяТаблица" Тогда
Для Каждого СтрокаВременнойТаблицы Из ДоступныеТаблицы.НайтиСтроки(Новый Структура("Тип", "ВременнаяТаблица")) Цикл
НоваяСтрока = мПлатформа.ДобавитьВТаблицуСлов(ВыгрузкаТаблицыСлов, СтрокаВременнойТаблицы.Имя, "Свойство",, "ВременнаяТаблица");
НоваяСтрока.Определение = "Локальный";
КонецЦикла;
КонецЕсли;
ТаблицаСлов.Загрузить(ВыгрузкаТаблицыСлов);
Исключение
Ошибка = ИнформацияОбОшибке();
Если Ошибка.Описание = "ОшибкаВычисленияВиртуальнойТаблицы" Тогда
Возврат;
КонецЕсли;
ВызватьИсключение;
КонецПопытки;
Для Каждого СтрокаСлова Из ТаблицаСлов Цикл
СтрокаСлова.НСлово = НРег(СтрокаСлова.Слово);
КонецЦикла;
СтруктураКлюча = Новый Структура("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка",
СтруктураТипаКонтекста.ИмяОбщегоТипа, ЯзыкПрограммы, СтруктураТипаКонтекста.ТипЯзыка);
Если Ложь
Или СтруктураТипаКонтекста.ИмяОбщегоТипа = "Неизвестный контекст"
Или СтруктураТипаКонтекста.ИмяОбщегоТипа = "Локальный"
Или мПлатформа.ТаблицаШаблоновКонтекстов.НайтиСтроки(СтруктураКлюча).Количество() > 0
Тогда
ЗаполнитьЛокальныеСвойстваИМетодыПоТексту(Ложь, СтруктураТипаКонтекста.ИмяОбщегоТипа = "Локальный", Истина, Ложь);
КонецЕсли;
Если Прав(мТекущееСлово, 1) = "(" Тогда
ЧистоеТекущееСлово = Лев(мТекущееСлово, СтрДлина(мТекущееСлово) - 1);
ТипТекущегоСлова = "Метод";
Иначе
ЧистоеТекущееСлово = мТекущееСлово;
ТипТекущегоСлова = "Свойство";
КонецЕсли;
КлючПоиска = Новый Структура("НСлово, Определение, ТипСлова", НРег(ЧистоеТекущееСлово), "Статистический", ТипТекущегоСлова);
НайденныеСтроки = ТаблицаСлов.НайтиСтроки(КлючПоиска);
Если НайденныеСтроки.Количество() > 0 Тогда
НайденнаяСтрока = НайденныеСтроки[0];
НайденнаяСтрока.Частота = НайденнаяСтрока.Частота - 1;
Если НайденнаяСтрока.Частота = 0 Тогда
ТаблицаСлов.Удалить(НайденнаяСтрока);
КонецЕсли;
КонецЕсли;
Если Истина
И Не ирОбщий.ВосстановитьЗначениеЛкс(ИмяКласса + ".ЛиОткрыватьПустойСписок") = Истина
И ТаблицаСлов.Количество() = 0
Тогда
Возврат;
КонецЕсли;
ТаблицаСлов.Свернуть("НСлово, Слово, ТипСлова, Определение, ТипЗначения", "Частота");
ТаблицаСлов.Сортировать("НСлово, ТипСлова, Определение, ТипЗначения, Частота");
КлючПоискаСтатистики = Новый Структура("ЯзыкПрограммы, ТипКонтекста", ЯзыкПрограммы, КонкретныйТип);
НайденныеСтроки = ТаблицаСтатистикиВыбора.НайтиСтроки(КлючПоискаСтатистики);
Для Каждого СтрокаРейтинга Из НайденныеСтроки Цикл
СтрокаСлова = ТаблицаСлов.Найти(СтрокаРейтинга.Слово, "Слово");
Если СтрокаСлова <> Неопределено Тогда
СтрокаСлова.Рейтинг = СтрокаРейтинга.Рейтинг;
КонецЕсли;
КонецЦикла;
Если мФормаАвтодополнение = Неопределено Тогда
Если Ложь
Или Не ирКэш.ЛиПлатформаWindowsЛкс()
Или ирОбщий.ЛиПерехватКлавиатурногоВводаЛкс()
Тогда
ИмяФормы = "Автодополнение";
Иначе
ИмяФормы = "АвтодополнениеCOM";
КонецЕсли;
мФормаАвтодополнение = ПолучитьФорму(ИмяФормы, ФормаВладелец);
мФормаАвтодополнение.КлючСохраненияПоложенияОкна = ЯзыкПрограммы;
КонецЕсли;
Попытка
мФормаАвтодополнение.СтруктураТипаКонтекста = СтруктураТипаКонтекста;
Исключение
ВызватьИсключение "Экземпляр формы автодополнения контекстной подсказки сломан ошибкой платформы. Переоткройте форму чтобы восстановить ее работу";
КонецПопытки;
Если ЗначениеЗаполнено(СтруктураТипаКонтекста.ТипЯзыка) Тогда
мФормаАвтодополнение.Контекст = СтруктураТипаКонтекста.ТипЯзыка;
Иначе
мФормаАвтодополнение.Контекст = мРодительскийКонтекст;
КонецЕсли;
мФормаАвтодополнение.ТекущееСлово = НачалоСлова;
мФормаАвтодополнение.ЗапомнитьПозициюКаретки();
ФормаВладелец.Активизировать();
//ирОбщий.Форма_АктивироватьОткрытьЛкс(ФормаВладелец); // https://www.hostedredmine.com/issues/911214
ПараметрЗакрытияПодсказки = мФормаАвтодополнение.ОткрытьМодально();
ирОбщий.УстановитьФокусВводаФормеЛкс(ФормаВладелец);
Если ПараметрЗакрытияПодсказки = Неопределено Тогда
Возврат;
КонецЕсли;
СтрокаРезультата = мФормаАвтодополнение.СтрокаСловаРезультата;
Если СтрокаРезультата = Неопределено Тогда
Возврат;
КонецЕсли;
Если Найти(НРег(СтрокаРезультата.Слово), НРег(НачалоСлова + КонецКонтекста)) = 1 Тогда
НеобрабатываемыйКонецСтроки = Сред(ТекущийКонецСтроки, СтрДлина(КонецКонтекста) + 1);
Иначе
НеобрабатываемыйКонецСтроки = ТекущийКонецСтроки;
RegExp.Pattern = "[" + шБуква + "\d]";
Если RegExp.Test(Лев(НеобрабатываемыйКонецСтроки, 1)) Тогда
НеобрабатываемыйКонецСтроки = " " + НеобрабатываемыйКонецСтроки;
КонецЕсли;
КонецЕсли;
Если Не мЭтоСтроковыйЛитерал И СтрокаРезультата.ТипСлова = "Метод" Тогда
Если Лев(КонецКонтекста, 1) = "(" Тогда
НеобрабатываемыйКонецСтроки = Сред(НеобрабатываемыйКонецСтроки, 2);
КонецЕсли;
СтрокаОкончания = "()";
Если Истина
И ПараметрЗакрытияПодсказки = Истина
И Прав(мТекущееСлово, 1) = "("
Тогда
СтрокаОкончания = "(";
Иначе
Если Истина
И ЯзыкПрограммы = 0
И Лев(НеобрабатываемыйКонецСтроки, 1) <> ";"
И СтрокаРезультата.ТипЗначения = ""
И СтрокаРезультата.Определение <> "Статистический"
//И ВычислятьТипыВСписке
Тогда
СтрокаОкончания = СтрокаОкончания + ";"
КонецЕсли;
КонецЕсли;
СмещениеКурсораВОкончании = СтрДлина(СтрокаОкончания);
Если ПараметрЗакрытияПодсказки = Истина Тогда
ТаблицаМетодовМодуля = мПлатформа.ПолучитьВнутреннююТаблицуМетаданныхСлов(СтруктураТипаКонтекста, СтрокаРезультата.Слово, "Метод");
Если ТаблицаМетодовМодуля.Количество() > 0 Тогда
СтрокаОписания = ТаблицаМетодовМодуля[0].ТаблицаСтруктурТипов[0].СтрокаОписания;
Если Ложь
Или (Истина
И ТипЗнч(СтрокаОписания) = Тип("COMОбъект")
И СтрокаОписания.Parameters.Count > 0)
Или (Истина
И ТипЗнч(СтрокаОписания) = Тип("СтрокаТаблицыЗначений")
И СтрокаОписания.Параметры <> Неопределено)
Тогда
СмещениеКурсораВОкончании = 1;
КонецЕсли;
Иначе
МассивОбщихТипов = мПлатформа.ПолучитьТаблицуОбщихТиповСтруктурыТипа(СтруктураТипаКонтекста);
КлючПоискаПараметров = Новый Структура("ТипКонтекста, Слово, ЯзыкПрограммы");
КлючПоискаПараметров.Слово = СтрокаРезультата.Слово;
КлючПоискаПараметров.ЯзыкПрограммы = ЯзыкПрограммы;
Для Каждого СтрокаОбщегоТипа Из МассивОбщихТипов Цикл
ОбщийТип = СтрокаОбщегоТипа.ИмяОбщегоТипа;
КлючПоискаПараметров.ТипКонтекста = ОбщийТип;
НайденныеСтроки = мПлатформа.ТаблицаПараметров.НайтиСтроки(КлючПоискаПараметров);
Если НайденныеСтроки.Количество() > 0 Тогда
СмещениеКурсораВОкончании = 1;
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЕсли;
Иначе
СтрокаОкончания = "";
СмещениеКурсораВОкончании = 0;
КонецЕсли;
// Обновим статистику выбора
Если Истина
И СтрокаРезультата.Определение <> "Локальный"
И СтрокаРезультата.Определение <> "Статистический"
Тогда
КлючПоиска = Новый Структура("ЯзыкПрограммы, ТипКонтекста, Слово", ЯзыкПрограммы, КонкретныйТип, СтрокаРезультата.Слово);
НайденныеСтроки = ТаблицаСтатистикиВыбора.НайтиСтроки(КлючПоиска);
Если НайденныеСтроки.Количество() > 0 Тогда
СтрокаСтатистикиВыбора = НайденныеСтроки[0];
Иначе
СтрокаСтатистикиВыбора = ТаблицаСтатистикиВыбора.Добавить();
ЗаполнитьЗначенияСвойств(СтрокаСтатистикиВыбора, КлючПоиска);
КонецЕсли;
СтрокаСтатистикиВыбора.Рейтинг = СтрокаСтатистикиВыбора.Рейтинг + 1;
КонецЕсли;
СтрокаДобавка = СтрокаРезультата.Слово + СтрокаОкончания;
Если мРодительскийКонтекст <> "" Тогда
СтрокаДобавка = мРодительскийКонтекст + "." + СтрокаДобавка;
КонецЕсли;
мРодительскийКонтекст = СтрокаДобавка;
Если Истина
И ПараметрЗакрытияПодсказки <> Истина
И (Ложь
Или Не ВычислятьТипыВСписке
Или СтрокаРезультата.ТипЗначения <> ""
Или СтрокаРезультата.Определение = "Статистический")
Тогда
СтрокаДобавка = СтрокаДобавка + ПараметрЗакрытияПодсказки;
мТекущееСлово = СтрокаРезультата.Слово;
Если ПараметрЗакрытияПодсказки = "." Тогда
Если СтрокаРезультата.Определение = "Статистический" Тогда
ТаблицаСтруктурТиповКонтекста = ОпределитьТипЗначенияКонтекста(мРодительскийКонтекст, " " + мТекстДляПоискаОпределения, мПредшествующийТекст, Истина);
Иначе
ТаблицаСтруктурТиповКонтекста = ОпределитьТипДочернегоКонтекста(ирОбщий.БыстрыйМассивЛкс(мФормаАвтодополнение.СтруктураТипаКонтекста),
мТекущееСлово, СтрокаРезультата.ТипСлова);
КонецЕсли;
КонецЕсли;
КонецЕсли;
ТекущееНачалоСтроки = Лев(ТекущееНачалоСтроки, мКонечнаяКолонка - 1 - СтрДлина(НачалоКонтекста)) + СтрокаДобавка;
ТекущаяСтрока = ТекущееНачалоСтроки + НеобрабатываемыйКонецСтроки;
Если ОригинальныйТекст = "" Тогда
ПолеТекстовогоДокумента.ВыделенныйТекст = "" + ТекущаяСтрока;
Иначе
Если ПолеТекстовогоДокумента.КоличествоСтрок() < мКонечнаяСтрока Тогда
ПолеТекстовогоДокумента.ДобавитьСтроку(ТекущаяСтрока);
Иначе
ПолеТекстовогоДокумента.ЗаменитьСтроку(мКонечнаяСтрока, ТекущаяСтрока);
КонецЕсли;
КонецЕсли;
УстановитьПризнакМодифицированностиФормы();
АвтоматическаяПодсказкаПоВызовуМетода = ирОбщий.ВосстановитьЗначениеЛкс(ИмяКласса + ".АвтоматическаяПодсказкаПоВызовуМетода");
Если АвтоматическаяПодсказкаПоВызовуМетода = Истина Тогда
мОткрытьСправкуПоПараметру = СмещениеКурсораВОкончании = 1;
КонецЕсли;
мКонечнаяКолонка = мКонечнаяКолонка + СтрДлина(СтрокаДобавка) - СтрДлина(НачалоКонтекста) - СтрДлина(СтрокаОкончания) + СмещениеКурсораВОкончании;
мНачальнаяКолонка = мКонечнаяКолонка;
НачалоКонтекста = мРодительскийКонтекст + ".";
НачалоСлова = "";
КонецЦикла;
КонецПроцедуры
Процедура ДобавитьCOMКлассыВСписокСлов(Знач КоллекцияКолонок, Знач Компоненты)
Для Каждого Класс Из Компоненты Цикл
Если Не ЗначениеЗаполнено(Класс.Name) Тогда
Продолжить;
КонецЕсли;
ИмяКласса = Класс.Name;
КоллекцияКолонок.Добавить(ИмяКласса);
КонецЦикла;
КонецПроцедуры
Процедура ЗагрузитьВТаблицуСловИзВнутреннейТаблицыСлов(Знач ВнутренняяТаблицаСлов, Знач ВыгрузкаТаблицыСлов)
Для Каждого ВнутренняяСтрокаСлова Из ВнутренняяТаблицаСлов Цикл
НоваяСтрока = ВыгрузкаТаблицыСлов.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, ВнутренняяСтрокаСлова);
ТаблицаСтруктурТипов = ВнутренняяСтрокаСлова.ТаблицаСтруктурТипов;
Если ТаблицаСтруктурТипов <> Неопределено Тогда
ОбновитьТипЗначенияИзТаблицыСтруктурТипов(НоваяСтрока, ТаблицаСтруктурТипов);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Процедура ОбновитьТипЗначенияИзТаблицыСтруктурТипов(Знач НоваяСтрока, Знач ТаблицаСтруктурТипов, ЗаменитьСуществующий = Истина) Экспорт
НовыйТипЗначения = ПредставлениеМассиваСтруктурТипов(ТаблицаСтруктурТипов);
Если Лев(НоваяСтрока.ТипЗначения, 2) = "??" Тогда
Если Истина
И ЗначениеЗаполнено(НовыйТипЗначения)
И Найти(НРег(НоваяСтрока.ТипЗначения), НРег(НовыйТипЗначения)) > 0
Тогда
НовыйТипЗначения = "";
КонецЕсли;
НоваяСтрока.ТипЗначения = СтрЗаменить(НоваяСтрока.ТипЗначения, "??", НовыйТипЗначения);
Если Не ЗначениеЗаполнено(НоваяСтрока.ТипЗначения) Тогда
НоваяСтрока.ТипЗначения = "?";
ИначеЕсли Лев(НоваяСтрока.ТипЗначения, 1) = "," Тогда
НоваяСтрока.ТипЗначения = СокрЛ(Сред(НоваяСтрока.ТипЗначения, 2));
КонецЕсли;
ИначеЕсли Ложь
Или ЗаменитьСуществующий
Или Не ЗначениеЗаполнено(НоваяСтрока.ТипЗначения)
Тогда
НоваяСтрока.ТипЗначения = НовыйТипЗначения;
КонецЕсли;
КонецПроцедуры
Процедура ПоискОбщегоМетода()
ФормаВыбора = ПолучитьФорму("ОбщиеМетоды");
ФормаВыбора.Открыть();
КонецПроцедуры
// Заменяет все символы табуляции в строке после первого печатного символа эквивалентным количеством пробелов.
//
// Параметры:
// Строка - Строка;
//
// Возвращаемое значение:
// Строка.
//
Функция ЗаменитьТабуляцииВСтроке(Знач Строка, ЛиТекущая = Ложь)
Табы = "";
А = 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);
КонецЕсли;
Возврат ПредставлениеТипаКонтекста;
КонецФункции
Процедура ОформитьЯчейкуТипаЗначения(ОформлениеСтроки, ДанныеСтроки) Экспорт
Если Истина
И ОформлениеСтроки.Ячейки.ТипЗначения.Видимость
И ЗначениеЗаполнено(ДанныеСтроки.ТипЗначения)
И Найти(ДанныеСтроки.ТипЗначения, ",") = 0
Тогда
Попытка
ОписаниеТипов = Новый ОписаниеТипов(ДанныеСтроки.ТипЗначения);
Исключение
ОписаниеТипов = Неопределено;
КонецПопытки;
Если ОписаниеТипов <> Неопределено Тогда
Типы = ОписаниеТипов.Типы();
Если Типы.Количество() > 0 Тогда
КартинкаТипа = ирОбщий.КартинкаТипаЛкс(Типы[0]);
Если КартинкаТипа <> Неопределено Тогда
ОформлениеСтроки.Ячейки.ТипЗначения.УстановитьКартинку(КартинкаТипа);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
/////////////////////////////////////////////////////////////////////////////////
// Шаблоны текста
// Выполняет шаблон текста.
//
// Параметры:
// Нет.
//
Процедура ВыполнитьШаблонТекста()
ВыделитьНачалоИКонецТекущейСтроки();
ПоследняяПозицияКурсора = 0;
КонечныйТекстЗамены = Неопределено;
ТаблицаШаблоновТекста = мПлатформа.ПолучитьТаблицуШаблоновТекста(ИмяКласса, мСообщенияЧерезПредупреждения);
Если Ложь
Или ТаблицаШаблоновТекста = Неопределено
Или ТаблицаШаблоновТекста.Количество() = 0
Тогда
КонечныйТекстЗамены = " ";
Иначе
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(СтрокаШаблона.Замена);
КонечныйТекстЗамены = "";
КешПараметров = Новый ТаблицаЗначений;
КешПараметров.Колонки.Добавить("ИмяПараметра");
КешПараметров.Колонки.Добавить("ЗначениеПараметра");
Для Каждого 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;
мКонечнаяКолонка = лКонечнаяКолонка;
мКонечнаяСтрока = лКонечнаяСтрока;
Иначе
Если ЧислоСтрокЗамены > 0 Тогда
мКонечнаяСтрока = мКонечнаяСтрока + ЧислоСтрокЗамены - 1;
КонецЕсли;
Если ЧислоСтрокЗамены > 1 Тогда
мКонечнаяКолонка = СтрДлина(НачалоСтроки + ТекущаяСтрокаВставки) + 1;
Иначе
мКонечнаяКолонка = мКонечнаяКолонка + СтрДлина(КонечныйТекстЗамены) - СтрДлина(НачалоКонтекста);
КонецЕсли;
КонецЕсли;
мНачальнаяСтрока = мКонечнаяСтрока;
мНачальнаяКолонка = мКонечнаяКолонка;
КонецЕсли;
КонецПроцедуры
//ирПортативный лФайл = Новый Файл(ИспользуемоеИмяФайла);
//ирПортативный ПолноеИмяФайлаБазовогоМодуля = Лев(лФайл.Путь, СтрДлина(лФайл.Путь) - СтрДлина("Модули\")) + "ирПортативный.epf";
//ирПортативный #Если Клиент Тогда
//ирПортативный Контейнер = Новый Структура();
//ирПортативный Оповестить("ирПолучитьБазовуюФорму", Контейнер);
//ирПортативный Если Не Контейнер.Свойство("ирПортативный", ирПортативный) Тогда
//ирПортативный ирПортативный = ВнешниеОбработки.ПолучитьФорму(ПолноеИмяФайлаБазовогоМодуля);
//ирПортативный ирПортативный.Открыть();
//ирПортативный КонецЕсли;
//ирПортативный #Иначе
//ирПортативный ирПортативный = ВнешниеОбработки.Создать(ПолноеИмяФайлаБазовогоМодуля, Ложь); // Это будет второй экземпляр объекта
//ирПортативный #КонецЕсли
//ирПортативный ирОбщий = ирПортативный.ПолучитьОбщийМодульЛкс("ирОбщий");
//ирПортативный ирКэш = ирПортативный.ПолучитьОбщийМодульЛкс("ирКэш");
//ирПортативный ирСервер = ирПортативный.ПолучитьОбщийМодульЛкс("ирСервер");
//ирПортативный ирПривилегированный = ирПортативный.ПолучитьОбщийМодульЛкс("ирПривилегированный");
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
мСообщенияЧерезПредупреждения = Ложь;
ТаблицаЛокальногоКонтекста = Новый ТаблицаЗначений;
ТаблицаЛокальногоКонтекста.Колонки.Добавить("Слово");
ТаблицаЛокальногоКонтекста.Колонки.Добавить("нСлово");
ТаблицаЛокальногоКонтекста.Колонки.Добавить("Глобальное", Новый ОписаниеТипов("Булево"));
ТаблицаЛокальногоКонтекста.Колонки.Добавить("ТипСлова");
ТаблицаЛокальногоКонтекста.Колонки.Добавить("ТипЗначения");
ТаблицаЛокальногоКонтекста.Колонки.Добавить("Метаданные");
ТаблицаЛокальногоКонтекста.Колонки.Добавить("ТаблицаСтруктурТипов");
ТаблицаЛокальногоКонтекста.Колонки.Добавить("Значение");
ТаблицаЛокальногоКонтекста.Индексы.Добавить("Слово, ТипСлова");
ПравилаВычисленияФункций = Новый ТаблицаЗначений;
ПравилаВычисленияФункций.Колонки.Добавить("Слово");
ПравилаВычисленияФункций.Колонки.Добавить("нСлово");
ПравилаВычисленияФункций.Колонки.Добавить("ТипКонтекста");
ПравилаВычисленияФункций.Колонки.Добавить("Правило");
ПравилаВычисленияФункций.Индексы.Добавить("Слово, ТипКонтекста");
МассивЗащитыОтРекурсии = Новый Массив;
мРазбиратьКонтекст = Истина;
мРасширенноеПолучениеМетаданныхADO = Ложь;
//мДоступныеТаблицыПолучены = Ложь;
мАвтоКонтекстнаяПомощь = Ложь;
СлужебноеПолеТекстовогоДокумента = мПлатформа.СлужебноеПолеТекстовогоДокумента;
мИменаОбщихТиповПоИменамКлассовCOM = Новый Соответствие;
ШиринаТабуляции = 4;
RegExp = мПлатформа.НовыйВычислительРегулярныхВыражений();
Если RegExp <> Неопределено Тогда
RegExp.IgnoreCase = Истина;
RegExp.MultiLine = Ложь;
КонецЕсли;
шБуква = мПлатформа.шБуква;
шИмя = мПлатформа.шИмя;
шЧисло = мПлатформа.шЧисло;
шИндекс = мПлатформа.шИндекс;
шСкобки = мПлатформа.шСкобки;
шРазделитель = мПлатформа.шРазделитель;
шКомментарий = мПлатформа.шКомментарий;
шНачалоЧисла = "\d+(?:\.)?\d*";
шНачалоСкобок = "(\((?:[^\)\(]*?(?:(?:\([^\)]*?\)[^\)\(]*?)*)*\))?)";
шИмяСкобки = "(?:" + шИмя + "|\?)" + шСкобки;
// Шаблоны программы
шДирективаПрепроцессора = "#[^\n]*\n";
шСтрокаПрограммы = """(?:(?:"""")|[^""\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 = "(?:(?:новый|New)" + "(?:" + шРазделитель + "(?:" + шИмя + "))?" + шРазделитель + "*" + "(?:\(""(?:" + шИмя+ "(?:\." + шИмя + ")*)""\))?"
+ "|(?:не" + шРазделитель + "+)?(?:" + шИмяСкобки + "?" + "(?:(?:\.(?:" + шИмя + ")" + шСкобки + "?)|" + шИндекс + ")*)|"
+ шЧисло + "|" + шСтрокаПрограммы + ")";
шВыражениеПрограммы = шРазделитель + "*" + шВыражениеПрограммы1 + "(?:" + шРазделитель + "*" + шОператорПрограммы + шРазделитель + "*"
+ шВыражениеПрограммы1 + ")*";
шНачалоВыраженияПрограммы = "(?:" + шРазделитель + "*(?:(?:"
+ шИмяСкобки + "?" + "(?:(?:\.(?:" + шИмя + ")" + шСкобки + "?)|" + шИндекс + ")*)|"
+ шЧисло + "|" + шСтрокаПрограммы + ")" + шРазделитель + "*" + шОператорПрограммы + ")*"
+ шРазделитель + "*(?:(?:" + шИмяСкобки + "?" + "(?:(?:\.(?:" + шИмя + ")" + шСкобки + "?)|" + шИндекс + ")*)|"
+ шНачалоЧисла + "|" + шНачалоСтрокиПрограммы + ")?";
шВызовМетодаПрограммы = "(?:" + шПредИмя + "(Новый|New)\s+)?(" + шИмяСкобки + "?" + "(?:(?:\.(?:" + шИмя + ")" + шСкобки + "?)|" + шИндекс + ")*?)"
+ "\(((?:(?:" + шВыражениеПрограммы + ")?" + шРазделитель + "*,)*)" + "(" + шНачалоВыраженияПрограммы + ")?" + шРазделитель + "*";
шПрисваивание = "(" + шРазделитель + "*=" + шРазделитель + "*((новый|New)" // Изменение для поддержки 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)" + шРазделитель + "+" + шВыражениеЗапроса + "|" + шРазделитель + "|,|\)|$)";
// К нему привязаны имена методов-трансляторов событий
ИмяКласса = "ПолеТекстаПрограммы";
мМаркерСлужебногоКомментария = "{: ";
СброситьРезультатРазбораПозицииВТексте();
#КонецЕсли