RDT1C/src/DataProcessors/ирКлсПолеТекстаПрограммы/Ext/ObjectModule.bsl
Администратор 6e3502634f .
2023-07-11 23:14:01 +03:00

7546 lines
540 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.

//ирПортативный Перем ирПортативный Экспорт;
//ирПортативный Перем ирОбщий Экспорт;
//ирПортативный Перем ирСервер Экспорт;
//ирПортативный Перем ирКэш Экспорт;
//ирПортативный Перем ирКлиент Экспорт;
Перем ИмяКласса Экспорт;
Перем СсылочнаяФормаКласса Экспорт;
Перем ДопКнопкиКомандныхПанелей Экспорт;
Перем СоответствиеЭУ Экспорт;
Перем мФормаАвтодополнение Экспорт;
Перем мФормаВызовМетода Экспорт;
Перем РегВыражение;
Перем СлужебноеПолеТекста Экспорт;
Перем мПарсер;
Перем ШиринаТабуляции;
Перем мПлатформа Экспорт;
Перем ТаблицаЛокальногоКонтекста;
Перем мНачальнаяСтрока Экспорт; // снаружи только для чтения
Перем мНачальнаяКолонка Экспорт; // снаружи только для чтения
Перем мКонечнаяСтрока Экспорт; // снаружи только для чтения
Перем мКонечнаяКолонка Экспорт; // снаружи только для чтения
Перем ТекущееНачалоСтроки;
Перем ОригинальнаяСтрока;
Перем ТекущийКонецСтроки;
Перем мНачалоКонтекста;
Перем мНачалоСлова;
Перем мКонецКонтекста;
Перем ОригинальныйТекст;
Перем ТекстБезКомментариевИОпасныхСтрок;
Перем мТекстДляПоискаОпределения Экспорт;
Перем мПозицияТекстаДляПоискаОпределения;
Перем мРодительскийКонтекст;
Перем мКонтекст;
Перем мВызовМетода Экспорт;
Перем мЭтоСтроковыйЛитерал Экспорт;
Перем мЭтоОбъявлениеПсевдонима Экспорт;
Перем мТекущееСлово;
Перем мПредшествующийТекст Экспорт;
Перем мНомерПараметра Экспорт;
Перем мИмяМетода Экспорт;
Перем мЭтоКонструктор Экспорт;
Перем мФактическиеПараметры Экспорт;
Перем мПервыйПараметр;
Перем мРазбиратьКонтекст;
Перем МассивЗащитыОтРекурсии;
Перем мАвтоКонтекстнаяПомощь Экспорт;
Перем мРасширенноеПолучениеМетаданныхADO Экспорт;
Перем ПравилаВычисленияФункций;
Перем мПоследнийРежимВызоваСправки;
Перем мИменаОбщихТиповПоИменамКлассовCOM;
Перем мДиалектSQL Экспорт;
Перем мДиалектыSQL Экспорт;
Перем мПараметрыДиалектаSQL Экспорт;
Перем мТерминалыЯзыкаЗапросов Экспорт;
Перем мПрефиксыПараметров Экспорт;
Перем мАнглийский1С;
Перем мМаркерСлужебногоКомментария Экспорт;
Перем мМаркерПорядкаОтладки Экспорт;
Перем мОткрытьСправкуПоПараметру Экспорт; // снаружи только для чтения
Перем мМодульМетаданных Экспорт;
Перем мСтруктурыТиповПодсказкиУдержания;
Перем МассивКомКлассов;
Перем мКонкретныйТипКонтекста;
Перем мСтруктураТипаКонтекста;
Перем мТолькоСсылочныеИменаТипов;
Перем мСоответствиеТиповСловHTML;
Перем РазрешеноСобытиеПередПоказомАвтодополнения;
Перем АвтоматическаяПодсказкаПоВызовуМетода Экспорт;
Перем АвтоматическаяПодсказкаАвтодополненияHTML Экспорт;
Перем ПоказыватьВсеТипыВСпискеАвтодополненияHTML Экспорт;
Перем ПредпочитатьHTMLРедакторКода Экспорт;
Перем мЭтоАвтоВызов;
Перем МаксСловНаходитьВТекстеПрограммы;
Перем мДоступныеПоляТаблиц;
Перем мМетодМодуля Экспорт;
Перем мПерваяСтрокаТелаМетодаМодуля Экспорт;
Перем мПоследняяСтрокаТелаМетодаМодуля Экспорт;
Перем мИсторияПереходов;
Перем шЧисло;
Перем шЛюбой;
Перем шБуква;
Перем шСтрокаПрограммы Экспорт;
Перем шНачалоСтрокиПрограммы;
Перем шСтрокаЗапроса;
Перем шИндекс;
Перем шСкобки;
Перем шНачалоСкобок;
Перем шИмя;
Перем шИмяСкобки;
Перем шПараметрЗапроса;
Перем шПредИмя;
Перем шРазделитель;
Перем шВыражениеПрограммы Экспорт;
Перем шВыражениеЗапроса;
Перем шВызовМетодаПрограммы;
Перем шВызовМетодаЗапроса;
Перем шИЗ;
Перем шОписаниеТаблицы;
Перем шОписаниеТаблицыСЗахватом;
Перем шПока;
Перем шЕсли;
Перем шВызватьИсключение;
Перем шНачалоТокена;
Перем шКонецТокена;
Перем шКомментарий;
Перем шПрисваивание;
Перем шПоискОписанияТаблицы;
// Инициализирует экземпляр класса.
//
// Параметры:
// *СтруктураЭкземляров - Структура, *Неопределено - содержит все объекты данного класса для данной формы;
// пФорма - Форма - владелец элементов управления;
// пПолеТекстовогоДокумента - ПолеТекста;
// *пКоманднаяПанель - КоманднаяПанель, *Неопределено - в конце которой будут размещены кнопки;
// *пЛиЯзыкЗапросов - Булево, *Ложь - режим языка запросов, иначе внутренний язык;
// *пМетодВыполнения - Строка, *"" - имя метода выполнения программного кода;
// *пКонтекстВыполнения - Тип, Запрос, Произвольный, *Неопределено - контекст выполнения программного кода или текста запроса;
// *пТипТекста - Строка, *"Алгоритм" - "Алгоритм" или "Выражение".
//
Процедура ИнициализироватьНеинтерактивно(пЯзыкПрограммы = 0, пМетодВыполнения = "", пКонтекстВыполнения = Неопределено, пТипТекста = "Алгоритм",
пКонфигурация = Неопределено, пПолеТекстовогоДокумента = Неопределено) Экспорт
ЭтотОбъект.ЯзыкПрограммы = пЯзыкПрограммы;
ЭтотОбъект.МетодВыполнения = пМетодВыполнения;
ЭтотОбъект.ТипТекста = пТипТекста;
Если пПолеТекстовогоДокумента <> Неопределено Тогда
#Если Клиент Тогда
ЭтотОбъект.ПолеТекста = ирКлиент.ОболочкаПоляТекстаЛкс(пПолеТекстовогоДокумента);
#КонецЕсли
КонецЕсли;
УстановитьКонфигурациюМетаданных(пКонфигурация, пКонтекстВыполнения);
ОчиститьТаблицуСловЛокальногоКонтекста();
мПрефиксыПараметров = мДиалектыSQL.Скопировать(, "ПрефиксПараметра");
мПрефиксыПараметров.Свернуть("ПрефиксПараметра");
мПрефиксыПараметров.ВыгрузитьКолонку(0);
Если ЯзыкПрограммы = 1 Тогда
Если КонтекстВыполнения = Неопределено Тогда
КонтекстВыполнения = Новый ПостроительЗапроса;
КонецЕсли;
шПредИмя = "(?:[^&#?" + шБуква + "\d\.]|^)";
ИнициироватьТерминалыЯзыкаЗапросов();
Иначе
шПредИмя = "(?:[^" + шБуква + "\d\.]|^)";
КонецЕсли;
Если МетодВыполнения = "" Тогда
ЭтотОбъект.МетодВыполнения = "ВыполнитьЛокально";
КонецЕсли;
Попытка
ПроверитьПрограммныйКод(, "");
Исключение
ирОбщий.СообщитьСУчетомМодальностиЛкс(ОписаниеОшибки());
ирОбщий.СообщитьСУчетомМодальностиЛкс("Задан неверный контекст выполнения программы. Будет использован общий контекст выполнения");
ЭтотОбъект.КонтекстВыполнения = ЭтотОбъект;
ЭтотОбъект.МетодВыполнения = "ВыполнитьПрограмму";
КонецПопытки;
КонецПроцедуры
Процедура ИнициироватьТерминалыЯзыкаЗапросов() Экспорт
Если мТерминалыЯзыкаЗапросов = Неопределено Тогда
мТерминалыЯзыкаЗапросов = Новый Соответствие;
мТерминалыЯзыкаЗапросов = ирОбщий.ТаблицаЗначенийИзТабличногоДокументаЛкс(мПлатформа.ПолучитьМакет("ТерминалыЯзыкаЗапросов"),,,, Истина);
мТерминалыЯзыкаЗапросов.Индексы.Добавить("Ключ");
мТерминалыЯзыкаЗапросов.Индексы.Добавить("МожетБытьПсевдонимом, Русский");
мТерминалыЯзыкаЗапросов.Индексы.Добавить("МожетБытьПсевдонимом, Английский");
КонецЕсли;
КонецПроцедуры
Процедура ПроверитьИнициировать() Экспорт
Если Не ЗначениеЗаполнено(ТипТекста) Тогда
ИнициализироватьНеинтерактивно();
КонецЕсли;
КонецПроцедуры
#Если Клиент Тогда
// Инициализирует экземпляр класса.
//
// Параметры:
// *СтруктураЭкземляров - Структура, *Неопределено - содержит все объекты данного класса для данной формы;
// пФорма - Форма - владелец элементов управления;
// пПолеТекстовогоДокумента - ПолеТекста;
// *пКоманднаяПанель - КоманднаяПанель, *Неопределено - в конце которой будут размещены кнопки;
// *пЛиЯзыкЗапросов - Булево, *Ложь - режим языка запросов, иначе внутренний язык;
// *пМетодВыполнения - Строка, *"" - имя метода выполнения программного кода;
// *пКонтекстВыполнения - Тип, Запрос, Произвольный, *Неопределено - контекст выполнения программного кода или текста запроса;
// *пТипТекста - Строка, *"Алгоритм" - "Алгоритм" или "Выражение".
//
Процедура Инициализировать(СтруктураЭкземляров = Неопределено, пФорма, пПолеТекстовогоДокумента, пКоманднаяПанель = Неопределено, пЯзыкПрограммы = 0, пМетодВыполнения = "",
пКонтекстВыполнения = Неопределено, пТипТекста = "Алгоритм", пКонфигурация = Неопределено, НеДобавлятьКнопкиЕслиСуществует = Ложь, Знач пЭтоЧастиныйЗапрос = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
мПлатформа.ПодключитьПерехватКлавиатуры();
СсылочнаяФормаКласса = Ложь;
КоманднаяПанель = пКоманднаяПанель;
УстановитьФормуВладельца(пФорма);
ЭтотОбъект.ЭтоЧастичныйЗапрос = пЭтоЧастиныйЗапрос;
ИнициализироватьНеинтерактивно(пЯзыкПрограммы, пМетодВыполнения, пКонтекстВыполнения, пТипТекста, пКонфигурация, пПолеТекстовогоДокумента);
Имя = ПолеТекста.ЭлементФормы.Имя;
Если КоманднаяПанель = Неопределено Тогда
КоманднаяПанель = ФормаВладелец.ЭлементыФормы.Добавить(Тип("КоманднаяПанель"), "КоманднаяПанель" + Имя, Ложь);
ПолеТекста.ЭлементФормы.КонтекстноеМеню = КоманднаяПанель;
КонецЕсли;
ФормаКласса = мПлатформа.ПолучитьМакетКомпоненты(ЭтотОбъект);
КнопкиМакета = ФормаКласса.ЭлементыФормы["КоманднаяПанель" + Формат(ЯзыкПрограммы, "ЧН=")].Кнопки;
Если ЯзыкПрограммы = 1 Тогда
КнопкаИсследоватьСхемуЗапроса = КнопкиМакета.Найти("ИсследоватьСхемуЗапроса");
КнопкаФорматировать = КнопкиМакета.Найти("Форматировать");
КнопкаВставитьИзБуфераОбменаВесьТекст = КнопкиМакета.Найти("ВставитьИзБуфераОбменаВесьТекст");
КнопкаКопироватьВБуферОбменаВесьТекст = КнопкиМакета.Найти("КопироватьВБуферОбменаВесьТекст");
КнопкиМакета = ирОбщий.МассивИзКоллекцииЛкс(КнопкиМакета);
Если Не ирКэш.ДоступнаСхемаЗапросаЛкс() Или ЭтоЧастичныйЗапрос Тогда
КнопкиМакета.Удалить(КнопкиМакета.Найти(КнопкаИсследоватьСхемуЗапроса));
КонецЕсли;
Если ЭтоЧастичныйЗапрос Тогда
КнопкиМакета.Удалить(КнопкиМакета.Найти(КнопкаФорматировать));
КнопкиМакета.Удалить(КнопкиМакета.Найти(КнопкаВставитьИзБуфераОбменаВесьТекст));
КнопкиМакета.Удалить(КнопкиМакета.Найти(КнопкаКопироватьВБуферОбменаВесьТекст));
КонецЕсли;
КонецЕсли;
ирКлиент.ДобавитьКнопкиКоманднойПанелиКомпонентыЛкс(ЭтотОбъект, КнопкиМакета, КоманднаяПанель,,, НеДобавлятьКнопкиЕслиСуществует);
КнопкиМакета = ФормаКласса.ЭлементыФормы.КоманднаяПанельОбщая.Кнопки;
Если пКоманднаяПанель = Неопределено Тогда
КнопкаУстановитьФокус = КнопкиМакета.Найти("УстановитьФокус");
КнопкиМакета = ирОбщий.МассивИзКоллекцииЛкс(КнопкиМакета);
КнопкиМакета.Удалить(КнопкиМакета.Найти(КнопкаУстановитьФокус));
КонецЕсли;
ирКлиент.ДобавитьКнопкиКоманднойПанелиКомпонентыЛкс(ЭтотОбъект, КнопкиМакета, КоманднаяПанель,,, НеДобавлятьКнопкиЕслиСуществует);
Попытка
ФормаВладелец.ПодключитьОбработчикОжидания("КлсПолеТекстаПрограммыАвтоОбновитьСправку", 100);;
ФормаВладелец.ОтключитьОбработчикОжидания("КлсПолеТекстаПрограммыАвтоОбновитьСправку");
Исключение
//КоманднаяПанель.Кнопки.Удалить(ирКлиент.КнопкаКоманднойПанелиЭкземпляраКомпонентыЛкс(ЭтотОбъект, "АвтоКонтекстнаяПомощь"));
Кнопка = ирКлиент.КнопкаКоманднойПанелиЭкземпляраКомпонентыЛкс(ЭтотОбъект, "АвтоКонтекстнаяПомощь");
Кнопка.Доступность = Ложь;
КонецПопытки;
//ФайлШаблоновТекста = ирОбщий.ВосстановитьЗначениеЛкс(ИмяКласса + ".ФайлШаблоновТекста");
//Если Ложь
// Или ТипЗнч(ФайлШаблоновТекста) <> Тип("Строка")
// Или ФайлШаблоновТекста = ""
//Тогда
// КнопкаВыполнитьШаблон = ирКлиент.КнопкаКоманднойПанелиЭкземпляраКомпонентыЛкс(ЭтотОбъект, "ВыполнитьШаблон");
// КнопкаВыполнитьШаблон.Доступность = Ложь;
// КнопкаВыполнитьШаблон.СочетаниеКлавиш = Новый СочетаниеКлавиш(Клавиша.Нет); // Чтобы освободить сочетание клавиш
//КонецЕсли;
Если СтруктураЭкземляров <> Неопределено Тогда
СтруктураЭкземляров.Вставить(Имя, ЭтотОбъект);
КонецЕсли;
КонецПроцедуры
Процедура ИнициализироватьСсылочно(пФорма, мСвойстваФормы, пПолеТекстовогоДокумента, пКоманднаяПанель = Неопределено,
пЯзыкПрограммы = 0, пМетодВыполнения = "", пКонтекстВыполнения = Неопределено, пТипТекста = "Алгоритм",
пКонфигурация = Неопределено) Экспорт
ИнициализироватьНеинтерактивно(пЯзыкПрограммы, пМетодВыполнения, пКонтекстВыполнения, пТипТекста);
СсылочнаяФормаКласса = Истина;
ПолеТекста = пПолеТекстовогоДокумента;
КоманднаяПанель = пКоманднаяПанель;
Имя = ПолеТекста.Имя;
УстановитьФормуВладельца(пФорма);
Если КоманднаяПанель = Неопределено Тогда
КоманднаяПанель = ФормаВладелец.ЭлементыФормы.Добавить(Тип("КоманднаяПанель"), "КоманднаяПанель" + Имя, Ложь);
ПолеТекста.КонтекстноеМеню = КоманднаяПанель;
КонецЕсли;
мСвойстваФормы.Компоненты.Добавить(ЭтотОбъект);
ФормаКласса = Вычислить("глПолучитьФормуКомпоненты(ЭтотОбъект)");
СоответствиеЭУ = Новый Соответствие;
СоответствиеЭУ.Вставить(ПолеТекста, ФормаКласса.ЭлементыФормы.ПолеТекста);
СоответствиеЭУ.Вставить(КоманднаяПанель, ФормаКласса.ЭлементыФормы.КП_Компонента);
КонецПроцедуры // Инициализировать()
Процедура УстановитьФормуВладельца(пФорма) Экспорт
ФормаВладелец = пФорма;
КонецПроцедуры // УстановитьВладельца()
// Освобождает ресурсы занятые экземпляром класса.
// Самое главное - очистить ссылки на формы и объекты БД.
//
// Параметры:
// Нет.
//
Процедура Уничтожить() Экспорт
Для Каждого Реквизит Из Метаданные().Реквизиты Цикл
ЭтотОбъект[Реквизит.Имя] = Неопределено;
КонецЦикла;
Если мФормаВызовМетода <> Неопределено Тогда
ЭтотОбъект.мФормаВызовМетода.ВладелецФормы = Неопределено;
КонецЕсли;
ЭтотОбъект.мФормаВызовМетода = Неопределено;
Если ЭтотОбъект.мФормаАвтодополнение <> Неопределено Тогда
ЭтотОбъект.мФормаАвтодополнение.ВладелецФормы = Неопределено;
КонецЕсли;
ЭтотОбъект.мФормаАвтодополнение = Неопределено;
ОчиститьТаблицуСловЛокальногоКонтекста();
СохранитьСтатистикуВыбораПодсказки();
КонецПроцедуры
Процедура СохранитьСтатистикуВыбораПодсказки() Экспорт
ирОбщий.СохранитьЗначениеЛкс("ирПлатформа.ТаблицаСтатистикиВыбора", мПлатформа.ТаблицаСтатистикиВыбора);
КонецПроцедуры
Процедура ВнешнееСобытиеОбъекта(Источник, Событие, Данные) Экспорт
Если Источник <> "KeyboardHook" Тогда
Возврат;
КонецЕсли;
Если Ложь
Или ФормаВладелец = Неопределено
Или Не ирКлиент.Форма_ВводДоступенЛкс(ФормаВладелец) // Для поля HTML это затратно
Тогда
Возврат;
КонецЕсли;
ирКлиент.Форма_ВнешнееСобытиеЛкс(ФормаВладелец, Источник, Событие, Данные);
//Формат строки данные:
//Первые 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);
Иначе
Символ = "";
КонецЕсли;
КодыКлавиш = ирКэш.КодыКлавишЛкс();
Если ФормаВладелец.ТекущийЭлемент = ПолеТекста.ЭлементФормы Тогда
Если Ложь
Или Найти(Данные, КодыКлавиш["CTRL+ALT+Space"]) = 1
Тогда
#Если Сервер И Не Сервер Тогда
ОткрытьАвтодополнение();
#КонецЕсли
ВыполнитьКоманду("ОткрытьАвтодополнение", Данные);
ИначеЕсли Найти(Данные, КодыКлавиш["ALT+F2"]) = 1 Тогда
// Антибаг платформы 8.3.19+ не обновляются пометки закладок
ирКлиент.ОткрытьИЗакрытьПустуюФормуЛкс();
ИначеЕсли Найти(Данные, КодыКлавиш["CTRL+[-]"]) = 1 Тогда
#Если Сервер И Не Сервер Тогда
ВернутьсяИзПерехода();
#КонецЕсли
ВыполнитьКоманду("ВернутьсяИзПерехода", Данные);
ИначеЕсли Ложь
Или Найти(Данные, КодыКлавиш["CTRL"]) = 1 // Мультиметка00452941 Так будет много лишних точек
Или Найти(Данные, КодыКлавиш["CTRL+ALT+P"]) = 1
Или Найти(Данные, КодыКлавиш["CTRL+F3"]) = 1
Или Найти(Данные, КодыКлавиш["CTRL+F"]) = 1
Или Найти(Данные, КодыКлавиш["CTRL+G"]) = 1
Или Найти(Данные, КодыКлавиш["F3"]) = 1
Тогда
// Запоминание срабатывает после системной обработки сочетания!
ЗапомнитьИсточникПерехода();
ИначеЕсли Ложь
Или Найти(Данные, КодыКлавиш["CTRL+C"]) = 1
Или Найти(Данные, КодыКлавиш["CTRL+V"]) = 1
Тогда
// Мультиметка00452941 Удаляем избыточные точки истории
УдалитьПоследнийПереходИзИстории();
КонецЕсли;
// Подсказка по вызову метода
Если Ложь
Или ЛиДоступноОткрытиеСвободнойФормы()
Или ТипЗнч(ПолеТекста.ЭлементФормы) = Тип("ПолеТекстовогоДокумента")
Тогда
Если Ложь
Или Найти(Данные, КодыКлавиш["CTRL+SHIFT+Space"]) = 1
Тогда
ВыполнитьКоманду("ПодсказатьПараметр");
КонецЕсли;
ФормаВызовМетода = ФормаВызовМетода();
БылаОткрыта = ФормаВызовМетода.Открыта();
Если Истина
И Не БылаОткрыта
И ЛиДоступноОткрытиеСвободнойФормы()
И (Ложь
Или Символ = "("
Или Символ = ",")
Тогда
Если АвтоматическаяПодсказкаПоВызовуМетода() Тогда
ВыполнитьКоманду("ПодсказатьПараметрАвто");
КонецЕсли;
КонецЕсли;
Если БылаОткрыта Тогда
ОбновитьПодсказкуПоВызовуМетода();
КонецЕсли;
Если Ложь
Или Найти(Данные, КодыКлавиш["ALT+Up"]) = 1
Или Найти(Данные, КодыКлавиш["ALT+Down"]) = 1
//Или Найти(Данные, КодыКлавиш["CTRL+Up"]) = 1
//Или Найти(Данные, КодыКлавиш["CTRL+Down"]) = 1
Или Найти(Данные, КодыКлавиш["Esc"]) = 1 // Работает только в поле HTML документа. В остальных местах платформа делает полный перехват
Тогда
ФормаВызовМетода.ВнешнееСобытие(Источник, Событие, Данные);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Процедура ОбновитьПодсказкуПоВызовуМетода()
ФормаВызовМетода = ФормаВызовМетода();
Если Не ФормаВызовМетода.Открыта() Или Не ФормаВызовМетода.Автообновление Тогда
Возврат;
КонецЕсли;
ФормаВызовМетода.ПараметрСтруктураТипаКонтекста = Неопределено;
//Если Форма.Открыта() Тогда
ФормаВызовМетода.ОбновитьИлиЗакрытьФорму(, Истина);
//КонецЕсли;
КонецПроцедуры
Функция ЛиМожноЗакрытьФорму() Экспорт
ФормаВызовМетода = ФормаВызовМетода();
Если ФормаВызовМетода.Открыта() Тогда
ФормаВызовМетода.Закрыть();
Результат = Ложь;
Иначе
Результат = Истина;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ФормаВызовМетода() Экспорт
Если мФормаВызовМетода = Неопределено Тогда
мФормаВызовМетода = ПолучитьФорму("ВызовМетода", ФормаВладелец);
КонецЕсли;
Возврат мФормаВызовМетода;
КонецФункции
Процедура ОткрытьПрикрепленнуюФормуВызоваМетода(Знач СтруктураТипаКонтекста, Знач ЭтаФорма = Неопределено) Экспорт
ТаблицаВладелец = СтруктураТипаКонтекста.СтрокаОписания.Владелец();
#Если Сервер И Не Сервер Тогда
ТаблицаВладелец = Новый ТаблицаЗначений;
#КонецЕсли
ФормаВызовМетода = ПолучитьФорму("ВызовМетода", ЭтаФорма, "Прикрепленное");
Если Не ФормаВызовМетода.Открыта() Тогда
ФормаВызовМетода.СоединяемоеОкно = Истина;
ФормаВызовМетода.КлючСохраненияПоложенияОкна = ФормаВызовМетода.КлючУникальности;
ФормаВызовМетода.СостояниеОкна = ВариантСостоянияОкна.Прикрепленное;
ФормаВызовМетода.ПоложениеПрикрепленногоОкна = ВариантПрикрепленияОкна.Низ;
КонецЕсли;
ФормаВызовМетода.ПараметрСтруктураТипаКонтекста = СтруктураТипаКонтекста;
Если ФормаВызовМетода.Открыта() Тогда
ФормаВызовМетода.ОбновитьИлиЗакрытьФорму();
Иначе
ФормаВызовМетода.Открыть();
КонецЕсли;
КонецПроцедуры
// Получает номер текущей строки в тексте (по конечной границе выделения).
//
// Параметры:
// Нет.
//
// Возвращаемое значение:
// Число.
//
Функция ПолучитьНомерТекущейСтроки(Начальной = Ложь) Экспорт
Если ПолеТекста <> Неопределено Тогда
ПолеТекста.ПолучитьГраницыВыделения(мНачальнаяСтрока, мНачальнаяКолонка, мКонечнаяСтрока, мКонечнаяКолонка);
Если Начальной Тогда
Возврат мНачальнаяСтрока;
Иначе
Возврат мКонечнаяСтрока;
КонецЕсли;
Иначе
Возврат Неопределено;
КонецЕсли;
КонецФункции // ПолучитьНомерТекущейСтроки()
// Получает текущее объектное выражение (на котором установлен курсор).
//
// Параметры:
// Нет.
//
// Возвращаемое значение:
// Строка - объектное выражение, в котором находится курсов.
//
Функция ТекущееОбъектноеВыражение(НомерСтроки = 0, НомерКолонки = 0, выхЕстьТочкаСправа = Ложь, КончитьОбработкуКоманды = Истина, Знач ЭтоПродолжениеОбработки = Ложь) Экспорт
Если ирОбщий.ПроверитьПлатформаНеWindowsЛкс(,, Истина) Тогда
Возврат Неопределено;
КонецЕсли;
мПлатформа.ИнициализацияОписанияМетодовИСвойств();
Если ЭтоПродолжениеОбработки Тогда
ПродолжитьОбработкуКоманды();
Иначе
КончитьОбработкуКоманды();
КонецЕсли;
Если НомерСтроки > ПолеТекста.КоличествоСтрок() Тогда
Возврат Неопределено;
КонецЕсли;
РазобратьТекущийКонтекст(, выхЕстьТочкаСправа,, НомерСтроки, НомерКолонки);
Если КончитьОбработкуКоманды Тогда
КончитьОбработкуКоманды();
КонецЕсли;
Если мЭтоСтроковыйЛитерал Тогда
мКонтекст = "";
КонецЕсли;
Возврат мКонтекст;
КонецФункции
// Получает текущее контекст параметра.
//
// Параметры:
// Нет.
//
// Возвращаемое значение:
// Структура -
// "ОбъектноеВыражение"
// "НомерПараметра"
//
Функция ПолучитьТекущийКонтекстПараметра() Экспорт
КончитьОбработкуКоманды();
РазобратьТекущийКонтекст(,, Истина);
КончитьОбработкуКоманды();
СтруктураРезультата = Новый Структура;
СтруктураРезультата.Вставить("ОбъектноеВыражение", мВызовМетода);
СтруктураРезультата.Вставить("ПервыйПараметр", мПервыйПараметр);
СтруктураРезультата.Вставить("НомерПараметра", мНомерПараметра);
Возврат СтруктураРезультата;
КонецФункции
// Разбирает контекст метода.
//
// Параметры:
// Нет.
//
Функция ТекущийКонтекстМетода()
РегВыражение.Global = Истина;
мКонтекст = "";
ОригинальныйТекст = ПолеТекста.ПолучитьТекст();
СлужебноеПолеТекста.УстановитьТекст(ОригинальныйТекст);
ПредшествующийТекст = "";
СледующийТекст = "";
МаксЧислоПредшествующихСтрок = 20; // Чтобы снизить вероятность зацикливания при вычислении рег.выражения
Если мКонечнаяСтрока > 1 Тогда
СлужебноеПолеТекста.УстановитьГраницыВыделения(Макс(1, мКонечнаяСтрока - МаксЧислоПредшествующихСтрок - 1), 1, мКонечнаяСтрока - 1, 333);
ПредшествующийТекст = СлужебноеПолеТекста.ВыделенныйТекст;
КонецЕсли;
МаксНомерСтроки = Мин(СлужебноеПолеТекста.КоличествоСтрок(), мКонечнаяСтрока + 100);
Если Истина
И МаксНомерСтроки > 0
И МаксНомерСтроки <= СлужебноеПолеТекста.КоличествоСтрок()
Тогда
СлужебноеПолеТекста.УстановитьГраницыВыделения(мКонечнаяСтрока + 1, 1, МаксНомерСтроки, 333);
СледующийТекст = СлужебноеПолеТекста.ВыделенныйТекст;
КонецЕсли;
ТекстДоКурсора = ПредшествующийТекст + ТекущееНачалоСтроки; // Так почему то иногда возникало смещение на 1 символ
ТекстПослеКурсора = ТекущийКонецСтроки + Символы.ПС + СледующийТекст;
Если мЭтоСтроковыйЛитерал Тогда
ТекстДоКурсора = ТекстДоКурсора + """";
ТекстПослеКурсора = """" + ТекстПослеКурсора;
Если ирОбщий.ЛиВнутриСтроковогоЛитералаЛкс(ТекстПослеКурсора) Тогда
ТекстПослеКурсора = ТекстПослеКурсора + """";
КонецЕсли;
КонецЕсли;
Если ЯзыкПрограммы = 0 Тогда
ШаблонПараметра = "(?:" + шВыражениеПрограммы + ")?" + шРазделитель + "*";
Иначе
ШаблонПараметра = "(?:" + шВыражениеЗапроса + ")?" + шРазделитель + "*";
КонецЕсли;
РегВыражение.Global = Ложь;
РегВыражение.MultiLine = Ложь;
РегВыражение.Pattern = "^(?:" + ШаблонПараметра + ",)*" + ШаблонПараметра + "\)";
Результат = РегВыражение.НайтиВхождения(ТекстПослеКурсора);
Если Результат.Количество() > 0 Тогда
//КонецВыражения = Лев(ТекстПослеКурсора, Результат[0].Length);
КонецВыражения = Результат[0].Value;
КонецЕсли;
РегВыражение.Global = Ложь;
РегВыражение.MultiLine = Ложь;
Если ЯзыкПрограммы = 1 Тогда
РегВыражение.Pattern = шВызовМетодаЗапроса + "$";
Иначе
РегВыражение.Pattern = шВызовМетодаПрограммы + "$";
КонецЕсли;
Результат = РегВыражение.НайтиВхождения(ТекстДоКурсора + Лев(КонецВыражения, СтрДлина(КонецВыражения) - 1) + ",");
//Результат = RegExp.НайтиВхождения(Лев(ОригинальныйТекст, СтрДлина(ТекстДоКурсора)+ СтрДлина(КонецВыражения) - 1) + ","); // Отрезаем последний символ зачем то
мФактическиеПараметры = Новый Массив;
Если Результат.Количество() > 0 Тогда
//ПоследнееВхождение = Результат[Результат.Количество() - 1];
ПоследнееВхождение = Результат[0];
//ДлинаТекста = СтрДлина(ОригинальныйТекст);
//Попытка
// СлужебноеПолеТекста.УстановитьГраницыВыделения(ПоследнееВхождение.FirstIndex + 1,
// Мин(ДлинаТекста, ПоследнееВхождение.FirstIndex + 1 + ПоследнееВхождение.Length));
//Исключение
// СлужебноеПолеТекста.УстановитьГраницыВыделения(ПоследнееВхождение.FirstIndex + 1,
// Мин(ДлинаТекста, ПоследнееВхождение.FirstIndex + 1 + ПоследнееВхождение.Length - 1)); // -1 надо делать из-за бага платформы (она не дает выделить последний символ в тексте)
//КонецПопытки;
//СлужебноеПолеТекста.ПолучитьГраницыВыделения(мНачальнаяСтрока, мНачальнаяКолонка, мКонечнаяСтрока, мКонечнаяКолонка);
мВызовМетода = ПоследнееВхождение.SubMatches(1) + "(";
ТекстПараметров = ПоследнееВхождение.SubMatches(5) + ПоследнееВхождение.SubMatches(14);
мЭтоКонструктор = ЗначениеЗаполнено(ПоследнееВхождение.SubMatches(0));
РегВыражение.Global = Истина;
Если ЯзыкПрограммы = 0 Тогда
ШаблонПараметра = "(" + шВыражениеПрограммы + ")?" ;
Иначе
ШаблонПараметра = "(" + шВыражениеЗапроса + ")?";
КонецЕсли;
РегВыражение.Pattern = ШаблонПараметра + шРазделитель + "*,";
Результат = РегВыражение.НайтиВхождения(ТекстПараметров);
ЛокальнаяПозицияКурсора = СтрДлина(ТекстПараметров) + 1 - СтрДлина(КонецВыражения);
Счетчик = 0;
Для Каждого Вхождение Из Результат Цикл
Счетчик = Счетчик + 1;
ПозицияВхождения = Вхождение.FirstIndex;
Если Истина
И (ПозицияВхождения + 1) <= ЛокальнаяПозицияКурсора
И (ПозицияВхождения + Вхождение.Length + 1) >= ЛокальнаяПозицияКурсора
Тогда
мНомерПараметра = Счетчик;
КонецЕсли;
мФактическиеПараметры.Добавить(СокрЛП(Вхождение.SubMatches(0)));
КонецЦикла;
Если мФактическиеПараметры.Количество() > 0 Тогда
мПервыйПараметр = мФактическиеПараметры[0];
КонецЕсли;
мИмяМетода = ирОбщий.ПервыйФрагментЛкс(ирОбщий.ПоследнийФрагментЛкс(мВызовМетода), "(");
СтруктураРезультата = Новый Структура;
СтруктураРезультата.Вставить("ОбъектноеВыражение", мВызовМетода);
СтруктураРезультата.Вставить("ОригинальныйТекст", Лев(ПоследнееВхождение.Value, СтрДлина(ПоследнееВхождение.Value) - 1) + ")");
СтруктураРезультата.Вставить("МассивПараметров", мФактическиеПараметры);
СтруктураРезультата.Вставить("НомерПараметра", мНомерПараметра);
СтруктураРезультата.Вставить("ЭтоКонструктор", мЭтоКонструктор);
Возврат СтруктураРезультата;
Иначе
Возврат Неопределено;
КонецЕсли;
КонецФункции
// Разбирает контекст метода.
//
// Параметры:
// Нет.
//
Функция УстановитьТекущийКонтекстМетода(НовыйТекст) Экспорт
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
ПолеТекста.УстановитьГраницыВыделения(мНачальнаяСтрока, мНачальнаяКолонка, мКонечнаяСтрока, мКонечнаяКолонка);
ВыделенныйТекст(НовыйТекст);
ПолеТекста.УстановитьГраницыВыделения(мНачальнаяСтрока, мНачальнаяКолонка, мНачальнаяСтрока, мНачальнаяКолонка,, ФормаВладелец);
КонецФункции
// Разбирает контекст УК.
//
// Параметры:
// Нет.
//
Функция ПолучитьТекущийКонтекстУК() Экспорт
мПлатформа.ИнициализацияОписанияМетодовИСвойств();
ПолеТекста.ПолучитьГраницыВыделения(мНачальнаяСтрока, мНачальнаяКолонка, мКонечнаяСтрока, мКонечнаяКолонка);
РегВыражение.Global = Истина;
ПрочитатьНачалоИКонецТекущейСтроки();
ИмяСтруктурыПараметров = "";
ОригинальныйТекст = ПолеТекста.ПолучитьТекст();
СлужебноеПолеТекста.УстановитьТекст(ОригинальныйТекст);
мПредшествующийТекст = "";
СледующийТекст = "";
Если мКонечнаяСтрока > 1 Тогда
СлужебноеПолеТекста.УстановитьГраницыВыделения(1, 1, мКонечнаяСтрока - 1, 333);
мПредшествующийТекст = СлужебноеПолеТекста.ВыделенныйТекст;
КонецЕсли;
МаксНомерСтроки = Мин(СлужебноеПолеТекста.КоличествоСтрок(), мКонечнаяСтрока + 100);
Если Истина
И МаксНомерСтроки > 0
И МаксНомерСтроки <= СлужебноеПолеТекста.КоличествоСтрок()
Тогда
СлужебноеПолеТекста.УстановитьГраницыВыделения(мКонечнаяСтрока + 1, 1, МаксНомерСтроки, 333);
СледующийТекст = СлужебноеПолеТекста.ВыделенныйТекст;
КонецЕсли;
ТекстДоКурсора = мПредшествующийТекст + Символы.ПС + ТекущееНачалоСтроки;
ТекстПослеКурсора = ТекущийКонецСтроки + Символы.ПС + СледующийТекст;
ШаблонУК = "(" + шИмя + ")" + шРазделитель + "*=" + шРазделитель + "*УК\((" + шИмя + ")\)";
РегВыражение.Global = Ложь;
РегВыражение.MultiLine = Ложь;
РегВыражение.Pattern = "^" + "(" + шРазделитель + "*)" + ШаблонУК;
Результат = РегВыражение.НайтиВхождения(ТекущееНачалоСтроки + ТекстПослеКурсора);
Если Результат.Количество() > 0 Тогда
Смещение = Результат[0].SubMatches(0);
ИмяСтруктурыПараметров = Результат[0].SubMatches(1);
МассивПараметров = Новый Массив;
МассивПараметров.Добавить(Результат[0].SubMatches(2));
Иначе
Возврат Неопределено;
КонецЕсли;
ШаблонПараметра = шРазделитель + "*" + ИмяСтруктурыПараметров + "\.(" + шИмя + ")" + шРазделитель + "*="
+ шРазделитель + "*(" + шВыражениеПрограммы + ")?" + шРазделитель + "*" + ";";
РегВыражение.Pattern = "^" + "(" + шРазделитель + "*)" + ШаблонУК + ";" + "((?:" + ШаблонПараметра + шРазделитель + "*" + ")*)";
Результат = РегВыражение.НайтиВхождения(ТекущееНачалоСтроки + ТекстПослеКурсора);
Если Результат.Количество() > 0 Тогда
ПолныйТекстВыражения = Результат[0].Value;
Иначе
Возврат Неопределено;
КонецЕсли;
//RegExp.Global = Ложь;
РегВыражение.MultiLine = Ложь;
РегВыражение.Pattern = ШаблонУК + ";" + "((?:" + ШаблонПараметра + шРазделитель + "*" + ")*)$";
Результат = РегВыражение.НайтиВхождения(мПредшествующийТекст + ПолныйТекстВыражения);
СтруктураПараметров = Новый Структура;
Если Результат.Количество() > 0 Тогда
ПоследнееВхождение = Результат[Результат.Количество() - 1];
Попытка
СлужебноеПолеТекста.УстановитьГраницыВыделения(ПоследнееВхождение.FirstIndex + 1,
ПоследнееВхождение.FirstIndex + 1 + ПоследнееВхождение.Length);
Исключение
СлужебноеПолеТекста.УстановитьГраницыВыделения(ПоследнееВхождение.FirstIndex + 1,
ПоследнееВхождение.FirstIndex + 1 + ПоследнееВхождение.Length - 1); // -1 надо делать из-за бага платформы (она не дает выделить последний символ в тексте)
КонецПопытки;
СлужебноеПолеТекста.ПолучитьГраницыВыделения(мНачальнаяСтрока, мНачальнаяКолонка, мКонечнаяСтрока, мКонечнаяКолонка);
//ИмяСтруктурыПараметров = Результат[0].SubMatches(0);
ТекстПараметров = ПоследнееВхождение.SubMatches(2);
РегВыражение.Global = Истина;
РегВыражение.Pattern = ШаблонПараметра;
Результат = РегВыражение.НайтиВхождения(ТекстПараметров);
//ЛокальнаяПозицияКурсора = СтрДлина(ТекстПараметров) - СтрДлина(ПолныйТекстВыражения);
Счетчик = 0;
Для Каждого Вхождение Из Результат Цикл
Счетчик = Счетчик + 1;
//Если Истина
// И (Вхождение.FirstIndex + 1) <= ЛокальнаяПозицияКурсора
// И (Вхождение.FirstIndex + Вхождение.Length + 1) >= ЛокальнаяПозицияКурсора
//Тогда
// мНомерПараметра = Счетчик;
//КонецЕсли;
СтруктураПараметров.Вставить(СокрЛП(Вхождение.SubMatches(0)), СокрЛП(Вхождение.SubMatches(1)));
КонецЦикла;
СтруктураРезультата = Новый Структура;
СтруктураРезультата.Вставить("ИмяСтруктурыПараметров", ИмяСтруктурыПараметров);
СтруктураРезультата.Вставить("МассивПараметров", МассивПараметров);
СтруктураРезультата.Вставить("ОригинальныйТекст", ПоследнееВхождение.Value);
СтруктураРезультата.Вставить("Смещение", Смещение);
СтруктураРезультата.Вставить("СтруктураПараметров", СтруктураПараметров);
СтруктураРезультата.Вставить("НомерПараметра", мНомерПараметра);
Возврат СтруктураРезультата;
Иначе
Возврат Неопределено;
КонецЕсли;
КонецФункции
Процедура ПродолжитьОбработкуКоманды() Экспорт
мРазбиратьКонтекст = Ложь;
КонецПроцедуры
// Вызывается в конце обработки команды.
//
// Параметры:
// Нет.
//
Процедура КончитьОбработкуКоманды() Экспорт
мРазбиратьКонтекст = Истина;
КонецПроцедуры
// Находит первое вхождение слова в тексте. Если слово найдено, устанавливается выделение и фокус.
//
// Параметры:
// СтрокаПоиска - -
// СловоЦеликом - Булево, "Переменная" -
// ПолеТекста - -
//
// Возвращаемое значение:
// - Булево - была ли найдена и выделена строка
//
Функция НайтиПоказатьСловоВТексте(СтрокаПоиска, Знач СловоЦеликомИлиШаблон = Истина, ПолеТекста = Неопределено, УстановитьФокус = Ложь, ИскатьСНачала = Ложь, Знач ВТекущемБлоке = Ложь) Экспорт
Если ПолеТекста = Неопределено Тогда
ПолеТекста = ЭтотОбъект.ПолеТекста;
КонецЕсли;
Если СловоЦеликомИлиШаблон = "Переменная" Тогда
СловоЦеликомИлиШаблон = ШаблонШаблонаПоискаСлова();
КонецЕсли;
Если мМетодМодуля <> Неопределено И ВТекущемБлоке Тогда
НачалоОбласти = мМетодМодуля.ПозицияОпределения;
КонецОбласти = мМетодМодуля.ПозицияТела + СтрДлина(мМетодМодуля.Тело);
Иначе
НачалоОбласти = Неопределено;
КонецОбласти = Неопределено;
КонецЕсли;
Если УстановитьФокус Тогда
ЗапомнитьИсточникПерехода();
КонецЕсли;
Результат = ирКлиент.НайтиПоказатьФрагментВПолеТекстаЛкс(ФормаВладелец, ПолеТекста, СтрокаПоиска, СловоЦеликомИлиШаблон, ИскатьСНачала,,, НачалоОбласти, КонецОбласти);
Если УстановитьФокус Тогда
УстановитьФокус();
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ШаблонШаблонаПоискаСлова(ЛиМетод = Ложь) Экспорт
Шаблон = шСтрокаПрограммы + "|(?:Новый|New)\s*#Слово#|(^|[^_a-zа-яё0-9"".])(#Слово#)\s*";
Если ЛиМетод Тогда
Возврат Шаблон + "\(";
Иначе
Возврат Шаблон + "($|[^_a-zа-яё0-9\(])";
КонецЕсли;
КонецФункции
// Вставляет в текущую позицию поля текстового документа ссылку на объект БД.
//
// Параметры:
// ЗначенияСвойствНового - Структура - если параметр будет добавлен, то к его строке будут применены эти значения свойств;
// <Параметр2> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>.
//
// Возвращаемое значение:
// - <Тип.Вид> - <описание значения>
// <продолжение описания значения>;
// <Значение2> - <Тип.Вид> - <описание значения>
// <продолжение описания значения>.
//
Функция ВставитьСсылкуНаОбъектБД(ТабличноеПолеПараметров, ИмяКолонкиИмени = "Имя", ИмяКолонкиЗначения = "Значение", ИмяСтруктурыПараметров = "",
ОбновитьКопиюСвойстваВНижнемРегистре = Ложь, НачальноеЗначениеВыбора = Неопределено, РазрешитьВыбор = Истина, ВставитьВТекст = Истина) Экспорт
ТаблицаПараметров = ТабличноеПолеПараметров.Значение;
ТекущееОбъектноеВыражение = ТекущееОбъектноеВыражение();
Если Истина
И РазрешитьВыбор
И НачальноеЗначениеВыбора = Неопределено
И ВставитьВТекст
Тогда
Если Ложь
Или ЯзыкПрограммы = 0
Или Лев(ТекущееОбъектноеВыражение, 1) = "&"
Тогда
ИмяПараметра = ТекущееОбъектноеВыражение;
Если ЯзыкПрограммы = 1 Тогда
ИмяПараметра = Сред(ИмяПараметра, 2);
Иначе
Если Истина
И Не ПустаяСтрока(ИмяСтруктурыПараметров)
И Найти(НРег(ИмяПараметра), НРег(ИмяСтруктурыПараметров) + ".") = 1
Тогда
ИмяПараметра = Сред(ИмяПараметра, СтрДлина(ИмяСтруктурыПараметров) + 2);
КонецЕсли;
КонецЕсли;
СтрокаНайденногоПараметра = ТаблицаПараметров.Найти(ИмяПараметра, ИмяКолонкиИмени);
Если СтрокаНайденногоПараметра <> Неопределено Тогда
Ответ = Вопрос("Использовать тип и значение выделенного в тексте параметра?", РежимДиалогаВопрос.ДаНет);
Если Ответ = КодВозвратаДиалога.Да Тогда
ЗначениеПараметра = СтрокаНайденногоПараметра[ИмяКолонкиЗначения];
Если ирОбщий.ЛиСсылкаНаОбъектБДЛкс(ЗначениеПараметра, Ложь) Тогда
НачальноеЗначениеВыбора = ЗначениеПараметра;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
//Если ЗначениеЗаполнено(НачальноеЗначениеВыбора) Тогда
Если НачальноеЗначениеВыбора <> Неопределено Тогда
ТипСсылки = ТипЗнч(НачальноеЗначениеВыбора);
Если Не ирОбщий.ЛиТипСсылкиБДЛкс(ТипСсылки, Ложь) Тогда
Возврат Неопределено;
КонецЕсли;
КонецЕсли;
Если РазрешитьВыбор Тогда
ВыделитьТекущееОбъектноеВыражение();
КонецЕсли;
Если ТипСсылки = Неопределено И Не ЗначениеЗаполнено(ТекущееОбъектноеВыражение) Тогда
СтруктураТипаКонтекста = ПолучитьСтруктуруТипаСправаОтРавно();
Если СтруктураТипаКонтекста <> Неопределено Тогда
Если ТипЗнч(СтруктураТипаКонтекста.Метаданные) = Тип("ОбъектМетаданных") Тогда
ТипСсылки = Тип(ирОбщий.ИмяТипаИзПолногоИмениМДЛкс(СтруктураТипаКонтекста.Метаданные.ПолноеИмя()));
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если РазрешитьВыбор И ТипСсылки = Неопределено Тогда
ПараметрыВыбораМетаданных = Новый Структура;
ПараметрыВыбораМетаданных.Вставить("ОтображатьСсылочныеОбъекты", Истина);
ПараметрыВыбораМетаданных.Вставить("ОтображатьПеречисления", Истина);
ПараметрыВыбораМетаданных.Вставить("ОтображатьВнешниеИсточникиДанных", Истина);
ФормаВыбора = ирКлиент.ПолучитьФормуВыбораОбъектаМетаданныхСтруктуройЛкс(ФормаВладелец,,, ПараметрыВыбораМетаданных);
Результат = ФормаВыбора.ОткрытьМодально();
Если Результат = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
ТипСсылки = Тип(ирОбщий.ИмяТипаИзПолногоИмениМДЛкс(Результат.ПолноеИмяОбъекта));
КонецЕсли;
Если НачальноеЗначениеВыбора = Неопределено Тогда
НачальноеЗначениеВыбора = Новый (ТипСсылки);
КонецЕсли;
Если РазрешитьВыбор Тогда
ЗначениеПараметра = ирКлиент.ВыбратьСсылкуЛкс(ТипСсылки, НачальноеЗначениеВыбора);
УстановитьФокус();
Иначе
ЗначениеПараметра = НачальноеЗначениеВыбора;
КонецЕсли;
Если ЗначениеПараметра = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
Если ТабличноеПолеПараметров.ИзменяетДанные Тогда
ФормаВладелец.Модифицированность = Истина;
КонецЕсли;
СтрокаПараметра = ирОбщий.НайтиДобавитьПараметрСсылкуВТаблицуЛкс(ТаблицаПараметров, ИмяКолонкиИмени, ИмяКолонкиЗначения, ЗначениеПараметра,, ОбновитьКопиюСвойстваВНижнемРегистре);
Если ВставитьВТекст Тогда
ТекстВставки = СтрокаПараметра[ИмяКолонкиИмени];
Если Ложь
Или ЯзыкПрограммы = 1
Или ЯзыкПрограммы = 2
Тогда
ТекстВставки = "&" + ТекстВставки;
КонецЕсли;
Если ЯзыкПрограммы = 0 Тогда
Если Не ПустаяСтрока(ИмяСтруктурыПараметров) Тогда
ТекстВставки = ИмяСтруктурыПараметров + "." + ТекстВставки;
КонецЕсли;
КонецЕсли;
ВыделенныйТекст(ТекстВставки);
КонецЕсли;
Возврат СтрокаПараметра;
КонецФункции
// Обрабатывает нажатие на кнопки
//
// Параметры:
// Кнопка - Кнопка.
//
// Возвращаемое значение:
// Булево - результат проверки.
//
Функция Нажатие(Кнопка, ОбновитьКонтекст = Ложь) Экспорт
Перем Результат;
Команда = ирОбщий.ПоследнийФрагментЛкс(Кнопка.Имя, "_");
Если Команда = "АвтоКонтекстнаяПомощь" Тогда
УстановитьАвтоКонтекстнаяПомощь(Не Кнопка.Пометка);
КонецЕсли;
Результат = ВыполнитьКоманду(Команда,, ОбновитьКонтекст);
Возврат Результат;
КонецФункции
Функция ВыполнитьКоманду(Знач Команда, Знач КодКлавиши = "", ОбновитьКонтекст = Истина)
КончитьОбработкуКоманды();
Если ОбновитьКонтекст Тогда
ФормаВладелец.КлсПолеТекстаПрограммыОбновитьКонтекст(ЭтотОбъект);
КонецЕсли;
Результат = Неопределено;
Попытка
мПлатформа.ИнициализацияОписанияМетодовИСвойств();
ПолеТекста.ПолучитьГраницыВыделения(мНачальнаяСтрока, мНачальнаяКолонка, мКонечнаяСтрока, мКонечнаяКолонка);
мОткрытьСправкуПоПараметру = Ложь;
Если Команда = "ОткрытьАвтодополнение" Тогда
ОткрытьАвтодополнение(КодКлавиши);
ИначеЕсли Команда = "ПоискОбщегоМетода" Тогда
ПоискОбщегоМетода();
ИначеЕсли Команда = "НайтиВызовыМетода" Тогда
НайтиВызовыМетода();
ИначеЕсли Команда = "ЗаменитьТабуляции" Тогда
ЗаменитьТабуляции();
ИначеЕсли Команда = "ВыделитьСлово" Тогда
// В платформе есть аналогичная системная команда, но для HTML редактора нужна.
ВыделитьТекущееСлово();
ИначеЕсли Команда = "ПереименоватьСлово" Тогда
ПереименоватьСлово();
ИначеЕсли Команда = "СравнитьТекст" Тогда
ВариантСинтаксиса = Неопределено;
Если ЯзыкПрограммы = 0 Тогда
ВариантСинтаксиса = "ВстроенныйЯзык";
ИначеЕсли ЯзыкПрограммы = 1 Тогда
ВариантСинтаксиса = "ЯзыкЗапросов";
ИначеЕсли ЯзыкПрограммы = 2 Тогда
ВариантСинтаксиса = "ЯзыкКомпоновки";
КонецЕсли;
ирКлиент.ЗапомнитьСодержимоеЭлементаФормыДляСравненияЛкс(ФормаВладелец, ПолеТекста, ВариантСинтаксиса);
ИначеЕсли Истина
И ЯзыкПрограммы = 1
И Команда = "УдалитьПереносы"
Тогда
УдалитьПереносы();
ИначеЕсли Команда = "КонструкторЗапросов1С" Тогда
Результат = ВызватьКонструкторЗапросов(Ложь);
ИначеЕсли Команда = "КонструкторЗапросовИР" Тогда
Результат = ВызватьКонструкторЗапросов(Истина);
ИначеЕсли Команда = "КонструкторЗапросов" Тогда
Результат = ВызватьКонструкторЗапросов();
ИначеЕсли Команда = "ВставитьИзБуфераОбменаВесьТекст" Тогда
ирКлиент.УстановитьТекстСОткатомЛкс(ПолеТекста, ирКлиент.ТекстИзБуфераОбменаОСЛкс());
ИначеЕсли Команда = "КопироватьВБуферОбменаВесьТекст" Тогда
ирКлиент.ТекстВБуферОбменаОСЛкс(ПолеТекста.ПолучитьТекст(), ?(ЯзыкПрограммы = 0, "ВстроенныйЯзык", "ЯзыкЗапросов"));
ИначеЕсли Команда = "КопироватьВБуферОбменаТекстВВидеКода" Тогда
КопироватьВБуферОбменаТекстВВидеКода();
ИначеЕсли Команда = "Закомментировать" Тогда
Закомментировать();
ИначеЕсли Команда = "Раскомментировать" Тогда
Раскомментировать();
ИначеЕсли Команда = "РедакторСтроковогоЛитерала" Тогда
Результат = ОткрытьРедакторСтроковогоЛитерала();
ИначеЕсли Команда = "ИсследоватьСхемуЗапроса" Тогда
Если ПроверитьПрограммныйКод() Тогда
СхемаЗапроса = Вычислить("Новый схемаЗапроса");
#Если Сервер И Не Сервер Тогда
СхемаЗапроса = Новый СхемаЗапроса;
#КонецЕсли
Если ирКэш.НомерВерсииПлатформыЛкс() >= 803014 Тогда
СхемаЗапроса.РежимКомпоновкиДанных = РежимКомпоновкиДанных;
КонецЕсли;
СхемаЗапроса.УстановитьТекстЗапроса(ПолеТекста.ПолучитьТекст());
ирОбщий.ИсследоватьЛкс(СхемаЗапроса);
КонецЕсли;
ИначеЕсли Команда = "ПерейтиКОпределению" Тогда
ПерейтиКОпределению();
Результат = мТекущееСлово;
ИначеЕсли Команда = "Проверить" Тогда
ПроверитьПрограммныйКод(Истина);
ИначеЕсли Команда = "УстановитьФокус" Тогда
УстановитьФокус();
ИначеЕсли Команда = "Форматировать" Тогда
ФорматироватьТекст();
ИначеЕсли Истина
И ЯзыкПрограммы = 0
И Команда = "Выполнить"
Тогда
ВыполнитьПрограммныйКод();
ИначеЕсли Команда = "КонтекстныйСинтаксПомощник" Тогда
мПоследнийРежимВызоваСправки = Команда;
ОткрытьКонтекстнуюСправку(, ФормаВладелец);
ИначеЕсли Команда = "СинтаксПомощник" Тогда
ОткрытьСправкуПоЯзыкуПрограммы();
ИначеЕсли Команда = "ПодсказатьПараметр" Тогда
мПоследнийРежимВызоваСправки = Команда;
ОткрытьСправкуПоПараметру();
ИначеЕсли Команда = "ПодсказатьПараметрАвто" Тогда
#Если ТолстыйКлиентОбычноеПриложение Тогда
Если ФормаВладелец.ТекущийЭлемент = ПолеТекста.ЭлементФормы Тогда
ОткрытьСправкуПоПараметру(, Ложь);
КонецЕсли;
#КонецЕсли
ИначеЕсли Команда = "Настройка" Тогда
ПолучитьФорму("ФормаНастройки", ФормаВладелец).Открыть();
ИначеЕсли Команда = "ВыполнитьШаблон" Тогда
ВыполнитьШаблонТекста();
ИначеЕсли Команда = "КонструкторОписанияТипов" Тогда
КонструкторОписанияТипов();
ИначеЕсли Команда = "НайтиСледующееHTML" Тогда
НайтиСледующееHTML();
ИначеЕсли Команда = "НайтиПредыдущееHTML" Тогда
НайтиПредыдущееHTML();
ИначеЕсли Команда = "ЗаменитьВхожденияHTML" Тогда
ЗаменитьВхожденияHTML();
ИначеЕсли Команда = "СочетанияКлавишHTML" Тогда
СочетанияКлавишHTML();
ИначеЕсли Команда = "КонструкторФорматнойСтроки" Тогда
КонструкторФорматнойСтроки();
ИначеЕсли Команда = "ВернутьсяИзПерехода" Тогда
ВернутьсяИзПерехода();
КонецЕсли;
Если Ложь
Или Команда = "ВыделитьСлово"
Или Команда = "Форматировать"
Или Команда = "ВыполнитьШаблон"
Или Команда = "ОткрытьАвтодополнение"
Или Команда = "ПодсказатьПараметрАвто"
Или Команда = "ЗаменитьТабуляции"
Или Команда = "УдалитьПереносы"
Или Команда = "ПерейтиКОпределению"
Или Команда = "КонструкторЗапросов1С"
Или Команда = "КонструкторЗапросовИР"
Или Команда = "КонструкторЗапросов"
Или Команда = "РедакторСтроковогоЛитерала"
Тогда
Если Результат <> Ложь Тогда
УстановитьГраницыВыделения();
Если мОткрытьСправкуПоПараметру Тогда
#Если ТолстыйКлиентОбычноеПриложение Тогда
// Антибаг 8.3.19+ https://www.hostedredmine.com/issues/956304
//ОткрытьСправкуПоПараметру(, Ложь);
ФормаПодсказкаПоПараметрам = ФормаВызовМетода();
ФормаПодсказкаПоПараметрам.ПодключитьОбработчикОжидания("ОткрытьОтложенно", 0.1, Истина);
#КонецЕсли
КонецЕсли;
КонецЕсли;
КонецЕсли;
Исключение
КончитьОбработкуКоманды();
ВосстановитьФокусВвода();
ВызватьИсключение;
КонецПопытки;
КончитьОбработкуКоманды();
ВосстановитьФокусВвода();
Возврат Результат;
КонецФункции
Процедура УстановитьГраницыВыделения() Экспорт
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
//Структура = ПолеТекста.ВыделениеДвумерное();
//Если Ложь
// // Экономная установка для подавления угасания мигания каретки из-за антибага платформы https://www.hostedredmine.com/issues/936432
// // Но баг платформы ЗаменитьСтроку() вызывает фактическое выделение всего предшествующего текста иногда без возможности получить настоящие границы выделения на 8.3.18 https://www.hostedredmine.com/issues/936821
// Или Структура.НачальнаяСтрока <> мНачальнаяСтрока
// Или Структура.НачальнаяКолонка <> мНачальнаяКолонка
// Или Структура.КонечнаяСтрока <> мКонечнаяСтрока
// Или Структура.КонечнаяКолонка <> мКонечнаяКолонка
//Тогда
ПолеТекста.УстановитьГраницыВыделения(мНачальнаяСтрока, мНачальнаяКолонка, мКонечнаяСтрока, мКонечнаяКолонка,, ФормаВладелец);
//КонецЕсли;
КонецПроцедуры
Процедура ФорматироватьТекст()
ВыделенныйТекст = ВыделенныйТекст();
ТолькоВыделенныйТекст = СтрДлина(ВыделенныйТекст) > 1;
Если ТолькоВыделенныйТекст Тогда
ТекстЗапроса = ВыделенныйТекст;
Иначе
ТекстЗапроса = ПолеТекста.ПолучитьТекст();
КонецЕсли;
КонструкторЗапроса = ПолучитьФорму("КонструкторЗапроса");
КонструкторЗапроса.ВосстановитьНастройкиФормы();
Попытка
Если ЗагрузитьТекстВКонструктор(ТекстЗапроса, КонструкторЗапроса) Тогда
НовыйТекст = КонструкторЗапроса.СобратьПолныйТекст(, Истина);
Если Не ТолькоВыделенныйТекст Тогда
ВыделитьВесьТекст();
КонецЕсли;
ЗаменитьВыделенныйТекстЗапросаСоСнятиемВыделения(НовыйТекст);
КонецЕсли;
Исключение
Сообщить(КраткоеПредставлениеОшибки(ИнформацияОбОшибке()));
Возврат;
КонецПопытки;
КонецПроцедуры
Функция ВыделенныйТекст(Знач НовыйТекст = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
Результат = ПолеТекста.ВыделенныйТекст(НовыйТекст);
Если НовыйТекст <> Неопределено Тогда
ПослеУстановкиВыделенногоМногострочногоТекста();
КонецЕсли;
Возврат Результат;
КонецФункции
Процедура ДобавитьВТекстЗапросаОтборыПоСтрокеРезультата(ТекущаяСтрокаРезультата, ИменаПолей = Неопределено) Экспорт
ТекстЗапроса = ПолеТекста.ПолучитьТекст();
КонструкторЗапроса = ПолучитьФорму("КонструкторЗапроса");
КонструкторЗапроса.ВосстановитьНастройкиФормы();
Если КонструкторЗапроса.ЗагрузитьТекстВКонструктор(ТекстЗапроса, КонструкторЗапроса) Тогда
КонструкторЗапроса.ЗагрузитьПоследнийЗапрос();
КонструкторЗапроса.ДобавитьОтборыПоСтрокеРезультата(ТекущаяСтрокаРезультата,, ИменаПолей);
ВыделитьВесьТекст();
ВыделенныйТекст(КонструкторЗапроса.СобратьПолныйТекст(, Истина));
КонструкторЗапроса.ЗагрузитьПараметрыВОбъект();
ПослеУстановкиВыделенногоМногострочногоТекста();
КонецЕсли;
КонецПроцедуры
Процедура ВыделитьВесьТекст(ПолеТекста = Неопределено) Экспорт
Если ПолеТекста = Неопределено Тогда
ПолеТекста = ЭтотОбъект.ПолеТекста;
КонецЕсли;
КоличествоСтрок = ПолеТекста.КоличествоСтрок();
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
ПолеТекста.УстановитьГраницыВыделения(1, 1, Макс(1, КоличествоСтрок), СтрДлина(ПолеТекста.ПолучитьСтроку(КоличествоСтрок) + 1),, ФормаВладелец);
КонецПроцедуры
Процедура ПослеУстановкиВыделенногоМногострочногоТекста()
Перем НачСтрока, НачКолонка, КонСтрока, КонКолонка;
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
Если ФормаВладелец = Неопределено Тогда
Возврат;
КонецЕсли;
Если ТипЗнч(ПолеТекста.ЭлементФормы) = Тип("ПолеТекстовогоДокумента") Тогда
// Антибаг платформы https://partners.v8.1c.ru/forum/topic/1860281 , http://www.hostedredmine.com/issues/840411
ПолеТекста.ПолучитьГраницыВыделения(НачСтрока, НачКолонка, КонСтрока, КонКолонка);
ПолеТекста.УстановитьГраницыВыделения(1, 1, 1, 1);
ПолеТекста.ЭлементФормы.ВыделенныйТекст = "";
ПолеТекста.УстановитьГраницыВыделения(НачСтрока, НачКолонка, КонСтрока, КонКолонка,, ФормаВладелец);
//// Антибаг платформы. 8.1.10.50
//Если ирКэш.НомерВерсииПлатформыЛкс() < 801012 Тогда
// ПолеТекста.УстановитьТекст(ПолеТекста.ПолучитьТекст());
//КонецЕсли;
УстановитьПризнакМодифицированностиФормы();
КонецЕсли;
КонецПроцедуры
// Устанавливает фокус на связанное поле текста программы
Процедура УстановитьФокус(Знач Мягко = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
ирОбщий.ПрисвоитьЕслиНеРавноЛкс(ФормаВладелец.ТекущийЭлемент, ПолеТекста.ЭлементФормы); // Условно меняем для ускорения
Если Не Мягко Тогда
ВосстановитьФокусВвода();
КонецЕсли;
КонецПроцедуры
// https://www.hostedredmine.com/issues/931798 и куча похожих
Процедура ВосстановитьФокусВвода()
Если Истина
И ФормаВладелец <> Неопределено
И ТипЗнч(ФормаВладелец.ТекущийЭлемент) = Тип("ПолеHTMLДокумента")
Тогда
// https://github.com/salexdv/bsl_console/issues/122
//ПолеТекста.РедакторHTML().focus();
//ПолеТекста.РедакторHTML().editor.focus();
ирКлиент.УстановитьФокусВводаФормеЛкс();
КонецЕсли;
КонецПроцедуры
Процедура АвтоОбновитьСправку() Экспорт
Если Ложь
Или Не ирКлиент.Форма_ВводДоступенЛкс(ФормаВладелец)
Или ФормаВладелец.ТекущийЭлемент <> ПолеТекста.ЭлементФормы
Тогда
Возврат;
КонецЕсли;
Если мПоследнийРежимВызоваСправки = Неопределено Тогда
Возврат;
КонецЕсли;
мЭтоАвтоВызов = Истина;
Кнопка = ирКлиент.КнопкаКоманднойПанелиЭкземпляраКомпонентыЛкс(ЭтотОбъект, мПоследнийРежимВызоваСправки);
Нажатие(Кнопка);
ФормаВладелец.Активизировать();
мЭтоАвтоВызов = Ложь;
КонецПроцедуры
Функция ПолучитьВыделенныйИлиВесьТекст() Экспорт
НовыйТекстЗапроса = ВыделенныйТекст();
Если ПустаяСтрока(НовыйТекстЗапроса) Тогда
НовыйТекстЗапроса = ПолеТекста.ПолучитьТекст();
КонецЕсли;
Возврат НовыйТекстЗапроса;
КонецФункции
// <Описание процедуры>
//
// Параметры:
// <Параметр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, ПоследняяСтрока, ДлинаПоследнейСтроки);
ЧислоПереносовСтрокНачальное = СтрЧислоСтрок(ВыделенныйТекст() + "й") - 1;
Если ЧислоПереносовСтрокНачальное > ПоследняяСтрока - ПерваяСтрока Тогда
// https://www.hostedredmine.com/issues/925662
Для Счетчик = 1 По Мин(2, ДлинаПоследнейСтроки - 1) Цикл
ДлинаПоследнейСтрокиБезПереноса = ДлинаПоследнейСтроки - Счетчик;
ПолеТекста.УстановитьГраницыВыделения(ПерваяСтрока, 1, ПоследняяСтрока, ДлинаПоследнейСтрокиБезПереноса);
Если СтрЧислоСтрок(ВыделенныйТекст() + "й") - 1 < ЧислоПереносовСтрокНачальное Тогда
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
ВыделенныйТекст(ВыделенныйФрагмент);
ПолеТекста.УстановитьГраницыВыделения(ПерваяСтрока, 1, ПоследняяСтрока, ДлинаПоследнейСтроки,, ФормаВладелец);
УстановитьПризнакМодифицированностиФормы();
КонецПроцедуры
Процедура ПрочитатьНачалоИКонецТекущейСтроки() Экспорт
СброситьРезультатРазбораПозицииВТексте();
//ОригинальнаяСтрока = СокрП(ПолеТекста.ПолучитьСтроку(мКонечнаяСтрока));
ОригинальнаяСтрока = ПолеТекста.ПолучитьСтроку(мКонечнаяСтрока);
Для Счетчик = 0 По мКонечнаяКолонка - СтрДлина(ОригинальнаяСтрока) - 2 Цикл
ОригинальнаяСтрока = ОригинальнаяСтрока + " ";
КонецЦикла;
ТекущееНачалоСтроки = Лев(ОригинальнаяСтрока, мКонечнаяКолонка - 1);
ТекущийКонецСтроки = Сред(ОригинальнаяСтрока, мКонечнаяКолонка);
КонецПроцедуры
// Замена операторов внешнего перехода https://partners.v8.1c.ru/forum/t/1849050/m/1849050
Функция ЗаменитьОператорыВнешнегоПерехода(Знач Текст = Неопределено, выхТипыВнешнихПереходов, выхЗаглушкаВозврата = "", выхИмяПараметраТипаВыхода = "") Экспорт
Перем ИмяМетода;
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
УникальнаяСтрока = "1092383289";
Если Не ЗначениеЗаполнено(выхЗаглушкаВозврата) Тогда
выхЗаглушкаВозврата = "Возврат" + УникальнаяСтрока + "=0";
КонецЕсли;
Если Не ЗначениеЗаполнено(выхИмяПараметраТипаВыхода) Тогда
выхИмяПараметраТипаВыхода = "ТипВыхода";
КонецЕсли;
Если Текст <> Неопределено Тогда
ПолеТекста.УстановитьТекст(Текст);
КонецЕсли;
Если выхТипыВнешнихПереходов = Неопределено Тогда
выхТипыВнешнихПереходов = Новый Структура;
КонецЕсли;
СтартоваяСтрока = 0;
Пока Истина Цикл
ИнформацияОбОшибке = ПроверитьТекстИВернутьОшибку(, СтартоваяСтрока,,, Истина);
Если ИнформацияОбОшибке = Неопределено Тогда
Прервать;
КонецЕсли;
#Если Сервер И Не Сервер Тогда
ИнформацияОбОшибке = ИнформацияОбОшибке();
#КонецЕсли
ОписаниеОшибки = ИнформацияОбОшибке.Описание;
Если Найти(ОписаниеОшибки, "Оператор Прервать") > 0 Тогда
ИмяОператора = "Прервать";
ИначеЕсли Найти(ОписаниеОшибки, "Оператор Продолжить") > 0 Тогда
ИмяОператора = "Продолжить";
ИначеЕсли Найти(ОписаниеОшибки, "Оператор Возврат") > 0 Тогда
ИмяОператора = "Возврат";
//ИначеЕсли Найти(ОписаниеОшибки, "Оператор Перейти") > 0 Тогда
// ИмяОператора = "Перейти"; // TODO
Иначе
Прервать;
КонецЕсли;
КоординатыОшибки = КоординатыОшибки(ИнформацияОбОшибке, СтартоваяСтрока);
выхТипыВнешнихПереходов.Вставить(ИмяОператора);
// Выделяем вхождение имени оператора в ПолеТекста
ПолеТекста.УстановитьГраницыВыделения(1, 1, КоординатыОшибки.НомерСтроки, КоординатыОшибки.НомерКолонки);
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.УстановитьТекст(СокрП(ВыделенныйТекст()));
КоличествоСтрок = ТекстовыйДокумент.КоличествоСтрок();
ДлинаПоследнейСтроки = СтрДлина(ТекстовыйДокумент.ПолучитьСтроку(КоличествоСтрок) + 1);
ПолеТекста.УстановитьГраницыВыделения(Макс(1, КоличествоСтрок), ДлинаПоследнейСтроки - СтрДлина(ИмяОператора), Макс(1, КоличествоСтрок), ДлинаПоследнейСтроки);
ВыделенныйТекст(выхИмяПараметраТипаВыхода + " = """ + ИмяОператора + """; " + выхЗаглушкаВозврата);
Если ИмяОператора = "Возврат" Тогда
ИнформацияОбОшибке = ПроверитьТекстИВернутьОшибку(, СтартоваяСтрока,,, Истина);
Если ИнформацияОбОшибке <> Неопределено Тогда
#Если Сервер И Не Сервер Тогда
ИнформацияОбОшибке = ИнформацияОбОшибке();
#КонецЕсли
ОписаниеОшибки = ИнформацияОбОшибке.Описание;
КоординатыОшибкиПосле = КоординатыОшибки(ИнформацияОбОшибке, СтартоваяСтрока);
Если КоординатыОшибкиПосле.НомерСтроки = КоординатыОшибки.НомерСтроки Тогда
ВыделенныйТекст("=");
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Текст = ПолеТекста.ПолучитьТекст();
Возврат Текст;
КонецФункции
Функция КоординатыОшибки(Знач ИнформацияОбОшибке, Знач СтартоваяСтрока = 0) Экспорт
КоординатыОшибки = Новый Структура("НомерСтроки, НомерКолонки");
РегВыражение.Pattern = "{[^\(]*\(([^\)]+)\)}";
ТекстКоординат = РегВыражение.НайтиВхождения(ИнформацияОбОшибке.Описание)[0].SubMatches(0);
Фрагменты = ирОбщий.СтрРазделитьЛкс(ТекстКоординат, ",", Истина);
КоординатыОшибки.НомерСтроки = Число(Фрагменты[0]) + СтартоваяСтрока;
КоординатыОшибки.НомерКолонки = Число(Фрагменты[1]);
Возврат КоординатыОшибки;
КонецФункции
Процедура ВыделитьТекущееСлово() Экспорт
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
ТекущееОбъектноеВыражение();
мНачальнаяКолонка = мКонечнаяКолонка - СтрДлина(мНачалоКонтекста);
Если Не ПустаяСтрока(мРодительскийКонтекст) Тогда
мНачальнаяКолонка = мНачальнаяКолонка + СтрДлина(мРодительскийКонтекст) + 1;
КонецЕсли;
мКонечнаяКолонка = мКонечнаяКолонка + СтрДлина(мКонецКонтекста);
Если Прав(мКонецКонтекста, 1) = "(" Тогда
мКонечнаяКолонка = мКонечнаяКолонка - 1;
КонецЕсли;
ПолеТекста.УстановитьГраницыВыделения(мНачальнаяСтрока, мНачальнаяКолонка, мКонечнаяСтрока, мКонечнаяКолонка,, ФормаВладелец);
КонецПроцедуры
Функция ПереименоватьСлово() Экспорт
Форма = ПолучитьФорму("ПереименоватьСлово");
РезультатФормы = Форма.ОткрытьМодально();
Возврат РезультатФормы;
КонецФункции
Процедура ВыделитьТекущееОбъектноеВыражение() Экспорт
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
ТекущееОбъектноеВыражение();
мНачальнаяКолонка = мКонечнаяКолонка - СтрДлина(мНачалоКонтекста);
мКонечнаяКолонка = мКонечнаяКолонка + СтрДлина(мКонецКонтекста);
Если Прав(мКонецКонтекста, 1) = "(" Тогда
мКонечнаяКолонка = мКонечнаяКолонка - 1;
КонецЕсли;
ПолеТекста.УстановитьГраницыВыделения(мНачальнаяСтрока, мНачальнаяКолонка, мКонечнаяСтрока, мКонечнаяКолонка,, ФормаВладелец);
КонецПроцедуры
// Получает путь к описанию заданного контекста.
//
// Параметры:
// ПутьКСлову - Строка;
// *СтрокаОписания - СтрокаТаблицыЗначений - возвращаемая строка описания;
// *ВключатьПутьКОписаниюТипаЗначения - Булево, *Неопределено - признак добавления в список выбора тип значения слова.
//
Функция НайтиПоказатьСправкуПоСлову(Знач ПутьКСлову, ВключатьПутьКОписаниюТипаЗначения = Ложь, выхФормаВыбора = Неопределено, РазрешитьАнализИмениТипа = Истина,
ВладелецФормы = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
МассивЗащитыОтРекурсии.Очистить();
ТаблицаСтруктурТиповКонтекста = ОпределитьТипЗначенияКонтекста(ПутьКСлову, " " + мТекстДляПоискаОпределения, мПредшествующийТекст, РазрешитьАнализИмениТипа, мЭтоКонструктор);
ОтносительныйПутьКОписанию = "";
СтруктураТипаКонтекста = ТаблицаСтруктурТиповКонтекста[0];
НайтиПоказатьСправкуПоСтруктуреТипа(ПутьКСлову, СтруктураТипаКонтекста, ВключатьПутьКОписаниюТипаЗначения, выхФормаВыбора, ВладелецФормы, ТаблицаСтруктурТиповКонтекста);
КонецФункции
Функция НайтиПоказатьСправкуПоСтруктуреТипа(Знач ПутьКСлову, Знач СтруктураТипа, ВключатьПутьКОписаниюТипаЗначения = Ложь, выхФормаВыбора = Неопределено, ВладелецФормы = Неопределено,
Знач ТаблицаСтруктурТиповКонтекста = Неопределено)
Если Истина
И ТипЗнч(СтруктураТипа.СтрокаОписания) <> Тип("СтрокаТаблицыЗначений")
И ТипЗнч(СтруктураТипа.Метаданные) = Тип("COMОбъект")
Тогда
Если мНомерПараметра > 0 Тогда
Возврат Неопределено;
КонецЕсли;
МетаданныеСлова = СтруктураТипа.Метаданные;
ИмяТипа = мПлатформа.ПолноеИмяТипаCOMОбъекта(МетаданныеСлова);
Попытка
Пустышка = МетаданныеСлова.Path_;
Исключение
Пустышка = Неопределено;
КонецПопытки;
Слово = ирОбщий.ПоследнийФрагментЛкс(ПутьКСлову, ".", Ложь);
Если Прав(ПутьКСлову, 1) = "(" Тогда
Слово = СтрЗаменить(Слово, "(", "");
КонецЕсли;
Если Пустышка <> Неопределено Тогда
// WMI
ИмяКлассаWMI = МетаданныеСлова.Path_.Class;
Если ЗначениеЗаполнено(Слово) Тогда
ОписаниеСлова = ирОбщий.ДокументацияСвойстваWMIЛкс(ИмяКлассаWMI, Слово);
Если ЗначениеЗаполнено(ОписаниеСлова) Тогда
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.УстановитьТекст(ОписаниеСлова);
ТекстовыйДокумент.Показать(ИмяКласса + "." + Слово);
КонецЕсли;
КонецЕсли;
Иначе
ЗапуститьПриложение("http://google.com/search?q=" + ирОбщий.ПервыйФрагментЛкс(ИмяТипа, " ") + "+" + Слово);
КонецЕсли;
Иначе
Если ВладелецФормы <> Неопределено И СтруктураТипа.СтрокаОписания <> Неопределено Тогда
ТаблицаВладелец = СтруктураТипа.СтрокаОписания.Владелец();
#Если Сервер И Не Сервер Тогда
ТаблицаВладелец = Новый ТаблицаЗначений;
#КонецЕсли
Если ТаблицаВладелец.Колонки.Найти("ЛиЭкспорт") <> Неопределено Тогда
ФормаВызовМетода = ФормаВызовМетода();
ФормаВызовМетода.ПараметрСтруктураТипаКонтекста = СтруктураТипа;
БылаОткрыта = ФормаВызовМетода.Открыта();
Если ЛиДоступноОткрытиеСвободнойФормы() Тогда
ОткрытьПодсказкуПоВызовуМетодаПассивно(ФормаВызовМетода, Ложь);
ФормаВызовМетода.Автозакрытие = Ложь;
Если Не БылаОткрыта Тогда
ирКлиент.Форма_АктивироватьОткрытьЛкс(ФормаВладелец);
КонецЕсли;
Иначе
ФормаВызовМетода.ОткрытьМодально();
КонецЕсли;
Возврат ФормаВызовМетода;
КонецЕсли;
КонецЕсли;
Если СтруктураТипа.ТипЯзыка = "ИмяТипа" Тогда
ВключатьПутьКОписаниюТипаЗначения = Истина;
КонецЕсли;
Слово = ирОбщий.ПоследнийФрагментЛкс(ПутьКСлову);
// Возможные роли слова без учета вычисленного контекста
ТаблицаСтруктурВозможныхТиповКонтекста = ирКлиент.НайтиВозможныеСтрокиОписанияСловаВСинтаксПомощникеЛкс(Слово, ЯзыкПрограммы);
Если ТаблицаСтруктурТиповКонтекста = Неопределено Тогда
ТаблицаСтруктурТиповКонтекста = Новый Массив;
ТаблицаСтруктурТиповКонтекста.Добавить(СтруктураТипа);
КонецЕсли;
СтруктураЦикла = Новый Соответствие;
СтруктураЦикла.Вставить("1.Предсказанные:", ТаблицаСтруктурТиповКонтекста);
СтруктураЦикла.Вставить("2.Возможные:", ТаблицаСтруктурВозможныхТиповКонтекста);
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
Если ВладелецФормы = Неопределено Тогда
ВладелецФормы = ФормаВладелец;
КонецЕсли;
мПлатформа.ВыбратьСтрокуОписанияИзМассиваСтруктурТипов(СтруктураЦикла, ВключатьПутьКОписаниюТипаЗначения, ВладелецФормы, Слово, мНомерПараметра,, выхФормаВыбора, мФактическиеПараметры.Количество());
КонецЕсли;
Возврат Неопределено;
КонецФункции
// Открывает контекстную справку по текущему слову или его типу.
//
// Параметры:
// *ПутьКСлову - Строка, *"" - используется для получения дочерних слов относительно текущего контекста.
//
Процедура ОткрытьКонтекстнуюСправку(ПутьКСлову = "", ВладелецФормы = Неопределено) Экспорт
//Если ирОбщий.ПроверитьПлатформаНеWindowsЛкс(,, Истина) Тогда
// Возврат;
//КонецЕсли;
//КончитьОбработкуКоманды();
РазобратьТекущийКонтекст();
РазрешитьАнализИмениТипа = Не ЗначениеЗаполнено(ПутьКСлову);
Если РазрешитьАнализИмениТипа Тогда
ПутьКСлову = мТекущееСлово;
КонецЕсли;
Если мРодительскийКонтекст <> "" Тогда
ПутьКСлову = мРодительскийКонтекст + "." + ПутьКСлову;
КонецЕсли;
НайтиПоказатьСправкуПоСлову(ПутьКСлову,,, РазрешитьАнализИмениТипа, ВладелецФормы);
КонецПроцедуры
// <Описание процедуры>
//
// Параметры:
// <Параметр1> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>.
//
Процедура ОткрытьСправкуПоЯзыкуПрограммы() Экспорт
//Если ирОбщий.ПроверитьПлатформаНеWindowsЛкс() Тогда
// Возврат;
//КонецЕсли;
Если ЯзыкПрограммы = 0 Тогда
Книга = "shcntx_ru";
ИначеЕсли ЯзыкПрограммы = 1 Тогда
Книга = "shquery_ru";
ИначеЕсли ЯзыкПрограммы = 2 Тогда
Книга = "dcsui_ru";
КонецЕсли;
ФормаСправка = ирКлиент.ПолучитьФормуЛкс("Обработка.ирСинтаксПомощник.Форма", , ФормаВладелец);
ФормаСправка.ТекущаяСтраницаУстановлена = Истина;
ФормаСправка.ОткрытьАдрес("//" + Книга);
КонецПроцедуры
// Открывает контекстную справку по текущему параметру метода.
//
// Параметры:
// *ПутьКСлову - Строка, *"" - используется для получения дочерних слов относительно текущего контекста.
//
Процедура ОткрытьСправкуПоПараметру(ПутьКСлову = "", ОткрыватьСинтаксПомощник = Истина) Экспорт
//Если ирОбщий.ПроверитьПлатформаНеWindowsЛкс(,, Истина) Тогда
// Возврат;
//КонецЕсли;
РазобратьТекущийКонтекст(,, Истина);
Если ПутьКСлову = "" Тогда
ПутьКСлову = мВызовМетода;
КонецЕсли;
// Если раскомментировать, то при вызове через мОткрытьСправкуПоПараметру не будет открываться окно
//Если Не ЗначениеЗаполнено(ПутьКСлову) Тогда
// Возврат;
//КонецЕсли;
Если ОткрыватьСинтаксПомощник И ирКэш.ЛиПлатформаWindowsЛкс() Тогда
ФормаСинтаксПомощникаДо = Неопределено;
ФормаСинтаксПомощникаПосле = Неопределено;
Если Не ЛиДоступноОткрытиеСвободнойФормы() Тогда
ФормаСинтаксПомощникаДо = ирКлиент.ПолучитьФормуЛкс("Обработка.ирСинтаксПомощник.Форма");
КонецЕсли;
НайтиПоказатьСправкуПоСлову(ПутьКСлову,, ФормаСинтаксПомощникаПосле);
КонецЕсли;
ФормаПодсказкаПоПараметрам = ФормаВызовМетода();
ФормаПодсказкаПоПараметрам.ПараметрСтруктураТипаКонтекста = Неопределено;
Если Не ФормаПодсказкаПоПараметрам.Открыта() И ЗначениеЗаполнено(мИмяМетода) Тогда
ФормаПодсказкаПоПараметрам.ЗапомнитьПозициюКаретки();
КонецЕсли;
Если ЛиДоступноОткрытиеСвободнойФормы() Тогда
Если Ложь
Или ОткрыватьСинтаксПомощник
Или Не ФормаПодсказкаПоПараметрам.Открыта()
Тогда
ОткрытьПодсказкуПоВызовуМетодаПассивно(ФормаПодсказкаПоПараметрам);
КонецЕсли;
Иначе
Если Истина
И Не мЭтоАвтоВызов
И ФормаСинтаксПомощникаДо <> Неопределено
И ФормаСинтаксПомощникаДо.Открыта() = ФормаСинтаксПомощникаПосле.Открыта()
Тогда
ФормаПодсказкаПоПараметрам.ОткрытьМодально();
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Процедура ОткрытьПодсказкуПоВызовуМетодаПассивно(Знач ФормаПодсказкаПоПараметрам, Знач Автообновление = Истина)
ФормаПодсказкаПоПараметрам.Автообновление = Автообновление;
ФормаПодсказкаПоПараметрам.Открыть();
ФормаПодсказкаПоПараметрам.Обновить(); // Нужно для ускорения срабатывания установки позиции окна и для 8.2, т.к. там форма форкус получает после завершения ПриОткрытии и только после этого сработает установка позиции окна
//ирКлиент.УстановитьФокусВводаФормеЛкс(); Не помогает восстановить мигание каретки
КонецПроцедуры
Функция УдалитьКомментарии(Текст) Экспорт
РегВыражение.Global = Истина;
РегВыражение.Multiline = Ложь;
Если Ложь
Или ЯзыкПрограммы = 1
Или ЯзыкПрограммы = 2
Тогда
// Не проверено
РегВыражение.Pattern = "(?:(?://[^\n]*" + ")|(" + шСтрокаЗапроса + ")|([\s\S])";
ШаблонЗамены = "$1$2$3$4";
ИначеЕсли ЯзыкПрограммы = 0 Тогда
шОднострочнаяСтрокаПрограммыСКавычки = """(?:(?:"""")|[^""\n])*""?";
шОднострочнаяСтрокаПрограммыСЧерты = "\n\s*\|(?:(?:"""")|[^""\n])*""?";
РегВыражение.Pattern = "//[^\n]*|" + "(" + "#[^\n]*" + ")|(" + шОднострочнаяСтрокаПрограммыСКавычки + ")|(" + шОднострочнаяСтрокаПрограммыСЧерты + ")|([\s\S])";
ШаблонЗамены = "$1$2$3$4";
КонецЕсли;
Результат = РегВыражение.Заменить(Текст, ШаблонЗамены);
Возврат Результат;
КонецФункции
// Меняет RegExp!
Функция ЭтоРусскийВариантТекстаЗапроса(Текст) Экспорт
ТекстБезКомментариев = СокрЛП(ЗалитьКомментарииИСтроковыеЛитералы(Текст));
РегВыражение.Pattern = "[А-ЯЁ]";
ЭтоРусскийЯзык = РегВыражение.Проверить(Лев(ТекстБезКомментариев, 1));
Возврат ЭтоРусскийЯзык;
КонецФункции
// Добавляет/заменяет/удаляет оператор ПОМЕСТИТЬ в запросе.
// Это неточный метод, основанный на regexp.
//
// Параметры:
// ТекстЗапроса - Строка;
// *ИмяВременнойТаблицы - Строка - если пустое, то оператор удаляется.
//
// Возвращаемое значение:
// Строка - исправленный текст запроса.
//
Функция ИзменитьОператорПоместитьЗапроса(ТекстЗапроса, ИмяВременнойТаблицы = "") Экспорт
ЭтоРусскийЯзык = ЭтоРусскийВариантТекстаЗапроса(ТекстЗапроса); // Меняет RegExp!
РегВыражение.Global = Истина;
шСтрокаЗапроса = """(?:(?:"""")|[^""\n])*(?:" + шРазделитель + "*(?:(?:"""")|[^""\n])*)*(?:""|$)";
ШаблонПОМЕСТИТЬИЗ = "(" + шСтрокаЗапроса + ")|(?:(" + шРазделитель + ")+(" + "(?:ПОМЕСТИТЬ|INTO(?:" + шРазделитель + "+TABLE)?)" + шРазделитель + "+" + шИмя + шРазделитель + "+)"
+ "|((?:ИЗ|FROM|ГДЕ|WHERE|СГРУППИРОВАТЬ|GROUP|УПОРЯДОЧИТЬ|ORDER|ИМЕЮЩИЕ|HAVING|ОБЪЕДИНИТЬ|UNION)" + шРазделитель + "+))|(.|\r|\n)";
РегВыражение.Pattern = ШаблонПОМЕСТИТЬИЗ;
Если ЗначениеЗаполнено(ИмяВременнойТаблицы) Тогда
Если ЭтоРусскийЯзык Тогда
ТерминПоместить = "ПОМЕСТИТЬ";
Иначе
ТерминПоместить = "INTO";
КонецЕсли;
Результат = РегВыражение.НайтиВхождения(ТекстЗапроса);
Текст = "";
ПредложениеДобавлено = Ложь;
Для Каждого Match Из Результат Цикл
Если Ложь
Или ПредложениеДобавлено
Или Не ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(Match.SubMatches(0))
Или Не ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(Match.SubMatches(4))
Тогда
Текст = Текст + Match.Value;
Иначе
Текст = Текст + "
|" + ТерминПоместить + "
| " + ИмяВременнойТаблицы;
Если Match.SubMatches(3) <> 0 Тогда // Видимо здесь ошибка
Текст = Текст + Символы.ПС + Match.SubMatches(3);
КонецЕсли;
ПредложениеДобавлено = Истина;
КонецЕсли;
КонецЦикла;
Если Не ПредложениеДобавлено Тогда
Текст = Текст + "
|" + ТерминПоместить + "
| " + ИмяВременнойТаблицы;
КонецЕсли;
Иначе
Текст = РегВыражение.Заменить(ТекстЗапроса, "$1$2$4$5");
КонецЕсли;
Возврат Текст;
КонецФункции
Функция ШаблонЗапросаДопускаетВстройкуВРодительскийЗапрос(Текст) Экспорт
РегВыражение.Global = Ложь;
РегВыражение.Pattern = шРазделитель + "*(?:ВЫБРАТЬ|SELECT)(?:" + шРазделитель + "+)\*(?:" + шРазделитель + "+)(?:ИЗ|FROM)(?:" + шРазделитель + "+(?:КАК|AS)?(?:" + шРазделитель + "+" + шИмя + "))" + шРазделитель + "*";
Результат = РегВыражение.Проверить(Текст);
Возврат Результат;
КонецФункции
Функция ПолучитьКомментарийИзТокеновЯзыкаЗапросов(Токен1, Токен2 = Неопределено, выхИмяЗапросаИзКомментария = "", выхИмяЧастиОбъединенияИзКомментария = "") Экспорт
Массив = Новый Массив();
Если Токен1 <> Неопределено И Токен1.Name = "Comment" Тогда
Массив.Добавить(Токен1);
КонецЕсли;
Если Токен2 <> Неопределено И Токен2.Name = "Comment" Тогда
Массив.Добавить(Токен2);
КонецЕсли;
ТекстКомментария = "";
Для Каждого Токен Из Массив Цикл
ТекстТокена = ПолучитьТекстИзТокена(Токен);
РазобратьКомментарий(ТекстКомментария, выхИмяЗапросаИзКомментария, выхИмяЧастиОбъединенияИзКомментария);
КонецЦикла;
Возврат ТекстКомментария;
КонецФункции
Процедура РазобратьКомментарий(ТекстКомментария, выхИмяЗапросаИзКомментария = Неопределено, выхИмяЧастиОбъединенияИзКомментария = Неопределено, выхПорядокОтладки = Неопределено) Экспорт
ЧистыйКомментарий = "";
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.УстановитьТекст(ТекстКомментария);
Для Счетчик = 1 По ТекстовыйДокумент.КоличествоСтрок() Цикл
СтрокаТекста = ТекстовыйДокумент.ПолучитьСтроку(Счетчик);
Если ПустаяСтрока(СтрокаТекста) Тогда
Продолжить;
КонецЕсли;
//Если Счетчик = 1 Тогда
Если Найти(СтрокаТекста, мПараметрыДиалектаSQL.СтрочныйКомментарий) = 1 Тогда
СтрокаТекста = Сред(СтрокаТекста, СтрДлина(мПараметрыДиалектаSQL.СтрочныйКомментарий) + 1);
КонецЕсли;
Если Найти(СтрокаТекста, мМаркерСлужебногоКомментария) = 1 Тогда
Продолжить;
КонецЕсли;
Если Найти(СтрокаТекста, мПлатформа.мМаркерИмениЗапросаПакета) = 1 Тогда
ИмяЗапросаИзКомментария = ирОбщий.СтрокаМеждуМаркерамиЛкс(СтрокаТекста, мПлатформа.мМаркерИмениЗапросаПакета, " ");
Если ирОбщий.ЛиИмяПеременнойЛкс(ИмяЗапросаИзКомментария) Тогда
выхИмяЗапросаИзКомментария = ИмяЗапросаИзКомментария;
КонецЕсли;
// Пропускаем служебные комментарии
Продолжить;
КонецЕсли;
Если Найти(СтрокаТекста, мПлатформа.мМаркерИмениЧастиОбъединения) = 1 Тогда
ИмяЧастиОбъединенияИзКомментария = ирОбщий.СтрокаМеждуМаркерамиЛкс(СтрокаТекста, мПлатформа.мМаркерИмениЧастиОбъединения, " ");
Если ирОбщий.ЛиИмяПеременнойЛкс(ИмяЧастиОбъединенияИзКомментария) Тогда
выхИмяЧастиОбъединенияИзКомментария = ИмяЧастиОбъединенияИзКомментария;
КонецЕсли;
// Пропускаем служебные комментарии
Продолжить;
КонецЕсли;
СтрокаТекста = СокрЛ(СтрокаТекста);
Если ирОбщий.СтрНачинаетсяСЛкс(СтрокаТекста, мМаркерПорядкаОтладки) = 1 Тогда
выхПорядокОтладки = Сред(СтрокаТекста, СтрДлина(мМаркерПорядкаОтладки) + 1);
// Пропускаем служебные комментарии
Продолжить;
КонецЕсли;
//КонецЕсли;
Если ЧистыйКомментарий <> "" Тогда
ЧистыйКомментарий = ЧистыйКомментарий + Символы.ПС;
КонецЕсли;
ЧистыйКомментарий = ЧистыйКомментарий + СтрокаТекста;
КонецЦикла;
ТекстКомментария = ЧистыйКомментарий;
КонецПроцедуры
// Разбирает текущий контекст по составляющим.
//
// Параметры:
// *ДеструктивныйАнализ - Булево, *Истина - текст для поиска определения оптимизировать.
//
Процедура РазобратьТекущийКонтекст(ЛиСправаОтРавенства = Ложь, выхЕстьТочкаСправа = Ложь, КакВызовМетода = Ложь, НомерСтроки = 0, НомерКолонки = 0) Экспорт
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
СлужебноеПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
Если Не мРазбиратьКонтекст Тогда
Возврат;
КонецЕсли;
мПлатформа.ИнициализацияОписанияМетодовИСвойств();
Если Не ЗначениеЗаполнено(НомерСтроки) Тогда
ПолеТекста.ПолучитьГраницыВыделения(мНачальнаяСтрока, мНачальнаяКолонка, мКонечнаяСтрока, мКонечнаяКолонка);
Иначе
мНачальнаяСтрока = НомерСтроки;
мКонечнаяСтрока = НомерСтроки;
мНачальнаяКолонка = НомерКолонки;
мКонечнаяКолонка = НомерКолонки;
КонецЕсли;
ПрочитатьНачалоИКонецТекущейСтроки();
мЭтоОбъявлениеПсевдонима = Ложь;
мЭтоСтроковыйЛитерал = ирОбщий.ЛиВнутриСтроковогоЛитералаЛкс(ТекущееНачалоСтроки);
Если КакВызовМетода Или мЭтоСтроковыйЛитерал Тогда
ТекущийКонтекстМетода();
КонецЕсли;
РегВыражение.Global = Ложь;
ШаблонПрефиксаПараметра = "(?:&|#|\?|@)?";
// Начало контекста
СтрокаШаблона = шПредИмя + "(";
Если Ложь
Или ЯзыкПрограммы = 1
Или ЯзыкПрограммы = 2
Тогда
СтрокаШаблона = "(?:" + шРазделитель + "+(КАК|AS|(?:ПОМЕСТИТЬ|INTO(?:" + шРазделитель + "+TABLE)?))" + шРазделитель + "*)?" + СтрокаШаблона + ШаблонПрефиксаПараметра + "(?:" + шИмя + ")?";
Иначе
СтрокаШаблона = "()" + СтрокаШаблона + шИмя;
КонецЕсли;
СтрокаШаблона = СтрокаШаблона + шСкобки + "?"
//+ "((\.(" + шИмя + ")" + шСкобки + "?)|" + шИндекс + ")*\.?)";
+ "((\.(" + шИмя + ")" + шСкобки + "?)|" + шИндекс + ")*\.?)?"; // 20.08.2020
Если ЛиСправаОтРавенства Тогда
СтрокаШаблона = СтрокаШаблона + шРазделитель + "*=" + шРазделитель + "*";
КонецЕсли;
СтрокаШаблона = СтрокаШаблона + "$";
РегВыражение.Pattern = СтрокаШаблона;
Результат = РегВыражение.НайтиВхождения(ТекущееНачалоСтроки);
Если Результат.Количество() > 0 Тогда
ПервоеВхождение = Результат[0];
мНачалоКонтекста = "" + ПервоеВхождение.SubMatches(1);
мЭтоОбъявлениеПсевдонима = ПервоеВхождение.SubMatches(0) <> Неопределено И Найти(мНачалоКонтекста, ".") = 0;
КонецЕсли;
ОригинальныйТекст = ПолеТекста.ПолучитьТекст();
// Конец контекста
РегВыражение.Global = Ложь;
Если Не ЛиСправаОтРавенства Тогда
РегВыражение.Pattern = "([" + шБуква + "\d]*\(?)(\.)?";
Результат = РегВыражение.НайтиВхождения(ТекущийКонецСтроки);
Если Результат.Количество() > 0 Тогда
мКонецКонтекста = Результат[0].SubMatches(0);
выхЕстьТочкаСправа = Результат[0].SubMatches(1) <> Неопределено;
КонецЕсли;
КонецЕсли;
Если Ложь
Или ЯзыкПрограммы = 1
Или ЯзыкПрограммы = 2
Тогда
СтрокаШаблона = ШаблонПрефиксаПараметра + "(?:" + шИмя + ")?";
Иначе
СтрокаШаблона = шИмя;
КонецЕсли;
СтрокаШаблона = "(?:((?:" + шИмяСкобки + "?" + "(?:(?:\." + шИмяСкобки + "?)|" + шИндекс + ")*))\.)?(" + СтрокаШаблона + ")?$";
// Родительский контекст по позиции курсора
РегВыражение.Pattern = СтрокаШаблона;
Результат = РегВыражение.НайтиВхождения(мНачалоКонтекста);
Если Результат.Количество() > 0 Тогда
ПервоеВхождение = Результат[0];
Если ПервоеВхождение.SubMatches(0) <> Неопределено Тогда
мРодительскийКонтекст = ПервоеВхождение.SubMatches(0);
КонецЕсли;
Если ПервоеВхождение.SubMatches(4) <> Неопределено Тогда
мНачалоСлова = ПервоеВхождение.SubMatches(4);
КонецЕсли;
КонецЕсли;
мТекущееСлово = мНачалоСлова + ирОбщий.ПервыйФрагментЛкс(мКонецКонтекста);
мКонтекст = мНачалоКонтекста + мКонецКонтекста;
ТекстБезКомментариевИОпасныхСтрок = ЗалитьКомментарииИСтроковыеЛитералы(ОригинальныйТекст);
мПозицияТекстаДляПоискаОпределения = 0;
мПредшествующийТекст = "";
мТекстДляПоискаОпределения = "";
мМетодМодуля = Неопределено;
мПерваяСтрокаТелаМетодаМодуля = 1;
мПоследняяСтрокаТелаМетодаМодуля = Неопределено;
// Здесь не учтена возможность наличия комментария слева от текущей позиции
Если мКонечнаяСтрока > 1 Тогда
СлужебноеПолеТекста.УстановитьТекст(ОригинальныйТекст);
СлужебноеПолеТекста.УстановитьГраницыВыделения(1, 1, мКонечнаяСтрока - 1, 333);
мПредшествующийТекст = СлужебноеПолеТекста.ВыделенныйТекст;
СлужебноеПолеТекста.УстановитьТекст(ТекстБезКомментариевИОпасныхСтрок);
СлужебноеПолеТекста.УстановитьГраницыВыделения(1, 1, мКонечнаяСтрока - 1, 333);
мТекстДляПоискаОпределения = СлужебноеПолеТекста.ВыделенныйТекст;
КонецЕсли;
НомерПервойСтрокиБлока = 1;
ЧислоСтрокВБлоке = 0;
Если ЯзыкПрограммы = 0 Тогда
Если Не ЭтоМодуль Тогда
мТекстДляПоискаОпределения = мТекстДляПоискаОпределения + Лев(ТекущееНачалоСтроки, СтрДлина(ТекущееНачалоСтроки) - СтрДлина(мНачалоКонтекста));
Иначе
ОбновитьМодульМетаданных(ОригинальныйТекст);
ОболочкаСлужебногоПоляТекста = ирКлиент.ОболочкаПоляТекстаЛкс(СлужебноеПолеТекста);
#Если Сервер И Не Сервер Тогда
ОболочкаСлужебногоПоляТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
ОболочкаСлужебногоПоляТекста.УстановитьТекст(ОригинальныйТекст);
Для Каждого СтрокаМетода Из мМодульМетаданных.Методы Цикл
ТекстБлока = СтрокаМетода.Тело;
ОболочкаСлужебногоПоляТекста.УстановитьГраницыВыделения(1, СтрокаМетода.ПозицияТела + 1);
НомерПервойСтрокиБлока = ОболочкаСлужебногоПоляТекста.ВыделениеДвумерное().КонечнаяСтрока;
мПозицияТекстаДляПоискаОпределения = СтрокаМетода.ПозицияТела + 1;
ЧислоСтрокВБлоке = ирОбщий.СтрЧислоСтрокЛкс(ТекстБлока);
мПерваяСтрокаТелаМетодаМодуля = НомерПервойСтрокиБлока;
мМетодМодуля = СтрокаМетода;
НомерПервойСтрокиБлока = НомерПервойСтрокиБлока + ЧислоСтрокВБлоке - 1;
мПоследняяСтрокаТелаМетодаМодуля = НомерПервойСтрокиБлока;
Если НомерПервойСтрокиБлока >= мНачальнаяСтрока Тогда
Прервать;
КонецЕсли;
КонецЦикла;
Если мМетодМодуля <> Неопределено И мМетодМодуля.Параметры <> Неопределено Тогда
Для Каждого СтрокаПараметра Из мМетодМодуля.Параметры Цикл
ТипЗначения = ирОбщий.ОписаниеТиповИзТекстаЛкс(СтрокаПараметра.ТипЗначения);
ДобавитьСловоЛокальногоКонтекста(СтрокаПараметра.Имя, "Свойство", ТипЗначения);
КонецЦикла;
КонецЕсли;
КонецЕсли;
Иначе
ПозицииЗапросовПакета = Новый Массив;
ЗапросыПакета = ирОбщий.РазбитьГрубоТекстПакетногоЗапросаНаЗапросыЛкс(ОригинальныйТекст, СтрДлина(мПредшествующийТекст), ПозицииЗапросовПакета);
#Если Сервер И Не Сервер Тогда
ЗапросыПакета = Новый Массив;
#КонецЕсли
Если ЗапросыПакета.Количество() > 0 Тогда
Для ИндексЗапроса = 0 По ЗапросыПакета.ВГраница() Цикл
ТекстБлока = ЗапросыПакета[ИндексЗапроса];
мПозицияТекстаДляПоискаОпределения = ПозицииЗапросовПакета[ИндексЗапроса];
ЧислоСтрокВБлоке = ирОбщий.СтрЧислоСтрокЛкс(ТекстБлока) - 1;
НомерПервойСтрокиБлока = НомерПервойСтрокиБлока + ЧислоСтрокВБлоке;
Если НомерПервойСтрокиБлока >= мНачальнаяСтрока Тогда
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЕсли;
НомерТекущейСтрокиВБлоке = 0;
Если ЧислоСтрокВБлоке > 0 Тогда
НомерТекущейСтрокиВБлоке = мКонечнаяСтрока - (НомерПервойСтрокиБлока - ЧислоСтрокВБлоке);
КонецЕсли;
Если НомерТекущейСтрокиВБлоке > 1 Тогда
мТекстДляПоискаОпределения = ТекстБлока;
ТекстБезКомментариевИОпасныхСтрок = ТекстБлока;
СлужебноеПолеТекста.УстановитьТекст(ТекстБлока);
СлужебноеПолеТекста.УстановитьГраницыВыделения(1, 1, НомерТекущейСтрокиВБлоке - 1, 333);
мПредшествующийТекст = СлужебноеПолеТекста.ВыделенныйТекст;
СлужебноеПолеТекста.УстановитьТекст(ОригинальныйТекст);
Иначе
мПредшествующийТекст = Прав(мПредшествующийТекст, 500); // Анализируем не более этого числа строк
КонецЕсли;
мПредшествующийТекст = мПредшествующийТекст + Лев(ТекущееНачалоСтроки, СтрДлина(ТекущееНачалоСтроки) - СтрДлина(мНачалоКонтекста));
ПродолжитьОбработкуКоманды();
КонецПроцедуры
// Сначала нужно разобрать контекст
Функция ТелоАктивногоМетода(НомераПервойСтрокиТела = 1) Экспорт
НомераПервойСтрокиТела = мПерваяСтрокаТелаМетодаМодуля;
Если мМетодМодуля <> Неопределено Тогда
Возврат мМетодМодуля.Тело;
Иначе
Возврат ОригинальныйТекст;
КонецЕсли;
КонецФункции
// Сначала нужно разобрать контекст
Функция ОпределениеАктивногоМетода() Экспорт
Если мМетодМодуля <> Неопределено Тогда
Возврат мМетодМодуля.ОпределениеСОписанием;
Иначе
Возврат ОригинальныйТекст;
КонецЕсли;
КонецФункции
Процедура ОбновитьМодульМетаданных(Знач Текст = Неопределено) Экспорт
Если Не ЭтоМодуль Тогда
Возврат
КонецЕсли;
Если Текст = Неопределено Тогда
Текст = ПолеТекста.ПолучитьТекст();
КонецЕсли;
мМодульМетаданных = мПлатформа.МодульМетаданных(Текст, Ложь, Истина);
КонецПроцедуры
// Выполняет программу на внутреннем языке.
//
// Параметры:
// Нет.
//
// Возвращаемое значение:
// Булево - безошибочность выполнения кода.
//
Функция ВыполнитьПрограммныйКод(Знач ЛиСинтаксическийКонтроль = Ложь, выхИнформацияОбОшибке = Неопределено, Знач ТекстДляВыполнения = "") Экспорт
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
Если Не ЗначениеЗаполнено(ТекстДляВыполнения) Тогда
ТекстДляВыполнения = ПолеТекста.ПолучитьТекст();
КонецЕсли;
Попытка
мПлатформа.ВыполнитьПрограммныйКодВКонтексте(КонтекстВыполнения, МетодВыполнения, ТекстДляВыполнения, ЛиСинтаксическийКонтроль);
Возврат Истина;
Исключение
выхИнформацияОбОшибке = ИнформацияОбОшибке();
Если Не ЛиСинтаксическийКонтроль Тогда
// Баг платформы. Зависает приложение, если пытаемся установить выделение на невидимой странице.
ФормаВладелец.ТекущийЭлемент = ПолеТекста.ЭлементФормы;
ирКлиент.ПоказатьОшибкуВТекстеПрограммыЛкс(ПолеТекста,,,,, выхИнформацияОбОшибке);
КонецЕсли;
Возврат Ложь;
КонецПопытки;
КонецФункции
Функция ЗаполнитьДоступныеТаблицы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С(Знач СтрокаПараметраТаблицы, Знач ДиалектSQL = "") Экспорт
Если ДиалектSQL = "" Тогда
ДиалектSQL = мДиалектSQL;
КонецЕсли;
Результат = Истина
И Найти(НРег(СтрокаПараметраТаблицы.Имя), "периодичность") = 1
И ирОбщий.СтрокиРавныЛкс(ДиалектSQL, "1С");
Возврат Результат;
КонецФункции
Функция ПоляДоступнойТаблицы(Знач СтрокаДоступнойТаблицы, Знач ПараметрыТаблицы = Неопределено, Знач ДиалектSQL = "", Знач ПородившийЗапрос = Неопределено) Экспорт
Если ДиалектSQL = "" Тогда
ДиалектSQL = мДиалектSQL;
КонецЕсли;
ПолноеИмяТаблицы = СтрокаДоступнойТаблицы.ПолноеИмя;
ИспользоватьКэширование = Истина
И СтрокаДоступнойТаблицы.Тип <> "ВременнаяТаблица"
И СтрокаДоступнойТаблицы.Тип <> "Параметр"
И ТипЗнч(Конфигурация) <> Тип("ОбъектМетаданныхКонфигурация");
Если ИспользоватьКэширование Тогда
ТаблицаПолей = мДоступныеПоляТаблиц[ПолноеИмяТаблицы];
Если ТаблицаПолей <> Неопределено Тогда
Возврат ТаблицаПолей;
КонецЕсли;
КонецЕсли;
ТаблицаПолей = Новый ТаблицаЗначений;
ТаблицаПолей.Колонки.Добавить("Имя", Новый ОписаниеТипов("Строка"));
ТаблицаПолей.Колонки.Добавить("ТипЗначения", Новый ОписаниеТипов("ОписаниеТипов"));
ТаблицаПолей.Колонки.Добавить("Метаданные");
Если СтрокаДоступнойТаблицы.Тип = "ВременнаяТаблица" Тогда
КолонкиРезультата = Новый Массив();
Если ПородившийЗапрос <> Неопределено Тогда
//КолонкиРезультата = ПородившийЗапрос.ЧастиОбъединения[0].ВыбранныеПоля;
КолонкиРезультата = ПородившийЗапрос.ПоляОбъединения;
Иначе
ТекстЗапроса = "SELECT * FROM " + ПолноеИмяТаблицы + " WHERE 1=0";
Если ТипЗнч(КонтекстВыполнения) = Тип("Запрос") Тогда
ВременныйЗапрос = Новый Запрос;
ВременныйЗапрос.МенеджерВременныхТаблиц = КонтекстВыполнения.МенеджерВременныхТаблиц;
ВременныйЗапрос.Текст = ТекстЗапроса;
РезультатВременногоЗапроса = Неопределено;
Попытка
РезультатВременногоЗапроса = ВременныйЗапрос.Выполнить();
Исключение
КонецПопытки;
Если РезультатВременногоЗапроса <> Неопределено Тогда
КолонкиРезультата = РезультатВременногоЗапроса.Выгрузить();
КолонкиРезультата = ирОбщий.ТаблицаСКолонкамиБезТипаNullЛкс(КолонкиРезультата, Ложь);
КолонкиРезультата = КолонкиРезультата.Колонки;
КонецЕсли;
ИначеЕсли ирОбщий.СтрокиРавныЛкс(ДиалектSQL, "WQL") Тогда
//
Иначе // ADO
Попытка
РезультатВременногоЗапроса = Конфигурация.Execute(ТекстЗапроса);
Исключение
ОписаниеОшибки = ОписаниеОшибки();
КонецПопытки;
Если РезультатВременногоЗапроса <> Неопределено Тогда
РезультатТаблица = Новый ТаблицаЗначений;
ирОбщий.ПолучитьКолонкиRecordsetADOЛкс(РезультатТаблица, РезультатВременногоЗапроса, Истина);
КолонкиРезультата = РезультатТаблица.Колонки;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Для Каждого ВыбранноеПоле Из КолонкиРезультата Цикл
Если ВыбранноеПоле.Имя = "" Тогда
ВызватьИсключение "Не определены имена полей таблицы """ + ПолноеИмяТаблицы + """";
КонецЕсли;
СтрокаПоля = ТаблицаПолей.Добавить();
СтрокаПоля.Имя = ВыбранноеПоле.Имя;
СтрокаПоля.ТипЗначения = ВыбранноеПоле.ТипЗначения;
КонецЦикла;
ИначеЕсли СтрокаДоступнойТаблицы.Тип = "Параметр" Тогда
КолонкиРезультата = Новый Массив();
ТаблицаПараметр = Неопределено;
Если КонтекстВыполнения.Параметры.Свойство(СтрокаДоступнойТаблицы.Имя, ТаблицаПараметр) Тогда
КолонкиРезультата = ТаблицаПараметр.Колонки;
КонецЕсли;
Для Каждого ВыбранноеПоле Из КолонкиРезультата Цикл
СтрокаПоля = ТаблицаПолей.Добавить();
СтрокаПоля.Имя = ВыбранноеПоле.Имя;
СтрокаПоля.ТипЗначения = ВыбранноеПоле.ТипЗначения;
КонецЦикла;
ИначеЕсли ТипЗнч(Конфигурация) = Тип("ОбъектМетаданныхКонфигурация") Тогда
ИндексПараметраПериодичность = Неопределено;
ОпределениеПараметраПериодичность = "";
Если ПараметрыТаблицы <> Неопределено Тогда
Для ИндексПараметра = 0 По ПараметрыТаблицы.Количество() - 1 Цикл
СтрокаПараметраТаблицы = ПараметрыТаблицы[ИндексПараметра];
Если ЭтоПараметрПериодичность1С(СтрокаПараметраТаблицы) Тогда
ИндексПараметраПериодичность = ИндексПараметра;
ОпределениеПараметраПериодичность = СтрокаПараметраТаблицы.Определение;
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
ПоляТаблицыБД = ирОбщий.ПоляТаблицыМДЛкс(ПолноеИмяТаблицы,, ИндексПараметраПериодичность, ОпределениеПараметраПериодичность, Ложь);
#Если Сервер И Не Сервер Тогда
ПоляТаблицыБД = НайтиПоСсылкам().Колонки;
#КонецЕсли
Если ПоляТаблицыБД <> Неопределено Тогда
_РежимОтладки = Ложь;
Если _РежимОтладки Тогда // Можно менять на Истина в точке останова, например условием ирОбщий.ПрЛкс(_РежимОтладки, 1, 1)
// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
Для Каждого ПолеТаблицыБД Из ПоляТаблицыБД Цикл
//Если ПолеТаблицыБД.ТипЗначения.СодержитТип(Тип("ТаблицаЗначений")) Тогда
// Продолжить;
//КонецЕсли;
СтрокаПоля = ТаблицаПолей.Добавить();
СтрокаПоля.Имя = ПолеТаблицыБД.Имя;
СтрокаПоля.ТипЗначения = ПолеТаблицыБД.ТипЗначения;
СтрокаПоля.Метаданные = ПолеТаблицыБД.Метаданные;
КонецЦикла;
Иначе
// Однострочный код использован для ускорения при разрешенной отладке. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика"
Для Каждого ПолеТаблицыБД Из ПоляТаблицыБД Цикл         СтрокаПоля = ТаблицаПолей.Добавить();   СтрокаПоля.Имя = ПолеТаблицыБД.Имя;   СтрокаПоля.ТипЗначения = ПолеТаблицыБД.ТипЗначения;   СтрокаПоля.Метаданные = ПолеТаблицыБД.Метаданные;   КонецЦикла;  
КонецЕсли;
ирОбщий.ДополнитьТаблицуПолейТаблицыБДВиртуальнымиПолямиЛкс(ТаблицаПолей, СтрокаДоступнойТаблицы, Истина);
КонецЕсли;
Иначе
СтрокаДоступнойТаблицы = ДоступнаяТаблицаПоИмениВыбранной(ПолноеИмяТаблицы);
Если ирОбщий.СтрокиРавныЛкс(ДиалектSQL, "WQL") Тогда
wbemFlagUseAmendedQualifiers = 131072; //&H20000
ОписаниеКласса = Конфигурация.Get(СтрокаДоступнойТаблицы.Имя, wbemFlagUseAmendedQualifiers);
ТаблицаКласса = Новый ТаблицаЗначений;
МассивКоллекцийСвойств = Новый Массив();
МассивКоллекцийСвойств.Добавить(ОписаниеКласса.Properties_);
//Если СобиратьСистемныеСвойстваWMI Тогда
// МассивКоллекцийСвойств.Добавить(ОписаниеКласса.SystemProperties_);
//КонецЕсли;
Для Каждого КоллекцияСвойств Из МассивКоллекцийСвойств Цикл
Для Каждого Свойство Из КоллекцияСвойств Цикл
ИмяТипа = ирОбщий.ИмяТипаИзКвалификаторовWMIЛкс(Свойство);
Попытка
ОписаниеТипов = Новый ОписаниеТипов(ИмяТипа,,,, Новый КвалификаторыСтроки(1024)); // Доделать распознавание типов
Исключение
ОписаниеТипов = Новый ОписаниеТипов();
КонецПопытки;
ПредставлениеСвойства = ирОбщий.ПолучитьОписаниеЭлементаWMIЛкс(Свойство, "DisplayName");
ТаблицаКласса.Колонки.Добавить(, ОписаниеТипов, ПредставлениеСвойства);
СтрокаПоля = ТаблицаПолей.Добавить();
СтрокаПоля.Имя = Свойство.Name;
СтрокаПоля.ТипЗначения = ОписаниеТипов;
//СтрокаПоля.Описание = ПредставлениеСвойства;
КонецЦикла;
КонецЦикла;
Иначе // ADO
Фильтры = Новый Массив();
Фильтры.Добавить(); //TABLE_CATALOG
Если ЗначениеЗаполнено(СтрокаДоступнойТаблицы.Схема) Тогда //TABLE_SCHEMA
Фильтры.Добавить(СтрокаДоступнойТаблицы.Схема);
Иначе
Фильтры.Добавить(Неопределено);
КонецЕсли;
Фильтры.Добавить(СтрокаДоступнойТаблицы.Имя); // TABLE_NAME
Фильтры = Новый COMSafeArray(Фильтры, "VT_VARIANT");
Состояние("Запрашиваем поля " + ПолноеИмяТаблицы + "...");
ОписаниеПолейRecordSet = Конфигурация.OpenSchema(4, Фильтры); //adSchemaColumns
ADOUtils = мПлатформа.ПолучитьADOUtils();
Если ADOUtils <> Неопределено Тогда
ОписаниеПолейТЗ = ADOUtils.ADORecordsetToValueTable(ОписаниеПолейRecordSet);
Для Каждого СтрокаТЗ Из ОписаниеПолейТЗ Цикл
СтрокаПоля = ТаблицаПолей.Добавить();
СтрокаПоля.Имя = СтрокаТЗ.COLUMN_NAME;
ЧисловаяРазрядность = СтрокаТЗ.NUMERIC_SCALE;
ДлинаТипа = СтрокаТЗ.CHARACTER_MAXIMUM_LENGTH;
ЧисловаяТочность = СтрокаТЗ.NUMERIC_PRECISION;
НомерТипа = СтрокаТЗ.DATA_TYPE;
FieldADO = ирОбщий.FieldADOЛкс(СтрокаПоля.Имя, НомерТипа, ДлинаТипа, ЧисловаяТочность, ЧисловаяРазрядность);
СтрокаПоля.ТипЗначения = ирОбщий.FieldADO_ПолучитьТип1CЛкс(FieldADO, Истина);
КонецЦикла;
Иначе
Пока Не ОписаниеПолейRecordSet.EOF() Цикл
СтрокаПоля = ТаблицаПолей.Добавить();
СтрокаПоля.Имя = ОписаниеПолейRecordSet.Fields("COLUMN_NAME").Value;
ЧисловаяРазрядность = ОписаниеПолейRecordSet.Fields("NUMERIC_SCALE").Value;
ДлинаТипа = ОписаниеПолейRecordSet.Fields("CHARACTER_MAXIMUM_LENGTH").Value;
ЧисловаяТочность = ОписаниеПолейRecordSet.Fields("NUMERIC_PRECISION").Value;
НомерТипа = ОписаниеПолейRecordSet.Fields("DATA_TYPE").Value;
FieldADO = ирОбщий.FieldADOЛкс(СтрокаПоля.Имя, НомерТипа, ДлинаТипа, ЧисловаяТочность, ЧисловаяРазрядность);
СтрокаПоля.ТипЗначения = ирОбщий.FieldADO_ПолучитьТип1CЛкс(FieldADO, Истина);
ОписаниеПолейRecordSet.MoveNext();
КонецЦикла;
КонецЕсли;
КонецЕсли;
Состояние();
КонецЕсли;
Если ИспользоватьКэширование Тогда
мДоступныеПоляТаблиц[ПолноеИмяТаблицы] = ТаблицаПолей;
КонецЕсли;
Возврат ТаблицаПолей;
КонецФункции
Функция ПолноеИмяВременнойТаблицы(Знач КраткоеИмяТаблицы, Знач ИсточникДанных1С = Неопределено) Экспорт
Результат = КраткоеИмяТаблицы;
Если Истина
И Найти(КраткоеИмяТаблицы, ".") = 0
И мПараметрыДиалектаSQL.Диалект = "1С"
И ЗначениеЗаполнено(ИсточникДанных1С)
И ИсточникДанных1С <> "<Локальный>"
Тогда
Результат = "ВнешнийИсточникДанных." + ИсточникДанных1С + ".ВременнаяТаблица." + Результат;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция КраткоеИмяВременнойТаблицы(ЛюбоеИмяТаблицы) Экспорт
Результат = ЛюбоеИмяТаблицы;
Если Истина
И мПараметрыДиалектаSQL.Диалект = "1С"
И Найти(Результат, ".") > 0
Тогда
Результат = ирОбщий.ПоследнийФрагментЛкс(Результат);
КонецЕсли;
Возврат Результат;
КонецФункции
Процедура ОчиститьДоступныеВременныеТаблицы(ТаблицаДоступныхТаблиц = Неопределено) Экспорт
Если ТаблицаДоступныхТаблиц = Неопределено Тогда
ТаблицаДоступныхТаблиц = ДоступныеТаблицы;
КонецЕсли;
ирОбщий.УдалитьСтрокиТаблицыИлиДереваПоЗначениюВКолонкеЛкс(ТаблицаДоступныхТаблиц, "Тип", "ВременнаяТаблица");
КонецПроцедуры
Процедура ОчиститьДоступныеНеВременныеТаблицы() Экспорт
ДоступныеВременныеТаблицы = ДоступныеТаблицы.Выгрузить(Новый Структура("Тип", "ВременнаяТаблица"));
ДоступныеТаблицы.Очистить();
ДоступныеТаблицы.Загрузить(ДоступныеВременныеТаблицы);
КонецПроцедуры
Функция ПрефиксПараметра() Экспорт
Возврат мПараметрыДиалектаSQL.ПрефиксПараметра;
КонецФункции
// Вызывает конструктор запросов и передает ему текст из текстового поля.
//
// Параметры:
// Нет.
//
Функция ВызватьКонструкторЗапросов(Знач ИспользуемСобственныйКонструктор = Неопределено) Экспорт
Если ирОбщий.ПроверитьПлатформаНеWindowsЛкс(,, Истина) Тогда
Возврат Ложь;
КонецЕсли;
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
РежимТолькоПросмотр = Ложь
Или ПолеТекста.ТолькоПросмотр()
Или ФормаВладелец.ТолькоПросмотр;
Если РежимТолькоПросмотр Тогда
Ответ = Вопрос("Текст запроса не может быть изменен. Открыть конструктор без возможности сохранения изменений?",
РежимДиалогаВопрос.ОКОтмена);
Если Ответ = КодВозвратаДиалога.Отмена Тогда
Возврат Ложь;
КонецЕсли;
КонецЕсли;
Если Не ирКэш.ЛиПлатформаWindowsЛкс() Тогда
ИспользуемСобственныйКонструктор = Ложь
КонецЕсли;
ПредпочитаюСобственныйКонструкторЗапроса = Ложь;
Если ИспользуемСобственныйКонструктор = Неопределено Тогда
ПредпочитаюСобственныйКонструкторЗапроса = ирОбщий.ВосстановитьЗначениеЛкс(ИмяКласса + ".ПредпочитаюСобственныйКонструкторЗапроса");
Если ПредпочитаюСобственныйКонструкторЗапроса = Неопределено Тогда
Ответ = Вопрос("Подсистема имеет собственный конструктор запроса. Приоритет его использования задается в настройках компоненты ""Контекстная подсказка"".
|Хотите установить приоритет его использования?", РежимДиалогаВопрос.ДаНет);
ПредпочитаюСобственныйКонструкторЗапроса = Ответ = КодВозвратаДиалога.Да;
ирОбщий.СохранитьЗначениеЛкс(ИмяКласса + ".ПредпочитаюСобственныйКонструкторЗапроса", ПредпочитаюСобственныйКонструкторЗапроса);
КонецЕсли;
КонецЕсли;
ИспользуемСобственныйКонструктор = Ложь
Или ИспользуемСобственныйКонструктор = Истина
Или мДиалектSQL <> "1С"
Или ПредпочитаюСобственныйКонструкторЗапроса;
Если ИспользуемСобственныйКонструктор Тогда
КонструкторЗапроса = ПолучитьФорму("КонструкторЗапроса");
КонструкторЗапроса.Конфигурация = Конфигурация;
Иначе
КонструкторЗапроса = Новый КонструкторЗапроса;
КонецЕсли;
//ОбрамитьСобранныйТекстСкобками = Ложь;
Если ЯзыкПрограммы = 1 Тогда
Если СтрДлина(СокрЛП(ВыделенныйТекст())) < 6 И Не ЭтоЧастичныйЗапрос Тогда
ТекстЗапроса = ПолеТекста.ПолучитьТекст();
НачальнаяСтрокаЗапроса = 0;
НачальнаяКолонкаЗапроса = 0;
Иначе
ТекстЗапроса = ВыделенныйТекст();
//Если Не ЗначениеЗаполнено(ТекстЗапроса) И ЭтоЧастичныйЗапрос Тогда
// ТекстЗапроса = "ВЫБРАТЬ 1";
// ОбрамитьСобранныйТекстСкобками = Истина;
//КонецЕсли;
НачальнаяСтрокаЗапроса = мНачальнаяСтрока - 1;
НачальнаяКолонкаЗапроса = мНачальнаяКолонка - 1;
КонецЕсли;
КонструкторЗапроса.РежимКомпоновкиДанных = РежимКомпоновкиДанных;
//КонструкторЗапроса.АвтодобавлениеПредставлений = Истина;
МассивВременныхТаблиц = Новый Массив;
Если Не ПустаяСтрока(ТекстЗапроса) Тогда
Если Истина
И ТипЗнч(КонтекстВыполнения) = Тип("Запрос")
И Не ИспользуемСобственныйКонструктор
Тогда
СтарыйТекстЗапроса = ТекстЗапроса;
ИнформацияОбОшибке = ПроверитьТекстИВернутьОшибку(ТекстЗапроса);
Попытка
ТекстЗапроса = мПлатформа.ЗамаскироватьВременныеТаблицы(КонтекстВыполнения, ТекстЗапроса, МассивВременныхТаблиц);
Исключение
ФормаВладелец.ТекущийЭлемент = ПолеТекста.ЭлементФормы;
ирКлиент.ПоказатьОшибкуВТекстеПрограммыЛкс(ПолеТекста, , , Истина,, ИнформацияОбОшибке());
Возврат Ложь;
КонецПопытки;
НоваяИнформацияОбОшибке = ПроверитьТекстИВернутьОшибку(ТекстЗапроса);
Если Истина
И НоваяИнформацияОбОшибке <> Неопределено
И ИнформацияОбОшибке = Неопределено
И Найти(ирОбщий.ПодробноеПредставлениеОшибкиЛкс(НоваяИнформацияОбОшибке), "Ожидается псевдоним запроса") > 0
Тогда
// Сюда попадаем, когда у временной таблицы нет псевдонима
ирОбщий.СообщитьСУчетомМодальностиЛкс("В запросе присутствуют временные таблицы без псевдонимов. "
+ "Для максимальной функциональности рекомендуется задать каждой временной таблице псевдоним",, СтатусСообщения.Внимание);
МассивВременныхТаблиц = Новый Массив;
ТекстЗапроса = СтарыйТекстЗапроса;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Иначе
РазобратьТекущийКонтекст();
ТекстПоля = ПолеТекста.ПолучитьТекст();
РегВыражение.Global = Истина;
РегВыражение.MultiLine = Ложь;
РегВыражение.Pattern = шСтрокаПрограммы;
Результат = РегВыражение.НайтиВхождения(ТекстПоля);
Успех = Ложь;
ДлинаТекстаДо = ТекущаяПозицияВТекстеОдномерная();
Для Каждого Вхождение Из Результат Цикл
ПозицияВхождения = Вхождение.FirstIndex;
Если Истина
И (ПозицияВхождения + 1) <= ДлинаТекстаДо
И (ПозицияВхождения + Вхождение.Length + 1) >= ДлинаТекстаДо
Тогда
ПолеТекста.УстановитьГраницыВыделения(ПозицияВхождения + 1, ПозицияВхождения + Вхождение.Length + 1);
Успех = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
ПолеТекста.ПолучитьГраницыВыделения(НачальнаяСтрокаЗапроса, НачальнаяКолонкаЗапроса, , );
НачальнаяСтрокаЗапроса = НачальнаяСтрокаЗапроса - 1;
НачальнаяКолонкаЗапроса = НачальнаяСтрокаЗапроса - 1;
Если Успех Тогда
ТекстЗапроса = ВыделенныйТекст();
Если Прав(ТекстЗапроса, 1) <> """" Тогда
ТекстЗапроса = ТекстЗапроса + """";
КонецЕсли;
ТекстЗапроса = Вычислить(ТекстЗапроса);
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "|", "");
Иначе
ТекстЗапроса = "";
КонецЕсли;
КонецЕсли;
Если ИспользуемСобственныйКонструктор Тогда
Парсер = мПлатформа.мПолучитьПарсер("ГрамматикаЯзыкаЗапросов");
Если Парсер = Неопределено Тогда
ирОбщий.СообщитьСУчетомМодальностиЛкс("Компонента анализа текста запроса не подключена");
Возврат Ложь;
КонецЕсли;
КонецЕсли;
Если Не ПустаяСтрока(ТекстЗапроса) Тогда
Если ИспользуемСобственныйКонструктор Тогда
РезультатРазбора = ЗагрузитьТекстВКонструктор(ТекстЗапроса, КонструкторЗапроса,, мДиалектSQL,, НачальнаяСтрокаЗапроса);
Если Не РезультатРазбора Тогда
Возврат Ложь;
КонецЕсли;
Иначе
СтруктуруРезультатаПакетногоЗапроса = мПлатформа.СтруктураРезультатаПакетногоЗапроса(ТекстЗапроса);
Если СтруктуруРезультатаПакетногоЗапроса.Количество() > 0 Тогда
Ответ = Вопрос("В комментариях обнаружены имена запросов. Стандартный конструктор запросов их удалит. Продолжить?", РежимДиалогаВопрос.ОКОтмена);
Если Ответ <> КодВозвратаДиалога.ОК Тогда
Возврат Ложь;
КонецЕсли;
КонецЕсли;
Попытка
КонструкторЗапроса.Текст = ТекстЗапроса;
Исключение
ФормаВладелец.ТекущийЭлемент = ПолеТекста.ЭлементФормы;
ирКлиент.ПоказатьОшибкуВТекстеПрограммыЛкс(ПолеТекста, НачальнаяСтрокаЗапроса, НачальнаяКолонкаЗапроса, Истина,, ИнформацияОбОшибке());
Возврат Ложь;
КонецПопытки;
КонецЕсли;
Иначе
Если ИспользуемСобственныйКонструктор Тогда
//КонструкторЗапроса.УстановитьДиалектSQL(мДиалектSQL);
КонструкторЗапроса.УстановитьДанные();
КонецЕсли;
КонецЕсли;
РезультатФормы = КонструкторЗапроса.ОткрытьМодально();
Если РезультатФормы = Истина Тогда
Если Не РежимТолькоПросмотр Тогда
НовыйТекстЗапроса = КонструкторЗапроса.Текст;
Если Истина
И ТипЗнч(Конфигурация) = Тип("ОбъектМетаданныхКонфигурация")
И ТипЗнч(КонтекстВыполнения) = Тип("Запрос")
Тогда
//RegExp.Global = Истина;
//RegExp.MultiLine = Ложь;
//RegExp.IgnoreCase = Истина;
//// Допустим 1 уровень скобок.
//шОдинарныеСкобки = "\([^\)\(]*?\)";
//шИмяВременнойТаблицы = "";
//Для Каждого ПодмененнаяВременнаяТаблица Из МассивВременныхТаблиц Цикл
// шИмяВременнойТаблицы = шИмяВременнойТаблицы + "|" + ПодмененнаяВременнаяТаблица;
//КонецЦикла;
//шИмяВременнойТаблицы = Сред(шИмяВременнойТаблицы, 2);
//RegExp.Pattern = "\(ВЫБРАТЬ(?:" + шОдинарныеСкобки + "|[^$\(\)])*?""ВременнаяТаблица"" = ""(" + шИмяВременнойТаблицы + ")""\)";
//НовыйТекстЗапроса = RegExp.Заменить(НовыйТекстЗапроса, "$1");
НовыйТекстЗапроса = мПлатформа.РазмаскироватьВременныеТаблицы(НовыйТекстЗапроса, МассивВременныхТаблиц);
КонецЕсли;
Если ЯзыкПрограммы = 1 Тогда
Если Не ЭтоЧастичныйЗапрос И НачальнаяСтрокаЗапроса = 0 Тогда
ВыделитьВесьТекст();
КонецЕсли;
//Если ОбрамитьСобранныйТекстСкобками Тогда
// НовыйТекстЗапроса = "(" + НовыйТекстЗапроса + ")";
//КонецЕсли;
Если ИспользуемСобственныйКонструктор Тогда
ЗаменитьВыделенныйТекстЗапросаСоСнятиемВыделения(НовыйТекстЗапроса, КонструкторЗапроса.мНомерТекущейСтрокиВСобранномТексте);
Иначе
ВыделенныйТекст(НовыйТекстЗапроса);
КонецЕсли;
ПослеУстановкиВыделенногоМногострочногоТекста();
Иначе
НовыйТекстЗапроса = ирОбщий.ТекстВВыражениеВстроенногоЯзыкаЛкс(НовыйТекстЗапроса);
ЧислоСтрокЗамены = СтрЧислоСтрок(НовыйТекстЗапроса);
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.УстановитьТекст(НовыйТекстЗапроса);
СдвинутыйТекст = ТекстовыйДокумент.ПолучитьСтроку(1);
ЗаменаТабуляции = ирОбщий.СтрокаПовторомЛкс(" ", ШиринаТабуляции);
ТекстНачальнойСтроки = ПолеТекста.ПолучитьСтроку(мНачальнаяСтрока);
ДлинаНачалаСтроки = СтрДлина(ТекстНачальнойСтроки) - СтрДлина(СокрЛ(ТекстНачальнойСтроки));
НачалоСтроки = Лев(ТекстНачальнойСтроки, ДлинаНачалаСтроки);
ДлинаРазвернутогоНачалаСтроки = СтрДлина(СтрЗаменить(НачалоСтроки, Символы.Таб, ЗаменаТабуляции));
ЧислоТабуляций = ДлинаРазвернутогоНачалаСтроки / ШиринаТабуляции;
ЧислоПробелов = ДлинаРазвернутогоНачалаСтроки % ШиринаТабуляции;
НачалоНовойСтроки = ирОбщий.СтрокаПовторомЛкс(Символы.Таб, ЧислоТабуляций);
НачалоНовойСтроки = НачалоНовойСтроки + ирОбщий.СтрокаПовторомЛкс(" ", ЧислоПробелов);
Для Счетчик = 2 По ЧислоСтрокЗамены Цикл
ТекущаяСтрокаВставки = ТекстовыйДокумент.ПолучитьСтроку(Счетчик);
СдвинутыйТекст = СдвинутыйТекст + Символы.ПС + НачалоНовойСтроки + ТекущаяСтрокаВставки;
КонецЦикла;
ВыделенныйТекст(СдвинутыйТекст);
ПослеУстановкиВыделенногоМногострочногоТекста();
КонецЕсли;
Возврат Истина;
КонецЕсли;
КонецЕсли;
Возврат Ложь;
КонецФункции
Процедура ЗаменитьВыделенныйТекстЗапросаСоСнятиемВыделения(Знач НовыйТекстЗапроса, Знач НомерТекущейСтрокиВСобранномТексте = 0)
ПолучитьНомерТекущейСтроки();
ВыделенныйТекст(НовыйТекстЗапроса);
мНачальнаяСтрока = мНачальнаяСтрока + НомерТекущейСтрокиВСобранномТексте;
мНачальнаяКолонка = 1;
мКонечнаяСтрока = мНачальнаяСтрока;
мКонечнаяКолонка = мНачальнаяКолонка;
КонецПроцедуры
Процедура ПоказатьТекущиеКоординаты(ПолеТекста, СтартоваяСтрокаДляОтображенияОшибок = 0)
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
// Антибаг платформы 8.1 . Терялся фокус
ФормаВладелец.ТекущийЭлемент = ПолеТекста.ЭлементФормы;
ПолеТекста.ПоказатьОшибку(мПарсер.CurrentLineNumber() + СтартоваяСтрокаДляОтображенияОшибок, мПарсер.CurrentColumnNumber(), ФормаВладелец);
КонецПроцедуры
Функция ПолучитьКоординатыВТекстеЗапроса(ПолеТекста, СтартоваяСтрокаДляОтображенияОшибок = 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 = Неопределено,
ИменованныеПараметры = Неопределено, СтартоваяСтрокаДляОтображенияОшибок = 0) Экспорт
Если ТекстЗапроса = Неопределено Тогда
ТекстЗапроса = ПолеТекста.ПолучитьТекст();
КонецЕсли;
Если КонструкторЗапроса <> Неопределено Тогда
КонструкторЗапроса.УстановитьДиалектSQL(ДиалектSQL, ИменованныеПараметры);
КонецЕсли;
ТаблицаКомментариев = Неопределено;
БылиПотери = Неопределено;
НачальныйТокен = РазобратьТекстЗапроса(ТекстЗапроса, СокращенноеДерево,,, Истина, ТаблицаКомментариев, БылиПотери, СтартоваяСтрокаДляОтображенияОшибок);
Если Истина
И НачальныйТокен <> Неопределено
И КонструкторЗапроса <> Неопределено
Тогда
КонструкторЗапроса.СлужебноеПолеТекста.УстановитьТекст(ТекстЗапроса);
Если ДиалектSQL = Неопределено Тогда
ДиалектSQL = мДиалектSQL;
КонецЕсли;
КонструкторЗапроса.ЗапросыПакета.Очистить();
КонструкторЗапроса.УстановитьДанные(НачальныйТокен, ТаблицаКомментариев, БылиПотери,, ПолучитьНомерТекущейСтроки());
КонецЕсли;
Возврат НачальныйТокен <> Неопределено;
КонецФункции
// Возвращает начальный токен (Структура) построенной структуры запроса.
//
// Параметры:
// ТекстЗапроса - -
// СокращенноеДерево - -
// ОбновлятьСостояние - -
// пПолеТекста - ОбработкаОбъект.ирПолеТекста, Неопределено, Null - при Неопределено будет использоваться связанное поле, при Null поле не будет использоваться
// СообщатьОПропущенныхТерминалах - -
// выхТаблицаКомментариев - -
// выхБылиПотери - -
// СтартоваяСтрокаДляОтображенияОшибок - -
//
// Возвращаемое значение:
// -
//
Функция РазобратьТекстЗапроса(ТекстЗапроса, СокращенноеДерево = Ложь, ОбновлятьСостояние = Истина, Знач пПолеТекста = Неопределено, СообщатьОПропущенныхТерминалах = Ложь, выхТаблицаКомментариев = Неопределено,
выхБылиПотери = Неопределено, СтартоваяСтрокаДляОтображенияОшибок = 0, Знач ПоказыватьОшибки = Истина) Экспорт
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
мПарсер = мПлатформа.мПолучитьПарсер("ГрамматикаЯзыкаЗапросов");
Если мПарсер = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
Если пПолеТекста = Null Тогда
пПолеТекста = Неопределено;
ИначеЕсли пПолеТекста = Неопределено Тогда
пПолеТекста = ПолеТекста;
Иначе
пПолеТекста = ирКлиент.ОболочкаПоляТекстаЛкс(пПолеТекста);
КонецЕсли;
Если ОбновлятьСостояние Тогда
ирОбщий.СостояниеЛкс("Синтаксический разбор...");
КонецЕсли;
выхТаблицаКомментариев = Новый ТаблицаЗначений;
выхТаблицаКомментариев.Колонки.Добавить("Позиция", Новый ОписаниеТипов("Число"));
выхТаблицаКомментариев.Колонки.Добавить("Текст", Новый ОписаниеТипов("Строка"));
выхТаблицаКомментариев.Колонки.Добавить("ЭтоРасширение", Новый ОписаниеТипов("Булево"));
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 + """"
+ ", ожидается: " + ПолучитьСтрокуОжидаемыхТокенов();
ирОбщий.СообщитьСУчетомМодальностиЛкс(ТекстОшибки,, СтатусСообщения.Важное);
Если пПолеТекста <> Неопределено Тогда
ПоказатьТекущиеКоординаты(пПолеТекста, СтартоваяСтрокаДляОтображенияОшибок);
КонецЕсли;
КонецЕсли;
КонецЕсли;
ИначеЕсли Ответ = gpMsgReduction Тогда
Если СокращенноеДерево Тогда
//ИмяПравила = мПарсер.CurrentReduction.ParentRule.RuleNonterminal.Name;
ИмяПравила = мПарсер.CurrentRuleName();
Если Ложь // Есть сомнения, что это работает как задумано
Или ИмяПравила = "Table"
Или ИмяПравила = "TableName"
Тогда
мПарсер.TrimReductions = Ложь;
TrimReductions = Ложь;
КонецЕсли;
КонецЕсли;
ИначеЕсли Ответ = gpMsgAccept Тогда
Закончили = Истина;
ИначеЕсли Ответ = gpMsgCommentError Тогда
ИначеЕсли Ответ = gpMsgTokenRead Тогда
Если мПарсер.IsCurrentTokenComment() Тогда
// Храним 2 последних токена
ТекущийТокен = мПарсер.CurrentToken();
ПрочитатьКомментарий(выхТаблицаКомментариев, ТекущийТокен, пПолеТекста, СообщатьОПропущенныхТерминалах, СтартоваяСтрокаДляОтображенияОшибок);
КонецЕсли;
ИначеЕсли Ответ = gpMsgInternalError Тогда
Закончили = Истина;
ИначеЕсли Ответ = gpMsgNotLoadedError Тогда
Закончили = Истина;
КонецЕсли;
КонецЦикла;
Если ОбновлятьСостояние Тогда
ирОбщий.СостояниеЛкс("");
КонецЕсли;
Если Ответ = 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Лкс(,, Истина) Тогда
Возврат Ложь;
КонецЕсли;
РежимТолькоПросмотр = Ложь
Или ПолеТекста.ТолькоПросмотр()
Или ФормаВладелец.ТолькоПросмотр;
Если РежимТолькоПросмотр Тогда
Ответ = Вопрос("Текст не может быть изменен. Открыть редактор без возможности сохранения измений?",
РежимДиалогаВопрос.ОКОтмена);
Если Ответ = КодВозвратаДиалога.Отмена Тогда
Возврат Ложь;
КонецЕсли;
КонецЕсли;
ТекстСтроковогоЛитерала = ВыделитьТекстТекущегоСтроковогоЛитерала();
ФормаРедактора = мПлатформа.ПолучитьФорму("Текст", , Новый УникальныйИдентификатор);
ФормаРедактора.НачальноеЗначениеВыбора = ТекстСтроковогоЛитерала;
Если ФормаРедактора.ОткрытьМодально() <> Неопределено Тогда
Если Не РежимТолькоПросмотр Тогда
НовыйТекстЗапроса = ФормаРедактора.Текст;
НовыйТекстЗапроса = ирОбщий.ТекстВВыражениеВстроенногоЯзыкаЛкс(НовыйТекстЗапроса);
ЗаменаТабуляции = ирОбщий.СтрокаПовторомЛкс(" ", ШиринаТабуляции);
ТекстНачальнойСтроки = ПолеТекста.ПолучитьСтроку(мНачальнаяСтрока);
ДлинаНачалаСтроки = СтрДлина(ТекстНачальнойСтроки) - СтрДлина(СокрЛ(ТекстНачальнойСтроки));
НачалоСтроки = Лев(ТекстНачальнойСтроки, ДлинаНачалаСтроки);
ДлинаРазвернутогоНачалаСтроки = СтрДлина(СтрЗаменить(НачалоСтроки, Символы.Таб, ЗаменаТабуляции));
ЧислоТабуляций = ДлинаРазвернутогоНачалаСтроки / ШиринаТабуляции;
ЧислоПробелов = ДлинаРазвернутогоНачалаСтроки % ШиринаТабуляции;
НачалоНовойСтроки = ирОбщий.СтрокаПовторомЛкс(Символы.Таб, ЧислоТабуляций);
НачалоНовойСтроки = НачалоНовойСтроки + ирОбщий.СтрокаПовторомЛкс(" ", ЧислоПробелов);
ВыделенныйТекст(СтрЗаменить(НовыйТекстЗапроса, Символы.ПС, Символы.ПС + НачалоНовойСтроки));
ПослеУстановкиВыделенногоМногострочногоТекста();
Возврат Истина;
КонецЕсли;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ВыделитьТекстТекущегоСтроковогоЛитерала() Экспорт
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
РазобратьТекущийКонтекст();
ТекстПоля = ПолеТекста.ПолучитьТекст();
РегВыражение.Global = Истина;
РегВыражение.MultiLine = Ложь;
РегВыражение.Pattern = шСтрокаПрограммы;
Результат = РегВыражение.НайтиВхождения(ТекстПоля);
Успех = Ложь;
ДлинаТекстаДо = ТекущаяПозицияВТекстеОдномерная();
Для Каждого Match Из Результат Цикл
ПозицияВхождения = Match.FirstIndex;
Если Истина
И (ПозицияВхождения + 1) <= ДлинаТекстаДо
И (ПозицияВхождения + Match.Length + 1) >= ДлинаТекстаДо
Тогда
ПолеТекста.УстановитьГраницыВыделения(ПозицияВхождения + 1, ПозицияВхождения + Match.Length + 1,, ФормаВладелец);
Успех = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
НачальнаяСтрокаЗапроса = 0;
НачальнаяКолонкаЗапроса = 0;
ПолеТекста.ПолучитьГраницыВыделения(НачальнаяСтрокаЗапроса, НачальнаяКолонкаЗапроса, , );
НачальнаяСтрокаЗапроса = НачальнаяСтрокаЗапроса - 1;
НачальнаяКолонкаЗапроса = НачальнаяСтрокаЗапроса - 1;
Если Успех Тогда
ТекстСтроковогоЛитерала = ВыделенныйТекст();
Если Ложь
Или Прав(ТекстСтроковогоЛитерала, 1) <> """"
Или СтрДлина(ТекстСтроковогоЛитерала) = 1
Тогда
ТекстСтроковогоЛитерала = ТекстСтроковогоЛитерала + """";
КонецЕсли;
ТекстСтроковогоЛитерала = Вычислить(ТекстСтроковогоЛитерала);
////ТекстСтроковогоЛитерала = СтрЗаменить(ТекстСтроковогоЛитерала, "|", "");
//RegExp.Pattern = "(\s*)\|((.|"""")*(\n|\r|""))";
//ТекстСтроковогоЛитерала = RegExp.Заменить(ТекстСтроковогоЛитерала, "$1 $2");
Иначе
ТекстСтроковогоЛитерала = Неопределено;
КонецЕсли;
Возврат ТекстСтроковогоЛитерала;
КонецФункции
Функция ТекущаяПозицияВТекстеОдномерная()
ДлинаТекстаДо = СтрДлина(мПредшествующийТекст) + 1; // +1 добавлено для срабатывания на однострочном литерале
Если мМетодМодуля <> Неопределено Тогда
ДлинаТекстаДо = ДлинаТекстаДо + мМетодМодуля.ПозицияТела;
КонецЕсли;
Возврат ДлинаТекстаДо;
КонецФункции
// Осуществляет переход к определению контекста.
//
// Параметры:
// Нет.
//
Процедура ПерейтиКОпределению(НомерСтроки = 0, НомерКолонки = 0, ТолькоТипы = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
Если ирОбщий.ПроверитьПлатформаНеWindowsЛкс(,, Истина) Тогда
Возврат;
КонецЕсли;
РазобратьТекущийКонтекст(,,, НомерСтроки, НомерКолонки);
Если ПустаяСтрока(мКонтекст) Тогда
Возврат;
КонецЕсли;
ПоследнееВхождение = Неопределено;
ПоследнееОпределение = Неопределено;
НайтиОпределениеСлова(мКонтекст, ПоследнееОпределение, ПоследнееВхождение);
МассивЗащитыОтРекурсии.Очистить();
Если ПоследнееВхождение <> Неопределено Тогда
ЗапомнитьИсточникПерехода();
Если ирОбщий.СтрКончаетсяНаЛкс(мКонтекст, "(") И ЯзыкПрограммы = 0 Тогда
НачальнаяПозицияОпределения = 0;
Иначе
НачальнаяПозицияОпределения = мПозицияТекстаДляПоискаОпределения;
КонецЕсли;
НачальнаяПозицияОпределения = НачальнаяПозицияОпределения + ПоследнееВхождение.FirstIndex + Найти(ПоследнееВхождение.Value, ПоследнееОпределение);
КонечнаяПозицияОпределения = НачальнаяПозицияОпределения + СтрДлина(ПоследнееОпределение);
СлужебноеПолеТекста.УстановитьГраницыВыделения(НачальнаяПозицияОпределения, КонечнаяПозицияОпределения);
СлужебноеПолеТекста.ПолучитьГраницыВыделения(мНачальнаяСтрока, мНачальнаяКолонка, мКонечнаяСтрока, мКонечнаяКолонка); // Там текст без комментариев и опасных строковых литералов
ПолеТекста.УстановитьГраницыВыделения(мНачальнаяСтрока, мНачальнаяКолонка, мКонечнаяСтрока, мКонечнаяКолонка,, ФормаВладелец);
ИначеЕсли ЯзыкПрограммы = 0 Тогда
ТаблицаСлов.Найти(НРег(мКонтекст), "НСлово");
ТаблицаСтруктурТипов = ОпределитьТипЗначенияКонтекста(мКонтекст, " " + мТекстДляПоискаОпределения, мПредшествующийТекст, Истина);
// TODO Сделать диалог выбора варианта
Для Каждого СтруктураТипа Из ТаблицаСтруктурТипов Цикл
Если ОткрытьОпределениеСтруктурыТипа(СтруктураТипа) Тогда
Прервать;
КонецЕсли;
КонецЦикла;
ИначеЕсли ЯзыкПрограммы = 1 Тогда
ОписаниеТаблицыБД = ирОбщий.ОписаниеТаблицыБДЛкс(мКонтекст);
Если ОписаниеТаблицыБД <> Неопределено Тогда
ирКлиент.ОткрытьОбъектМетаданныхЛкс(ОписаниеТаблицыБД.ПолноеИмяМД);
Иначе
ТаблицаСтруктурТиповКонтекста = ОпределитьТипЗначенияКонтекста(мРодительскийКонтекст, " " + мТекстДляПоискаОпределения, мПредшествующийТекст, Истина);
СтруктураТипаКонтекста = ТаблицаСтруктурТиповКонтекста[0];
ИмяТаблицы = мПлатформа.ИмяТипаИзСтруктурыТипа(СтруктураТипаКонтекста);
ОписаниеТаблицы = ирОбщий.ОписаниеТаблицыБДЛкс(ИмяТаблицы);
Если ОписаниеТаблицы <> Неопределено Тогда
ирКлиент.ОткрытьКолонкуБДЛкс(ИмяТаблицы, мТекущееСлово);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Функция ОткрытьОпределениеСтруктурыТипа(Знач СтруктураТипа, Знач ЭтоОбщийТип = Ложь)
Если СтруктураТипа.СтрокаОписания <> Неопределено Тогда
ТаблицаВладелец = СтруктураТипа.СтрокаОписания.Владелец();
#Если Сервер И Не Сервер Тогда
ТаблицаВладелец = Новый ТаблицаЗначений;
#КонецЕсли
Если ТаблицаВладелец.Колонки.Найти("ЛиЭкспорт") <> Неопределено Тогда
// Экспортный метод модуля
СтрокаСозданияРодителя = ТаблицаВладелец.Колонки.Имя.Заголовок;
Если ЗначениеЗаполнено(СтрокаСозданияРодителя) Тогда
Ответ = Вопрос("Перейти к определению метода через открытие вспомогательной внешней обработки в открытом конфигураторе?", РежимДиалогаВопрос.ОКОтмена);
Если Ответ = КодВозвратаДиалога.ОК Тогда
ирОбщий.ПерейтиКОпределениюМетодаВКонфигуратореЛкс(СтрокаСозданияРодителя + "." + ирОбщий.СтрокаБезКонцаЛкс(мТекущееСлово, 1));
КонецЕсли;
Возврат Истина;
КонецЕсли;
ИначеЕсли Истина
И ТаблицаВладелец.Колонки.Найти("Значение") <> Неопределено
И ирОбщий.ЛиСсылкаНаОбъектБДЛкс(СтруктураТипа.СтрокаОписания.Значение)
И ЗначениеЗаполнено(СтруктураТипа.СтрокаОписания.Значение)
Тогда
//ирКлиент.ОткрытьСсылкуВРедактореОбъектаБДЛкс(СтруктураТипа.СтрокаОписания.Значение);
ирКлиент.ОткрытьЗначениеЛкс(СтруктураТипа.СтрокаОписания.Значение);
Возврат Истина;
ИначеЕсли Истина
И ТаблицаВладелец.Колонки.Найти("ТипЗначения") <> Неопределено
И СтруктураТипа.СтрокаОписания.ТипЗначения = "Картинка"
И ТипЗнч(СтруктураТипа.Метаданные) = Тип("ОбъектМетаданных")
Тогда
ирКлиент.ОткрытьЗначениеЛкс(БиблиотекаКартинок[СтруктураТипа.Метаданные.Имя]);
Возврат Истина;
КонецЕсли;
КонецЕсли;
Если ТипЗнч(СтруктураТипа.Метаданные) = Тип("ОбъектМетаданных") Тогда
ПолноеИмяМД = СтруктураТипа.Метаданные.ПолноеИмя();
ирКлиент.ОткрытьОбъектМетаданныхЛкс(СтруктураТипа.Метаданные);
Возврат Истина;
КонецЕсли;
Если ЭтоОбщийТип Тогда
ПутьКСлову = СтруктураТипа.ИмяОбщегоТипа;
Иначе
ПутьКСлову = мКонтекст;
КонецЕсли;
НайтиПоказатьСправкуПоСтруктуреТипа(ПутьКСлову, СтруктураТипа);
Возврат Ложь;
КонецФункции
// Ищем в мТекстДляПоискаОпределения
Функция НайтиОпределениеСлова(Слово, ПоследнееОпределение = Неопределено, ПоследнееВхождение = Неопределено) Экспорт
ПоследнееОпределение = Неопределено;
Если ЯзыкПрограммы = 1 Тогда
РегВыражение.Global = Ложь;
РегВыражение.Pattern = СтрЗаменить(шПоискОписанияТаблицы, "#Идентификатор#", ирОбщий.ПреобразоватьТекстДляРегулярныхВыраженийЛкс(Слово));
РезультатТекста = РегВыражение.НайтиВхождения(мТекстДляПоискаОпределения);
Если РезультатТекста.Количество() > 0 Тогда
ПоследнееВхождение = РезультатТекста[0];
ПоследнееОпределение = ПоследнееВхождение.SubMatches(3);
лНачальнаяСтрока = 0;
лНачальнаяКолонка = 0;
лКонечнаяСтрока = 0;
лКонечнаяКолонка = 0;
СлужебноеПолеТекста.УстановитьГраницыВыделения(мПозицияТекстаДляПоискаОпределения + ПоследнееВхождение.FirstIndex + 1,
мПозицияТекстаДляПоискаОпределения + ПоследнееВхождение.FirstIndex + 1 + СтрДлина(ПоследнееОпределение));
СлужебноеПолеТекста.ПолучитьГраницыВыделения(лНачальнаяСтрока, лНачальнаяКолонка, лКонечнаяСтрока, лКонечнаяКолонка);
Если Истина
И лНачальнаяСтрока = мНачальнаяСтрока И лНачальнаяКолонка <= мНачальнаяКолонка
И лКонечнаяСтрока = мКонечнаяСтрока И лКонечнаяКолонка >= мКонечнаяКолонка
Тогда
РегВыражение.Global = Ложь;
ШаблонСозданияТаблицы = "(?:" + шРазделитель + ")+" + "(?:ПОМЕСТИТЬ|INTO(?:" + шРазделитель + "+TABLE)?)" + шРазделитель + "+(#Идентификатор#)" + шРазделитель;
РегВыражение.Pattern = СтрЗаменить(ШаблонСозданияТаблицы, "#Идентификатор#", ирОбщий.ПреобразоватьТекстДляРегулярныхВыраженийЛкс(Слово));
РезультатТекста = РегВыражение.НайтиВхождения(ТекстБезКомментариевИОпасныхСтрок);
Если РезультатТекста.Количество() > 0 Тогда
ПоследнееОпределение = РезультатТекста[0].SubMatches(0);
ПоследнееВхождение = ирОбщий.СоздатьОбъектПоИмениМетаданныхЛкс("Обработка.ирОболочкаРегВхождение");
ЗаполнитьЗначенияСвойств(ПоследнееВхождение, РезультатТекста[0],, "SubMatches"); // Создаем неполноценный объект ради изменения свойства FirstIndex
ПоследнееВхождение.FirstIndex = ПоследнееВхождение.FirstIndex - мПозицияТекстаДляПоискаОпределения;
КонецЕсли;
КонецЕсли;
Иначе
МаркерЗначение = "ЗНАЧЕНИЕ(";
Если Прав(мПредшествующийТекст, СтрДлина(МаркерЗначение)) = МаркерЗначение Тогда
РегВыражение.Global = Ложь;
РегВыражение.Pattern = шИмя;
Если РегВыражение.Проверить(Слово) Тогда
Попытка
ПредопределенноеЗначение = ПредопределенноеЗначение(Слово);
Исключение
ПредопределенноеЗначение = Неопределено;
КонецПопытки;
Если ПредопределенноеЗначение <> Неопределено Тогда
ОткрытьЗначение(ПредопределенноеЗначение);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Иначе
РегВыражение.Global = Истина;
ЭкранированноеСлово = ирОбщий.ПреобразоватьТекстДляРегулярныхВыраженийЛкс(ирОбщий.ПервыйФрагментЛкс(Слово, "("));
Если ирОбщий.СтрКончаетсяНаЛкс(Слово, "(") Тогда
// Ищем определение метода в тексте модуля
РегВыражение.Pattern = ирОбщий.СтрЗаменитьЛкс(мПлатформа.ПолучитьШаблоныДляАнализаВстроенногоЯзыка().ОписаниеМетодаЧистое, шИмя, ЭкранированноеСлово);
РезультатТекста = РегВыражение.НайтиВхождения(ОригинальныйТекст);
Иначе
//шПрисваивание = "(" + шРазделитель + "*=" + шРазделитель + "*((Новый|New)" + шРазделитель + "+(" + шИмя + ")|(" + шИмяСкобки + "?" + шИндекс
// + "?(\." + шИмяСкобки + "?" + шИндекс + "?)*)" + "|(" + шЧисло + ")|(" + шСтрокаПрограммы + ")))";
ШаблонКоллекции = "(" + шРазделитель + "+Из" + шРазделитель + "+(" + шИмяСкобки + "?" + шИндекс + "?" + "(\." + шИмяСкобки + "?" + шИндекс + "?)*))";
РегВыражение.Pattern = шПредИмя + ЭкранированноеСлово + "(" + шПрисваивание + "|" + ШаблонКоллекции + ")";
РезультатТекста = РегВыражение.НайтиВхождения(мТекстДляПоискаОпределения);
КонецЕсли;
Если РезультатТекста.Количество() > 0 Тогда
ПоследнееВхождение = РезультатТекста[РезультатТекста.Количество() - 1];
ПоследнееОпределение = ПоследнееВхождение.SubMatches(0);
//Если ПоследнееВхождение.SubMatches(1) <> Неопределено Тогда
// // Это присвоение
// ПоследнееОпределение = ПоследнееВхождение.SubMatches(1);
//Иначе
// // Это обход коллекции
// ПоследнееОпределение = ПоследнееВхождение.SubMatches(20);
//КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат ПоследнееОпределение;
КонецФункции
// <Описание процедуры>
//
// Параметры:
// <Параметр1> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>.
//
Процедура ДобавитьТипЭлементаКоллекцииВТаблицуСтруктурТипов(СтруктураТипаКоллекции, СтруктураТипаЭлементаКоллекции, ТаблицаСтруктурТипов)
БазовыеТипы = мПлатформа.ПолучитьТипыЭлементовКоллекции(СтруктураТипаКоллекции);
Если БазовыеТипы.Количество() > 0 Тогда
Для Каждого БазовыйТип Из БазовыеТипы Цикл
СтруктураКлюча = Новый Структура("БазовыйТип, ЯзыкПрограммы", БазовыйТип, ЯзыкПрограммы);
НайденныеСтроки = мПлатформа.ТаблицаОбщихТипов.НайтиСтроки(СтруктураКлюча);
Если НайденныеСтроки.Количество() > 0 Тогда
СтруктураТипаЭлементаКоллекции.СтрокаОписания = НайденныеСтроки[0];
СтруктураТипаЭлементаКоллекции.ИмяОбщегоТипа = НайденныеСтроки[0].Слово;
Если ТипЗнч(СтруктураТипаКоллекции.Метаданные) <> Тип("КоллекцияОбъектовМетаданных") Тогда
СтруктураТипаЭлементаКоллекции.Метаданные = СтруктураТипаКоллекции.Метаданные;
КонецЕсли;
Иначе
СтруктураТипаЭлементаКоллекции.ИмяОбщегоТипа = БазовыйТип;
КонецЕсли;
мПлатформа.ДобавитьВТаблицуСтруктурТипов(ТаблицаСтруктурТипов, СтруктураТипаЭлементаКоллекции);
КонецЦикла;
Иначе
мПлатформа.ДобавитьВТаблицуСтруктурТипов(ТаблицаСтруктурТипов, СтруктураТипаЭлементаКоллекции);
КонецЕсли;
КонецПроцедуры // ДобавитьТипЭлементаКоллекцииВТаблицуСтруктурТипов()
// Вычисляет массив структур типа дочернего контекста.
//
// Параметры:
// МассивРодительскихСтрутурТипа - Массив - родительских структур типа;
// ТекущееСлово - Строка - дочернеее слово;
// ТипСлова - Строка - тип слова;
// *ТекущийИндекс - Строка, *Неопределено - выражение в квадратных скобках;
// *ТекущиеАргументы - Строка, *"" - аргументы метода;
// *ПредшествующийТекст - Строка, *"" - текст для поиска определения таблицы в режиме языка запросов.
//
// Возвращаемое значение:
// МассивСтрутурТипа - Массив - дочерних структур типа.
//
Функция ОпределитьТипДочернегоКонтекста(МассивРодительскихСтрутурТипа, ТекущееСлово, ТипСлова, ТекущийИндекс = Неопределено, ТекущиеАргументы = "", ПредшествующийТекст = "",
ПолныйАнализ = Истина)
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ТаблицаСвойствТипа = мПлатформа.НоваяТаблицаСвойствТипа(); // Ускорение
ТаблицаСтруктурТипов = мПлатформа.НоваяТаблицаСтруктурТипа();
СчетчикТипов = 0;
Для Каждого РодительскаяСтрутураТипа Из МассивРодительскихСтрутурТипа Цикл
СчетчикТипов = СчетчикТипов + 1;
Если Истина
И Не ПолныйАнализ
И СчетчикТипов > 50
Тогда
Прервать;
КонецЕсли;
Если РодительскаяСтрутураТипа.ИмяОбщегоТипа <> "Неизвестный контекст" Тогда
МетаданныеРодителя = РодительскаяСтрутураТипа.Метаданные;
Если Не ЗначениеЗаполнено(ТекущийИндекс) Тогда
// Ищем правило вычисления
Если ТипСлова = "Метод" Тогда
КлючСтроки = Новый Структура;
КлючСтроки.Вставить("ТипКонтекста", РодительскаяСтрутураТипа.ИмяОбщегоТипа);
КлючСтроки.Вставить("НСлово", НРег(ТекущееСлово));
НайденныеСтроки = ПравилаВычисленияФункций.НайтиСтроки(КлючСтроки);
Если НайденныеСтроки.Количество() > 0 Тогда
РегВыражение.Global = Истина;
Если ЯзыкПрограммы = 0 Тогда
РегВыражение.Pattern = "(" + шВыражениеПрограммы + ")?" + шРазделитель + "*,";
Иначе
РегВыражение.Pattern = "(" + шВыражениеЗапроса + ")?" + шРазделитель + "*,";
КонецЕсли;
Результат = РегВыражение.НайтиВхождения(Нрег(Сред(ТекущиеАргументы, 2, СтрДлина(ТекущиеАргументы) - 2) + ","));
МассивПараметров = Новый Массив;
Для Каждого Вхождение Из Результат Цикл
МассивПараметров.Добавить(СокрЛП(Вхождение.SubMatches(0)));
КонецЦикла;
//Попытка
лТаблицаСтруктурТипов = Вычислить(НайденныеСтроки[0].Правило + "(ТаблицаЛокальногоКонтекста, МассивПараметров)");
ирОбщий.ЗагрузитьВТаблицуЗначенийЛкс(лТаблицаСтруктурТипов, ТаблицаСтруктурТипов);
Продолжить;
//Исключение КонецПопытки;
КонецЕсли;
КонецЕсли;
// Ищем предопределенное слово
Если Истина
И РодительскаяСтрутураТипа.ИмяОбщегоТипа = "Локальный"
//И (Ложь
// Или ЯзыкПрограммы = 0
// Или ЯзыкПрограммы = 2)
Тогда
СтруктураКлюча = Новый Структура("НСлово", Нрег(ТекущееСлово));
Если ТипСлова <> Неопределено Тогда
СтруктураКлюча.Вставить("ТипСлова", ТипСлова);
КонецЕсли;
НайденныеСтроки = ТаблицаЛокальногоКонтекста.НайтиСтроки(СтруктураКлюча);
Если НайденныеСтроки.Количество() > 0 Тогда
ирОбщий.ЗагрузитьВТаблицуЗначенийЛкс(НайденныеСтроки[0].ТаблицаСтруктурТипов, ТаблицаСтруктурТипов);
Продолжить;
КонецЕсли;
КонецЕсли;
Если ЯзыкПрограммы = 1 Тогда
ВиртуальнаяТаблица = Новый Структура("Выражение, НомерСтроки");
ВиртуальнаяТаблица.Выражение = "." + ТекущееСлово;
Если ЗначениеЗаполнено(ТекущиеАргументы) Тогда
//ВиртуальнаяТаблица.Выражение = ВиртуальнаяТаблица.Выражение + "." + ТекущиеАргументы; // Кажется это было сделано умышленно
ВиртуальнаяТаблица.Выражение = ВиртуальнаяТаблица.Выражение + ТекущиеАргументы; // https://www.hostedredmine.com/issues/958394
КонецЕсли;
ВиртуальнаяТаблица.НомерСтроки = СтрЧислоСтрок(ПредшествующийТекст);
Иначе
ВиртуальнаяТаблица = Неопределено;
КонецЕсли;
ТаблицаСвойствТипа.Очистить();
мПлатформа.СвойстваТипаПредопределенные(РодительскаяСтрутураТипа, ТекущееСлово, ТипСлова, ВиртуальнаяТаблица, ЯзыкПрограммы, Конфигурация,,, ТаблицаСвойствТипа);
Если ТаблицаСвойствТипа.Количество() > 0 Тогда
МаксКоличествоВариантов = 5;
КоличествоВариантов = 0;
Для Каждого СтрокаСлова Из ТаблицаСвойствТипа Цикл
ирОбщий.ЗагрузитьВТаблицуЗначенийЛкс(СтрокаСлова.ТаблицаСтруктурТипов, ТаблицаСтруктурТипов);
КоличествоВариантов = КоличествоВариантов + 1;
Если КоличествоВариантов >= МаксКоличествоВариантов Тогда
Прервать;
КонецЕсли;
КонецЦикла;
Если Истина
И РодительскаяСтрутураТипа.ИмяОбщегоТипа = "БлокировкаДанных"
И ТипСлова = "Метод"
И ТекущееСлово = "Добавить"
Тогда
ТаблицаСтруктурТипов.ЗаполнитьЗначения(ирОбщий.СтрокаМеждуМаркерамиЛкс(ТекущиеАргументы, """", """"), "Метаданные");
КонецЕсли;
Продолжить;
ИначеЕсли Истина
И ЗначениеЗаполнено(РодительскаяСтрутураТипа.ТипЯзыка)
И РодительскаяСтрутураТипа.ИмяОбщегоТипа = "Строка"
Тогда
ЗаполнитьЗначенияСвойств(ТаблицаСтруктурТипов.Добавить(), РодительскаяСтрутураТипа);
Продолжить;
КонецЕсли;
Иначе
//Попытка
// Пустышка = Новый Структура(ТекущееСлово);
//Исключение
// Пустышка = Неопределено;
//КонецПопытки;
//Если Ложь
// Или Пустышка = Неопределено
// Или НРег(ТекущийИндекс) <> НРег("""" + ТекущееСлово + """") // Противный случай отработается внутри СвойстваТипаМетаданные
//Тогда
// // Это - произвольный элемент коллекции
// ДобавитьТипЭлементаКоллекцииВТаблицуСтруктурТипов(РодительскаяСтрутураТипа, СтруктураТипа, ТаблицаСтруктурТипов);
// Продолжить;
//КонецЕсли;
КонецЕсли;
ТаблицаСвойствТипа.Очистить();
мПлатформа.СвойстваТипаМетаданные(РодительскаяСтрутураТипа,
ТекущееСлово, ТипСлова, ВиртуальнаяТаблица, ЯзыкПрограммы, ТекущийИндекс,,, ЛиСерверныйКонтекст, МодульМетаданныхКонтекста(РодительскаяСтрутураТипа), ТаблицаСвойствТипа);
Если ТаблицаСвойствТипа.Количество() > 0 Тогда
Для Каждого СтрокаСлова Из ТаблицаСвойствТипа Цикл
Если СтрокаСлова.ТаблицаСтруктурТипов <> Неопределено Тогда
ирОбщий.ЗагрузитьВТаблицуЗначенийЛкс(СтрокаСлова.ТаблицаСтруктурТипов, ТаблицаСтруктурТипов);
КонецЕсли;
КонецЦикла;
Продолжить;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Возврат ТаблицаСтруктурТипов;
КонецФункции
Функция МодульМетаданныхКонтекста(Знач РодительскаяСтрутураТипа)
Если РодительскаяСтрутураТипа.ИмяОбщегоТипа = "Локальный" Тогда
МодульМетаданных = мМодульМетаданных;
Иначе
МодульМетаданных = Неопределено;
КонецЕсли;
Возврат МодульМетаданных;
КонецФункции
// Определяет тип значения слова в режиме внутреннего языка.
//
// Параметры:
// ТекстДляПоискаОпределения - Строка - где ищем определение;
// Контекст - Строка - последовательность идентификаторов через "." без круглых и квадратных скобок.
//
// Возвращаемое значение:
// Структура - "ИмяОбщегоТипа", "ПерсональныйТип".
//
Функция ОпределитьТипЗначенияКонтекста(Знач Контекст = "", Знач ТекстДляПоискаОпределения = "", Знач ПредшествующийТекст = "", Знач РазрешитьАнализИмениТипа = Ложь,
Знач ЭтоВызовКонструктора = Ложь, ПолныйАнализ = Истина) Экспорт
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
РегВыражение = Обработки.ирОболочкаРегВыражение.Создать();
#КонецЕсли
ТаблицаСтруктурТипов = мПлатформа.НоваяТаблицаСтруктурТипа();
СтруктураТипа = мПлатформа.НоваяСтруктураТипа();
//Если ЗначениеЗаполнено(Конфигурация) Тогда
СтруктураТипа.Метаданные = Конфигурация;
//Иначе
// СтруктураТипа.Метаданные = мПлатформа.мМетаданные;
//КонецЕсли;
Если РазрешитьАнализИмениТипа Тогда
Если ЯзыкПрограммы = 1 Тогда
мТолькоСсылочныеИменаТипов = Истина;
РегВыражение.Global = Истина;
РегВыражение.Pattern = шПредИмя + "(?:ССЫЛКА|REFS)" + шРазделитель + "+$";
Результат = РегВыражение.НайтиВхождения(ПредшествующийТекст);
Если Результат.Количество() > 0 Тогда
СтруктураТипа.ТипЯзыка = "ИмяТипа";
КонецЕсли;
//RegExp.Pattern = шПредИмя + "(?:ВЫРАЗИТЬ|CAST)" + шРазделитель + "*\(" + шВыражениеЗапроса + шРазделитель + "+(?:КАК|AS)" + шРазделитель + "+$"; // Привязка к концу вызывала катастрофическое шагание назад
РегВыражение.Pattern = шПредИмя + "(?:ВЫРАЗИТЬ|CAST)" + шРазделитель + "*\(" + шВыражениеЗапроса + шРазделитель + "+(?:КАК|AS)" + шРазделитель + "+"; // 08.02.2023
Результат = РегВыражение.НайтиВхождения(ПредшествующийТекст, Истина);
Если Истина
И Результат.Количество() > 0
И ПустаяСтрока(Сред(ПредшествующийТекст, Результат[0].FirstIndex + Результат[0].Length)) // 08.02.2023
Тогда
СтруктураТипа.ТипЯзыка = "ИмяТипа";
мТолькоСсылочныеИменаТипов = Ложь;
КонецЕсли;
РегВыражение.Pattern = шПредИмя + "(?:ТИП|TYPE)" + шРазделитель + "*\(" + шРазделитель + "*$";
Результат = РегВыражение.НайтиВхождения(ПредшествующийТекст);
Если Результат.Количество() > 0 Тогда
СтруктураТипа.ТипЯзыка = "ИмяТипа";
мТолькоСсылочныеИменаТипов = Ложь;
КонецЕсли;
РегВыражение.Pattern = шПредИмя + "(?:ЗНАЧЕНИЕ|VALUE)" + шРазделитель + "*\(" + шРазделитель + "*$";
Результат = РегВыражение.НайтиВхождения(ПредшествующийТекст);
Если Результат.Количество() > 0 Тогда
СтруктураТипа.ТипЯзыка = "ЗначениеВЗапросе";
КонецЕсли;
Иначе
РегВыражение.Global = Истина;
РегВыражение.Pattern = шПредИмя + "(?:Новый|New)" + шРазделитель + "+$";
Результат = РегВыражение.НайтиВхождения(ПредшествующийТекст);
Если Результат.Количество() > 0 Тогда
СтруктураТипа.Вставить("Конструктор", Истина);
СтруктураТипа.ТипЯзыка = "ИмяТипа";
КонецЕсли;
РегВыражение.Pattern = шПредИмя + "(?:Новый|New)" + шРазделитель + "*\(" + шРазделитель + "*""$";
Результат = РегВыражение.НайтиВхождения(ПредшествующийТекст);
Если Результат.Количество() > 0 Тогда
// Активная следующая строка блокирует недокументированные возможности.
//СтруктураТипа.Вставить("Конструктор", Истина);
СтруктураТипа.ТипЯзыка = "ИмяТипа";
КонецЕсли;
РегВыражение.Pattern = шПредИмя + "Тип" + шРазделитель + "*\(" + шРазделитель + "*""$";
Результат = РегВыражение.НайтиВхождения(ПредшествующийТекст);
Если Результат.Количество() > 0 Тогда
СтруктураТипа.ТипЯзыка = "ИмяТипа";
КонецЕсли;
РегВыражение.Pattern = шПредИмя + "(?:Новый|New)" + шРазделитель + "*ОписаниеТипов\(" + шРазделитель + "*""[^""]*$";
Результат = РегВыражение.НайтиВхождения(ПредшествующийТекст);
Если Результат.Количество() > 0 Тогда
СтруктураТипа.ТипЯзыка = "ИмяТипа";
КонецЕсли;
КонецЕсли;
Если Ложь
Или СтруктураТипа.ТипЯзыка = "ИмяТипа"
Или СтруктураТипа.ТипЯзыка = "ЗначениеВЗапросе"
Тогда
СтруктураТипа.ИмяОбщегоТипа = "";
Иначе
Если мЭтоСтроковыйЛитерал Тогда
Результат = ОпределитьТипЗначенияКонтекста(мВызовМетода, ТекстДляПоискаОпределения, ПредшествующийТекст,,, ПолныйАнализ);
Возврат Результат;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Ложь
Или Контекст = Неопределено
Или Контекст = ""
Тогда
Если СтруктураТипа.ИмяОбщегоТипа = "Неизвестный контекст" Тогда
СтруктураТипа.ИмяОбщегоТипа = "Локальный";
КонецЕсли;
Иначе
РегВыражение.Global = Ложь;
РегВыражение.Pattern = "(((\.(" + шИмя + "|\?|)" + шСкобки + "?)|" + шИндекс + ")*)" +
"((\.(" + шИмя + "|\?|)" + шНачалоСкобок + "?)|" + шИндекс + ")$";
Результат = РегВыражение.НайтиВхождения("." + Контекст);
Если Результат.Количество() > 0 Тогда
МассивРодительскихСтрутурТипа = Новый Массив;
РодительскийКонтекст = Сред(Результат[0].SubMatches(0), 2);
ТекущееСлово = Результат[0].SubMatches(8);
ТекущийИндекс = Результат[0].SubMatches(10);
ТекущиеАргументы = Результат[0].SubMatches(9);
ТипСлова = "Свойство";
Если Не ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(ТекущийИндекс) Тогда
ТекущееСлово = Сред(ТекущийИндекс, 2, СтрДлина(ТекущийИндекс) - 2);
КонецЕсли;
Если ЯзыкПрограммы = 1 Тогда
ТипСлова = Неопределено;
Если РодительскийКонтекст = "" Тогда
Если ЗначениеЗаполнено(ТекущееСлово) Тогда
РегВыражение.Global = Ложь;
РегВыражение.Pattern = СтрЗаменить(шПоискОписанияТаблицы, "#Идентификатор#", ирОбщий.ПреобразоватьТекстДляРегулярныхВыраженийЛкс(ТекущееСлово));
РезультатТекста = РегВыражение.НайтиВхождения(ТекстДляПоискаОпределения);
Если РезультатТекста.Количество() > 0 Тогда
ПоследнееВхождение = РезультатТекста[0];
СледРекурсии = МассивЗащитыОтРекурсии.Найти(ПоследнееВхождение.FirstIndex);
Если СледРекурсии = Неопределено Тогда
МассивЗащитыОтРекурсии.Добавить(ПоследнееВхождение.FirstIndex);
ПрисвоенныйКонтекст = ПоследнееВхождение.SubMatches(3);
Если ПрисвоенныйКонтекст <> Контекст Тогда
МассивСтруктурПрисвоенныхТипов = ОпределитьТипЗначенияКонтекста(ПрисвоенныйКонтекст, ТекстДляПоискаОпределения,
Лев(ТекстДляПоискаОпределения, ПоследнееВхождение.FirstIndex - 1), РазрешитьАнализИмениТипа,, ПолныйАнализ);
ирОбщий.ЗагрузитьВТаблицуЗначенийЛкс(МассивСтруктурПрисвоенныхТипов, ТаблицаСтруктурТипов);
КонецЕсли;
КонецЕсли;
КонецЕсли;
ИначеЕсли ЗначениеЗаполнено(ТекущиеАргументы) Тогда
ТекущееСлово = ирОбщий.УдалитьВнешниеСкобкиВыраженияЛкс(ТекущиеАргументы);
Если ирОбщий.СтрНачинаетсяСЛкс(ТекущееСлово, "Выразить(") Тогда
ТекущиеАргументы = ирОбщий.СтрокаМеждуМаркерамиЛкс(ТекущееСлово, "(", ")", Ложь, Истина);
ТекущееСлово = "ВЫРАЗИТЬ";
РегВыражение.Pattern = шРазделитель + "(?:КАК|AS)" + шРазделитель + "+(" + шИмя + "(?:\." + шИмя + ")*)";
Результат = РегВыражение.НайтиВхождения(ТекущиеАргументы);
Если Результат.Количество() > 0 Тогда
ИмяТипаВыражения = Результат[Результат.Количество() - 1].Submatches(0);
Если Найти(ИмяТипаВыражения, ".") > 0 Тогда
ИмяТипаВыражения = ирОбщий.ИмяТипаИзПолногоИмениМДЛкс(ИмяТипаВыражения);
КонецЕсли;
СтруктураТипа = мПлатформа.СтруктураТипаИзКонкретногоТипа(Тип(ИмяТипаВыражения));
СтруктураТипа.ИмяОбщегоТипа = СтрЗаменить(СтруктураТипа.ИмяОбщегоТипа, ирОбщий.ПеревестиСтроку("Ссылка") + ".", ".");
ЗаполнитьЗначенияСвойств(ТаблицаСтруктурТипов.Добавить(), СтруктураТипа);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Иначе
ТипСлова = "Свойство";
Если Истина
И Не ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(ТекущиеАргументы)
И Не СтруктураТипа.ТипЯзыка = "ИмяТипа"
Тогда
// Это метод или функция
Если ЭтоВызовКонструктора Тогда
ТипСлова = "Конструктор";
Иначе
ТипСлова = "Метод";
КонецЕсли;
КонецЕсли;
РегВыражение.Global = Истина;
ШаблонКоллекции = "(" + шРазделитель + "+Из" + шРазделитель + "+(" + шИмяСкобки + "?" + шИндекс + "?" + "(\." + шИмяСкобки + "?" + шИндекс + "?)*))";
РегВыражение.Pattern = шПредИмя + ирОбщий.ПреобразоватьТекстДляРегулярныхВыраженийЛкс(Контекст)
+ "(" + шПрисваивание + "|" + ШаблонКоллекции + ")";
РезультатТекста = РегВыражение.НайтиВхождения(ТекстДляПоискаОпределения);
Если РезультатТекста.Количество() > 0 Тогда
СтруктураТипа = мПлатформа.НоваяСтруктураТипа();
ПоследнееВхождение = РезультатТекста[РезультатТекста.Количество() - 1];
Если Не ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(ПоследнееВхождение.SubMatches(1)) Тогда
// Пропускаем пустое присвоение https://www.hostedredmine.com/issues/947747
ПрисвоенныйКонтекст = ПоследнееВхождение.SubMatches(2);
Если Не ЗначениеЗаполнено(ПрисвоенныйКонтекст) И РезультатТекста.Количество() > 1 Тогда
ПоследнееВхождение = РезультатТекста[РезультатТекста.Количество() - 2];
КонецЕсли;
КонецЕсли;
Если Не ирОбщий.ЛиПустаяПодгруппа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); // При этом может открыться форма Automation-сервера например RegexBuddy так делает
Если МетаданныеСлова = Неопределено Тогда
ИмяОсновногоКлассаCOM = ирОбщий.ПоследнийФрагментЛкс(ПолноеИмяОсновногоКлассаCOM);
ИмяОбщегоТипа = ИмяОсновногоКлассаCOM + " {" + ПолноеИмяОсновногоКлассаCOM + "}";
Иначе
ИмяОбщегоТипа = мПлатформа.ПолноеИмяТипаCOMОбъекта(МетаданныеСлова);
Если ирОбщий.СтрокиРавныЛкс(ИмяОбщегоТипа, "COMОбъект") Тогда
ИмяОсновногоКлассаCOM = ирОбщий.ПоследнийФрагментЛкс(ПолноеИмяОсновногоКлассаCOM);
ИмяОбщегоТипа = ИмяОсновногоКлассаCOM + " {" + ПолноеИмяОсновногоКлассаCOM + "}";
КонецЕсли;
СтруктураКОМТипа.Вставить("Метаданные", МетаданныеСлова);
КонецЕсли;
СтруктураКОМТипа.Вставить("ИмяОбщегоТипа", ИмяОбщегоТипа);
мИменаОбщихТиповПоИменамКлассовCOM[ПолноеИмяОсновногоКлассаCOM] = СтруктураКОМТипа;
КонецЕсли;
ЗаполнитьЗначенияСвойств(СтруктураТипа, СтруктураКОМТипа);
ИначеЕсли ТипНового <> Неопределено Тогда
СтруктураТипа = мПлатформа.СтруктураТипаИзКонкретногоТипа(ТипНового, ЯзыкПрограммы);
КонецЕсли;
КонецЕсли;
мПлатформа.ДобавитьВТаблицуСтруктурТипов(ТаблицаСтруктурТипов, СтруктураТипа);
ИначеЕсли Не ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(ПоследнееВхождение.SubMatches(6)) Тогда
ТаблицаСтруктурТипов = ОпределитьТипЗначенияКонтекста(ПрисвоенныйКонтекст, Лев(ТекстДляПоискаОпределения, ПоследнееВхождение.FirstIndex - 1),
Лев(ТекстДляПоискаОпределения, ПоследнееВхождение.FirstIndex - 1), РазрешитьАнализИмениТипа,, ПолныйАнализ);
Для Каждого СтруктураТипа Из ТаблицаСтруктурТипов Цикл
СтруктураКлюча = Новый Структура("Слово, ЯзыкПрограммы", СтруктураТипа.ИмяОбщегоТипа, ЯзыкПрограммы);
СтруктураТипа.СтрокаОписания = Неопределено;
// Было закомментировано
//НайденныеСтроки = мПлатформа.ТаблицаОбщихТипов.НайтиСтроки(СтруктураКлюча);
//Если НайденныеСтроки.Количество() > 0 Тогда
// СтруктураТипа.СтрокаОписания = НайденныеСтроки[0];
//КонецЕсли;
КонецЦикла;
Иначе
// **** TODO Сделать определение примитивного типа
СтруктураТипа.ИмяОбщегоТипа = "Примитивный";
мПлатформа.ДобавитьВТаблицуСтруктурТипов(ТаблицаСтруктурТипов, СтруктураТипа);
КонецЕсли;
Иначе
// Это обход коллекции
ПрисвоенныйКонтекст = ПоследнееВхождение.SubMatches(15);
// **** Раньше текст для поиска определения передавался неизменным. Тестовый режим
ТаблицаСтруктурТиповКоллекции = ОпределитьТипЗначенияКонтекста(ПрисвоенныйКонтекст, Лев(ТекстДляПоискаОпределения, ПоследнееВхождение.FirstIndex - 1),
Лев(ТекстДляПоискаОпределения, ПоследнееВхождение.FirstIndex - 1),,, ПолныйАнализ);
//// Структура типов коллекции всегда имеет ровно один элемент
//СтруктураКлюча = Новый Структура("Слово, ЯзыкПрограммы", СтруктураТипаКоллекции.ИмяОбщегоТипа, ЯзыкПрограммы);
//НайденныеСтроки = мПлатформа.ТаблицаОбщихТипов.НайтиСтроки(СтруктураКлюча);
//Если НайденныеСтроки.Количество() > 0 Тогда
// БазовыеТипы = ирОбщий.СтрРазделитьЛкс(НайденныеСтроки[0].ТипЭлементаКоллекции, ",", Истина);
// Для Каждого БазовыйТип Из БазовыеТипы Цикл
// СтруктураКлюча = Новый Структура("БазовыйТип, ЯзыкПрограммы", БазовыйТип, ЯзыкПрограммы);
// НайденныеСтроки = мПлатформа.ТаблицаОбщихТипов.НайтиСтроки(СтруктураКлюча);
// Если НайденныеСтроки.Количество() > 0 Тогда
// СтруктураТипа.СтрокаОписания = НайденныеСтроки[0];
// СтруктураТипа.ИмяОбщегоТипа = НайденныеСтроки[0].Слово;
// СтруктураТипа.Метаданные = СтруктураТипаКоллекции.Метаданные;
// КонецЕсли;
// мПлатформа.ДобавитьВТаблицуСтруктурТипов(ТаблицаСтруктурТипов, СтруктураТипа);
// КонецЦикла;
//Иначе
// мПлатформа.ДобавитьВТаблицуСтруктурТипов(ТаблицаСтруктурТипов, СтруктураТипа);
//КонецЕсли;
ДобавитьТипЭлементаКоллекцииВТаблицуСтруктурТипов(ТаблицаСтруктурТиповКоллекции[0], СтруктураТипа, ТаблицаСтруктурТипов);
КонецЕсли;
Если Не ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(ТекущийИндекс) Тогда
МассивРодительскихСтрутурТипа = ТаблицаСтруктурТипов;
ТаблицаСтруктурТипов = мПлатформа.НоваяТаблицаСтруктурТипа();
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если МассивРодительскихСтрутурТипа.Количество() = 0 Тогда
МассивРодительскихСтрутурТипа = ОпределитьТипЗначенияКонтекста(РодительскийКонтекст, ТекстДляПоискаОпределения, ПредшествующийТекст, РазрешитьАнализИмениТипа,, ПолныйАнализ);
КонецЕсли;
МассивДочернихСтруктурТипа = ОпределитьТипДочернегоКонтекста(МассивРодительскихСтрутурТипа, ТекущееСлово, ТипСлова, ТекущийИндекс, ТекущиеАргументы, ПредшествующийТекст, ПолныйАнализ);
ирОбщий.ЗагрузитьВТаблицуЗначенийЛкс(МассивДочернихСтруктурТипа, ТаблицаСтруктурТипов);
Если ТипСлова = "Свойство" И Не СтруктураТипа.Конструктор Тогда
ТекстДляЗаполненияМетаданных = ТекстДляПоискаОпределения;
Для Каждого СтруктураТипаЦикл Из ТаблицаСтруктурТипов Цикл
Если Ложь
Или СтруктураТипаЦикл.ИмяОбщегоТипа = "Структура"
Или СтруктураТипаЦикл.ИмяОбщегоТипа = "ФиксированнаяСтруктура"
Тогда
РегВыражение.Global = Ложь;
ШаблонКонструкторСоСвойствами = Контекст + "\s*=\s*Новый\s+Структура\s*\(\s*""((?:" + шИмя + "\s*,\s*)*" + шИмя + ")""";
РегВыражение.Pattern = ШаблонКонструкторСоСвойствами;
РезультатСвойств = РегВыражение.НайтиВхождения(ТекстДляЗаполненияМетаданных);
Если РезультатСвойств.Количество() > 0 Тогда
СтруктураТипаЦикл.Метаданные = Новый Структура(РезультатСвойств[0].SubMatches(0));
ИначеЕсли Истина
И ТипЗнч(СтруктураТипаЦикл.Метаданные) <> Тип("Структура")
И ТипЗнч(СтруктураТипаЦикл.Метаданные) <> Тип("ФиксированнаяСтруктура")
Тогда
СтруктураТипаЦикл.Метаданные = Новый Структура;
КонецЕсли;
ШаблонУстановкаТекста = Контекст + "\s*\.\s*Вставить\s*\(\s*""(" + шИмя + ")""";
РегВыражение.Pattern = ШаблонУстановкаТекста;
РегВыражение.Global = Истина;
РезультатСвойств = РегВыражение.НайтиВхождения(ТекстДляЗаполненияМетаданных);
Для Каждого ВхождениеСвойства Из РезультатСвойств Цикл
СтруктураТипаЦикл.Метаданные.Вставить(ВхождениеСвойства.SubMatches(0));
КонецЦикла;
ИначеЕсли Ложь
Или СтруктураТипаЦикл.ИмяОбщегоТипа = "ТаблицаЗначений"
Или СтруктураТипаЦикл.ИмяОбщегоТипа = "ДеревоЗначений"
Тогда
РегВыражение.Global = Ложь;
Если Истина
И ТипЗнч(СтруктураТипаЦикл.Метаданные) <> Тип("ДеревоЗначений")
И ТипЗнч(СтруктураТипаЦикл.Метаданные) <> Тип("ТаблицаЗначений")
Тогда
СтруктураТипаЦикл.Метаданные = Новый ТаблицаЗначений;
КонецЕсли;
ШаблонУстановкаТекста = Контекст + "\s*\.\s*Колонки\s*.\s*Добавить\s*\(\s*""(" + шИмя + ")""";
РегВыражение.Pattern = ШаблонУстановкаТекста;
РегВыражение.Global = Истина;
РезультатСвойств = РегВыражение.НайтиВхождения(ТекстДляЗаполненияМетаданных);
Колонки = СтруктураТипаЦикл.Метаданные.Колонки;
Для Каждого ВхождениеСвойства Из РезультатСвойств Цикл
ИмяКолонки = ВхождениеСвойства.SubMatches(0);
Попытка
Колонки.Добавить(ИмяКолонки);
Исключение
Пустышка = 0;
КонецПопытки;
КонецЦикла;
ИначеЕсли Ложь
Или СтруктураТипаЦикл.ИмяОбщегоТипа = "Запрос"
Или СтруктураТипаЦикл.ИмяОбщегоТипа = "ПостроительЗапроса"
Или СтруктураТипаЦикл.ИмяОбщегоТипа = "ПостроительОтчета"
Тогда
РегВыражение.Global = Ложь;
ШаблонУстановкаТекста = Контекст + "\s*\.\s*Текст\s*=\s*(" + шСтрокаПрограммы + ")";
РегВыражение.Pattern = ШаблонУстановкаТекста;
РегВыражение.Global = Истина;
РезультатСвойств = РегВыражение.НайтиВхождения(ТекстДляЗаполненияМетаданных);
Для Каждого ВхождениеСвойства Из РезультатСвойств Цикл
ПрисвоенноеЗначение = ВхождениеСвойства.SubMatches(0);
Если Лев(ПрисвоенноеЗначение, 1) = """" Тогда
Попытка
ТекстЗапроса = Вычислить(ПрисвоенноеЗначение);
Прервать;
Исключение
ТекстЗапроса = "";
КонецПопытки;
КонецЕсли;
КонецЦикла;
Если ЗначениеЗаполнено(ТекстЗапроса) Тогда
ПостроительЗапроса = Новый ПостроительЗапроса;
Попытка
ПостроительЗапроса.Текст = ТекстЗапроса;
ПостроительЗапроса.ЗаполнитьНастройки();
Исключение
ПостроительЗапроса = Неопределено;
КонецПопытки;
Если ПостроительЗапроса <> Неопределено Тогда
СтруктураТипаЦикл.Метаданные = ПостроительЗапроса;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если Истина
И ЯзыкПрограммы = 1
И РодительскийКонтекст = ""
И СтруктураТипа.ИмяОбщегоТипа = "Неизвестный контекст"
И МассивСтруктурПрисвоенныхТипов = Неопределено
Тогда
Если ТипЗнч(КонтекстВыполнения) = Тип("Запрос") Тогда
ВременныйЗапрос = Новый Запрос;
ВременныйЗапрос.МенеджерВременныхТаблиц = КонтекстВыполнения.МенеджерВременныхТаблиц;
ВременныйЗапрос.Текст = "ВЫБРАТЬ * ИЗ " + ТекущееСлово + " ГДЕ ЛОЖЬ";
Попытка
// Активное вычисление!
СтруктураТипа.Метаданные = ВременныйЗапрос.Выполнить();
СтруктураТипа.ИмяОбщегоТипа = "ВременнаяТаблица";
СтруктураТипа.ВиртуальнаяТаблица.Выражение = ТекущееСлово; // Используем не по назначению
Исключение
КонецПопытки;
Иначе
СтрокаДоступнойТаблицы = НайтиДобавитьДоступнуюВременнуюТаблицу(ТекущееСлово);
ТаблицаДоступныхПолей = ПоляДоступнойТаблицы(СтрокаДоступнойТаблицы);
Если ТаблицаДоступныхПолей.Колонки.Найти("Заголовок") = Неопределено Тогда
ТаблицаДоступныхПолей.Колонки.Добавить("Заголовок");
КонецЕсли;
СтруктураТипа.ИмяОбщегоТипа = "ВременнаяТаблица";
СтруктураТипа.Метаданные = ирОбщий.УстановитьМетаданныеКоллекцииЛкс(ТаблицаДоступныхПолей);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ТаблицаСтруктурТипов.Количество() = 0 Тогда
мПлатформа.ДобавитьВТаблицуСтруктурТипов(ТаблицаСтруктурТипов, СтруктураТипа);
КонецЕсли;
Возврат ТаблицаСтруктурТипов;
КонецФункции
Процедура ОбновитьКонтекстВыраженияЗапросаПоНастройкеКомпоновкиЛкс(НастройкаКомпоновки) Экспорт
#Если Сервер И Не Сервер Тогда
НастройкаКомпоновки = Новый НастройкиКомпоновкиДанных;
#КонецЕсли
ОчиститьТаблицуСловЛокальногоКонтекста();
Для Каждого ДоступноеПоле Из НастройкаКомпоновки.ДоступныеПоляОтбора.Элементы Цикл
НрегПервыйФрагмент = ирОбщий.ПервыйФрагментЛкс(НРег(ДоступноеПоле.Поле));
Если НрегПервыйФрагмент = НРег("ПараметрыДанных") Тогда
Для Каждого ДоступныйПараметр Из ДоступноеПоле.Элементы Цикл
ИмяСвойства = мПараметрыДиалектаSQL.ПрефиксПараметра + ирОбщий.ПоследнийФрагментЛкс(ДоступныйПараметр.Поле);
ДобавитьСловоЛокальногоКонтекста(ИмяСвойства, "Свойство", , ДоступныйПараметр,,,, "СтрокаТаблицы"); // Виртуальный тип
КонецЦикла;
Иначе
ДобавитьСловоЛокальногоКонтекста("" + ДоступноеПоле.Поле, "Свойство",, ДоступноеПоле,,,, "СтрокаТаблицы"); // Виртуальный тип
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Процедура УстановитьПризнакМодифицированностиФормы()
Если ПолеТекста.ЭлементФормы.ИзменяетДанные Тогда
ФормаВладелец.Модифицированность = Истина;
КонецЕсли;
КонецПроцедуры
Функция ПолучитьСтруктуруТипаСправаОтРавно() Экспорт
КончитьОбработкуКоманды();
ТаблицаСтруктурТипов = ТаблицаСтруктурТиповТекущегоВыражения(Истина);
КончитьОбработкуКоманды();
СписокТиповКонтекста = Новый СписокЗначений;
МассивДляПроверкиДублей = Новый Массив;
Для Каждого СтруктураТипаКонтекста Из ТаблицаСтруктурТипов Цикл
ИмяОбщегоТипа = СтруктураТипаКонтекста.ИмяОбщегоТипа;
Если Ложь
Или Не мПлатформа.ЭтоАгрегатныйОбщийТип(ИмяОбщегоТипа, ЯзыкПрограммы)
Или ТипЗнч(СтруктураТипаКонтекста.Метаданные) <> Тип("ОбъектМетаданных")
Или (Истина
И ЯзыкПрограммы = 0
И Найти(ИмяОбщегоТипа, "Ссылка.") = 0)
Тогда
Продолжить;
КонецЕсли;
ПредставлениеКонкретногоТипа = "";
ПредставлениеКонкретногоТипа = ПредставлениеКонкретногоТипа + мПлатформа.ИмяТипаИзСтруктурыТипа(СтруктураТипаКонтекста);
Если МассивДляПроверкиДублей.Найти(ПредставлениеКонкретногоТипа) = Неопределено Тогда
СписокТиповКонтекста.Добавить(СтруктураТипаКонтекста, ПредставлениеКонкретногоТипа);
МассивДляПроверкиДублей.Добавить(ПредставлениеКонкретногоТипа);
КонецЕсли;
КонецЦикла;
Если СписокТиповКонтекста.Количество() > 0 Тогда
Ответ = Вопрос("Хотите использовать предсказанные равенством метаданные?", РежимДиалогаВопрос.ДаНет);
Если Ответ = КодВозвратаДиалога.Нет Тогда
Возврат Неопределено;
КонецЕсли;
КонецЕсли;
Если СписокТиповКонтекста.Количество() = 1 Тогда
ВыбраннаяСтруктураТипа = СписокТиповКонтекста[0].Значение;
КонкретныйТип = СписокТиповКонтекста[0].Представление;
ИначеЕсли СписокТиповКонтекста.Количество() > 1 Тогда
СписокТиповКонтекста.СортироватьПоПредставлению();
ВыбранныйТип = СписокТиповКонтекста.ВыбратьЭлемент("Выберите тип контекста");
Если ВыбранныйТип <> Неопределено Тогда
ВыбраннаяСтруктураТипа = ВыбранныйТип.Значение;
КонкретныйТип = ВыбранныйТип.Представление;
КонецЕсли;
КонецЕсли;
//Если ВыбраннаяСтруктураТипа <> Неопределено Тогда
// СтруктураТипаКонтекста = мПлатформа.НоваяСтруктураТипа();
// ЗаполнитьЗначенияСвойств(СтруктураТипаКонтекста, ВыбраннаяСтруктураТипа);
//КонецЕсли;
Возврат ВыбраннаяСтруктураТипа;
КонецФункции//ПолучитьСтруктуруТипаСправоОтРавно
Функция ТаблицаСтруктурТиповТекущегоВыражения(ЛиСправаОтРавенства = Ложь, БезКонструкторов = Ложь, ПолныйАнализ = Истина) Экспорт
РазобратьТекущийКонтекст(ЛиСправаОтРавенства);
лКонтекст = ?(ЛиСправаОтРавенства, мКонтекст, мРодительскийКонтекст);
МассивЗащитыОтРекурсии.Очистить();
Попытка
ТаблицаСтруктурТиповКонтекста = ОпределитьТипЗначенияКонтекста(лКонтекст, " " + мТекстДляПоискаОпределения, мПредшествующийТекст, Истина,, ПолныйАнализ);
Исключение
Ошибка = ИнформацияОбОшибке();
Если Ошибка.Описание = "ОшибкаВычисленияВиртуальнойТаблицы" Тогда
Возврат Новый ТаблицаЗначений;
КонецЕсли;
ВызватьИсключение;
КонецПопытки;
Если БезКонструкторов Тогда
Для Каждого СтрокаТаблицы Из ТаблицаСтруктурТиповКонтекста.НайтиСтроки(Новый Структура("Конструктор", Истина)) Цикл
ТаблицаСтруктурТиповКонтекста.Удалить(СтрокаТаблицы);
КонецЦикла;
КонецЕсли;
Возврат ТаблицаСтруктурТиповКонтекста;
КонецФункции
Функция ПодготовитьИмяПараметраМетода(ИмяПараметра) Экспорт
//ирОбщий.ДекодироватьТекстИзXMLЛкс(СтрокаПараметра.Параметр);
ИмяПараметра = СтрЗаменить(ИмяПараметра, "&gt;", "");
ИмяПараметра = СтрЗаменить(ИмяПараметра, "&lt;", "");
Возврат ИмяПараметра;
КонецФункции
// Вызывает контекстную подсказку в текстовом поле.
//
// Параметры:
// Нет.
//
Процедура ОткрытьАвтодополнение(КодКлавиши = "")
Если ирОбщий.ПроверитьПлатформаНеWindowsЛкс(,, Истина) Тогда
Возврат;
КонецЕсли;
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
// Мультиметка00452941 Удаляем лишние точки истории из-за запоминания по нажатию CTRL
УдалитьПоследнийПереходИзИстории();
Если Ложь
Или ПолеТекста.ТолькоПросмотр()
Или ФормаВладелец.ТолькоПросмотр
Тогда
Возврат;
КонецЕсли;
Если Истина
//И Найти(КодКлавиши, "04128") = 1 // CTRL+SPACE
И КодКлавиши = "" // Вызов из обработчика нажатия кнопки
И ТипЗнч(ПолеТекста.ЭлементФормы) = Тип("ПолеHTMLДокумента")
И ирКэш.НомерВерсииПлатформыЛкс() <= 803016
Тогда
// https://github.com/salexdv/bsl_console/issues/124
ПолеТекста.РедакторHTML().triggerSuggestions();
Возврат;
КонецЕсли;
//Если Истина
// И ЯзыкПрограммы = 1
// И Не мДоступныеТаблицыПолучены
//Тогда
// Если ирОбщий.СтрокиРавныЛкс(мДиалектSQL, "1С") Тогда
// ИначеЕсли ирОбщий.СтрокиРавныЛкс(мДиалектSQL, "WQL") Тогда
// Иначе
// ЗаполнитьДоступныеТаблицыADO(); // Может быть очень долго
// Для Каждого СтрокаДоступнойТаблицы Из ДоступныеТаблицы Цикл
// ДобавитьСловоЛокальногоКонтекста(СтрокаДоступнойТаблицы.Имя,,,, Истина,,, "ВременнаяТаблица");
// КонецЦикла;
// КонецЕсли;
//КонецЕсли;
КонкретныйТип = Неопределено;
СтруктураТипаКонтекста = Неопределено;
ТаблицаСтруктурТиповКонтекста = Неопределено;
Пока Истина Цикл
Успешно = ЗаполнитьТаблицуСлов(ТаблицаСтруктурТиповКонтекста, КонкретныйТип, СтруктураТипаКонтекста);
Если Не Успешно Тогда
Возврат;
КонецЕсли;
Если Истина
И ТаблицаСлов.Количество() = 0
И Не ирОбщий.ВосстановитьЗначениеЛкс(ИмяКласса + ".ЛиОткрыватьПустойСписок") = Истина
Тогда
Возврат;
КонецЕсли;
ТаблицаСлов.Сортировать("НСлово, ТипСлова, Определение, ТипЗначения, Частота");
КлючПоискаСтатистики = Новый Структура("ЯзыкПрограммы, ТипКонтекста", ЯзыкПрограммы, КонкретныйТип);
НайденныеСтроки = мПлатформа.ТаблицаСтатистикиВыбора.НайтиСтроки(КлючПоискаСтатистики);
ТаблицаСловТЗ = ТаблицаСлов.Выгрузить(, "НСлово, Рейтинг");
ТаблицаСловТЗ.Индексы.Добавить("НСлово");
Для Каждого СтрокаРейтинга Из НайденныеСтроки Цикл
СтрокаСлова = ТаблицаСловТЗ.Найти(НРег(СтрокаРейтинга.Слово), "НСлово");
Если СтрокаСлова <> Неопределено Тогда
СтрокаСлова.Рейтинг = СтрокаРейтинга.Рейтинг;
КонецЕсли;
КонецЦикла;
ТаблицаСлов.ЗагрузитьКолонку(ТаблицаСловТЗ.ВыгрузитьКолонку("Рейтинг"), "Рейтинг");
Если мФормаАвтодополнение = Неопределено Тогда
Если Ложь
Или Не ирКэш.ЛиПлатформаWindowsЛкс()
Или ирКлиент.ЛиПерехватКлавиатурногоВводаЛкс()
Тогда
ИмяФормы = "Автодополнение";
Иначе
ИмяФормы = "АвтодополнениеCOM";
КонецЕсли;
мФормаАвтодополнение = ПолучитьФорму(ИмяФормы, ФормаВладелец);
мФормаАвтодополнение.КлючСохраненияПоложенияОкна = ЯзыкПрограммы;
КонецЕсли;
Попытка
мФормаАвтодополнение.СтруктураТипаКонтекста = СтруктураТипаКонтекста;
Исключение
ВызватьИсключение "Экземпляр формы автодополнения контекстной подсказки сломан ошибкой платформы. Переоткройте форму чтобы восстановить ее работу";
КонецПопытки;
Если ЗначениеЗаполнено(СтруктураТипаКонтекста.ТипЯзыка) Тогда
мФормаАвтодополнение.Контекст = СтруктураТипаКонтекста.ТипЯзыка;
Иначе
мФормаАвтодополнение.Контекст = мРодительскийКонтекст;
КонецЕсли;
мФормаАвтодополнение.ТекущееСлово = мНачалоСлова;
мФормаАвтодополнение.ЗапомнитьПозициюКаретки();
ФормаВладелец.Активизировать();
//ирКлиент.Форма_АктивироватьОткрытьЛкс(ФормаВладелец); // https://www.hostedredmine.com/issues/911214
ПараметрЗакрытияПодсказки = мФормаАвтодополнение.ОткрытьМодально();
Если ПараметрЗакрытияПодсказки = Неопределено Тогда
Возврат;
КонецЕсли;
СтрокаРезультата = мФормаАвтодополнение.СтрокаСловаРезультата;
Если СтрокаРезультата = Неопределено Тогда
Возврат;
КонецЕсли;
ВставитьВыбранноеСловоАвтодополнения(СтрокаРезультата, КонкретныйТип, СтруктураТипаКонтекста, ТаблицаСтруктурТиповКонтекста, ПараметрЗакрытияПодсказки);
КонецЦикла;
КонецПроцедуры
Процедура УдалитьПоследнийПереходИзИстории()
Если мИсторияПереходов <> Неопределено И мИсторияПереходов.Количество() > 0 Тогда
мИсторияПереходов.Удалить(0);
КонецЕсли;
КонецПроцедуры
Функция ЗаполнитьТаблицуСлов(ТаблицаСтруктурТиповКонтекста = Неопределено, выхКонкретныйТип = Неопределено, выхСтруктураТипаКонтекста = Неопределено, РазрешитьОткрытиеОкон = Истина,
Знач УдалитьФункциюНовый = Ложь) Экспорт
ВычислятьТипы = ПоказыватьВсеТипыВСпискеАвтодополненияHTML();
РегВыражение.Global = Истина;
ТаблицаСтатистикиВыбора = мПлатформа.ТаблицаСтатистикиВыбора;
#Если Сервер И Не Сервер Тогда
ТаблицаСтатистикиВыбора = Новый ТаблицаЗначений;
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
Если ТаблицаСтруктурТиповКонтекста = Неопределено Тогда
ТаблицаСтруктурТиповКонтекста = ТаблицаСтруктурТиповТекущегоВыражения();
КонецЕсли;
Если ТаблицаСтруктурТиповКонтекста.Количество() = 0 Тогда
Возврат Ложь;
КонецЕсли;
ТаблицаСлов.Очистить();
Если мЭтоСтроковыйЛитерал Тогда
ВыбраннаяСтруктураТипа = ТаблицаСтруктурТиповКонтекста[0];
Иначе
СписокТиповКонтекста = Новый СписокЗначений;
СоответствиеСтруктурТипов = Новый Соответствие;
МассивДляПроверкиДублей = Новый Массив;
Для Каждого СтруктураТипаКонтекста Из ТаблицаСтруктурТиповКонтекста Цикл
ИмяОбщегоТипа = СтруктураТипаКонтекста.ИмяОбщегоТипа;
Если Истина
И Не ЗначениеЗаполнено(СтруктураТипаКонтекста.ТипЯзыка)
И Не мПлатформа.ЭтоАгрегатныйОбщийТип(ИмяОбщегоТипа, ЯзыкПрограммы)
Тогда
Продолжить;
КонецЕсли;
ПредставлениеКонкретногоТипа = "";
//Если СтруктураТипаКонтекста.СтрокаОписания <> Неопределено Тогда
// // Наверное логичнее было бы из ОпределитьТипЗначенияКонтекста ее получать
// РодительскаяСтруктураТипа = мПлатформа.НоваяСтруктураТипа();
// Если СтруктураТипаКонтекста.СтрокаОписания.Владелец().Колонки.Найти("ТипКонтекста") <> Неопределено Тогда
// ЗаполнитьЗначенияСвойств(РодительскаяСтруктураТипа, СтруктураТипаКонтекста);
// РодительскаяСтруктураТипа.ИмяОбщегоТипа = СтруктураТипаКонтекста.СтрокаОписания.ТипКонтекста;
// КонецЕсли;
// ПредставлениеКонкретногоТипа = ПредставлениеКонкретногоТипа
// + мПлатформа.ИмяТипаИзСтруктурыТипа(РодительскаяСтруктураТипа) + " / ";
//КонецЕсли;
ПредставлениеКонкретногоТипа = ПредставлениеКонкретногоТипа + мПлатформа.ИмяТипаИзСтруктурыТипа(СтруктураТипаКонтекста);
Если МассивДляПроверкиДублей.Найти(ПредставлениеКонкретногоТипа) = Неопределено Тогда
СписокТиповКонтекста.Добавить(ПредставлениеКонкретногоТипа, ПредставлениеКонкретногоТипа);
МассивДляПроверкиДублей.Добавить(ПредставлениеКонкретногоТипа);
КонецЕсли;
МассивСтруктурТипа = СоответствиеСтруктурТипов[ПредставлениеКонкретногоТипа];
Если МассивСтруктурТипа = Неопределено Тогда
МассивСтруктурТипа = Новый Массив;
КонецЕсли;
МассивСтруктурТипа.Добавить(СтруктураТипаКонтекста);
СоответствиеСтруктурТипов[ПредставлениеКонкретногоТипа] = МассивСтруктурТипа;
КонецЦикла;
Если СписокТиповКонтекста.Количество() = 0 Тогда
ВыбраннаяСтруктураТипа = ТаблицаСтруктурТиповКонтекста[0];
выхКонкретныйТип = мПлатформа.ИмяТипаИзСтруктурыТипа(СтруктураТипаКонтекста);
Иначе
ВыбраннаяСтруктураТипа = Неопределено;
Если СписокТиповКонтекста.Количество() > 1 Тогда
Если Не РазрешитьОткрытиеОкон Тогда
Возврат Ложь;
КонецЕсли;
СписокТиповКонтекста.СортироватьПоПредставлению();
НачальныйВыбор = Неопределено;
КлючПоискаСтатистики = Новый Структура("ЯзыкПрограммы, ТипКонтекста", ЯзыкПрограммы, "<Выбор типа>");
ВыбранныеРанееТипы = ТаблицаСтатистикиВыбора.Скопировать(КлючПоискаСтатистики);
ВыбранныеРанееТипы.Сортировать("Рейтинг Убыв");
Для Каждого СтрокаТипа Из ВыбранныеРанееТипы Цикл
Для Каждого ЭлементСписка Из СписокТиповКонтекста Цикл
Если СтрокаТипа.Слово = ЭлементСписка.Представление Тогда
НачальныйВыбор = ЭлементСписка;
Прервать;
КонецЕсли;
КонецЦикла;
Если НачальныйВыбор <> Неопределено Тогда
Прервать;
КонецЕсли;
КонецЦикла;
ВыбранныйЭлементСписка = СписокТиповКонтекста.ВыбратьЭлемент("Выберите тип контекста", НачальныйВыбор);
Если ВыбранныйЭлементСписка = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
выхКонкретныйТип = ВыбранныйЭлементСписка.Представление;
// Обновим статистику выбора
КлючПоискаСтатистики.Вставить("Слово", выхКонкретныйТип);
НайденныеСтроки = ТаблицаСтатистикиВыбора.НайтиСтроки(КлючПоискаСтатистики);
Если НайденныеСтроки.Количество() > 0 Тогда
СтрокаСтатистикиВыбора = НайденныеСтроки[0];
Иначе
СтрокаСтатистикиВыбора = ТаблицаСтатистикиВыбора.Добавить();
ЗаполнитьЗначенияСвойств(СтрокаСтатистикиВыбора, КлючПоискаСтатистики);
КонецЕсли;
СтрокаСтатистикиВыбора.Рейтинг = СтрокаСтатистикиВыбора.Рейтинг + 1;
Иначе
ВыбранныйЭлементСписка = СписокТиповКонтекста[0];
выхКонкретныйТип = ВыбранныйЭлементСписка.Представление;
КонецЕсли;
МассивСтруктурТипа = СоответствиеСтруктурТипов[выхКонкретныйТип];
Для Каждого СтруктураТипа Из МассивСтруктурТипа Цикл
Если Ложь
Или ВыбраннаяСтруктураТипа = Неопределено
Или ТипЗнч(ВыбраннаяСтруктураТипа.Метаданные) = Тип("ОбъектМетаданныхКонфигурация")
Тогда
ВыбраннаяСтруктураТипа = СтруктураТипа;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЕсли;
выхСтруктураТипаКонтекста = мПлатформа.НоваяСтруктураТипа();
Если ВыбраннаяСтруктураТипа.ТипЯзыка <> "ИмяТипа" И мЭтоСтроковыйЛитерал Тогда
// Находимся внутри строкового литерала на позиции параметра
КоллекцияЭлементовМД = Новый Массив;
Если Истина
И ВыбраннаяСтруктураТипа.СтрокаОписания <> Неопределено
И ВыбраннаяСтруктураТипа.СтрокаОписания.Владелец().Колонки.Найти("ЛиЭкспорт") = Неопределено
Тогда
ИмяПараметра = "";
СтрокиПараметров = мПлатформа.ТаблицаПараметровМетода(ВыбраннаяСтруктураТипа.СтрокаОписания);
СтрокиПараметров = СтрокиПараметров.НайтиСтроки(Новый Структура("Номер", мНомерПараметра));
Для Каждого СтрокаПараметра Из СтрокиПараметров Цикл
Если Найти(СтрокаПараметра.ТипЗначения, "Строка") > 0 Тогда
ИмяПараметра = ПодготовитьИмяПараметраМетода(СтрокаПараметра.Параметр);
Прервать;
КонецЕсли;
КонецЦикла;
// Имена свойств
Если Ложь
Или ТипЗнч(ВыбраннаяСтруктураТипа.Метаданные) = Тип("ТаблицаЗначений")
Или ТипЗнч(ВыбраннаяСтруктураТипа.Метаданные) = Тип("ДеревоЗначений")
Или ТипЗнч(ВыбраннаяСтруктураТипа.Метаданные) = Тип("РезультатЗапроса")
Тогда
КоллекцияЭлементовМД = ВыбраннаяСтруктураТипа.Метаданные.Колонки;
ИначеЕсли Истина
И ТипЗнч(ВыбраннаяСтруктураТипа.Метаданные) = Тип("Структура")
И ИмяПараметра = "Ключ"
Тогда
КоллекцияЭлементовМД = ирОбщий.ВыгрузитьСвойствоКоллекцииЛкс(ВыбраннаяСтруктураТипа.Метаданные);
ИначеЕсли ТипЗнч(ВыбраннаяСтруктураТипа.Метаданные) = Тип("ОбъектМетаданных") Тогда
Если ИмяПараметра = "Макет" Тогда
КоллекцияЭлементовМД = ВыбраннаяСтруктураТипа.Метаданные.Макеты;
ИначеЕсли ИмяПараметра = "Форма" Тогда
КоллекцияЭлементовМД = ВыбраннаяСтруктураТипа.Метаданные.Формы;
Иначе
ИмяТаблицыБД = ирКэш.ИмяТаблицыИзМетаданныхЛкс(ВыбраннаяСтруктураТипа.Метаданные.ПолноеИмя());
Если ЗначениеЗаполнено(ИмяТаблицыБД) Тогда
КоллекцияЭлементовМД = ирОбщий.ПоляТаблицыБДЛкс(ИмяТаблицыБД);
КонецЕсли;
КонецЕсли;
ИначеЕсли ИмяПараметра = "ИмяПользователяИБ" Тогда
ПользователиИБ = ПользователиИнформационнойБазы.ПолучитьПользователей();
Для Каждого Пользователь Из ПользователиИБ Цикл
КоллекцияЭлементовМД.Добавить(Пользователь.Имя);
КонецЦикла;
ИначеЕсли ИмяПараметра = "Роль" Тогда
КоллекцияЭлементовМД = Метаданные.Роли;
ИначеЕсли ИмяПараметра = "ИмяПользователяИБ" Тогда
ПользователиИБ = ПользователиИнформационнойБазы.ПолучитьПользователей();
Для Каждого Пользователь Из ПользователиИБ Цикл
КоллекцияЭлементовМД.Добавить(Пользователь.Имя);
КонецЦикла;
ИначеЕсли ИмяПараметра = "ОбщийМакет" Тогда
КоллекцияЭлементовМД = Метаданные.ОбщиеМакеты;
ИначеЕсли Истина
И ВыбраннаяСтруктураТипа.СтрокаОписания.Слово = "ПолучитьОбщуюФорму"
И ИмяПараметра = "Форма"
Тогда
КоллекцияЭлементовМД = Метаданные.ОбщиеФормы;
ИначеЕсли Истина
И ВыбраннаяСтруктураТипа.СтрокаОписания.Слово = "НайтиПредопределенное"
И ВыбраннаяСтруктураТипа.СтрокаОписания.ТипКонтекста = "МенеджерРегламентныхЗаданий"
И ИмяПараметра = "Метаданные"
Тогда
КоллекцияЭлементовМД = Метаданные.РегламентныеЗадания;
ИначеЕсли Истина
И ВыбраннаяСтруктураТипа.СтрокаОписания.Слово = "ПравоДоступа"
И ИмяПараметра = "Право"
Тогда
КоллекцияЭлементовМД = ирОбщий.ТаблицаЗначенийИзТабличногоДокументаЛкс(мПлатформа.ПолучитьМакет("ВидыПравДоступа"));
ИначеЕсли Истина
И ВыбраннаяСтруктураТипа.СтрокаОписания.Слово = "ЗаполнитьЗначенияСвойств"
И (Ложь
Или ИмяПараметра = "СписокСвойств"
Или ИмяПараметра = "ИсключаяСвойства")
Тогда
СтруктураТипаПараметра = ОпределитьТипЗначенияКонтекста(мПервыйПараметр, мТекстДляПоискаОпределения);
КоллекцияЭлементовМД = мПлатформа.ПолучитьТаблицуСловСтруктурыТипа(СтруктураТипаПараметра[0]).Скопировать(Новый Структура("ТипСлова", "Свойство")).ВыгрузитьКолонку("Слово");
ИначеЕсли Истина
И (Ложь
Или ВыбраннаяСтруктураТипа.СтрокаОписания.Слово = "ПолучитьФункциональнуюОпцию"
Или ВыбраннаяСтруктураТипа.СтрокаОписания.Слово = "ПолучитьФункциональнуюОпциюИнтерфейса"
Или ВыбраннаяСтруктураТипа.СтрокаОписания.Слово = "ПолучитьФункциональнуюОпциюФормы")
И ИмяПараметра = "Имя"
Тогда
КоллекцияЭлементовМД = Метаданные.ФункциональныеОпции;
ИначеЕсли Истина
И ТипЗнч(ВыбраннаяСтруктураТипа.Метаданные) = Тип("ПостроительЗапроса")
И (Ложь
Или ИмяПараметра = "ПутьКДанным"
Или ИмяПараметра = "Описание")
Тогда
ИмяПараметра = "ПутьКДанным";
ПостроительЗапроса = ВыбраннаяСтруктураТипа.Метаданные;
#Если Сервер И Не Сервер Тогда
ПостроительЗапроса = Новый ПостроительЗапроса;
#КонецЕсли
КоллекцияЭлементовМД = ПостроительЗапроса.ДоступныеПоля;
КонецЕсли;
//Если Ложь
// // ФоновыеЗадания.Выполнить("")
// Или (Истина
// И ВыбраннаяСтруктураТипа.СтрокаОписания.Слово = "Выполнить"
// И ВыбраннаяСтруктураТипа.СтрокаОписания.ТипКонтекста = "МенеджерФоновыхЗаданий"
// И ИмяПараметра = "ИмяМетода")
// // БлокировкаДанных.Добавить("")
// Или (Истина
// И ВыбраннаяСтруктураТипа.СтрокаОписания.Слово = "Добавить"
// И ВыбраннаяСтруктураТипа.СтрокаОписания.ТипКонтекста = "БлокировкаДанных"
// И ИмяПараметра = "ПространствоБлокировки")
// Или (Истина
// И ВыбраннаяСтруктураТипа.СтрокаОписания.Слово = "УстановитьЗначение"
// И ВыбраннаяСтруктураТипа.СтрокаОписания.ТипКонтекста = "ЭлементБлокировкиДанных"
// И ИмяПараметра = "ПолеПространстваБлокировок")
//Тогда
ВыбраннаяСтруктураТипа.ТипЯзыка = ИмяПараметра;
выхСтруктураТипаКонтекста.ТипЯзыка = ИмяПараметра;
//КонецЕсли;
КонецЕсли;
Если ВыбраннаяСтруктураТипа.ТипЯзыка = "ИмяМетода" Тогда
Если ЗначениеЗаполнено(мРодительскийКонтекст) Тогда
выхСтруктураТипаКонтекста.ИмяОбщегоТипа = "ОбщийМодуль";
выхСтруктураТипаКонтекста.Метаданные = Метаданные.ОбщиеМодули.Найти(мРодительскийКонтекст);
ВнутренняяТаблицаСлов = мПлатформа.СвойстваТипаМетаданные(выхСтруктураТипаКонтекста,, "Метод",,,,,, Истина);
ВнутренняяТаблицаСлов.Колонки.Добавить("Определение");
ВнутренняяТаблицаСлов.ЗаполнитьЗначения("Метаданные", "Определение");
ЗагрузитьВТаблицуСловИзВнутреннейТаблицыСлов(ВнутренняяТаблицаСлов, ТаблицаСлов);
Иначе
КоллекцияЭлементовМД = Новый Массив;
Для Каждого КлючИЗначение Из ирКэш.ДоступныеОбщиеМодулиЛкс(Истина) Цикл
КоллекцияЭлементовМД.Добавить(КлючИЗначение.Значение);
КонецЦикла;
КонецЕсли;
ИначеЕсли ВыбраннаяСтруктураТипа.ТипЯзыка = "ИмяПредопределенногоЗначения" Тогда
КоллекцияЭлементовМД = Новый Массив;
Если ЗначениеЗаполнено(мРодительскийКонтекст) Тогда
ТаблицаТиповМетаОбъектов = ирКэш.ТипыМетаОбъектов(Ложь);
КорневойТип = ирОбщий.ПервыйФрагментЛкс(мРодительскийКонтекст);
КоллекцияЭлементовМД.Добавить("ПустаяСсылка");
Если Найти(мРодительскийКонтекст, ".") > 0 Тогда
ОбъектМД = Метаданные.НайтиПоПолномуИмени(мРодительскийКонтекст);
Если ирОбщий.ЛиКорневойТипПеречисленияЛкс(КорневойТип) Тогда
#Если Сервер И Не Сервер Тогда
ОбъектМД = Метаданные.Перечисления.ABCКлассификация;
#КонецЕсли
Для Каждого ЗначениеПеречисления Из ОбъектМД.ЗначенияПеречисления Цикл
КоллекцияЭлементовМД.Добавить(ЗначениеПеречисления.Имя);
КонецЦикла;
Иначе
#Если Сервер И Не Сервер Тогда
ОбъектМД = Метаданные.Справочники.Валюты;
#КонецЕсли
Если Истина
И ирКэш.НомерВерсииПлатформыЛкс() > 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КлассыВСписокСлов(МассивКомКлассов, Компоненты);
КонецЕсли;
КоллекцияЭлементовМД = МассивКОМКлассов;
КонецЕсли;
выхСтруктураТипаКонтекста.ИмяОбщегоТипа = "Строка";
Для Каждого ЭлементКоллекцииМД Из КоллекцияЭлементовМД Цикл
СтрокаСлова = ТаблицаСлов.Добавить();
Если ТипЗнч(ЭлементКоллекцииМД) = Тип("Строка") Тогда
СтрокаСлова.Слово = ЭлементКоллекцииМД;
Иначе
СтрокаСлова.Слово = ЭлементКоллекцииМД.Имя;
КонецЕсли;
СтрокаСлова.ТипСлова = "Свойство";
СтрокаСлова.Определение = "Метаданные";
СтрокаСлова.ТипЗначения = "Строка";
КонецЦикла;
Иначе
Если Истина
И ЯзыкПрограммы = 1
И (Ложь
Или ВыбраннаяСтруктураТипа.ИмяОбщегоТипа = "Локальный"
Или ВыбраннаяСтруктураТипа.ИмяОбщегоТипа = "")
Тогда
Если Истина
И ВыбраннаяСтруктураТипа.ТипЯзыка = "ИмяТипа"
И Не мТолькоСсылочныеИменаТипов
Тогда
ИменаФиксированныхТипов = Новый Массив;
ИменаФиксированныхТипов.Добавить("БУЛЕВО");
ИменаФиксированныхТипов.Добавить("ДАТА");
ИменаФиксированныхТипов.Добавить("СТРОКА");
ИменаФиксированныхТипов.Добавить("ЧИСЛО");
Для Каждого ЭлементКоллекцииМД Из ИменаФиксированныхТипов Цикл
СтрокаСлова = ТаблицаСлов.Добавить();
СтрокаСлова.Слово = ЭлементКоллекцииМД;
СтрокаСлова.ТипСлова = "Свойство";
СтрокаСлова.Определение = "Предопределенный";
СтрокаСлова.ТипЗначения = "Тип";
КонецЦикла;
КонецЕсли;
Если ВыбраннаяСтруктураТипа.ТипЯзыка = "" Тогда
Для Каждого ОписаниеТаблицы Из ДоступныеТаблицы.НайтиСтроки(Новый Структура("Тип, Схема", "ВременнаяТаблица", "")) Цикл
СтрокаСлова = ТаблицаСлов.Добавить();
СтрокаСлова.Слово = ОписаниеТаблицы.Имя;
СтрокаСлова.ТипСлова = "Свойство";
СтрокаСлова.Определение = "Локальный";
СтрокаСлова.ТипЗначения = ОписаниеТаблицы.Тип;
КонецЦикла;
СтрокаСлова = ТаблицаСлов.Добавить();
СтрокаСлова.Слово = СокрП(мМаркерПорядкаОтладки);
СтрокаСлова.ТипСлова = "Конструкция";
КонецЕсли;
КонецЕсли;
ЗаполнитьЗначенияСвойств(выхСтруктураТипаКонтекста, ВыбраннаяСтруктураТипа);
КонецЕсли;
ТаблицаСтруктурТиповКонтекста.Очистить();
Попытка
ВыгрузкаТаблицыСлов = мПлатформа.ПолучитьТаблицуСловСтруктурыТипа(выхСтруктураТипаКонтекста, ЯзыкПрограммы, Конфигурация, ВнешниеФункцииКомпоновкиДанных, ВычислятьТипы,,,
ЛиСерверныйКонтекст,, МодульМетаданныхКонтекста(выхСтруктураТипаКонтекста));
СловаДляУточненияТипа = ВыгрузкаТаблицыСлов.НайтиСтроки(Новый Структура("МожноУточнитьТип", Истина));
//Если ВычислятьТипы Или СловаДляУточненияТипа.Количество() < 100 Тогда
Для Каждого ВнутренняяСтрокаСлова Из СловаДляУточненияТипа Цикл
ОбновитьТипЗначенияИзТаблицыСтруктурТипов(ВнутренняяСтрокаСлова, ВнутренняяСтрокаСлова.ТаблицаСтруктурТипов, Ложь);
КонецЦикла;
//КонецЕсли;
#Если Сервер И Не Сервер Тогда
ВыгрузкаТаблицыСлов = Новый ТаблицаЗначений;
#КонецЕсли
Если Ложь
Или выхСтруктураТипаКонтекста.ИмяОбщегоТипа = "Локальный"
Или выхСтруктураТипаКонтекста.ИмяОбщегоТипа = "ВнешнийИсточникДанных.<Имя внешнего источника>.ВременнаяТаблица"
Тогда
ВыгрузкаТаблицыСлов.Индексы.Добавить("Слово, ТипСлова");
Если выхСтруктураТипаКонтекста.ИмяОбщегоТипа = "Локальный" Тогда
// Добавим слова из таблицы локального контекста
Для Каждого СтрокаСлова Из ТаблицаЛокальногоКонтекста Цикл
НоваяСтрока = мПлатформа.ДобавитьВТаблицуСлов(ВыгрузкаТаблицыСлов, СтрокаСлова.Слово, СтрокаСлова.ТипСлова);
Если Не ЗначениеЗаполнено(НоваяСтрока.Определение) Тогда
НоваяСтрока.Определение = "Локальный";
КонецЕсли;
//Если ЗаполнятьТипы Тогда // Если откладывать вычисление типа, то потом через метод УточнитьТипЗначенияВСтрокеТаблицыСлов он не вычислится
НоваяСтрока.ТипЗначения = мПлатформа.ПредставлениеМассиваСтруктурТипов(СтрокаСлова.ТаблицаСтруктурТипов);
//КонецЕсли;
КонецЦикла;
КонецЕсли;
Если выхСтруктураТипаКонтекста.ИмяОбщегоТипа = "ВнешнийИсточникДанных.<Имя внешнего источника>.ВременнаяТаблица" Тогда
Для Каждого СтрокаВременнойТаблицы Из ДоступныеТаблицы.НайтиСтроки(Новый Структура("Тип", "ВременнаяТаблица")) Цикл
НоваяСтрока = мПлатформа.ДобавитьВТаблицуСлов(ВыгрузкаТаблицыСлов, СтрокаВременнойТаблицы.Имя, "Свойство",, "ВременнаяТаблица");
НоваяСтрока.Определение = "Локальный";
КонецЦикла;
КонецЕсли;
КонецЕсли;
ирОбщий.ЗагрузитьВТаблицуЗначенийЛкс(ВыгрузкаТаблицыСлов, ТаблицаСлов);
Исключение
Ошибка = ИнформацияОбОшибке();
Если Ошибка.Описание = "ОшибкаВычисленияВиртуальнойТаблицы" Тогда
Возврат Ложь;
КонецЕсли;
ВызватьИсключение;
КонецПопытки;
СтруктураКлюча = Новый Структура("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка",
выхСтруктураТипаКонтекста.ИмяОбщегоТипа, ЯзыкПрограммы, выхСтруктураТипаКонтекста.ТипЯзыка);
ДобавлятьЛокальныйКонтекст = Ложь
Или ЗначениеЗаполнено(мРодительскийКонтекст)
Или выхСтруктураТипаКонтекста.ИмяОбщегоТипа = "Неизвестный контекст"
Или выхСтруктураТипаКонтекста.ИмяОбщегоТипа = "Локальный"
Или мПлатформа.ТаблицаШаблоновКонтекстов.НайтиСтроки(СтруктураКлюча).Количество() > 0;
Если РазрешитьОткрытиеОкон Или ВычислятьТипы Или ДобавлятьЛокальныйКонтекст Тогда
Для Каждого СтрокаСлова Из ТаблицаСлов Цикл
СтрокаСлова.НСлово = НРег(СтрокаСлова.Слово);
КонецЦикла;
Если ДобавлятьЛокальныйКонтекст Тогда
ЗаполнитьЛокальныеСвойстваИМетодыПоТексту(Ложь, выхСтруктураТипаКонтекста.ИмяОбщегоТипа = "Локальный", Истина, Ложь);
//Если Истина
// И УдалитьФункциюНовый // https://www.hostedredmine.com/issues/963017
// И выхСтруктураТипаКонтекста.ИмяОбщегоТипа = "Локальный"
//Тогда
// СтрокаСловаНовый = ТаблицаСлов.НайтиСтроки(Новый Структура("Слово, ТипСлова", "Новый", "Метод"));
// Если СтрокаСловаНовый.Количество() > 0 Тогда
// ТаблицаСлов.Удалить(СтрокаСловаНовый[0]);
// КонецЕсли;
//КонецЕсли;
КонецЕсли;
Если Прав(мТекущееСлово, 1) = "(" Тогда
ЧистоеТекущееСлово = Лев(мТекущееСлово, СтрДлина(мТекущееСлово) - 1);
ТипТекущегоСлова = "Метод";
Иначе
ЧистоеТекущееСлово = мТекущееСлово;
ТипТекущегоСлова = "Свойство";
КонецЕсли;
КлючПоиска = Новый Структура("НСлово, Определение, ТипСлова", НРег(ЧистоеТекущееСлово), "Статистический", ТипТекущегоСлова);
НайденныеСтроки = ТаблицаСлов.НайтиСтроки(КлючПоиска);
Если НайденныеСтроки.Количество() > 0 Тогда
НайденнаяСтрока = НайденныеСтроки[0];
НайденнаяСтрока.Частота = НайденнаяСтрока.Частота - 1;
Если НайденнаяСтрока.Частота = 0 Тогда
ТаблицаСлов.Удалить(НайденнаяСтрока);
КонецЕсли;
КонецЕсли;
ТаблицаСлов.Свернуть("НСлово, Слово, ТипСлова, Определение, ТипЗначения", "Частота");
КонецЕсли;
Возврат Истина;
КонецФункции
Процедура ВставитьВыбранноеСловоАвтодополнения(СтрокаРезультата, КонкретныйТип, СтруктураТипаКонтекста, ТаблицаСтруктурТиповКонтекста = Неопределено, ПараметрЗакрытияПодсказки = Истина) Экспорт
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
ТаблицаСтатистикиВыбора = мПлатформа.ТаблицаСтатистикиВыбора;
Если Найти(НРег(СтрокаРезультата.Слово), НРег(мНачалоСлова + мКонецКонтекста)) = 1 Тогда
НеобрабатываемыйКонецСтроки = Сред(ТекущийКонецСтроки, СтрДлина(мКонецКонтекста) + 1);
Иначе
НеобрабатываемыйКонецСтроки = ТекущийКонецСтроки;
РегВыражение.Pattern = "[" + шБуква + "\d]";
Если РегВыражение.Проверить(Лев(НеобрабатываемыйКонецСтроки, 1)) Тогда
НеобрабатываемыйКонецСтроки = " " + НеобрабатываемыйКонецСтроки;
КонецЕсли;
КонецЕсли;
СтрокаНачала = "";
Если Не мЭтоСтроковыйЛитерал И СтрокаРезультата.ТипСлова = "Метод" Тогда
Если Лев(мКонецКонтекста, 1) = "(" Тогда
НеобрабатываемыйКонецСтроки = Сред(НеобрабатываемыйКонецСтроки, 2);
КонецЕсли;
СтрокаОкончания = "()";
Если Истина
И ПараметрЗакрытияПодсказки = Истина
И Прав(мТекущееСлово, 1) = "("
Тогда
СтрокаОкончания = "(";
Иначе
Если Истина
И ЯзыкПрограммы = 0
И Лев(НеобрабатываемыйКонецСтроки, 1) <> ";"
И СтрокаРезультата.ТипЗначения = ""
И СтрокаРезультата.Определение <> "Статистический"
Тогда
СтрокаОкончания = СтрокаОкончания + ";"
КонецЕсли;
КонецЕсли;
СмещениеКурсораВОкончании = СтрДлина(СтрокаОкончания);
Если ПараметрЗакрытияПодсказки = Истина Тогда
ТаблицаМетодовМодуля = мПлатформа.СвойстваТипаМетаданные(СтруктураТипаКонтекста, СтрокаРезультата.Слово, "Метод",,,,,,, мМодульМетаданных);
Если ТаблицаМетодовМодуля.Количество() > 0 Тогда
СтрокаОписания = ТаблицаМетодовМодуля[0].ТаблицаСтруктурТипов[0].СтрокаОписания;
Если Ложь
Или (Истина
И ТипЗнч(СтрокаОписания) = Тип("COMОбъект")
И СтрокаОписания.Parameters.Count > 0)
Или (Истина
И ТипЗнч(СтрокаОписания) = Тип("СтрокаТаблицыЗначений")
И СтрокаОписания.Параметры <> Неопределено)
Тогда
СмещениеКурсораВОкончании = 1;
КонецЕсли;
Иначе
МассивОбщихТипов = мПлатформа.ТаблицаОбщихТиповИзСтруктурыТипа(СтруктураТипаКонтекста);
КлючПоискаПараметров = Новый Структура("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка, НСлово, ТипСлова"); // Индекс
КлючПоискаПараметров.НСлово = НРег(СтрокаРезультата.Слово);
КлючПоискаПараметров.ЯзыкПрограммы = ЯзыкПрограммы;
КлючПоискаПараметров.ТипЯзыка = "";
КлючПоискаПараметров.ТипСлова = СтрокаРезультата.ТипСлова;
СмещениеКурсораВОкончании = 2;
Для Каждого СтрокаОбщегоТипа Из МассивОбщихТипов Цикл
КлючПоискаПараметров.ТипКонтекста = СтрокаОбщегоТипа.ИмяОбщегоТипа;
СтрокиКонтекста = мПлатформа.ТаблицаКонтекстов.НайтиСтроки(КлючПоискаПараметров);
Если СтрокиКонтекста.Количество() > 0 Тогда
НайденныеСтроки = мПлатформа.ТаблицаПараметровМетода(СтрокиКонтекста[0]);
Если НайденныеСтроки.Количество() > 0 Тогда
СмещениеКурсораВОкончании = 1;
Прервать;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЕсли;
ИначеЕсли Истина
И ПараметрЗакрытияПодсказки = "."
И ЯзыкПрограммы <> 0
И СтрокаРезультата.ТипСлова = "Свойство"
И Найти(СтрокаРезультата.Слово, мПараметрыДиалектаSQL.ПрефиксПараметра) = 1
Тогда
СтрокаНачала = "(";
СтрокаОкончания = ")";
СмещениеКурсораВОкончании = 1;
Иначе
СтрокаОкончания = "";
СмещениеКурсораВОкончании = 0;
КонецЕсли;
// Обновим статистику выбора
Если Истина
И СтрокаРезультата.Определение <> "Локальный"
И СтрокаРезультата.Определение <> "Статистический"
Тогда
КлючПоиска = Новый Структура("ЯзыкПрограммы, ТипКонтекста, Слово", ЯзыкПрограммы, КонкретныйТип, СтрокаРезультата.Слово);
НайденныеСтроки = ТаблицаСтатистикиВыбора.НайтиСтроки(КлючПоиска);
Если НайденныеСтроки.Количество() > 0 Тогда
СтрокаСтатистикиВыбора = НайденныеСтроки[0];
Иначе
СтрокаСтатистикиВыбора = ТаблицаСтатистикиВыбора.Добавить();
ЗаполнитьЗначенияСвойств(СтрокаСтатистикиВыбора, КлючПоиска);
КонецЕсли;
СтрокаСтатистикиВыбора.Рейтинг = СтрокаСтатистикиВыбора.Рейтинг + 1;
КонецЕсли;
СтрокаДобавка = СтрокаНачала + СтрокаРезультата.Слово + СтрокаОкончания;
Если мРодительскийКонтекст <> "" Тогда
СтрокаДобавка = мРодительскийКонтекст + "." + СтрокаДобавка;
КонецЕсли;
мРодительскийКонтекст = СтрокаДобавка;
Если Истина
И ПараметрЗакрытияПодсказки <> Истина
Тогда
СтрокаДобавка = СтрокаДобавка + ПараметрЗакрытияПодсказки;
мТекущееСлово = СтрокаРезультата.Слово;
Если ПараметрЗакрытияПодсказки = "." Тогда
Если СтрокаРезультата.Определение = "Статистический" Тогда
ТаблицаСтруктурТиповКонтекста = ОпределитьТипЗначенияКонтекста(мРодительскийКонтекст, " " + мТекстДляПоискаОпределения, мПредшествующийТекст, Истина);
Иначе
ТаблицаСтруктурТиповКонтекста = ОпределитьТипДочернегоКонтекста(ирОбщий.ЗначенияВМассивЛкс(СтруктураТипаКонтекста), мТекущееСлово, СтрокаРезультата.ТипСлова);
КонецЕсли;
КонецЕсли;
КонецЕсли;
ТекущееНачалоСтроки = Лев(ТекущееНачалоСтроки, мКонечнаяКолонка - 1 - СтрДлина(мНачалоКонтекста)) + СтрокаДобавка;
ТекущаяСтрока = ТекущееНачалоСтроки + НеобрабатываемыйКонецСтроки;
Если ОригинальныйТекст = "" Тогда
ВыделенныйТекст("" + ТекущаяСтрока);
Иначе
Если ПолеТекста.КоличествоСтрок() < мКонечнаяСтрока Тогда
ПолеТекста.ДобавитьСтроку(ТекущаяСтрока);
Иначе
ПолеТекста.ЗаменитьСтроку(мКонечнаяСтрока, ТекущаяСтрока); // Баг платформы. Вызывает выделение всего предшествующего текста на 8.3.18
КонецЕсли;
КонецЕсли;
УстановитьПризнакМодифицированностиФормы();
Если АвтоматическаяПодсказкаПоВызовуМетода() Тогда
мОткрытьСправкуПоПараметру = СмещениеКурсораВОкончании = 1;
КонецЕсли;
мКонечнаяКолонка = мКонечнаяКолонка + СтрДлина(СтрокаДобавка) - СтрДлина(мНачалоКонтекста) - СтрДлина(СтрокаОкончания) + СмещениеКурсораВОкончании;
мНачальнаяКолонка = мКонечнаяКолонка;
мНачалоКонтекста = мРодительскийКонтекст + ".";
мНачалоСлова = "";
УстановитьГраницыВыделения();
КонецПроцедуры
Функция АвтоматическаяПодсказкаПоВызовуМетода(Обновить = Ложь) Экспорт
Если АвтоматическаяПодсказкаПоВызовуМетода = Неопределено Или Обновить Тогда
АвтоматическаяПодсказкаПоВызовуМетода = ирОбщий.ВосстановитьЗначениеЛкс(ИмяКласса + ".АвтоматическаяПодсказкаПоВызовуМетода") <> Ложь;
КонецЕсли;
Возврат АвтоматическаяПодсказкаПоВызовуМетода;
КонецФункции
Функция АвтоматическаяПодсказкаАвтодополненияHTML(Обновить = Ложь) Экспорт
Если АвтоматическаяПодсказкаАвтодополненияHTML = Неопределено Или Обновить Тогда
АвтоматическаяПодсказкаАвтодополненияHTML = ирОбщий.ВосстановитьЗначениеЛкс(ИмяКласса + ".АвтоматическаяПодсказкаАвтодополненияHTML") <> Ложь;
КонецЕсли;
Возврат АвтоматическаяПодсказкаАвтодополненияHTML;
КонецФункции
Функция ПоказыватьВсеТипыВСпискеАвтодополненияHTML(Обновить = Ложь) Экспорт
Если ПоказыватьВсеТипыВСпискеАвтодополненияHTML = Неопределено Или Обновить Тогда
ПоказыватьВсеТипыВСпискеАвтодополненияHTML = ирОбщий.ВосстановитьЗначениеЛкс(ИмяКласса + ".ПоказыватьВсеТипыВСпискеАвтодополненияHTML") = Истина;
КонецЕсли;
Возврат ПоказыватьВсеТипыВСпискеАвтодополненияHTML;
КонецФункции
Функция ПредпочитатьHTMLРедакторКода(Обновить = Ложь) Экспорт
Если Не ирКэш.ДоступенРедакторМонакоЛкс() Тогда
Возврат Ложь;
КонецЕсли;
Если ПредпочитатьHTMLРедакторКода = Неопределено Или Обновить Тогда
ПредпочитатьHTMLРедакторКода = ирОбщий.ВосстановитьЗначениеЛкс(ИмяКласса + ".ПредпочитатьHTMLРедакторКода") = Истина;
КонецЕсли;
Возврат ПредпочитатьHTMLРедакторКода;
КонецФункции
Процедура ДобавитьCOMКлассыВСписокСлов(Знач КоллекцияКолонок, Знач Компоненты)
Для Каждого Класс Из Компоненты Цикл
Если Не ЗначениеЗаполнено(Класс.Name) Тогда
Продолжить;
КонецЕсли;
ИмяКласса = Класс.Name;
КоллекцияКолонок.Добавить(ИмяКласса);
КонецЦикла;
КонецПроцедуры
Процедура ЗагрузитьВТаблицуСловИзВнутреннейТаблицыСлов(Знач ВнутренняяТаблицаСлов, Знач ВыгрузкаТаблицыСлов)
Для Каждого ВнутренняяСтрокаСлова Из ВнутренняяТаблицаСлов Цикл
НоваяСтрока = ВыгрузкаТаблицыСлов.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, ВнутренняяСтрокаСлова);
ТаблицаСтруктурТипов = ВнутренняяСтрокаСлова.ТаблицаСтруктурТипов;
Если ТаблицаСтруктурТипов <> Неопределено Тогда
ОбновитьТипЗначенияИзТаблицыСтруктурТипов(НоваяСтрока, ТаблицаСтруктурТипов);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Функция УточнитьТипЗначенияВСтрокеТаблицыСлов(Знач СтруктураТипаКонтекста, Знач ТекущаяСтрока, Знач ВернутьСтруктуруТипа = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
ТекущаяСтрока = ТаблицаСлов.Добавить();
#КонецЕсли
НужноУточнитьТип = Ложь
Или Лев(ТекущаяСтрока.ТипЗначения, 2) = "??"
Или Найти(ТекущаяСтрока.ТипЗначения, "<") > 0;
Если НужноУточнитьТип Или ВернутьСтруктуруТипа Тогда
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ОписанияСлов = мПлатформа.ПолучитьТаблицуСловСтруктурыТипа(СтруктураТипаКонтекста, ЯзыкПрограммы, Конфигурация,, Истина,, ТекущаяСтрока.ТипСлова, ЛиСерверныйКонтекст, ТекущаяСтрока.Слово,
МодульМетаданныхКонтекста(СтруктураТипаКонтекста), Истина);
Если ОписанияСлов.Количество() > 0 Тогда
Если НужноУточнитьТип Тогда
ОбновитьТипЗначенияИзТаблицыСтруктурТипов(ТекущаяСтрока, ОписанияСлов[0].ТаблицаСтруктурТипов, ТекущаяСтрока.Определение <> "Метаданные");
КонецЕсли;
Возврат ОписанияСлов[0].ТаблицаСтруктурТипов;
КонецЕсли;
КонецЕсли;
Возврат Неопределено;
КонецФункции
Процедура ПоискОбщегоМетода()
ФормаВыбора = ПолучитьФорму("ОбщиеМетоды");
ФормаВыбора.Открыть();
КонецПроцедуры
Процедура НайтиВызовыМетода()
РазобратьТекущийКонтекст();
Если ЗначениеЗаполнено(мРодительскийКонтекст) Тогда
ТаблицаСтруктурТиповРодителя = ОпределитьТипЗначенияКонтекста(мРодительскийКонтекст, " " + мТекстДляПоискаОпределения, мПредшествующийТекст, Истина);
СтруктураТипаРодителя = ТаблицаСтруктурТиповРодителя[0];
КонецЕсли;
ТаблицаСтруктурТиповКонтекста = ОпределитьТипЗначенияКонтекста(мКонтекст, " " + мТекстДляПоискаОпределения, мПредшествующийТекст, Истина);
СтруктураТипаКонтекста = ТаблицаСтруктурТиповКонтекста[0];
ПолноеИмяМетода = "";
ПараметрИскатьНепрямые = Неопределено;
Если СтруктураТипаКонтекста.ТипЯзыка = "ИмяТипа" Тогда
ПолноеИмяМетода = "Новый ";
ПараметрИскатьНепрямые = Ложь;
Если Прав(мТекущееСлово, 1) <> "(" Тогда
мТекущееСлово = мТекущееСлово + "(";
КонецЕсли;
СтруктураТипаКонтекста = Неопределено;
Иначе
Если Прав(мТекущееСлово, 1) <> "(" Тогда
Возврат;
КонецЕсли;
Если Истина
И СтруктураТипаРодителя <> Неопределено
И СтруктураТипаРодителя.ИмяОбщегоТипа = "ОбщийМодуль"
Тогда
ПолноеИмяМетода = СтруктураТипаРодителя.Метаданные.Имя + ".";
ПараметрИскатьНепрямые = Ложь;
СтруктураТипаКонтекста = Неопределено;
ИначеЕсли Истина
И СтруктураТипаКонтекста.СтрокаОписания <> Неопределено
И СтруктураТипаКонтекста.СтрокаОписания.Владелец().Колонки.Найти("ТипКонтекста") <> Неопределено
И СтруктураТипаКонтекста.СтрокаОписания.ТипКонтекста = "Глобальный"
Тогда
ПараметрИскатьНепрямые = Ложь;
Иначе
ПараметрИскатьНепрямые = Истина;
КонецЕсли;
КонецЕсли;
ПолноеИмяМетода = ПолноеИмяМетода + ирОбщий.СтрокаБезКонцаЛкс(мТекущееСлово, 1);
ФормаВызовов = ПолучитьФорму("ПоискВызововМетода",, ПолноеИмяМетода);
ФормаВызовов.ПараметрИскатьНепрямые = ПараметрИскатьНепрямые;
ФормаВызовов.ПараметрСтруктураТипаКонтекста = СтруктураТипаКонтекста;
ФормаВызовов.Открыть();
ФормаВызовов.ОбновитьДанные();
КонецПроцедуры
// Заменяет все символы табуляции в строке после первого печатного символа эквивалентным количеством пробелов.
//
// Параметры:
// Строка - Строка;
//
// Возвращаемое значение:
// Строка.
//
Функция ЗаменитьТабуляцииВСтроке(Знач Строка, ЛиТекущая = Ложь)
Табы = "";
А = 1; НачалоСтроки = Истина;
Пока А <= СтрДлина(Строка) Цикл
Если Сред(Строка, А, 1) <> Символы.Таб И НачалоСтроки Тогда
// Найдем начало строки без табов
Табы = Лев(Строка, А-1);
Строка = Прав(Строка, СтрДлина(Строка) - А + 1);
НачалоСтроки = Ложь;
ИначеЕсли Сред(Строка, А, 1) = Символы.Таб И НЕ НачалоСтроки Тогда
// Удалим табы из строки
Строка = Лев(Строка, А - 1) + Лев(" ", 4 - СтрДлина(Лев(Строка, А - 1)) % 4)
+ Прав(Строка, СтрДлина(Строка) - А);
Если Истина
И ЛиТекущая
И мКонечнаяКолонка > А
Тогда
мКонечнаяКолонка = мКонечнаяКолонка + 3 - СтрДлина(Лев(Строка, А - 1)) % 4;
КонецЕсли;
КонецЕсли;
А = А + 1;
КонецЦикла;
Возврат Табы + Строка;
КонецФункции
// Заменяет все символы табуляции в каждой строке текста после первого печатного символа эквивалентным
// количеством пробелов.
//
// Параметры:
// Нет.
//
Процедура ЗаменитьТабуляции()
Если Ложь
Или ПолеТекста.ТолькоПросмотр()
Или ФормаВладелец.ТолькоПросмотр
Тогда
Возврат;
КонецЕсли;
КоличествоСтрок = ПолеТекста.КоличествоСтрок();
Для А = 1 По КоличествоСтрок Цикл
Строка = ЗаменитьТабуляцииВСтроке(ПолеТекста.ПолучитьСтроку(А), (А = мКонечнаяСтрока));
ПолеТекста.ЗаменитьСтроку(А, Строка);
КонецЦикла;
УстановитьПризнакМодифицированностиФормы();
мНачальнаяКолонка = мКонечнаяКолонка;
КонецПроцедуры // ЗаменитьТабуляции()
Процедура УстановитьАвтоКонтекстнаяПомощь(НовыйРежим)
Кнопка = ирКлиент.КнопкаКоманднойПанелиЭкземпляраКомпонентыЛкс(ЭтотОбъект, "АвтоКонтекстнаяПомощь");
Если Кнопка = Неопределено Тогда
// Это сделано временно для работы в ссылочном режиме
Возврат;
КонецЕсли;
мАвтоКонтекстнаяПомощь = НовыйРежим;
Если мАвтоКонтекстнаяПомощь Тогда
ФормаВладелец.ПодключитьОбработчикОжидания("КлсПолеТекстаПрограммыАвтоОбновитьСправку", 1);
Иначе
ФормаВладелец.ОтключитьОбработчикОжидания("КлсПолеТекстаПрограммыАвтоОбновитьСправку");
КонецЕсли;
Кнопка.Пометка = мАвтоКонтекстнаяПомощь;
КонецПроцедуры
// Удаляет все символы переноса строки из текста.
//
// Параметры:
// Нет.
//
Процедура УдалитьПереносы()
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
Если Ложь
Или ПолеТекста.ТолькоПросмотр()
Или ФормаВладелец.ТолькоПросмотр
Тогда
Возврат;
КонецЕсли;
Текст = ПолеТекста.ПолучитьТекст();
Текст = СокрЛП(Текст);
Если Истина
И Лев(Текст, 1) = """"
И Лев(Текст, 2) <> """"""
Тогда
Текст = "|" + Сред(Текст, 2);
КонецЕсли;
ОбработанныеСтроки = Новый Массив;
Для Каждого СтрокаТекста Из ирОбщий.СтрРазделитьЛкс(Текст, Символы.ПС) Цикл
Если Лев(СокрЛ(СтрокаТекста), 1) = "|" Тогда
СтрокаТекста = СтрЗаменить(СтрокаТекста, """""", """");
СтрокаТекста = СтрЗаменить(СтрокаТекста, "|", "");
КонецЕсли;
ОбработанныеСтроки.Добавить(СтрокаТекста);
КонецЦикла;
Текст = ирОбщий.СтрСоединитьЛкс(ОбработанныеСтроки, Символы.ПС);
Если Истина
И Прав(Текст, 1) = """"
И Прав(Текст, 2) <> """"""
Тогда
Текст = Лев(Текст, СтрДлина(Текст) - 1);
КонецЕсли;
Если Истина
И Прав(Текст, 2) = """;"
И Прав(Текст, 3) <> """"";"
Тогда
Текст = Лев(Текст, СтрДлина(Текст) - 2);
КонецЕсли;
ПолеТекста.УстановитьТекст(Текст);
УстановитьПризнакМодифицированностиФормы();
КонецПроцедуры
// Добавляет слово локального контекста.
//
// Параметры:
// Слово - Строка;
// ТипСлова - Строка - "Метод", "Свойство";
// *ТипЗначения - ОписаниеТипов, *Неопределено - ;
// *Метаданные - Произвольный, *Неопределено - используется, если ТипЗначения задан;
// *Глобальное - Булево, *Ложь - это слово глобального контекста;
// *ТаблицаСтруктурТипа - ТаблицаЗначений, *Неопределено;
//
Процедура ДобавитьСловоЛокальногоКонтекста(Слово, ТипСлова = "Свойство", Знач ТипЗначения = Неопределено,
пМетаданные = Неопределено, Глобальное = Ложь, Значение = Неопределено, ТаблицаСтруктурТипов = Неопределено, Знач ИмяОбщегоТипа = "") Экспорт
КлючСтроки = Новый Структура;
КлючСтроки.Вставить("нСлово", Нрег(Слово));
КлючСтроки.Вставить("ТипСлова", ТипСлова);
НайденныеСтроки = ТаблицаЛокальногоКонтекста.НайтиСтроки(КлючСтроки);
Если НайденныеСтроки.Количество() = 0 Тогда
НоваяСтрока = ТаблицаЛокальногоКонтекста.Добавить();
Иначе
НоваяСтрока = НайденныеСтроки[0];
КонецЕсли;
НоваяСтрока.ТаблицаСтруктурТипов = ТаблицаСтруктурТипов;
Если НоваяСтрока.ТаблицаСтруктурТипов = Неопределено Тогда
НоваяСтрока.ТаблицаСтруктурТипов = мПлатформа.НоваяТаблицаСтруктурТипа();
КонецЕсли;
Если ЗначениеЗаполнено(ИмяОбщегоТипа) Тогда
СтруктураТипа = НоваяСтрока.ТаблицаСтруктурТипов.Добавить();
СтруктураТипа.ИмяОбщегоТипа = ИмяОбщегоТипа;
СтруктураТипа.Метаданные = пМетаданные;
КонецЕсли;
ЗаполнитьЗначенияСвойств(НоваяСтрока, КлючСтроки);
НоваяСтрока.Значение = Значение;
НоваяСтрока.Слово = Слово;
НоваяСтрока.Глобальное = Глобальное;
Если Значение <> Неопределено Тогда
СтруктураТипа = мПлатформа.СтруктураТипаИзЗначения(Значение, ЯзыкПрограммы,
Новый Структура("СтрокаОписания, Метаданные", НоваяСтрока, пМетаданные)); // Циклическая ссылка СтрокаОписания
ЗаполнитьЗначенияСвойств(НоваяСтрока.ТаблицаСтруктурТипов.Добавить(), СтруктураТипа);
КонецЕсли;
Если ТипЗначения <> Неопределено Тогда
Для Каждого Тип Из ТипЗначения.Типы() Цикл
СтруктураТипа = мПлатформа.СтруктураТипаИзКонкретногоТипа(Тип, ЯзыкПрограммы,
Новый Структура("СтрокаОписания, Метаданные", НоваяСтрока, пМетаданные)); // Циклическая ссылка СтрокаОписания
ЗаполнитьЗначенияСвойств(НоваяСтрока.ТаблицаСтруктурТипов.Добавить(), СтруктураТипа);
КонецЦикла;
КонецЕсли;
Если Значение <> Неопределено Тогда
Если ТипЗначения = Неопределено Тогда
ТипЗначения = Новый ОписаниеТипов;
КонецЕсли;
ТипЗначения = Новый ОписаниеТипов(ТипЗначения, ирОбщий.ЗначенияВМассивЛкс(ТипЗнч(Значение)));
КонецЕсли;
НоваяСтрока.ТипЗначения = ТипЗначения;
КонецПроцедуры
// Добавляет правило вычисления типа значения функции.
// При вызове правила вычисляется "Правило(<СтрокаАргументов>)", а оно должно вернуть ТаблицаСтруктурТипов.
//
// Параметры:
// Слово - Строка;
// ТипСлова - Строка - "Метод", "Свойство";
// *ТипЗначения - ОписаниеТипов, *Неопределено;
// *Метаданные - Произвольный, *Неопределено;
// *Глобальное - Булево, *Ложь - это слово глобального контекста.
//
Процедура ДобавитьПравилоВычисленияФункции(Слово, Правило, ТипКонтекста = "Локальный") Экспорт
КлючСтроки = Новый Структура;
КлючСтроки.Вставить("НСлово", Нрег(Слово));
КлючСтроки.Вставить("ТипКонтекста", ТипКонтекста);
НайденныеСтроки = ПравилаВычисленияФункций.НайтиСтроки(КлючСтроки);
Если НайденныеСтроки.Количество() = 0 Тогда
НоваяСтрока = ПравилаВычисленияФункций.Добавить();
Иначе
НоваяСтрока = НайденныеСтроки[0];
КонецЕсли;
ЗаполнитьЗначенияСвойств(НоваяСтрока, КлючСтроки);
НоваяСтрока.Правило = Правило;
НоваяСтрока.Слово = Слово;
КонецПроцедуры
// Добавляет переменную локального контекста.
//
// Параметры:
// ИмяПеременной - Строка;
// ДопустимыеТипы - Строка, ТаблицаЗначений;
//
Процедура ДобавитьПеременнуюЛокальногоКонтекста(ИмяПеременной, ДопустимыеТипы) Экспорт
КлючСтроки = Новый Структура;
КлючСтроки.Вставить("нСлово", НРег(ИмяПеременной));
КлючСтроки.Вставить("ТипСлова", "Свойство");
НайденныеСтроки = ТаблицаЛокальногоКонтекста.НайтиСтроки(КлючСтроки);
Если НайденныеСтроки.Количество() = 0 Тогда
НоваяСтрока = ТаблицаЛокальногоКонтекста.Добавить();
НоваяСтрока.ТаблицаСтруктурТипов = мПлатформа.НоваяТаблицаСтруктурТипа();
Иначе
НоваяСтрока = НайденныеСтроки[0];
КонецЕсли;
ЗаполнитьЗначенияСвойств(НоваяСтрока, КлючСтроки);
НоваяСтрока.Слово = ИмяПеременной;
Если ТипЗнч(ДопустимыеТипы) = Тип("Строка") Тогда
МассивСериализованныхТипов = ирОбщий.СтрРазделитьЛкс(ДопустимыеТипы, ";");
//ТаблицаСтруктурТипов = мПлатформа.НоваяТаблицаСтруктурТипа();
ТаблицаСтруктурТипов = НоваяСтрока.ТаблицаСтруктурТипов;
Для Каждого СериализованныйТип Из МассивСериализованныхТипов Цикл
СтруктураТипа = мПлатформа.СтруктураТипаИзСтрокиВнутр(СериализованныйТип);
СтруктураТипа.Вставить("СтрокаОписания", НоваяСтрока); // Циклическая ссылка СтрокаОписания
мПлатформа.ДобавитьВТаблицуСтруктурТипов(ТаблицаСтруктурТипов, СтруктураТипа);
КонецЦикла;
НоваяСтрока.ТаблицаСтруктурТипов = ТаблицаСтруктурТипов;
Иначе
НоваяСтрока.ТаблицаСтруктурТипов = ДопустимыеТипы;
КонецЕсли;
КонецПроцедуры
// Удаляет слово локального контекста.
//
// Параметры:
// Слово - Строка;
// ТипСлова - Строка.
//
Процедура УдалитьСловоЛокальногоКонтекста(Слово, ТипСлова) Экспорт
КлючСтроки = Новый Структура;
КлючСтроки.Вставить("нСлово", НРег(Слово));
КлючСтроки.Вставить("ТипСлова", ТипСлова);
СтрокиСлова = ТаблицаЛокальногоКонтекста.НайтиСтроки(КлючСтроки);
Если СтрокиСлова.Количество() > 0 Тогда
ТаблицаЛокальногоКонтекста.Удалить(СтрокиСлова[0]);
КонецЕсли;
КонецПроцедуры
// Устанавливает доступность действий, изменяющих данные.
//
// Параметры:
// НовыйТолькоПросмотр - Булево.
//
Процедура УстановитьТолькоПросмотр(НовыйТолькоПросмотр) Экспорт
ФормаКласса = ПолучитьФорму("ФормаМакет");
МассивКоллекцийКнопок = Новый Массив;
МассивКоллекцийКнопок.Добавить(ФормаКласса.ЭлементыФормы["КоманднаяПанель" + Формат(ЯзыкПрограммы, "ЧН=")].Кнопки);
МассивКоллекцийКнопок.Добавить(ФормаКласса.ЭлементыФормы.КоманднаяПанельОбщая.Кнопки);
Для Каждого КнопкиМакета Из МассивКоллекцийКнопок Цикл
Для Каждого КнопкаМакета Из КнопкиМакета Цикл
Если КнопкаМакета.ТипКнопки <> ТипКнопкиКоманднойПанели.Действие Тогда
Продолжить;
КонецЕсли;
КонечноеИмя = ирКлиент.СформироватьИмяЭлементаУправленияЭкземпляраЛкс(ЭтотОбъект, КнопкаМакета.Имя);
Кнопка = КоманднаяПанель.Кнопки.Найти(КонечноеИмя);
Если Кнопка.ИзменяетДанные Тогда
Кнопка.Доступность = Не НовыйТолькоПросмотр;
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецПроцедуры // УстановитьТолькоПросмотр()
Процедура ОформитьЯчейкуТипаЗначения(ОформлениеСтроки, ДанныеСтроки) Экспорт
Если Истина
И ОформлениеСтроки.Ячейки.ТипЗначения.Видимость
И ЗначениеЗаполнено(ДанныеСтроки.ТипЗначения)
//И Найти(ДанныеСтроки.ТипЗначения, ",") = 0
Тогда
СтрокаИменТипов = ДанныеСтроки.ТипЗначения;
РегВыражение = ирКэш.ВычислительРегВыраженийЛкс();
#Если Сервер И Не Сервер Тогда
РегВыражение = Обработки.ирОболочкаРегВыражение.Создать();
#КонецЕсли
РегВыражение.Global = Истина;
РегВыражение.Pattern = "\(.*?\)";
СтрокаИменТипов = РегВыражение.Заменить(СтрокаИменТипов, "");
Попытка
ОписаниеТипов = Новый ОписаниеТипов(СтрокаИменТипов);
Исключение
ОписаниеТипов = Неопределено;
КонецПопытки;
Если ОписаниеТипов <> Неопределено Тогда
Типы = ОписаниеТипов.Типы();
Если Типы.Количество() > 0 Тогда
КартинкаТипа = ирКлиент.КартинкаТипаЛкс(Типы[0]);
Если КартинкаТипа <> Неопределено Тогда
ОформлениеСтроки.Ячейки.ТипЗначения.УстановитьКартинку(КартинкаТипа);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
// Выполняет шаблон текста.
//
// Параметры:
// Нет.
//
Процедура ВыполнитьШаблонТекста()
Если ПолеТекста.ТолькоПросмотр() Тогда
Возврат;
КонецЕсли;
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ПрочитатьНачалоИКонецТекущейСтроки();
НадежноУстановитьФокус = Ложь;
ПоследняяПозицияКурсора = 0;
ТаблицаШаблоновТекста = мПлатформа.ПолучитьТаблицуШаблоновТекста(ИмяКласса);
КонечныйТекстЗамены = " ";
Если Ложь
Или ТаблицаШаблоновТекста = Неопределено
Или ТаблицаШаблоновТекста.Количество() = 0
Тогда
//
Иначе
РегВыражение.Global = Ложь;
СтрокаРазделителейШаблоновТекста = ";.,:()[]";
РегВыражение.Pattern = "([^\s" + ирОбщий.ПреобразоватьТекстДляРегулярныхВыраженийЛкс(СтрокаРазделителейШаблоновТекста) + "]*)$";
Результат = РегВыражение.НайтиВхождения(ТекущееНачалоСтроки);
Если Результат.Количество() > 0 Тогда
НачалоМаркера = Результат[0].SubMatches(0);
Если ЗначениеЗаполнено(НачалоМаркера) Тогда
//СтрокаШаблона = ТаблицаШаблоновТекста.Найти(НРег(НачалоМаркера), "ШаблонБезКвадратныхСкобок");
СтрокаШаблона = Неопределено;
Для каждого ТекСтрокаШаблона Из ТаблицаШаблоновТекста Цикл
Если ТекСтрокаШаблона.Шаблон = НРег(НачалоМаркера) Тогда
СтрокаШаблона = ТекСтрокаШаблона;
Прервать;
КонецЕсли;
МинимальнаяДлинаСовпадения = Найти(ТекСтрокаШаблона.Шаблон, "[");
Если МинимальнаяДлинаСовпадения > 0 Тогда
Если СтрДлина(НачалоМаркера) < МинимальнаяДлинаСовпадения - 1 Тогда
Продолжить;
КонецЕсли;
ШаблонБезСкобок = СтрЗаменить(ТекСтрокаШаблона.Шаблон, "[", "");
ШаблонБезСкобок = СтрЗаменить(ШаблонБезСкобок, "]", "");
Если Найти(ШаблонБезСкобок, НРег(НачалоМаркера)) = 1 Тогда
СтрокаШаблона = ТекСтрокаШаблона;
Прервать;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если СтрокаШаблона = Неопределено Тогда
НачалоМаркера = "";
Иначе
РегВыражение.Global = Истина;
РегВыражение.MultiLine = Ложь;
РегВыражение.Pattern = "(<\?\s*(""[^""\^]*"")?(?:,\s*(" + мПлатформа.шИмя + "))?>)|(.|\r|\n)";
Результат = РегВыражение.НайтиВхождения(СтрокаШаблона.Замена);
КонечныйТекстЗамены = "";
КешПараметров = Новый ТаблицаЗначений;
КешПараметров.Колонки.Добавить("ИмяПараметра");
КешПараметров.Колонки.Добавить("ЗначениеПараметра");
Для Каждого Match Из Результат Цикл
УправляющаяКонструкция = Match.SubMatches(0);
Если ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(УправляющаяКонструкция) Тогда
КонечныйТекстЗамены = КонечныйТекстЗамены + Match.SubMatches(3);
Иначе
ИмяПараметраШаблона = Match.SubMatches(1);
ТипШаблона = Match.SubMatches(2);
Если ТипШаблона = "КонструкторОписанияТипов" Тогда
КонечныйТекстЗамены = ТекстИзКонструктораОписанияТипов();
ИначеЕсли ТипШаблона = "ТекстЗапроса" Тогда
//ВызватьКонструкторЗапросов();
ИначеЕсли Не ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(ИмяПараметраШаблона) Тогда
ИмяПараметраШаблона = Сред(ИмяПараметраШаблона, 2, СтрДлина(ИмяПараметраШаблона) - 2);
ВведеннаяСтрока = "";
Если ИмяПараметраШаблона <> "" Тогда
СтрокаКэша = КешПараметров.Найти(ИмяПараметраШаблона, "ИмяПараметра");
Если СтрокаКэша <> Неопределено Тогда
ВведеннаяСтрока = СтрокаКэша.ЗначениеПараметра;
Иначе
СтрокаКэша = КешПараметров.Добавить();
СтрокаКэша.ИмяПараметра = ИмяПараметраШаблона;
НадежноУстановитьФокус = Истина;
ВвестиЗначение(ВведеннаяСтрока, ИмяПараметраШаблона, Тип("Строка"));
СтрокаКэша.ЗначениеПараметра = ВведеннаяСтрока;
КонецЕсли;
КонецЕсли;
КонечныйТекстЗамены = КонечныйТекстЗамены + ВведеннаяСтрока;
Иначе
ПоследняяПозицияКурсора = СтрДлина(КонечныйТекстЗамены) + 1;
КонецЕсли;
КонецЕсли;
КонецЦикла;
ЗаменаТабуляции = ирОбщий.СтрокаПовторомЛкс(" ", ШиринаТабуляции);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если КонечныйТекстЗамены <> Неопределено Тогда
КонечныйТекстЗаменыТД = Новый ТекстовыйДокумент;
КонечныйТекстЗаменыТД.УстановитьТекст(КонечныйТекстЗамены);
лКонечнаяСтрока = 0;
лКонечнаяКолонка = 0;
Если ПоследняяПозицияКурсора > 0 Тогда
СлужебноеПолеТекста.УстановитьТекст(КонечныйТекстЗамены);
Если ПоследняяПозицияКурсора <= СтрДлина(КонечныйТекстЗамены) Тогда
СлужебноеПолеТекста.УстановитьГраницыВыделения(ПоследняяПозицияКурсора, ПоследняяПозицияКурсора);
СлужебноеПолеТекста.ПолучитьГраницыВыделения(лКонечнаяСтрока, лКонечнаяКолонка, лКонечнаяСтрока, лКонечнаяКолонка);
Иначе
лКонечнаяСтрока = КонечныйТекстЗаменыТД.КоличествоСтрок();
лКонечнаяКолонка = СтрДлина(КонечныйТекстЗаменыТД.ПолучитьСтроку(КонечныйТекстЗаменыТД.КоличествоСтрок())) + 1;
КонецЕсли;
КонецЕсли;
ЧислоСтрокЗамены = КонечныйТекстЗаменыТД.КоличествоСтрок();
СтрокаДобавка = КонечныйТекстЗаменыТД.ПолучитьСтроку(1);
ДлинаНачалаСтроки = мКонечнаяКолонка - СтрДлина(НачалоМаркера) - 1;
НачалоСтроки = Лев(ТекущееНачалоСтроки, ДлинаНачалаСтроки);
ТекущееНачалоСтроки = НачалоСтроки + СтрокаДобавка;
ТекущаяСтрока = ТекущееНачалоСтроки;
Если ЧислоСтрокЗамены = 1 Тогда
ТекущаяСтрока = ТекущаяСтрока + ТекущийКонецСтроки;
КонецЕсли;
ПолеТекста.ЗаменитьСтроку(мКонечнаяСтрока, "" + ТекущаяСтрока);
ДлинаРазвернутогоНачалаСтроки = СтрДлина(СтрЗаменить(НачалоСтроки, Символы.Таб, ЗаменаТабуляции));
ЧислоТабуляций = ДлинаРазвернутогоНачалаСтроки / ШиринаТабуляции;
ЧислоПробелов = ДлинаРазвернутогоНачалаСтроки % ШиринаТабуляции;
НачалоНовойСтроки = ирОбщий.СтрокаПовторомЛкс(Символы.Таб, ЧислоТабуляций);
НачалоНовойСтроки = НачалоНовойСтроки + ирОбщий.СтрокаПовторомЛкс(" ", ЧислоПробелов);
Для Счетчик = 2 По ЧислоСтрокЗамены - 1 Цикл
ТекущаяСтрокаВставки = КонечныйТекстЗаменыТД.ПолучитьСтроку(Счетчик);
ПолеТекста.ВставитьСтроку(мКонечнаяСтрока + Счетчик - 1, НачалоНовойСтроки + ТекущаяСтрокаВставки);
КонецЦикла;
Если ЧислоСтрокЗамены > 1 Тогда
ТекущаяСтрокаВставки = КонечныйТекстЗаменыТД.ПолучитьСтроку(ЧислоСтрокЗамены);
ПолеТекста.ВставитьСтроку(мКонечнаяСтрока + ЧислоСтрокЗамены - 1, НачалоНовойСтроки + ТекущаяСтрокаВставки + ТекущийКонецСтроки);
КонецЕсли;
Если лКонечнаяСтрока > 0 Тогда
Если лКонечнаяСтрока = 1 Тогда
лКонечнаяКолонка = лКонечнаяКолонка + СтрДлина(НачалоСтроки);
Иначе
лКонечнаяКолонка = лКонечнаяКолонка + СтрДлина(НачалоНовойСтроки);
КонецЕсли;
лКонечнаяСтрока = лКонечнаяСтрока + мКонечнаяСтрока - 1;
мКонечнаяКолонка = лКонечнаяКолонка;
мКонечнаяСтрока = лКонечнаяСтрока;
Иначе
Если ЧислоСтрокЗамены > 0 Тогда
мКонечнаяСтрока = мКонечнаяСтрока + ЧислоСтрокЗамены - 1;
КонецЕсли;
Если ЧислоСтрокЗамены > 1 Тогда
мКонечнаяКолонка = СтрДлина(НачалоСтроки + ТекущаяСтрокаВставки) + 1;
Иначе
мКонечнаяКолонка = мКонечнаяКолонка + СтрДлина(КонечныйТекстЗамены) - СтрДлина(НачалоМаркера);
КонецЕсли;
КонецЕсли;
мНачальнаяСтрока = мКонечнаяСтрока;
мНачальнаяКолонка = мКонечнаяКолонка;
КонецЕсли;
УстановитьФокус();
КонецПроцедуры
Функция ТекстИзКонструктораОписанияТипов()
ОписаниеТипов = ирКлиент.РедактироватьОписаниеРедактируемыхТиповЛкс();
Если ОписаниеТипов <> Неопределено Тогда
Результат = ирОбщий.ВыражениеВстроенногоЯзыкаСозданиеОписанияТиповЛкс(ОписаниеТипов);
КонецЕсли;
Возврат Результат;
КонецФункции
Процедура КонструкторОписанияТипов()
НовыйТекст = ТекстИзКонструктораОписанияТипов();
Если ЗначениеЗаполнено(НовыйТекст) Тогда
ПолеТекста.ВыделенныйТекст(НовыйТекст);
КонецЕсли;
КонецПроцедуры
Процедура ОкружитьВыделенныеСтроки(Знач НачалоОкружения, Знач КонецОкружения, Знач СмещатьВправо = Истина) Экспорт
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
НомерНачальнойСтроки = ПолучитьНомерТекущейСтроки(Истина);
ВыделенныйТекст = ПолеТекста.ВыделенныйТекст();
Смещение = "";
Если СмещатьВправо Тогда
Смещение = Символы.Таб;
КонецЕсли;
СмещениеПервойСтроки = Лев(ВыделенныйТекст, СтрДлина(ВыделенныйТекст) - СтрДлина(СокрЛ(ВыделенныйТекст)));
ПолеТекста.ВставитьТекст(
"" + СмещениеПервойСтроки + НачалоОкружения + "
|" + Смещение + ирОбщий.ДобавитьМногострочнуюСтрокуВТекстЛкс("", ВыделенныйТекст, Смещение) + "
|" + СмещениеПервойСтроки + КонецОкружения);
НомерНачальнойКолонки = СтрДлина(СмещениеПервойСтроки) + 1;
ПолеТекста.УстановитьГраницыВыделения(НомерНачальнойСтроки, НомерНачальнойКолонки, НомерНачальнойСтроки, НомерНачальнойКолонки,, ФормаВладелец);
УстановитьПризнакМодифицированностиФормы();
КонецПроцедуры
Функция ПредставлениеЗначенияВЯзыкеЗапросов(Знач Значение, Знач ВыводитьСообщение = Ложь, Знач ПараметрыДиалектаSQL = Неопределено, Знач Английский1С = Неопределено) Экспорт
Если Английский1С = Неопределено Тогда
Английский1С = мАнглийский1С;
КонецЕсли;
Результат = "";
ТипЗначенияПараметра = ТипЗнч(Значение);
ОбъектМД = Метаданные.НайтиПоТипу(ТипЗначенияПараметра);
Если ОбъектМД <> Неопределено Тогда
КорневойТип = ирОбщий.ПервыйФрагментЛкс(ОбъектМД.ПолноеИмя());
Если ирОбщий.ЛиКорневойТипСсылкиЛкс(КорневойТип) Тогда
Если ирОбщий.ЛиТипСсылкиТочкиМаршрутаЛкс(ТипЗначенияПараметра) Тогда
Результат = "ТочкаМаршрута." + Значение.Имя;
ИначеЕсли Значение.Пустая() Тогда
Результат = "ПустаяСсылка";
ИначеЕсли ирОбщий.ЛиКорневойТипПеречисленияЛкс(КорневойТип) Тогда
Результат = XMLСтрока(Значение);
ИначеЕсли ирОбщий.ЛиКорневойТипОбъектаСПредопределеннымЛкс(КорневойТип) Тогда
Если Значение.Предопределенный Тогда
Результат = ирОбщий.ПолучитьМенеджерЛкс(ОбъектМД).ПолучитьИмяПредопределенного(Значение);
КонецЕсли;
КонецЕсли;
КонецЕсли;
ИначеЕсли ТипЗначенияПараметра = Тип("ВидДвиженияБухгалтерии") Тогда
Результат = "ВидДвиженияБухгалтерии." + Значение;
ИначеЕсли ТипЗначенияПараметра = Тип("ВидДвиженияНакопления") Тогда
Результат = "ВидДвиженияНакопления." + Значение;
КонецЕсли;
Если ЗначениеЗаполнено(Результат) Тогда
Если ОбъектМД <> Неопределено Тогда
Результат = ОбъектМД.ПолноеИмя() + "." + Результат;
КонецЕсли;
Результат = "ЗНАЧЕНИЕ(" + Результат + ")";
ИначеЕсли ТипЗначенияПараметра = Тип("Неопределено") Тогда
Результат = СловоЯзыкаЗапросов("UNDEFINED", ПараметрыДиалектаSQL, Английский1С);
ИначеЕсли ТипЗначенияПараметра = Тип("Null") Тогда
Результат = "NULL";
Иначе
Если ПараметрыДиалектаSQL = Неопределено Тогда
ПараметрыДиалектаSQL = мПараметрыДиалектаSQL;
КонецЕсли;
Если ТипЗначенияПараметра = Тип("СтандартнаяДатаНачала") Тогда
Значение = Значение.Дата;
ТипЗначенияПараметра = ТипЗнч(Значение);
КонецЕсли;
Если ТипЗначенияПараметра = Тип("Дата") Тогда
Если ПараметрыДиалектаSQL.Это1С Тогда
Результат = СловоЯзыкаЗапросов("DATETIME", ПараметрыДиалектаSQL, Английский1С) + "(" + XMLСтрока(Год(Значение)) + ", " + XMLСтрока(Месяц(Значение)) + ", " + XMLСтрока(День(Значение));
Если НачалоДня(Значение) <> Значение Тогда
Результат = Результат + ", " + XMLСтрока(Час(Значение)) + ", " + XMLСтрока(Минута(Значение)) + ", " + XMLСтрока(Секунда(Значение));
КонецЕсли;
Результат = Результат + ")";
ИначеЕсли ирОбщий.СтрокиРавныЛкс(ПараметрыДиалектаSQL.Диалект, "WQL") Тогда
Значение = ирОбщий.ПолучитьЛитералДатыДляWQLЛкс(Значение);
Иначе// Если ирОбщий.СтрокиРавныЛкс(КодЯзыка, "WQL") Тогда
Результат = "'" + Формат(Значение, "ДФ='yyyyMMdd HH:mm:ss'; ДП=") + "'";
КонецЕсли;
ИначеЕсли ТипЗначенияПараметра = Тип("Число") Тогда
Результат = XMLСтрока(Значение);
ИначеЕсли ТипЗначенияПараметра = Тип("Булево") Тогда
Если Значение Тогда
Результат = СловоЯзыкаЗапросов("TRUE", ПараметрыДиалектаSQL, Английский1С);
Иначе
Результат = СловоЯзыкаЗапросов("FALSE", ПараметрыДиалектаSQL, Английский1С);
КонецЕсли;
ИначеЕсли ТипЗначенияПараметра = Тип("Строка") Тогда
Если ПараметрыДиалектаSQL.Это1С Тогда
Результат = """" + СтрЗаменить(Значение, """", """""") + """";
Иначе
Результат = "'" + Значение + "'";
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Результат = "" Тогда
Если ВыводитьСообщение Тогда
ирОбщий.СообщитьЛкс(ирОбщий.СтрШаблонЛкс("Литеральное представление значения ""%1"" в языке запросов не предусмотрено", ирОбщий.РасширенноеПредставлениеЗначенияЛкс(Значение)));
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция СловоЯзыкаЗапросов(Ключ, ПараметрыДиалектаSQL = Неопределено, Английский1С = Неопределено) Экспорт
Если ПараметрыДиалектаSQL = Неопределено Тогда
ПараметрыДиалектаSQL = мПараметрыДиалектаSQL;
КонецЕсли;
Если Английский1С = Неопределено Тогда
Английский1С = мАнглийский1С;
КонецЕсли;
Результат = Неопределено;
Если ирОбщий.СтрокиРавныЛкс("AS", Ключ) Тогда
Если Не ПараметрыДиалектаSQL.КАК Тогда
Результат = "";
КонецЕсли;
КонецЕсли;
Если Результат = Неопределено Тогда
СтрокаТерминала = мТерминалыЯзыкаЗапросов.Найти(Ключ, "Ключ");
Если ПараметрыДиалектаSQL <> Неопределено И ПараметрыДиалектаSQL.Это1С Тогда
Если СтрокаТерминала = Неопределено Тогда
ВызватьИсключение "Не найден терминал """ + Ключ + """ языка запросов 1C";
КонецЕсли;
Если Не Английский1С Тогда
Результат = СтрокаТерминала.Русский;
Иначе
Результат = СтрокаТерминала.Английский;
КонецЕсли;
Иначе
Результат = Ключ;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция НайтиВыбранныеТаблицыВТекстеЗапроса(Знач СтрокаЗапросаПакета, Знач НачальнаяПозицияЗапроса, Знач ПолеТекстаЗапроса) Экспорт
#Если Сервер И Не Сервер Тогда
СтрокаЗапросаПакета = Новый ДеревоЗначений;
#КонецЕсли
СтрокаЗапросаПакета.СложныйАнализВыполнен = Истина;
//Шаблон = шИЗ;
Шаблон = "((?:ИЗ|FROM)" + шРазделитель + "+" + шОписаниеТаблицы + "[\s\S]*?)(?:$|\sОБЪЕДИНИТЬ(?:\s+ВСЕ)?\s+|\sUNION(?:\s+ALL)?\s+|\sУПОРЯДОЧИТЬ\s+[^\)]*$|\ORDER\s+[^\)]*$)";
ВхожденияИЗ = ирОбщий.НайтиРегВыражениеЛкс(СтрокаЗапросаПакета.Текст, Шаблон);
НачальнаяПозицияЧасти = НачальнаяПозицияЗапроса;
Для Каждого ВхождениеИЗ Из ВхожденияИЗ Цикл
Если ВхожденияИЗ.Количество() > 1 Тогда
СтрокаЧастиОбъединения = СтрокаЗапросаПакета.Строки.Вставить(0);
Если Истина
И СтрокаЗапросаПакета.ТипУзла = "<CreateRoot>"
И СтрокаЗапросаПакета.Строки.Количество() = 1
Тогда
СтрокаЧастиОбъединения.ТипУзла = "<CreateQuery>";
Иначе
СтрокаЧастиОбъединения.ТипУзла = "<SelectQuery>";
КонецЕсли;
СтрокаЧастиОбъединения.СложныйАнализВыполнен = Истина;
СтрокаЧастиОбъединения.Порядок = -СтрокаЗапросаПакета.Строки.Количество();
СтрокаЧастиОбъединения.Имя = "Выборка";
КонечнаяПозицияЧасти = НачальнаяПозицияЗапроса + ВхождениеИЗ.ПозицияВхождения + СтрДлина(ВхождениеИЗ.Подгруппа0);
ПолеТекстаЗапроса.УстановитьГраницыВыделения(НачальнаяПозицияЧасти, КонечнаяПозицияЧасти);
ТекстИсточника = ПолеТекстаЗапроса.ВыделенныйТекст;
//ТекстИсточника = Сред(СлужебноеПолеТекста.Получитьтекст(), НачальнаяПозицияЧасти, КонечнаяПозицияЧасти - НачальнаяПозицияЧасти);
НачальнаяПозицияЧасти = НачальнаяПозицияЗапроса + ВхождениеИЗ.ПозицияВхождения + СтрДлина(ВхождениеИЗ.ТекстВхождения);
ЗаполнитьСтрокуУпрощеннойСтруктурыЗапроса(СтрокаЧастиОбъединения, ПолеТекстаЗапроса);
Иначе
СтрокаЧастиОбъединения = СтрокаЗапросаПакета;
КонецЕсли;
Найденные = ирОбщий.НайтиРегВыражениеЛкс(ВхождениеИЗ.ТекстВхождения, шОписаниеТаблицыСЗахватом);
Для Каждого Найденное Из Найденные Цикл
НачальнаяПозиция = НачальнаяПозицияЗапроса + ВхождениеИЗ.ПозицияВхождения + Найденное.ПозицияВхождения;
КонечнаяПозиция = НачальнаяПозиция + СтрДлина(Найденное.Подгруппа0);
Если Лев(Найденное.Подгруппа0, 1) = "(" Тогда
НачальнаяПозиция = НачальнаяПозиция + 1;
КонечнаяПозиция = КонечнаяПозиция - 1;
ТипУзла = "<FromUnion>";
Иначе
ТипУзла = "<TableWithName>";
КонецЕсли;
ПолеТекстаЗапроса.УстановитьГраницыВыделения(НачальнаяПозиция, КонечнаяПозиция);
ТекстИсточника = ПолеТекстаЗапроса.ВыделенныйТекст;
//ТекстИсточника = Сред(СлужебноеПолеТекста.Получитьтекст(), НачальнаяПозиция, КонечнаяПозиция - НачальнаяПозиция);
КорневойТипТаблицы = ирОбщий.ПервыйФрагментЛкс(СокрЛ(ТекстИсточника));
Если Ложь
Или Найденное.Подгруппа4 = "ЧИСЛО" // Ложное срабатываение ВЫРАЗИТЬ ВЫБОР ... КОНЕЦ КАК ЧИСЛО
Или ТекстИсточника = "КОНЕЦ" // Ложное срабатываение ВЫРАЗИТЬ ВЫБОР ... КОНЕЦ КАК ЧИСЛО
Или (Истина
// {ГДЕ (АналитикаУчета.Договор) КАК Договор}
// ОБЪЕДИНИТЬ ВЫБРАТЬ АналитикаУчета.Партнер КАК Партнер
И мПараметрыДиалектаSQL.Это1С
И Найти(ТекстИсточника, ".") > 0
И Не ирОбщий.ЛиКорневойТипТаблицыБДЛкс(КорневойТипТаблицы)
И Не ирОбщий.ЛиКорневойТипПеречисленияЛкс(КорневойТипТаблицы)
И Не ирОбщий.СтрНачинаетсяСЛкс(СокрЛ(ТекстИсточника), "ВЫБРАТЬ")
И Не ирОбщий.СтрНачинаетсяСЛкс(СокрЛ(ТекстИсточника), "SELECT")
)
Тогда
Продолжить;
КонецЕсли;
СтрокаИсточника = СтрокаЧастиОбъединения.Строки.Вставить(0);
СтрокаИсточника.Порядок = -СтрокаЧастиОбъединения.Строки.Количество();
СтрокаИсточника.Имя = Найденное.Подгруппа4;
СтрокаИсточника.ТипУзла = ТипУзла;
ЗаполнитьСтрокуУпрощеннойСтруктурыЗапроса(СтрокаИсточника, ПолеТекстаЗапроса);
КонецЦикла;
КонецЦикла;
КонецФункции
Процедура ЗаполнитьСтрокуУпрощеннойСтруктурыЗапроса(Знач СтрокаДерева, Знач ПолеТекстаЗапроса)
лНачальнаяСтрока = 0;
лНачальнаяКолонка = 0;
лКонечнаяСтрока = 0;
лКонечнаяКолонка = 0;
ПолеТекстаЗапроса.ПолучитьГраницыВыделения(лНачальнаяСтрока, лНачальнаяКолонка, лКонечнаяСтрока, лКонечнаяКолонка);
СтрокаДерева.Текст = ПолеТекстаЗапроса.ВыделенныйТекст;
ГраницыДвумерные = Новый Структура();
ГраницыДвумерные.Вставить("НачальнаяСтрока", лНачальнаяСтрока);
ГраницыДвумерные.Вставить("НачальнаяКолонка", лНачальнаяКолонка);
ГраницыДвумерные.Вставить("КонечнаяСтрока", лКонечнаяСтрока);
ГраницыДвумерные.Вставить("КонечнаяКолонка", лКонечнаяКолонка);
СтрокаДерева.СтрокаДанных = ГраницыДвумерные;
КонецПроцедуры
///////////////////
// Редактор HTML
Процедура РедакторHTML_Инициировать(ПолеHTML) Экспорт
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ФормаКласса = мПлатформа.ПолучитьМакетКомпоненты(ЭтотОбъект);
КнопкиМакета = ФормаКласса.ЭлементыФормы.КПРедакторHTML.Кнопки.КонтекстноеМеню.Кнопки;
КонтекстноеМеню = ПолеHTML.КонтекстноеМеню;
Если КонтекстноеМеню = Неопределено Тогда
КонтекстноеМеню = ФормаВладелец.ЭлементыФормы.Добавить(Тип("КоманднаяПанель"), "КонтекстноеМеню" + ПолеHTML.Имя, Ложь);
КонтекстноеМеню.ИсточникДействий = ПолеHTML;
ПолеHTML.КонтекстноеМеню = КонтекстноеМеню;
КонецЕсли;
ирКлиент.ДобавитьКнопкиКоманднойПанелиКомпонентыЛкс(ЭтотОбъект, КнопкиМакета, КонтекстноеМеню,,, Истина);
ПолеТекстаHTML = ирКлиент.ОболочкаПоляТекстаЛкс(ПолеHTML);
#Если Сервер И Не Сервер Тогда
ПолеТекстаHTML = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
ПолеТекстаHTML.Инициировать();
РедакторHTML = ПолеHTML.Документ.defaultView;
Инфо = Новый СистемнаяИнформация();
РедакторHTML.minimap(Ложь);
РедакторHTML.init(Инфо.ВерсияПриложения);
Если ЯзыкПрограммы = 1 Тогда
РедакторHTML.setLanguageMode("bsl_query");
ИначеЕсли ЯзыкПрограммы = 2 Тогда
РедакторHTML.setLanguageMode("dcs_query");
КонецЕсли;
РедакторHTML.setOption("disableContextQueryConstructor", Истина);
РедакторHTML.setOption("disableNativeSuggestions", Истина); // События не перестают вызываться
РедакторHTML.setOption("disableNativeSignatures", Истина); // События не перестают вызываться
РедакторHTML.setOption("disableNativeHovers", Истина); // События не перестают вызываться
РедакторHTML.setOption("skipInsertSuggestionAcceptor", Истина); // Отключаем вставку точки при выборе слова из списка https://github.com/salexdv/bsl_console/issues/120#issuecomment-844372676
РедакторHTML.setOption("skipAcceptionSelectedSuggestion", Истина); // Отключаем стандартную обработку вставки активного пункта подсказки. Практически 'СтандартнаяОбработка = Ложь'
РедакторHTML.setOption("renderQueryDelimiters", Истина); // Разделители запросов пакета https://github.com/salexdv/bsl_console/issues/218
//РедакторHTML.enableBeforeSignatureEvent(Истина);
РедакторHTML.setOption("generateBeforeSignatureEvent", Истина);
//РедакторHTML.enableBeforeShowSuggestEvent(Истина);
РедакторHTML.setOption("generateBeforeShowSuggestEvent", Истина);
//РедакторHTML.enableSelectSuggestEvent(Истина);
РедакторHTML.setOption("generateSelectSuggestEvent", Истина);
//РедакторHTML.enableBeforeHoverEvent(Истина);
РедакторHTML.setOption("generateBeforeHoverEvent", Истина);
//РедакторHTML.enableModificationEvent(Истина);
РедакторHTML.setOption("generateModificationEvent", Истина);
РедакторHTML.disableKeyBinding(2082); // CTRL(2048)+D(34) - CTRL+D
РедакторHTML.disableKeyBinding(2118); // CTRL(2048)+D(70) - F12
РедакторHTML.setActiveSuggestionAcceptors("."); // По нажатию точки выполняется вставка активного слова и ввод точки // Много нежелательных срабатываний
КонецПроцедуры
Функция ДобавитьПодсказкуПоЗначениюВыражения(Знач ЗначениеВыражения = Неопределено, Знач ОбъектноеВыражение, Знач ПодсказкаМассив, СтруктураТипа = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
ПодсказкаМассив = Новый Массив;
#КонецЕсли
ЕстьОписаниеТипа = Ложь;
Если СтруктураТипа = Неопределено Тогда
СтруктураТипа = мПлатформа.СтруктураТипаИзЗначения(ЗначениеВыражения, ЯзыкПрограммы);
КонецЕсли;
ИмяТипаЗначения = мПлатформа.ИмяТипаИзСтруктурыТипа(СтруктураТипа);
ИмяОбщегоТипа = СтруктураТипа.ИмяОбщегоТипа;
СтрокаОбщегоТипа = мПлатформа.ТаблицаОбщихТипов.Найти(НРег(ИмяОбщегоТипа), "НСлово");
Если СтрокаОбщегоТипа <> Неопределено Тогда
ЕстьОписаниеТипа = ЗначениеЗаполнено(СтрокаОбщегоТипа.ПутьКОписанию);
КонецЕсли;
Если ИмяТипаЗначения = "Строка" Тогда
ПодсказкаЗначения = "Знач: """ + ЗначениеВыражения + """";
Иначе
Если ТипЗнч(ЗначениеВыражения) = Тип("Строка") Тогда
ПодсказкаЗначения = ЗначениеВыражения;
Иначе
ПодсказкаЗначения = ирОбщий.РасширенноеПредставлениеЗначенияЛкс(ЗначениеВыражения,, Ложь, Истина);
КонецЕсли;
Если Ложь
Или ТипЗнч(ЗначениеВыражения) = Тип("Неопределено")
Или ТипЗнч(ЗначениеВыражения) = Тип("Null")
Тогда
ПодсказкаЗначения = "Знач: " + ПодсказкаЗначения;
Иначе
ПодсказкаЗначения = "[Знач](" + ОбъектноеВыражение + "): " + ПодсказкаЗначения;
КонецЕсли;
Если ПодсказкаЗначения = ИмяТипаЗначения Тогда
ПодсказкаЗначения = "";
Иначе
ПодсказкаЗначения = ПодсказкаЗначения + " ";
КонецЕсли;
Если ЕстьОписаниеТипа Тогда
ИмяСсылкиТипа = "_Тип" + XMLСтрока(мСтруктурыТиповПодсказкиУдержания.Количество());
ПодсказкаЗначения = ПодсказкаЗначения + "[[" + ИмяТипаЗначения + "]](" + ИмяСсылкиТипа + ")";
мСтруктурыТиповПодсказкиУдержания.Вставить(ИмяСсылкиТипа, СтруктураТипа);
Иначе
ПодсказкаЗначения = ПодсказкаЗначения + "[" + ИмяТипаЗначения + "]";
КонецЕсли;
КонецЕсли;
ПодсказкаМассив.Добавить(ПодсказкаЗначения);
Возврат ИмяТипаЗначения;
КонецФункции
Функция ДобавитьПодсказкуПоДопустимымТипам(Знач ИмяТипаЗначения, Знач ПодсказкаМассив, Знач ОбъектноеВыражение) Экспорт
ТаблицаСтруктурТипов = ТаблицаСтруктурТиповТекущегоВыражения(Истина, Истина, Ложь);
Если Истина
И ЯзыкПрограммы = 1
И ТаблицаСтруктурТипов[0].ИмяОбщегоТипа = "ВременнаяТаблица"
И ТипЗнч(КонтекстВыполнения) = Тип("Запрос")
Тогда
ВременныйЗапрос = Новый Запрос;
ВременныйЗапрос.МенеджерВременныхТаблиц = КонтекстВыполнения.МенеджерВременныхТаблиц;
ИмяВременнойТаблицы = ТаблицаСтруктурТипов[0].ВиртуальнаяТаблица.Выражение;
ВременныйЗапрос.Текст = "ВЫБРАТЬ КОЛИЧЕСТВО(*) ИЗ " + ИмяВременнойТаблицы;
КоличествоСтрокВТаблице = ВременныйЗапрос.Выполнить().Выгрузить()[0][0];
ДобавитьПодсказкуПоЗначениюВыражения(ИмяВременнойТаблицы + "(" + КоличествоСтрокВТаблице + ")", ОбъектноеВыражение, ПодсказкаМассив, ТаблицаСтруктурТипов[0]);
КонецЕсли;
ПредставлениеДопустимыхТипов = мПлатформа.ПредставлениеМассиваСтруктурТипов(ТаблицаСтруктурТипов, Истина);
Если Истина
И ПредставлениеДопустимыхТипов <> "?"
И ПредставлениеДопустимыхТипов <> "ОбщийМодуль"
И ПредставлениеДопустимыхТипов <> "ВременнаяТаблица"
И ЗначениеЗаполнено(ПредставлениеДопустимыхТипов)
И ПредставлениеДопустимыхТипов <> ИмяТипаЗначения
Тогда
ИмяСсылкиТипа = "_Тип" + XMLСтрока(мСтруктурыТиповПодсказкиУдержания.Количество());
мСтруктурыТиповПодсказкиУдержания.Вставить(ИмяСсылкиТипа, ТаблицаСтруктурТипов);
ПредставлениеДопустимыхТипов = "[Допустимые типы](" + ИмяСсылкиТипа + "): " + ПредставлениеДопустимыхТипов;
ПодсказкаМассив.Добавить(ПредставлениеДопустимыхТипов);
КонецЕсли;
Если ПредставлениеДопустимыхТипов <> "ОбщийМодуль" Тогда
ПодсказкаМассив.Добавить("[Определение](" + XMLСтрока(мКонечнаяСтрока) + "," + XMLСтрока(мКонечнаяКолонка) + ")");
КонецЕсли;
Возврат ПредставлениеДопустимыхТипов;
КонецФункции
Процедура ОткрытьОписаниеТипаПоГиперссылке(Знач ИмяОбщегоТипа) Экспорт
Если Истина
И ирОбщий.СтрНачинаетсяСЛкс(ИмяОбщегоТипа, "_Тип")
И мСтруктурыТиповПодсказкиУдержания.Свойство(ИмяОбщегоТипа)
Тогда
СтруктураТипа = мСтруктурыТиповПодсказкиУдержания[ИмяОбщегоТипа];
Если ТипЗнч(СтруктураТипа) = Тип("ТаблицаЗначений") Тогда
ТаблицаДляПользователя = мПлатформа.ТаблицаСтруктурТиповДляПользователя(СтруктураТипа, Ложь);
СписокВыбора = Новый СписокЗначений;
Для Каждого СтрокаТаблицы Из ТаблицаДляПользователя Цикл
Если ирОбщий.СтрокиРавныЛкс(СтрокаТаблицы.Имя, "null") Тогда
Продолжить;
КонецЕсли;
СписокВыбора.Добавить(СтрокаТаблицы.СтруктураТипа, СтрокаТаблицы.Имя);
КонецЦикла;
СписокВыбора = ирОбщий.СвернутьСписокЗначенийПоПредставлениюЛкс(СписокВыбора);
Если СписокВыбора.Количество() = 1 Тогда
СтруктураТипа = СписокВыбора[0];
Иначе
СтруктураТипа = СписокВыбора.ВыбратьЭлемент("Выберите тип значения");
Если СтруктураТипа = Неопределено Тогда
Возврат;
КонецЕсли;
КонецЕсли;
СтруктураТипа = СтруктураТипа.Значение;
КонецЕсли;
ОткрытьОпределениеСтруктурыТипа(СтруктураТипа, Истина);
Иначе
ирКлиент.ОткрытьОписаниеТипаПоИмениТипаЛкс(ИмяОбщегоТипа);
КонецЕсли;
КонецПроцедуры
// антибаг редактора https://github.com/salexdv/bsl_console/issues/78#issuecomment-836447865
Функция ЧистоеСловоСпискаПодсказкиHTML(ВыбранноеСлово) Экспорт
Возврат ирОбщий.СтрокаМеждуМаркерамиЛкс(ВыбранноеСлово, "Элемент ", ",", Истина);
КонецФункции
Процедура РедакторHTML_ПередПоказомПодсказкиУдержания(Знач Событие, Знач ФункцияВычислитьВыражение) Экспорт
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
НомерКолонки23 = Событие.params.column;
НомерСтроки23 = Событие.params.line;
ТекущееСлово = Событие.params.word;
мСтруктурыТиповПодсказкиУдержания = Новый Структура;
Если ТекущееСлово = Неопределено Тогда
Возврат;
КонецЕсли;
КончитьОбработкуКоманды();
ОбъектноеВыражение = ТекущееОбъектноеВыражение(НомерСтроки23, НомерКолонки23,, Ложь);
ПодсказкаМассив = Новый Массив;
Если Истина
И (Ложь
Или Найти(ОбъектноеВыражение, "(") = 0
Или ирОбщий.СтрКончаетсяНаЛкс(ОбъектноеВыражение, "(")
Или ирОбщий.СтрНачинаетсяСЛкс(ОбъектноеВыражение, "("))
И (Ложь
Или ирОбщий.ЛиИмяПеременнойЛкс(Лев(ОбъектноеВыражение, 1))
Или Лев(ОбъектноеВыражение, 1) = мПараметрыДиалектаSQL.ПрефиксПараметра
Или Лев(ОбъектноеВыражение, 1) = "(")
Тогда
ФормаВладелец.КлсПолеТекстаПрограммыОбновитьКонтекст(ЭтотОбъект);
ИмяТипаЗначения = "";
Если Ложь
Или (ЯзыкПрограммы > 0 И Лев(ОбъектноеВыражение, 1) = мПараметрыДиалектаSQL.ПрефиксПараметра)
Или (ЯзыкПрограммы = 0 И Не ирОбщий.СтрКончаетсяНаЛкс(ОбъектноеВыражение, "("))
Тогда
УспехЗначения = Истина;
ЗначениеВыражения = Вычислить("ФормаВладелец." + ФункцияВычислитьВыражение + "(ОбъектноеВыражение, УспехЗначения)");
Если УспехЗначения Тогда
ИмяТипаЗначения = ДобавитьПодсказкуПоЗначениюВыражения(ЗначениеВыражения, ОбъектноеВыражение, ПодсказкаМассив);
КонецЕсли;
КонецЕсли;
ПредставлениеДопустимыхТипов = ДобавитьПодсказкуПоДопустимымТипам(ИмяТипаЗначения, ПодсказкаМассив, ОбъектноеВыражение);
КонецЕсли;
КончитьОбработкуКоманды();
СтруктураПодсказки = Новый Соответствие;
СтруктураПодсказки.Вставить(ТекущееСлово.word, ПодсказкаМассив);
РедакторHTML = ПолеТекста.РедакторHTML();
РедакторHTML.setCustomHovers(ирОбщий.ОбъектВСтрокуJSONЛкс(СтруктураПодсказки));
КонецПроцедуры
Процедура РедакторHTML_ПередПоказомСигнатуры(НомерПараметра, ИмяМетодаОтРедактора, НомерСигнатуры, Триггер) Экспорт
Если РазрешеноСобытиеПередПоказомАвтодополнения = Ложь Или НомерСигнатуры > 0 Тогда
// https://github.com/salexdv/bsl_console/issues/182
РазрешеноСобытиеПередПоказомАвтодополнения = Истина;
Возврат;
КонецЕсли;
Если Триггер <> Неопределено И Не АвтоматическаяПодсказкаПоВызовуМетода() Тогда
Возврат;
КонецЕсли;
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
РедакторHTML = ПолеТекста.РедакторHTML();
//РедакторHTML.hideSignatureList();
Если Не ЛиДоступноОткрытиеСвободнойФормы() Тогда
КончитьОбработкуКоманды();
ФормаВладелец.КлсПолеТекстаПрограммыОбновитьКонтекст(ЭтотОбъект);
СтруктураПодсказки = СтруктураПодсказкиМетода(, Триггер <> Неопределено);
Если СтруктураПодсказки.Количество() = 0 Тогда
Возврат;
КонецЕсли;
ВариантыСинтаксиса = Новый Соответствие;
ВариантыСинтаксиса.Вставить(ирОбщий.ПоследнийФрагментЛкс(ИмяМетодаОтРедактора, " "), СтруктураПодсказки);
РедакторHTML.setCustomSignatures(ирОбщий.ОбъектВСтрокуJSONЛкс(ВариантыСинтаксиса));
//РедакторHTML.enableBeforeShowSuggestEvent(Ложь);
РедакторHTML.setOption("generateBeforeShowSuggestEvent", Ложь);
РазрешеноСобытиеПередПоказомАвтодополнения = Ложь;
РедакторHTML.triggerSigHelp();
//РедакторHTML.enableBeforeShowSuggestEvent(Истина);
РедакторHTML.setOption("generateBeforeShowSuggestEvent", Истина);
//ИмяМетодаОтРедактора = ФормаВызовМетода.ИмяМетода;
//НомерПараметра = мНомерПараметра - 1;
КонецЕсли;
КонецПроцедуры
Функция СтруктураПодсказкиМетода(Знач ПараметрСтруктураТипаКонтекста = Неопределено, Знач ТолькоПолезноеОписание = Истина, Знач ДляСпискаАвтодополнения = Ложь)
СтруктураПодсказки = Новый Массив;
ФормаВызовМетода = ФормаВызовМетода();
ФормаВызовМетода.ПараметрСтруктураТипаКонтекста = ПараметрСтруктураТипаКонтекста;
ФормаВызовМетода.ОбновитьИлиЗакрытьФорму(, Истина);
Если Не ФормаВызовМетода.ЕстьПолезнаяИнформация И ТолькоПолезноеОписание Тогда
Возврат СтруктураПодсказки;
КонецЕсли;
Для ИндексВарианта = 0 По ФормаВызовМетода.ВариантыСинтаксиса.Количество() - 1 Цикл
Если Истина
И ФормаВызовМетода.ВариантыСинтаксиса.Количество() > 1
Тогда
ФормаВызовМетода.УстановитьВариантСинтаксисаПоИндексу(ИндексВарианта);
КонецЕсли;
ПодсказкаСлова = Новый Структура();
ПараметрыМетода = Новый Массив;
КраткиеОписанияПараметров = Новый Массив;
Для Каждого СтрокаПараметра Из ФормаВызовМетода.ТаблицаПараметров Цикл
ЛиНеОбязательный = ФормаВызовМетода.ЛиНеОбязательныйПараметр(СтрокаПараметра);
СтруктураПараметра = Новый Структура();
КраткоеПредставлениеПараметра = ""
//+ ?(СтрокаПараметра.Знач = "Знач", "`", СтрокаПараметра.Знач)
+ СтрокаПараметра.Имя
+ ?(ЛиНеОбязательный, "?", "");
// Мало пользы, лишние неудобства при поиске нужного параметра. Поэтому пока отключено
//Если ЗначениеЗаполнено(СтрЗаменить(СтрокаПараметра.ТипЗначения, "?", "")) Тогда
// КраткоеПредставлениеПараметра = КраткоеПредставлениеПараметра + " [" + ирОбщий.ПредставлениеЗначенияСОграничениемДлиныЛкс(СокрЛП(СтрокаПараметра.ТипЗначения), 20) + "]";
//КонецЕсли;
КраткиеОписанияПараметров.Добавить(КраткоеПредставлениеПараметра);
СтруктураПараметра.Вставить("label", КраткоеПредставлениеПараметра);
ОписаниеПараметра =
"Обяз.: " + ?(Не ЛиНеОбязательный, "Да", "Нет, " + СтрокаПараметра.Значение) + "; Возвр.: " + ?(Не ЗначениеЗаполнено(СтрокаПараметра.Знач), "?", ?(СтрокаПараметра.Знач = "Знач", "Нет", "Да")) + "
|Тип: " + ирОбщий.ПредставлениеЗначенияСОграничениемДлиныЛкс(СокрЛП(СтрокаПараметра.ТипЗначения), 200) + ".";
Если ЗначениеЗаполнено(СтрокаПараметра.Описание) Тогда
ОписаниеПараметра = ОписаниеПараметра + "
|> " + СтрокаПараметра.Описание;
КонецЕсли;
СтруктураПараметра.Вставить("documentation", ОписаниеПараметра);
ПараметрыМетода.Добавить(СтруктураПараметра);
КонецЦикла;
ПредставлениеМетода = "";
Если Не ДляСпискаАвтодополнения Тогда
ПредставлениеМетода = ПредставлениеМетода + ирОбщий.ПредставлениеЗначенияСОграничениемДлиныЛкс(ФормаВызовМетода.ИмяМетода, 13);
КонецЕсли;
ПредставлениеМетода = ПредставлениеМетода + "(" + ирОбщий.СтрСоединитьЛкс(КраткиеОписанияПараметров, ", ") + ")";
Если ЗначениеЗаполнено(ФормаВызовМетода.ТипЗначенияМетода) Тогда
Если Не ДляСпискаАвтодополнения Тогда
ПредставлениеМетода = ПредставлениеМетода + " [" + ирОбщий.ПредставлениеЗначенияСОграничениемДлиныЛкс(СокрЛП(ФормаВызовМетода.ТипЗначенияМетода), 15) + "]";
КонецЕсли;
КонецЕсли;
ПодсказкаСлова.Вставить("label", ПредставлениеМетода);
ПодсказкаСлова.Вставить("parameters", ПараметрыМетода);
ОписаниеМетода = "";
Если ЗначениеЗаполнено(ФормаВызовМетода.ТекущийВариант) Тогда
ОписаниеМетода = ОписаниеМетода + "Вариант: " + ФормаВызовМетода.ТекущийВариант + "." + Символы.ПС;
КонецЕсли;
ОписаниеМетода = ОписаниеМетода + ФормаВызовМетода.ОписаниеМетода;
ПодсказкаСлова.Вставить("documentation", ОписаниеМетода);
СтруктураПодсказки.Добавить(ПодсказкаСлова);
КонецЦикла;
Возврат СтруктураПодсказки;
КонецФункции
Процедура РедакторHTML_ПередПоказомАвтодополнения(Триггер, ПоследнееВыражение, ПоследнееСлово) Экспорт
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
РедакторHTML = ПолеТекста.РедакторHTML();
//РедакторHTML.hideSuggestionsList();
Последние2Символа = Прав(ПоследнееВыражение, 2);
ПрефиксПараметра = мПараметрыДиалектаSQL.ПрефиксПараметра;
//Сообщить(Триггер);
Если Ложь
Или Триггер = "space"
Или (Истина
И АвтоматическаяПодсказкаАвтодополненияHTML()
И (Ложь
Или Триггер = Неопределено // ввод буквы или после выбора слова списка вводом "."
Или Триггер = "." И Последние2Символа <> ".."
Или ЯзыкПрограммы <> 0 И Триггер = ПрефиксПараметра И Последние2Символа <> (ПрефиксПараметра + ПрефиксПараметра)
Или ЯзыкПрограммы = 0 И Триггер = """" И Последние2Символа <> """"""
Или ирОбщий.ЛиИмяПеременнойЛкс(Триггер) // Иначе слишком часто вызывается затратное обновление списка слов локального контекста
Или ЯзыкПрограммы = 0 И ирОбщий.СтрокиРавныЛкс(ПоследнееСлово, "новый")
Или ЯзыкПрограммы = 0 И ирОбщий.СтрокиРавныЛкс(ПоследнееСлово, "new")))
Тогда
Если Триггер = "backspace" Тогда
//РедакторHTML.enableBeforeShowSuggestEvent(Ложь);
РедакторHTML.setOption("generateBeforeShowSuggestEvent", Ложь);
РедакторHTML.showPreviousCustomSuggestions();
//РедакторHTML.enableBeforeShowSuggestEvent(Истина);
РедакторHTML.setOption("generateBeforeShowSuggestEvent", Истина);
Иначе
ФормаВызовМетода = ФормаВызовМетода();
Если ФормаВызовМетода.Открыта() Тогда
ФормаВызовМетода.Закрыть();
КонецЕсли;
КончитьОбработкуКоманды();
ФормаВладелец.КлсПолеТекстаПрограммыОбновитьКонтекст(ЭтотОбъект);
РазобратьТекущийКонтекст();
Если ЯзыкПрограммы = 0 И Триггер = """" Тогда
ПоказатьСписок = мЭтоСтроковыйЛитерал;
ИначеЕсли Истина
И Триггер <> "space"
И ЯзыкПрограммы = 1
И мЭтоОбъявлениеПсевдонима
Тогда
ПоказатьСписок = Ложь;
Иначе
ПоказатьСписок = Не (мКонтекст = "" И Триггер = ".");
КонецЕсли;
Если ПоказатьСписок Тогда
//РедакторHTML.enableSuggestActivationEvent(Истина, Истина); // Второй параметр включает отображение типов для всех слов списка автодополнения https://github.com/salexdv/bsl_console/issues/119
РедакторHTML.setOption("generateSuggestActivationEvent", Истина);
РедакторHTML.setOption("alwaysDisplaySuggestDetails", Истина);
УспехЗаполнения = ЗаполнитьТаблицуСлов(, мКонкретныйТипКонтекста, мСтруктураТипаКонтекста, Триггер = "space", Истина);
Если Истина
И УспехЗаполнения
И (Ложь
Или Триггер = "space"
Или ТаблицаСлов.Количество() > 0)
Тогда
СтруктураПодсказки = Новый Массив;
КодыТиповСлов = Новый Структура;
СоответствиеТипаСлова();
Для Каждого СтрокаСоответствия Из мСоответствиеТиповСловHTML Цикл
Если Не ЗначениеЗаполнено(СтрокаСоответствия.Имя) Тогда
Продолжить;
КонецЕсли;
КодыТиповСлов.Вставить(СтрокаСоответствия.Имя, СоответствиеТипаСлова(СтрокаСоответствия.Имя).Код);
КонецЦикла;
Для Каждого СтрокаСлова Из ТаблицаСлов Цикл
ПодсказкаСлова = Новый Структура();
ПодсказкаСлова.Вставить("name", СтрокаСлова.Слово);
//ТекстВставки = СтрокаСлова.Слово;
//ПодсказкаСлова.Вставить("text", ТекстВставки); // Закомментировал, т.к. пользы от этого нет, а вред есть https://github.com/salexdv/bsl_console/issues/171
ПодсказкаСлова.Вставить("kind", КодыТиповСлов[СтрокаСлова.ТипСлова]);
ПодсказкаСлова.Вставить("detail", СтрокаСлова.ТипЗначения);
Если СтрокаСлова.ТипСлова = "Конструкция" Тогда
ПодсказкаСлова.Вставить("sort", "-1"); // https://www.hostedredmine.com/issues/963233
КонецЕсли;
ПодсказкаСлова.Вставить("detail", СтрокаСлова.ТипЗначения);
ПодсказкаСлова.Вставить("documentation", "_"); // Нужно чтобы окно детального описания открывалось
СтруктураПодсказки.Добавить(ПодсказкаСлова);
КонецЦикла;
СтрокаСпискаАвтодополненияHTML = ирОбщий.ОбъектВСтрокуJSONЛкс(СтруктураПодсказки);
Если СтрокаСпискаАвтодополненияHTML <> Неопределено Тогда
РедакторHTML.setOption("showSnippetsOnCustomSuggestions", мСтруктураТипаКонтекста.ИмяОбщегоТипа = "Локальный"); // Штатные сниппеты https://github.com/salexdv/bsl_console/issues/200
//РедакторHTML.enableBeforeShowSuggestEvent(Ложь);
РедакторHTML.setOption("generateBeforeShowSuggestEvent", Ложь);
РедакторHTML.showCustomSuggestions(СтрокаСпискаАвтодополненияHTML);
//РедакторHTML.enableBeforeShowSuggestEvent(Истина);
РедакторHTML.setOption("generateBeforeShowSuggestEvent", Истина);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Функция СоответствиеТипаСлова(Знач ВстроенныйТипСлова = "", Знач ИмяКлюча = "Имя")
Если мСоответствиеТиповСловHTML = Неопределено Тогда
мСоответствиеТиповСловHTML = ирОбщий.ТаблицаЗначенийИзТабличногоДокументаЛкс(ПолучитьМакет("ТипыСловHTML"));
#Если Сервер И Не Сервер Тогда
мСоответствиеТиповСловHTML = Новый ТаблицаЗначений;
#КонецЕсли
мСоответствиеТиповСловHTML.Колонки.Добавить("НКод");
мСоответствиеТиповСловHTML.Индексы.Добавить("Имя");
мСоответствиеТиповСловHTML.Индексы.Добавить("НКод");
Для Каждого СтрокаТЗ Из мСоответствиеТиповСловHTML Цикл
СтрокаТЗ.НКод = НРег(СтрокаТЗ.Код);
КонецЦикла;
КонецЕсли;
НайденнаяСтрока = мСоответствиеТиповСловHTML.Найти(ВстроенныйТипСлова, ИмяКлюча);
//Если НайденнаяСтрока = Неопределено Тогда
// НайденнаяСтрока = мСоответствиеТиповСловHTML[0];
//КонецЕсли;
Возврат НайденнаяСтрока;
КонецФункции
Процедура РедакторHTML_ПриВыбореСтрокиАвтодополнения(Триггер, ПоследнееВыражение, ВыбранноеСлово, ТипСловаHTML, ТекстВставки, ПоследнееСлово)
Если ирОбщий.СтрНачинаетсяСЛкс(Триггер, "force-") Тогда
ПараметрЗакрытия = Прав(Триггер, 1);
Если Найти(ПоследнееВыражение, ".") > 0 Тогда
ВыделенныйТекст(ПараметрЗакрытия);
Возврат;
КонецЕсли;
Иначе
ПараметрЗакрытия = Истина;
КонецЕсли;
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
РедакторHTML = ПолеТекста.РедакторHTML();
РедакторHTML.hideSuggestionsList();
КончитьОбработкуКоманды();
РазобратьТекущийКонтекст();
ОтборСлов = Новый Структура("Слово", ЧистоеСловоСпискаПодсказкиHTML(ВыбранноеСлово));
ТипСлова = ТипСловаИзТипаСловаHTML(ТипСловаHTML);
Если ТипСлова = "Шаблон" Тогда
мНачальнаяКолонка = мНачальнаяКолонка - СтрДлина(ПоследнееСлово);
УстановитьГраницыВыделения();
РедакторHTML.insertSnippet(ТекстВставки);
Возврат;
КонецЕсли;
Если ЗначениеЗаполнено(ТипСлова) Тогда
ОтборСлов.Вставить("ТипСлова", ТипСлова);
КонецЕсли;
НайденныеСтроки = ТаблицаСлов.НайтиСтроки(ОтборСлов);
Если НайденныеСтроки.Количество() = 0 Тогда
//Возврат;
НоваяСтрока = ТаблицаСлов.Добавить();
НоваяСтрока.Слово = ВыбранноеСлово;
НоваяСтрока.ТипСлова = "Свойство";
НайденныеСтроки = ирОбщий.ЗначенияВМассивЛкс(НоваяСтрока);
КонецЕсли;
СтрокаТаблицыСлов = НайденныеСтроки[0];
ВставитьВыбранноеСловоАвтодополнения(СтрокаТаблицыСлов, мКонкретныйТипКонтекста, мСтруктураТипаКонтекста,, ПараметрЗакрытия);
Если ПараметрЗакрытия = "." Тогда
РедакторHTML.triggerSuggestions();
КонецЕсли;
Если мОткрытьСправкуПоПараметру = Истина Тогда
Если ЛиДоступноОткрытиеСвободнойФормы() Тогда
ОткрытьСправкуПоПараметру(, Ложь);
Иначе
РедакторHTML.triggerSigHelp();
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Функция ТипСловаИзТипаСловаHTML(Знач ТипСловаHTML)
Перем ТипСлова;
ТипСлова = СоответствиеТипаСлова(ирОбщий.ПоследнийФрагментЛкс(ТипСловаHTML, "-"), "НКод").Имя;
Возврат ТипСлова;
КонецФункции
Функция ЛиДоступноОткрытиеСвободнойФормы()
Возврат Не (ирКэш.ЛиСеансТолстогоКлиентаУПЛкс() Или ФормаВладелец.МодальныйРежим);
КонецФункции
Процедура РедакторHTML_ОбработатьСобытие(Событие) Экспорт
//Сообщить("Отладка. " + Событие.event);
Попытка
Если Событие.event = "EVENT_BEFORE_SIGNATURE" Тогда
РедакторHTML_ПередПоказомСигнатуры(Событие.params.activeParameter, Событие.params.word, Событие.params.activeSignature, Событие.params.triggerCharacter);
ИначеЕсли Событие.event = "EVENT_ON_SELECT_SUGGEST_ROW" Тогда
РедакторHTML_ПриВыбореСтрокиАвтодополнения(Событие.params.trigger, Событие.params.last_expression, Событие.params.selected, Событие.params.kind, Событие.params.insert_text, Событие.params.last_word);
ИначеЕсли Ложь
Или Событие.event = "EVENT_ON_ACTIVATE_SUGGEST_ROW"
Или Событие.event = "EVENT_ON_DETAIL_SUGGEST_ROW"
Тогда
РедакторHTML_ПриАктивацииСтрокиАвтодополнения(Событие.params.trigger, Событие.params.focused, Событие.params.row_id, Событие.params.sideDetailIsOpened, Событие.params.kind);
ИначеЕсли Событие.event = "EVENT_BEFORE_SHOW_SUGGEST" Тогда
РедакторHTML_ПередПоказомАвтодополнения(Событие.params.trigger, Событие.params.last_expression, Событие.params.last_word);
КонецЕсли;
Исключение
// Антибаг платформы https://www.hostedredmine.com/issues/962188
ирОбщий.СообщитьЛкс(ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Процедура РедакторHTML_ПриАктивацииСтрокиАвтодополнения(Триггер, ТекущееСлово, НомерСлова, ЛиОтдельноеОписаниеАктивно, ТипСловаHTML) Экспорт
// Показывать надо обязательно каждый раз, т.к. редактор забывает предыдущие уточнения типа
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
ТипСлова = ТипСловаИзТипаСловаHTML(ТипСловаHTML);
Если ТипСлова = "Шаблон" Тогда
Возврат;
КонецЕсли;
РедакторHTML = ПолеТекста.РедакторHTML();
СтрокаТаблицыСлов = ТаблицаСлов.Найти(ЧистоеСловоСпискаПодсказкиHTML(ТекущееСлово), "Слово");
Если СтрокаТаблицыСлов <> Неопределено Тогда
ТаблицаСтруктурТипов = УточнитьТипЗначенияВСтрокеТаблицыСлов(мСтруктураТипаКонтекста, СтрокаТаблицыСлов, ЛиОтдельноеОписаниеАктивно);
СтруктураОписания = Новый Массив;
Если мСтруктураТипаКонтекста.Конструктор Тогда
ДетальноеОписаниеДляСписка = "";
Иначе
ДетальноеОписаниеДляСписка = СтрокаТаблицыСлов.ТипЗначения;
Если ЗначениеЗаполнено(ДетальноеОписаниеДляСписка) Тогда
СтруктураОписания.Добавить("> Тип: " + ДетальноеОписаниеДляСписка);
КонецЕсли;
КонецЕсли;
Если ЛиОтдельноеОписаниеАктивно И ТаблицаСтруктурТипов <> Неопределено Тогда
Если Ложь
Или мСтруктураТипаКонтекста.Конструктор
Или СтрокаТаблицыСлов.ТипСлова = "Метод"
Тогда
Если мСтруктураТипаКонтекста.Конструктор Тогда
СтруктураТипа = мПлатформа.НоваяСтруктураТипа();
СтруктураТипа.ИмяОбщегоТипа = "Глобальный";
ТаблицаСтруктурТипов = мПлатформа.СвойстваТипаПредопределенные(СтруктураТипа, СтрокаТаблицыСлов.Слово, "Конструктор",, ЯзыкПрограммы, Конфигурация)[0].ТаблицаСтруктурТипов;
КонецЕсли;
//ПараметрыМетода = мПлатформа.ТаблицаПараметровМетода(ТаблицаСтруктурТипов[0]);
СтруктураПодсказкиМетода = СтруктураПодсказкиМетода(ТаблицаСтруктурТипов[0], Триггер <> Неопределено, Истина);
Если СтруктураПодсказкиМетода.Количество() > 0 Тогда
СтруктураОписания.Вставить(0, "> Параметры: " + СтруктураПодсказкиМетода[0].label);
Если СтруктураПодсказкиМетода.Количество() > 1 Тогда
СтруктураОписания.Вставить(0, "> Варианты: " + СтруктураПодсказкиМетода.Количество());
КонецЕсли;
ОписаниеСлова = СтруктураПодсказкиМетода[0].documentation;
Если ЗначениеЗаполнено(ОписаниеСлова) Тогда
СтруктураОписания.Добавить("> Описание: " + ОписаниеСлова);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
СтруктураОписания.Добавить("> Определение: " + СтрокаТаблицыСлов.Определение);
ДетальноеОписаниеОтдельное = ирОбщий.СтрСоединитьЛкс(СтруктураОписания, Символы.ПС);
Если Триггер = "hover" Тогда
РедакторHTML.setSuggestItemDetailById(НомерСлова, ДетальноеОписаниеДляСписка, ДетальноеОписаниеОтдельное);
Иначе
МаксВысотаТочек = 800;
РедакторHTML.setActiveSuggestDetail(ДетальноеОписаниеДляСписка, ДетальноеОписаниеОтдельное, МаксВысотаТочек);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Процедура РедакторHTML_ОтключитьСочетанияПереключенияСигнатуры() Экспорт
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
РедакторHTML = ПолеТекста.РедакторHTML();
// https://github.com/salexdv/bsl_console/issues/130
// Коды клавиш https://microsoft.github.io/monaco-editor/api/enums/monaco.keycode.html
РедакторHTML.disableKeyBinding(512+16); // ALT(512)+ArrowUp(16)
РедакторHTML.disableKeyBinding(512+18); // ALT(512)+ArrowDown(18)
КонецПроцедуры
Процедура РедакторHTML_ВключитьСочетанияПереключенияСигнатуры() Экспорт
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
РедакторHTML = ПолеТекста.РедакторHTML();
// https://github.com/salexdv/bsl_console/issues/130
РедакторHTML.enableKeyBinding(528); // ALT(512)+ArrowUp(16)
РедакторHTML.enableKeyBinding(530); // ALT(512)+ArrowDown(18)
КонецПроцедуры
Процедура РедакторHTML_ОбработатьКликНаГиперссылке(Событие, ФункцияПерейтиКОпределению, ФункцияВычислитьВыражение) Экспорт
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
Если ПолеТекста.ОбработатьКликНаГиперссылке(Событие) Тогда
Возврат;
КонецЕсли;
РедакторHTML = ПолеТекста.РедакторHTML();
РедакторHTML.hideHoverList();
ЗаголовокГиперссылки = Событие.params.label;
ЗначениеГиперссылки = Событие.params.href;
Если ЗаголовокГиперссылки = "Определение" Тогда
Координаты = ирОбщий.СтрРазделитьЛкс(ЗначениеГиперссылки, ",");
НомерСтроки = Число(Координаты[0]);
НомерКолонки = Число(Координаты[1]);
Если Не Вычислить("ФормаВладелец." + ФункцияПерейтиКОпределению + "(НомерСтроки, НомерКолонки)") Тогда
ПерейтиКОпределению(НомерСтроки, НомерКолонки);
КонецЕсли;
ИначеЕсли ЗаголовокГиперссылки = "Знач" Тогда
УспехВычисления = Истина;
ЗначениеВыражения = Вычислить("ФормаВладелец." + ФункцияВычислитьВыражение + "(ЗначениеГиперссылки, УспехВычисления)");
Если УспехВычисления Тогда
ирКлиент.ОткрытьЗначениеЛкс(ЗначениеВыражения);
КонецЕсли;
ИначеЕсли Ложь
Или Лев(ЗаголовокГиперссылки, 1) = "["
Или ЗаголовокГиперссылки = "Допустимые типы"
Тогда
ОткрытьОписаниеТипаПоГиперссылке(ЗначениеГиперссылки);
Иначе
ОткрытьКонтекстнуюСправку(ЗначениеГиперссылки);
КонецЕсли;
КонецПроцедуры
Процедура КомандаРедактораHTML(Команда)
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
РедакторHTML = ПолеТекста.РедакторHTML();
РедакторHTML.editor.trigger("", Команда);
КонецПроцедуры
Процедура ЗаменитьВхожденияHTML()
КомандаРедактораHTML("editor.action.changeAll");
КонецПроцедуры
Процедура СочетанияКлавишHTML()
ирКлиент.ОткрытьТекстЛкс(ПолучитьМакет("СочетанияКлавишHTML").ПолучитьТекст(), "Сочетания клавиш HTML редактора", "Обычный", Истина, "СочетанияКлавишHTML");
КонецПроцедуры
Процедура ОткрытьКонструкторФорматнойСтроки(ФорматнаяСтрока)
Конструктор = Новый КонструкторФорматнойСтроки();
Попытка
Конструктор.Текст = ФорматнаяСтрока;
Исключение
Инфо = ИнформацияОбОшибке();
ирОбщий.СообщитьЛкс("Ошибка в тексте форматной строки:" + Символы.ПС + Инфо.Причина.Описание);
Возврат;
КонецПопытки;
Если Конструктор.ОткрытьМодально() Тогда
Результат = Конструктор.Текст;
Результат = СтрЗаменить(Результат, "'", "");
Результат = """" + Результат + """";
ВыделенныйТекст(Результат);
КонецЕсли;
КонецПроцедуры
Процедура КонструкторФорматнойСтроки()
ФорматнаяСтрока = СтрЗаменить(СтрЗаменить(ВыделитьТекстТекущегоСтроковогоЛитерала(), "|", ""), """", "");
ОткрытьКонструкторФорматнойСтроки(ФорматнаяСтрока);
КонецПроцедуры
Процедура НайтиСледующееHTML()
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
РедакторHTML = ПолеТекста.РедакторHTML();
РедакторHTML.nextMatch();
КонецПроцедуры
Процедура НайтиПредыдущееHTML()
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
РедакторHTML = ПолеТекста.РедакторHTML();
РедакторHTML.previousMatch();
КонецПроцедуры
Процедура РедакторHTML_Перерисовать() Экспорт
#Если Сервер И Не Сервер Тогда
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
//ПолеТекста.Перерисовать();
//ОбновитьПодсказкуПоВызовуМетода();
КонецПроцедуры
Процедура ПанельРедактораКодаПриСменеСтраницы(Знач ПанельРедактора, Знач Поле1, Знач Поле2, Знач ИсходныйТекст) Экспорт
#Если Сервер И Не Сервер Тогда
Поле1 = Обработки.ирОболочкаПолеТекста.Создать();
Поле2 = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
ТекущаяСтраница = ПанельРедактора.ТекущаяСтраница;
Если ТекущаяСтраница = ПанельРедактора.Страницы.РедакторHTML Тогда
ЭтотОбъект.ПолеТекста = Поле2;
ПолеТекста.ЗагрузитьСостояниеИзПоляТекстаЛкс(Поле1, ИсходныйТекст);
Иначе
ЭтотОбъект.ПолеТекста = Поле1;
ПолеТекста.ЗагрузитьСостояниеИзПоляТекстаЛкс(Поле2, ИсходныйТекст);
КонецЕсли;
КонецПроцедуры
#КонецЕсли
Процедура УстановитьКонфигурациюМетаданных(пКонфигурация = Неопределено, пКонтекстВыполнения = Неопределено, Знач Диалект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;
КонецЕсли;
ЭтотОбъект.мПараметрыДиалектаSQL = мДиалектыSQL.Найти(мДиалектSQL, "Диалект");
ЭтотОбъект.мРасширенноеПолучениеМетаданныхADO = РасширенноеПолучениеМетаданныхADO = Истина;
//Иначе
// Если пКонфигурация <> Неопределено Тогда
// ЭтотОбъект.Конфигурация = пКонфигурация;
// Иначе
// ЭтотОбъект.Конфигурация = мПлатформа.мМетаданные;
// КонецЕсли;
//КонецЕсли;
//Если ирОбщий.СтрокиРавныЛкс(мДиалектSQL, "1С") Тогда
// мДоступныеТаблицыПолучены = Истина;
//ИначеЕсли ирОбщий.СтрокиРавныЛкс(мДиалектSQL, "WQL") Тогда
// //ЗаполнитьДоступныеТаблицыWQL(); // Слишком долго
// мДоступныеТаблицыПолучены = Истина;
//Иначе
// мДоступныеТаблицыПолучены = Ложь;
//КонецЕсли;
ЭтотОбъект.КонтекстВыполнения = пКонтекстВыполнения;
КонецПроцедуры
// Очишает таблицу слов локального контекста.
//
// Параметры:
// Нет.
//
Процедура ОчиститьТаблицуСловЛокальногоКонтекста() Экспорт
Для Каждого СтрокаЛокальногоКонтекста Из ТаблицаЛокальногоКонтекста Цикл
// Разрываем циклические ссылки в СтрокаОписания
СтрокаЛокальногоКонтекста.ТаблицаСтруктурТипов = Неопределено;
КонецЦикла;
ТаблицаЛокальногоКонтекста.Очистить();
КонецПроцедуры
// <Описание функции>
//
// Параметры:
// <Параметр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 Тогда
лКонтекстВыполнения = КонтекстВыполнения;
лМетодВыполнения = МетодВыполнения;
Попытка
ИнформацияОбОшибке = мПлатформа.ВыполнитьПрограммныйКодВКонтексте(лКонтекстВыполнения, лМетодВыполнения, ТекстДляПроверки, Истина);
Исключение
ИнформацияОбОшибке = ИнформацияОбОшибке();
КонецПопытки;
КонецЕсли;
Если СамаяВложеннаяПричина И ИнформацияОбОшибке <> Неопределено Тогда
#Если Сервер И Не Сервер Тогда
ИнформацияОбОшибке = ИнформацияОбОшибке();
#КонецЕсли
Пока ИнформацияОбОшибке.Причина <> Неопределено Цикл
ИнформацияОбОшибке = ИнформацияОбОшибке.Причина;
КонецЦикла;
КонецЕсли;
Возврат ИнформацияОбОшибке;
КонецФункции
// Выполняет проверку синтаксиса программного кода или текста запроса.
//
// Параметры:
// *СообщатьОбУспешнойПроверке - Булево, *Ложь;
// *ТекстДляПроверки - Строка, *Неопределено - проверяемый текст (используется весь текст или этот).
//
// Возвращаемое значение:
// Булево - результат проверки.
//
Функция ПроверитьПрограммныйКод(СообщатьОбУспешнойПроверке = Ложь, ТекстДляПроверки = Неопределено, Контекст = "") Экспорт
СтартоваяСтрока = 0;
СтартоваяКолонка = 0;
ИнформацияОбОшибке = ПроверитьТекстИВернутьОшибку(ТекстДляПроверки, СтартоваяСтрока, СтартоваяКолонка, Контекст);
Если ЗначениеЗаполнено(Контекст) Тогда
ПредставлениеКонтекста = " (Проверка " + Контекст + ")";
КонецЕсли;
Если ИнформацияОбОшибке <> Неопределено Тогда
Если ТипЗнч(ИнформацияОбОшибке) = Тип("ИнформацияОбОшибке") Тогда
#Если Клиент Тогда
Если ФормаВладелец <> Неопределено Тогда
ФормаВладелец.ТекущийЭлемент = ПолеТекста.ЭлементФормы;
КонецЕсли;
ирКлиент.ПоказатьОшибкуВТекстеПрограммыЛкс(ПолеТекста, СтартоваяСтрока, СтартоваяКолонка, ЯзыкПрограммы, , ИнформацияОбОшибке,, ПредставлениеКонтекста);
#КонецЕсли
Иначе
// Ошибка обработана и отображена ранее
КонецЕсли;
Иначе
Если СообщатьОбУспешнойПроверке Тогда
СообщитьОбУспешнойПроверке(ПредставлениеКонтекста);
КонецЕсли;
КонецЕсли;
Возврат ИнформацияОбОшибке = Неопределено;
КонецФункции
Процедура СообщитьОбУспешнойПроверке(Знач ПредставлениеКонтекста = "") Экспорт
ирОбщий.СообщитьСУчетомМодальностиЛкс(ирОбщий.ПредставлениеИзИдентификатораЛкс(ПолеТекста.ЭлементФормы.Имя)
+ ПредставлениеКонтекста + ": Синтаксических ошибок не обнаружено!");
КонецПроцедуры
Процедура СброситьРезультатРазбораПозицииВТексте()
мНомерПараметра = 0;
мНачалоКонтекста = "";
мНачалоСлова = "";
мКонецКонтекста = "";
выхЕстьТочкаСправа = Ложь;
мРодительскийКонтекст = "";
мКонтекст = "";
мЭтоСтроковыйЛитерал = Ложь;
мЭтоОбъявлениеПсевдонима = Ложь;
мЭтоКонструктор = Ложь;
мАргументы = "";
мПервыйПараметр = "";
мФактическиеПараметры = Новый Массив;
КонецПроцедуры
// Заменяет все печатаемые символы, кроме идентификаторов в кавычках, внутри комментариев и строковых литералов на заданный символ.
//
// Параметры:
// Текст - Строка;
// СимволЗамена - Строка.
//
// Возвращаемое значение:
// Строка.
//
Функция ЗалитьКомментарииИСтроковыеЛитералы(Знач Текст, СимволЗамена = " ", ЗалитьСтроковыеЛитералы = Ложь, ЗалитьУсловия = Истина) Экспорт
РегВыражение.Global = Истина;
РегВыражение.Multiline = Ложь;
// Количество символов в тексте меняется, но позиции строк сохраняются
Если Ложь
Или ЯзыкПрограммы = 1
Или ЯзыкПрограммы = 2
Тогда
////RegExp.Pattern = "(""" + шИмя+ "(?:\." + шИмя + ")*"")|(" + "//(:)?[^\n]*" + ")|(" + шСтрокаЗапроса + ")|(.|\n|\r)";
//RegExp.Pattern = "(""" + шИмя+ "(?:\." + шИмя + ")*"")|(?:" + "//:([^\n]*)" + ")|(?:" + "//[^\n]*" + ")|(" + шСтрокаЗапроса + ")|(.|\n|\r)";
РегВыражение.Pattern = "(""" + шИмя+ "(?:\." + шИмя + ")*"")|(?:" + "//:([^\n]*)" + ")|(?:" + "//[^\n]*" + ")|(" + шСтрокаЗапроса + ")|([\s\S])";
ШаблонЗамены = "$1$2$3$4";
ИначеЕсли ЯзыкПрограммы = 0 Тогда
//RegExp.Pattern = "(""" + шИмя+ "(?:\." + шИмя + ")*"")|(" + "//(:)?[^\n]*" + ")|(" + шСтрокаПрограммы + ")|(.|\n|\r)";
шОднострочнаяСтрокаПрограммыСКавычки = """(?:(?:"""")|[^""\n])*""?";
шОднострочнаяСтрокаПрограммыСЧерты = "(?:(\n)\s*\|(?:(?:"""")|[^""\n])*""?)";
// + шОднострочнаяСтрокаПрограммыСКавычки + "|" + шОднострочнаяСтрокаПрограммыСЧерты + "|(.|\n|\r)";
РегВыражение.Pattern = "(""" + шИмя + "(?:\.[" + шБуква + "\d]+)*"")" // имена ProgId от COM объектов бывают "Forms.TextBox.1"
+ "|(""(?:" + шИмя + "\s*,\s*)*" + шИмя + """)" // создание структуры
+ "|" + "//:([^\n]*)" + "|" + "//[^\n]*"
+ "|"+ "(?:" + "#[^\n]*" + ")" // Инструкции препроцессора
+ "|" + "(?:" + "~" + шИмя + ")|"; // Присвоение типа выражению в комментарии
ШаблонЗамены = "$1$2$3$4";
Если ЗалитьСтроковыеЛитералы Тогда
РегВыражение.Pattern = РегВыражение.Pattern + шОднострочнаяСтрокаПрограммыСКавычки + "|" + шОднострочнаяСтрокаПрограммыСЧерты + "";
ШаблонЗамены = ШаблонЗамены + "$5";
Иначе
// http://www.hostedredmine.com/issues/885452
КонецЕсли;
РегВыражение.Pattern = РегВыражение.Pattern + "|([\s\S])";
КонецЕсли;
ЗалитыйТекст = РегВыражение.Заменить(Текст, ШаблонЗамены);
Если Истина
И ЗалитьУсловия
И СтрДлина(ЗалитыйТекст) < 10000 // Долго на больших текстах!
Тогда
// Заливаем условия, чтобы проверка равенства в них не считалась присвоением
// В будущем можно отказаться от этого блока и собирать все возможные типы, а потом давать юзеру выбирать.
Если ЯзыкПрограммы = 0 Тогда
РегВыражение.Pattern = "(" + шЕсли + ")|(" + шПока + ")";
ЗалитыйТекстОригинал = ЗалитыйТекст;
Результат = РегВыражение.НайтиВхождения(ЗалитыйТекстОригинал);
ЗалитыйТекст = Новый Запись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 - ТекущаяПозицияВОригинале));
ЗалитыйТекст.ЗаписатьБезОбработки(НачалоТокена + РегВыражение.Заменить(Сред(НайденныйТекст, 1 + СтрДлина(НачалоТокена), СтрДлина(НайденныйТекст) - СтрДлина(НачалоТокена) - СтрДлина(КонецТокена)), СимволЗамена)
+ КонецТокена);
ТекущаяПозицияВОригинале = Match.FirstIndex + 1 + СтрДлина(Match.Value);
КонецЦикла;
ЗалитыйТекст.ЗаписатьБезОбработки(Сред(ЗалитыйТекстОригинал, ТекущаяПозицияВОригинале));
ЗалитыйТекст = ЗалитыйТекст.Закрыть();
КонецЕсли;
КонецЕсли;
Возврат ЗалитыйТекст;
КонецФункции
Процедура ЗаполнитьЛокальныеСвойстваИМетодыПоТексту(ОчиститьТаблицуСлов = Истина, ВключатьКонструкции = Истина, УчитыватьРодительскийКонтекст = Ложь, ОбновитьТекстДляАнализа = Истина,
ВключатьГлобальныйКонтекст = Ложь, Знач ТекстДляАнализа = "", Знач ТекстСинтаксическиКорректен = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
РегВыражение = Обработки.ирОболочкаРегВыражение.Создать();
#КонецЕсли
Если ирОбщий.ПроверитьПлатформаНеWindowsЛкс(, "Заполнение параметров", Истина) Тогда
Возврат;
КонецЕсли;
Если Не ЗначениеЗаполнено(ТекстДляАнализа) Тогда
Если ОбновитьТекстДляАнализа Тогда
ТекстДляАнализа = ПолеТекста.ПолучитьТекст();
КонецЕсли;
КонецЕсли;
Если ЗначениеЗаполнено(ТекстДляАнализа) Или ОбновитьТекстДляАнализа Тогда
ТекстБезКомментариевИОпасныхСтрок = ЗалитьКомментарииИСтроковыеЛитералы(ТекстДляАнализа,, Истина, Ложь);
КонецЕсли;
Если ОчиститьТаблицуСлов Тогда
ТаблицаСлов.Очистить();
КонецЕсли;
Если ВключатьКонструкции Тогда
Если ЯзыкПрограммы = 0 Тогда
СписокСловЯзыка = мПлатформа.КлючевыеСловаВстроенногоЯзыка();
ИначеЕсли ЯзыкПрограммы = 1 Тогда
ВключаяРусские = ТипЗнч(Конфигурация) = Тип("ОбъектМетаданныхКонфигурация");
СписокСловЯзыка = мПлатформа.КлючевыеСловаЯзыкаЗапросов(РежимКомпоновкиДанных, ВключаяРусские, Истина);
ИначеЕсли ЯзыкПрограммы = 2 Тогда
//СписокСловЯзыка = мПлатформа.КлючевыеСловаЯзыкаЗапросов();
СписокСловЯзыка = Новый СписокЗначений;
СписокСловЯзыка.Добавить("РАЗЛИЧНЫЕ"); // Криво https://www.hostedredmine.com/issues/931487
КонецЕсли;
Для Каждого ЭлементСписка Из СписокСловЯзыка Цикл
НоваяСтрока = ТаблицаСлов.Добавить();
НоваяСтрока.Слово = ЭлементСписка.Значение;
НоваяСтрока.НСлово = НРег(НоваяСтрока.Слово);
НоваяСтрока.ТипСлова = "Конструкция";
НоваяСтрока.Определение = "Предопределенный";
КонецЦикла;
КонецЕсли;
Если ВключатьГлобальныйКонтекст Тогда
СтруктураТипа = мПлатформа.НоваяСтруктураТипа();
СтруктураТипа.ИмяОбщегоТипа = "Глобальный";
СтруктураТипа.Метаданные = Метаданные;
ТаблицаГлобальногоКонтекста = мПлатформа.ПолучитьТаблицуСловСтруктурыТипа(СтруктураТипа);
Для Каждого СтрокаСлова Из ТаблицаГлобальногоКонтекста Цикл
НоваяСтрока = ТаблицаСлов.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаСлова);
НоваяСтрока.НСлово = НРег(НоваяСтрока.Слово);
//НоваяСтрока.Слово = ЭлементСписка.Значение;
//НоваяСтрока.ТипСлова = "Конструкция";
//НоваяСтрока.Определение = "Предопределенный";
КонецЦикла;
КонецЕсли;
//Поиск использованных свойств и методов данного контекста.
РегВыражение.Global = Истина;
Если Ложь
Или Не УчитыватьРодительскийКонтекст
Или мРодительскийКонтекст = ""
Тогда
Шаблон = "(?:(?:[^." + шБуква + "\d]|^)\s*(" + шИмя + ")(?=\s*\())"
+ "|(?:[^." + шБуква + "\d]|^)\s*(" + шИмя + ")(?=(?:\.(?:" + шИмя + ")?)+|[^\(?:\." + шБуква + "\d]|$)"
+ "|(?:(" + шПараметрЗапроса + "))";
КоличествоПодгрупп = 3;
Иначе
Шаблон = "(?:[^." + шБуква + "\d]|^)\s*(?:" + ирОбщий.ПреобразоватьТекстДляРегулярныхВыраженийЛкс(мРодительскийКонтекст) + "\.(" + шИмя + ")(?=\s*\())"
+ "|(?:[^." + шБуква + "\d]|^)\s*(?:" + ирОбщий.ПреобразоватьТекстДляРегулярныхВыраженийЛкс(мРодительскийКонтекст) + "\.(" + шИмя + ")(?=[^\(?:" + шБуква + "\d]|$))";
КоличествоПодгрупп = 2;
КонецЕсли;
ТаблицаСловТЗ = ТаблицаСлов.Выгрузить(, "НСлово, ТипСлова, Частота");
ТаблицаСловТЗ.Индексы.Добавить("НСлово");
Если ЯзыкПрограммы = 0 Тогда
РегВыражение.Pattern = "(?:" + шСтрокаПрограммы + "|" + шКомментарий + "|(?:Новый|New)\s+" + шИмя + ")";
Иначе
РегВыражение.Pattern = "(?:" + шСтрокаПрограммы + "|" + шКомментарий + ")";
КонецЕсли;
ВременныйТекст = РегВыражение.Заменить(ТекстБезКомментариевИОпасныхСтрок, "");
РегВыражение.Pattern = Шаблон;
Результат = РегВыражение.НайтиВхождения(ВременныйТекст,, Истина);
Счетчик = 0;
Для Каждого Match Из Результат Цикл
Счетчик = Счетчик + 1;
Если Счетчик = МаксСловНаходитьВТекстеПрограммы Тогда
Прервать;
КонецЕсли;
Подгруппа1 = Match.SubMatches(0);
Подгруппа2 = Match.SubMatches(1);
Если КоличествоПодгрупп = 3 Тогда
Подгруппа3 = Match.SubMatches(2);
Иначе
Подгруппа3 = Неопределено;
КонецЕсли;
Если Подгруппа1 <> Неопределено Тогда
Слово = Подгруппа1;
ТипСлова = "Метод";
ИначеЕсли Подгруппа2 <> Неопределено Тогда
Слово = Подгруппа2;
ТипСлова = "Свойство";
ИначеЕсли Подгруппа3 <> Неопределено Тогда
Слово = Подгруппа3;
ТипСлова = "Свойство";
Если Истина
И ОчиститьТаблицуСлов
И ВключатьГлобальныйКонтекст
И ЗначениеЗаполнено(ТекстДляАнализа)
И ТекстСинтаксическиКорректен
И (Ложь
Или Не УчитыватьРодительскийКонтекст
Или мРодительскийКонтекст = "")
Тогда
// Вызов из консоли кода для заполнения выходных параметров. https://www.hostedredmine.com/issues/947841
ИнформацияОбОшибке = ПроверитьТекстИВернутьОшибку(ТекстДляАнализа + ";Сообщить(" + Слово + ")");
Если ИнформацияОбОшибке <> Неопределено Тогда
Продолжить;
КонецЕсли;
КонецЕсли;
Иначе
Продолжить;
КонецЕсли;
СтруктураКлюча = Новый Структура("НСлово", НРег(Слово));
НайденныеСтроки = ТаблицаСловТЗ.НайтиСтроки(СтруктураКлюча);
НоваяСтрока = Неопределено;
Для Каждого НайденнаяСтрока Из НайденныеСтроки Цикл
Если Ложь
Или ЯзыкПрограммы = 1
Или (Истина
И ТипСлова = "Метод"
И НайденнаяСтрока.ТипСлова = "Метод")
Или (Истина
И ТипСлова <> "Метод"
И НайденнаяСтрока.ТипСлова <> "Метод")
Тогда
НоваяСтрока = НайденнаяСтрока;
Прервать;
КонецЕсли;
КонецЦикла;
Если НоваяСтрока = Неопределено Тогда
НоваяСтрока = ТаблицаСлов.Добавить();
НоваяСтрока.Определение = "Статистический";
НоваяСтрока.Слово = Слово;
НоваяСтрока.НСлово = НРег(НоваяСтрока.Слово);
НоваяСтрока.ТипСлова = ТипСлова;
КонецЕсли;
НоваяСтрока.Частота = НоваяСтрока.Частота + 1;
КонецЦикла;
ТаблицаСлов.ЗагрузитьКолонку(ТаблицаСловТЗ.ВыгрузитьКолонку("Частота"), "Частота");
КонецПроцедуры
Процедура ОбновитьТипЗначенияИзТаблицыСтруктурТипов(Знач НоваяСтрока, Знач ТаблицаСтруктурТипов, ЗаменитьСуществующий = Истина) Экспорт
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
СтарыйТипЗначения = НоваяСтрока.ТипЗначения;
Если Лев(СтарыйТипЗначения, 2) = "??" Тогда
НовыйТипЗначения = мПлатформа.ПредставлениеМассиваСтруктурТипов(ТаблицаСтруктурТипов);
Если Истина
И ЗначениеЗаполнено(НовыйТипЗначения)
И Найти(НРег(СтарыйТипЗначения), НРег(НовыйТипЗначения)) > 0
И НовыйТипЗначения <> "??"
Тогда
НовыйТипЗначения = "";
КонецЕсли;
ОстатокТипа = Сред(СтарыйТипЗначения, 4);
Если ОстатокТипа <> "" И Найти(НовыйТипЗначения, ОстатокТипа) = 1 Тогда
НоваяСтрока.ТипЗначения = НовыйТипЗначения;
Иначе
НоваяСтрока.ТипЗначения = СтрЗаменить(СтарыйТипЗначения, "??", НовыйТипЗначения);
КонецЕсли;
Если Не ЗначениеЗаполнено(НоваяСтрока.ТипЗначения) Тогда
НоваяСтрока.ТипЗначения = "?";
ИначеЕсли Лев(НоваяСтрока.ТипЗначения, 1) = "," Тогда
НоваяСтрока.ТипЗначения = СокрЛ(Сред(НоваяСтрока.ТипЗначения, 2));
КонецЕсли;
ИначеЕсли Ложь
Или ЗаменитьСуществующий
Или Не ЗначениеЗаполнено(СтарыйТипЗначения)
Или Найти(СтарыйТипЗначения, "<") > 0
Тогда
НоваяСтрока.ТипЗначения = мПлатформа.ПредставлениеМассиваСтруктурТипов(ТаблицаСтруктурТипов);
КонецЕсли;
КонецПроцедуры
Функция СобратьКомментарийМетода(ОписаниеМетода = "", Знач СтрокаРезультата = Неопределено, ЗначенияПараметров = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
ЗначенияПараметров = Новый Структура;
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ПрефиксОписанияПараметра = "// ";
КомментарийМетода = Новый Массив;
Для Каждого Параметр Из Параметры Цикл
ТаблицаСвойств = Неопределено;
Если Не ЗначениеЗаполнено(Параметр.ТипЗначения) Тогда
ЗначениеПараметра = Параметр.Значение;
Если ЗначенияПараметров <> Неопределено И ЗначенияПараметров.Свойство(Параметр.Имя) Тогда
ЗначениеПараметра = ЗначенияПараметров[Параметр.Имя];
КонецЕсли;
СтруктураТипа = мПлатформа.СтруктураТипаИзЗначения(ЗначениеПараметра);
ИмяОбщегоТипа = мПлатформа.ИмяТипаИзСтруктурыТипа(СтруктураТипа);
ТаблицаЗначений = Неопределено;
Если Ложь
Или ТипЗнч(ЗначениеПараметра) = Тип("Структура")
Или ТипЗнч(ЗначениеПараметра) = Тип("ФиксированнаяСтруктура")
Тогда
ТаблицаСвойств = мПлатформа.ПолучитьТаблицуСловСтруктурыТипа(СтруктураТипа,,,,,, "Свойство");
ИначеЕсли Ложь
Или ТипЗнч(ЗначениеПараметра) = Тип("ТаблицаЗначений")
Или ТипЗнч(ЗначениеПараметра) = Тип("ДеревоЗначений")
Тогда
ТаблицаЗначений = ЗначениеПараметра;
ИначеЕсли Ложь
Или ТипЗнч(ЗначениеПараметра) = Тип("СтрокаТаблицыЗначений")
Или ТипЗнч(ЗначениеПараметра) = Тип("СтрокаДереваЗначений")
Тогда
ТаблицаЗначений = ЗначениеПараметра.Владелец();
КонецЕсли;
Если ТаблицаЗначений <> Неопределено Тогда
СтруктураТипа = мПлатформа.СтруктураТипаИзЗначения(ТаблицаЗначений);
ТаблицаСвойств = мПлатформа.ПолучитьТаблицуСловСтруктурыТипа(СтруктураТипа,,,,,, "Метод",, "Найти");
ТаблицаСвойств = мПлатформа.ПолучитьТаблицуСловСтруктурыТипа(ТаблицаСвойств[0].ТаблицаСтруктурТипов[0],,,,,, "Свойство");
КонецЕсли;
Параметр.ТипЗначения = ИмяОбщегоТипа;
КонецЕсли;
КомментарийМетода.Добавить(ПрефиксОписанияПараметра + Параметр.Имя + " - " + Параметр.ТипЗначения + " - " + Параметр.Комментарий);
Если ТаблицаСвойств <> Неопределено И ТаблицаСвойств.Количество() > 0 Тогда
КомментарийМетода[КомментарийМетода.ВГраница()] = КомментарийМетода[КомментарийМетода.ВГраница()] + ":";
Для Каждого Свойство Из ТаблицаСвойств Цикл
ОбновитьТипЗначенияИзТаблицыСтруктурТипов(Свойство, Свойство.ТаблицаСтруктурТипов);
КомментарийМетода.Добавить(ПрефиксОписанияПараметра + " * " + Свойство.Слово + " - " + Свойство.ТипЗначения + " - " + Параметр.Комментарий);
КонецЦикла;
КонецЕсли;
КонецЦикла;
КомментарийМетода = ирОбщий.СтрСоединитьЛкс(КомментарийМетода, Символы.ПС) + Символы.ПС;
Если ЗначениеЗаполнено(КомментарийМетода) Тогда
КомментарийМетода = "//.
|// Параметры:" + Символы.ПС + КомментарийМетода;
КонецЕсли;
Если ЗначениеЗаполнено(ОписаниеМетода) Тогда
КомментарийМетода = Сред(ирОбщий.ДобавитьМногострочнуюСтрокуВТекстЛкс(, ОписаниеМетода, "// ", Истина), 2) + Символы.ПС + КомментарийМетода;
КонецЕсли;
Если СтрокаРезультата <> Неопределено Тогда
КомментарийМетода = КомментарийМетода + "// Возвращаемое значение:" + Символы.ПС + ПрефиксОписанияПараметра + СтрокаРезультата.ТипЗначения + " - " + СтрокаРезультата.Комментарий + Символы.ПС;
КонецЕсли;
Если Не ЗначениеЗаполнено(КомментарийМетода) Тогда
КомментарийМетода = "";
КонецЕсли;
Возврат КомментарийМетода;
КонецФункции
Функция УстановитьТекст(Знач Текст, Активировать = Ложь, НачальныйТекстДляСравнения = Неопределено, СохранитьГраницыВыделения = Ложь) Экспорт
ОчиститьИсториюПереходов();
ПолеТекста.УстановитьТекст(Текст, Активировать, НачальныйТекстДляСравнения, СохранитьГраницыВыделения);
КонецФункции
Процедура ОчиститьИсториюПереходов() Экспорт
мИсторияПереходов = Неопределено;
КонецПроцедуры
Процедура ЗапомнитьИсточникПерехода() Экспорт
Если мИсторияПереходов = Неопределено Тогда
мИсторияПереходов = Новый Массив;
КонецЕсли;
АдресУхода = ПолеТекста.ВыделениеДвумерное();
Если Истина
И мИсторияПереходов.Количество() > 0
И ирОбщий.СравнитьЗначенияСвойствЛкс(мИсторияПереходов[0], АдресУхода)
Тогда
Возврат;
КонецЕсли;
мИсторияПереходов.Вставить(0, АдресУхода);
КонецПроцедуры
Процедура ВернутьсяИзПерехода() Экспорт
Пока Истина Цикл
Если мИсторияПереходов = Неопределено Или мИсторияПереходов.Количество() = 0 Тогда
Возврат;
КонецЕсли;
АдресУхода = мИсторияПереходов[0];
Если ирОбщий.СравнитьЗначенияСвойствЛкс(ПолеТекста.ВыделениеДвумерное(), АдресУхода) Тогда
мИсторияПереходов.Удалить(0);
Иначе
Прервать;
КонецЕсли;
КонецЦикла;
ПолеТекста.УстановитьВыделениеДвумерное(АдресУхода);
мИсторияПереходов.Удалить(0);
КонецПроцедуры
//ирПортативный лФайл = Новый Файл(ИспользуемоеИмяФайла);
//ирПортативный ПолноеИмяФайлаБазовогоМодуля = Лев(лФайл.Путь, СтрДлина(лФайл.Путь) - СтрДлина("Модули\")) + "ирПортативный.epf";
//ирПортативный #Если Клиент Тогда
//ирПортативный Контейнер = Новый Структура();
//ирПортативный Оповестить("ирПолучитьБазовуюФорму", Контейнер);
//ирПортативный Если Не Контейнер.Свойство("ирПортативный", ирПортативный) Тогда
//ирПортативный ирПортативный = ВнешниеОбработки.ПолучитьФорму(ПолноеИмяФайлаБазовогоМодуля);
//ирПортативный ирПортативный.Открыть();
//ирПортативный КонецЕсли;
//ирПортативный #Иначе
//ирПортативный ирПортативный = ВнешниеОбработки.Создать(ПолноеИмяФайлаБазовогоМодуля, Ложь); // Это будет второй экземпляр объекта
//ирПортативный #КонецЕсли
//ирПортативный ирОбщий = ирПортативный.ОбщийМодульЛкс("ирОбщий");
//ирПортативный ирКэш = ирПортативный.ОбщийМодульЛкс("ирКэш");
//ирПортативный ирСервер = ирПортативный.ОбщийМодульЛкс("ирСервер");
//ирПортативный ирКлиент = ирПортативный.ОбщийМодульЛкс("ирКлиент");
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
#КонецЕсли
#Если Клиент Тогда
СлужебноеПолеТекста = мПлатформа.СлужебноеПолеТекста;
#КонецЕсли
ТаблицаЛокальногоКонтекста = Новый ТаблицаЗначений;
ТаблицаЛокальногоКонтекста.Колонки.Добавить("Слово");
ТаблицаЛокальногоКонтекста.Колонки.Добавить("нСлово");
ТаблицаЛокальногоКонтекста.Колонки.Добавить("Глобальное", Новый ОписаниеТипов("Булево"));
ТаблицаЛокальногоКонтекста.Колонки.Добавить("ТипСлова");
ТаблицаЛокальногоКонтекста.Колонки.Добавить("ТипЗначения");
ТаблицаЛокальногоКонтекста.Колонки.Добавить("Метаданные");
ТаблицаЛокальногоКонтекста.Колонки.Добавить("ТаблицаСтруктурТипов");
ТаблицаЛокальногоКонтекста.Колонки.Добавить("Значение");
ТаблицаЛокальногоКонтекста.Индексы.Добавить("Слово, ТипСлова");
ПравилаВычисленияФункций = Новый ТаблицаЗначений;
ПравилаВычисленияФункций.Колонки.Добавить("Слово");
ПравилаВычисленияФункций.Колонки.Добавить("нСлово");
ПравилаВычисленияФункций.Колонки.Добавить("ТипКонтекста");
ПравилаВычисленияФункций.Колонки.Добавить("Правило");
ПравилаВычисленияФункций.Индексы.Добавить("Слово, ТипКонтекста");
МассивЗащитыОтРекурсии = Новый Массив;
мРазбиратьКонтекст = Истина;
мРасширенноеПолучениеМетаданныхADO = Ложь;
//мДоступныеТаблицыПолучены = Ложь;
мАвтоКонтекстнаяПомощь = Ложь;
мИменаОбщихТиповПоИменамКлассовCOM = Новый Соответствие;
мСтруктурыТиповПодсказкиУдержания = Новый Структура;
мДоступныеПоляТаблиц = Новый Соответствие;
ШиринаТабуляции = 4;
МаксСловНаходитьВТекстеПрограммы = 1000;
РегВыражение = ирОбщий.НовыйВычислительРегВыражений();
РегВыражение.IgnoreCase = Истина;
РегВыражение.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)" + "(?:" + шРазделитель + "(?:" + шИмя + "))?" + шРазделитель + "*" + "(?:\(""(?:" + шИмя+ "(?:\." + шИмя + ")*)""\))?"
+ "|(?:(?:не|not)" + шРазделитель + "+)?(?:(?:(?:новый|New)" + шРазделитель + ")?" + шИмяСкобки + "?" + "(?:(?:\.(?:" + шИмя + ")" + шСкобки + "?)|" + шИндекс + ")*)|"
+ шЧисло + "|" + шСтрокаПрограммы + ")";
шВыражениеПрограммы = шРазделитель + "*" + шВыражениеПрограммы1 + "(?:" + шРазделитель + "*" + шОператорПрограммы + шРазделитель + "*"
+ шВыражениеПрограммы1 + ")*";
шНачалоВыраженияПрограммы = "(?:" + шРазделитель + "*(?:(?:"
+ шИмяСкобки + "?" + "(?:(?:\.(?:" + шИмя + ")" + шСкобки + "?)|" + шИндекс + ")*)|"
+ шЧисло + "|" + шСтрокаПрограммы + ")" + шРазделитель + "*" + шОператорПрограммы + ")*"
+ шРазделитель + "*(?:(?:" + шИмяСкобки + "?" + "(?:(?:\.(?:" + шИмя + ")" + шСкобки + "?)|" + шИндекс + ")*)|"
+ шНачалоЧисла + "|" + шНачалоСтрокиПрограммы + ")?";
шВызовМетодаПрограммы = "(?:" + шПредИмя + "(Новый|New)\s+)?(" + шИмяСкобки + "?" + "(?:(?:\.(?:" + шИмя + ")" + шСкобки + "?)|" + шИндекс + ")*?)"
+ "\(((?:(?:" + шВыражениеПрограммы + ")?" + шРазделитель + "*,)*)" + "(" + шНачалоВыраженияПрограммы + ")?" + шРазделитель + "*";
шПрисваивание = "(" + шРазделитель + "*=" + шРазделитель + "*((новый|New)" // Изменение для поддержки ProgID типа Forms.TextBox.1
+ "(?:" + шРазделитель + "+(" + шИмя + "))?" + шРазделитель + "*(?:\(""(" + шИмя+ "(?:\.[" + шБуква + "\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)" + шРазделитель + "+" + шИмяЗапроса;
шОписаниеТаблицыСЗахватом = "(" + шСкобки + "|" + шТаблицаЗапроса + "|&" + шИмя + ")" + шРазделитель + "+(?:КАК|AS)" + шРазделитель + "+(" + шИмяЗапроса + ")";
шВыражениеЗапроса =
"(?:" + шРазделитель + "*(?:" + шСкобки + "|(?:&|\?|@)" + шИмя + "|" + шЧисло + "|" + шСтрокаЗапроса + "|" + ШаблонВыбора
//+ "|" + шИмяСкобки + "?" + "(?:\." + шИмяСкобки + "?" + ")*)" + шРазделитель + "*" + шОператорЗапроса + ")*"
+ "|" + шИмяСкобки + "?" + "(?:\." + шИмяСкобки + "?" + ")*)" + шРазделитель + "*" + шОператорЗапроса + ")*?" // Сделал захват ленивым, чтобы избежать катастрофического шагания назад
+ шРазделитель + "*(?:" + шСкобки + "|(?:&|\?|@)" + шИмя + "|" + шЧисло + "|" + шСтрокаЗапроса + "|" + ШаблонВыбора
+ "|" + шИмяСкобки + "?" + "(?:\." + шИмяСкобки + "?" + ")*)";
шНачалоВыраженияЗапроса =
"(?:" + шРазделитель + "*(?:" + шСкобки + "|(?:&|\?|@)" + шИмя + "|" + шЧисло + "|" + шСтрокаЗапроса + "|" + ШаблонВыбора
+ "|" + шИмяЗапроса + шСкобки + "?" + "(?:\." + шИмяЗапроса + шСкобки + "?" + ")*)" + шРазделитель + "*" + шОператорЗапроса + ")*?" // Сделал захват ленивым, чтобы избежать катастрофического шагания назад
+ шРазделитель + "*(?:" + шСкобки + "|(?:&|\?|@)" + шИмя + "|" + шЧисло + "|" + шНачалоСтрокиЗапроса + "|" + ШаблонНачалаВыбора
+ "|" + шИмяЗапроса + шСкобки + "?" + "(?:\." + шИмяЗапроса + шСкобки + "?" + ")*)?";
шВызовМетодаЗапроса = "()?(" + шИмяЗапроса + шСкобки + "?" + "(?:(?:\.(?:" + шИмяЗапроса + ")" + шСкобки + "?)|" + шИндекс + ")*)"
+ "\(((?:(?:" + шВыражениеЗапроса + ")?" + шРазделитель + "*,)*)" + "(" + шНачалоВыраженияЗапроса + ")?" + шРазделитель + "*";
ШаблонОписанияПоля = шВыражениеЗапроса + шРазделитель + "+КАК" + шРазделитель + "+" + шИмяЗапроса;
ШаблонВЫБРАТЬ = "(?:ВЫБРАТЬ|SELECT)(" + шРазделитель + "+(?:РАЗРЕШЕННЫЕ|ALLOWED))?(" + ШаблонОписанияПоля + ",)*" + ШаблонОписанияПоля;
шИЗ = "(?:ИЗ|FROM)" + шРазделитель + "+" + шОписаниеТаблицы + "(" + ШаблонСоединения + шОписаниеТаблицы
+ шРазделитель + "+(?:ПО|ON)" + шРазделитель + "+" + шВыражениеЗапроса + "|" + шРазделитель + "*,"
+ шРазделитель + "*" + шОписаниеТаблицы + ")*";
шПоискОписанияТаблицы = "(" + ШаблонСоединения + ")?(" + шСкобки + "|" + шТаблицаЗапроса + "|&" + шИмя
+ ")" + шРазделитель + "+(?:КАК|AS)" + шРазделитель + "+" + "#Идентификатор#(" + шРазделитель
+ "+(?:ПО|ON)" + шРазделитель + "+" + шВыражениеЗапроса + "|" + шРазделитель + "|,|\)|$)";
// К нему привязаны имена методов-трансляторов событий
ИмяКласса = "ПолеТекстаПрограммы";
мМаркерСлужебногоКомментария = "{: ";
мМаркерПорядкаОтладки = "ПорядокОтладки ";
мЭтоАвтоВызов = Ложь;
СброситьРезультатРазбораПозицииВТексте();
мАнглийский1С = Метаданные.ВариантВстроенногоЯзыка = Метаданные.СвойстваОбъектов.ВариантВстроенногоЯзыка.Английский;