RDT1C/src/DataProcessors/ирПлатформа/Ext/ObjectModule.bsl
Администратор 8625cf5191 .
2025-09-29 21:23:34 +03:00

14986 lines
1.1 MiB
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.

//ирПортативный Перем ирПортативный Экспорт;
//ирПортативный Перем ирОбщий Экспорт;
//ирПортативный Перем ирСервер Экспорт;
//ирПортативный Перем ирКэш Экспорт;
//ирПортативный Перем ирКлиент Экспорт;
Перем ВерсияПлатформы Экспорт;
Перем ЭтоФайловаяБаза Экспорт;
Перем мМетаданные Экспорт;
Перем мПустойМодуль; // см. МодульМетаданных
Перем ЭтоИнтеграция Экспорт;
Перем СоответствиеВидовСравнения Экспорт;
Перем МаркерНачалаАлгоритма Экспорт;
Перем МаркерКонцаАлгоритма Экспорт;
Перем МакетыКомпонент Экспорт;
Перем мКэшПустыхЗначений Экспорт;
Перем ВложенностьИндикации Экспорт;
Перем КэшОбъектов Экспорт;
Перем ВремяОбъект Экспорт;
Перем мСловарьПеревода;
Перем АрхитектураПроцессора Экспорт;
Перем ВыполнятьАлгоритмыЧерезВнешниеОбработки Экспорт;
Перем ВнешняяОбработкаСервисы Экспорт;
Перем ФайловыйКэшАлгоритмовДопускаетРедактирование Экспорт;
Перем ФормаПустышка Экспорт;
Перем КешАлгоритмов;
Перем СубПутьКФайлуМодуляВнешнейОбработки;
Перем СубПутьКФайлуМодуляФормыВнешнейОбработки;
Перем СубПутьКФайлуМакетаВнешнейОбработки;
Перем СубПутьКФайлуЗаголовкаВнешнейОбработки;
Перем СубПутьККонтрольномуФайлуВнешнейОбработки;
Перем ПутьККаталогуСлужебныхВременныхФайлов;
Перем мЕстьАдминистративныеПраваУУчетнойЗаписиОС;
Перем СообщениеОНеобходимостиОбновитьКэшМодулейВыводилось;
Перем ПапкаКешаВнешнихОбработокАлгоритмов Экспорт;
Перем ПапкаВнешнихКомпонент Экспорт;
Перем ПапкаКэшаМодулей Экспорт;
Перем ПапкаКэшаРолей Экспорт;
Перем КаталогФайловогоКэша Экспорт;
Перем СтруктураПодкаталоговФайловогоКэша Экспорт;
Перем ИмяФайлаПакера Экспорт;
Перем ШаблоныВнешнейОбработки;
Перем ШаблоныВнешнейОбработкиСМакетом;
Перем ФайлРегистратораКомпонентCU;
Перем ФайлРегистратораNetКомпонент;
Перем МассивСравненияТекстов Экспорт;
Перем мВопросОтключенияПроверкиМодальностиЗадавался Экспорт;
Перем мПроверкаСовместимостиКонфигурацииВыполнялась Экспорт;
Перем мПроверкаЗащитыОтОпасныхДействийВыполнялась Экспорт;
Перем мПроверкаСоединенияADOЭтойБДВыполнялась Экспорт;
Перем мПерехватКлавиатуры;
Перем мНомерВерсииПлатформы;
Перем АсинхронностьЗапрещена Экспорт;
Перем РежимОтладки Экспорт; // Отключает использование однострочных сверток кода. Снижает скорость, но облегчает отладку.
Перем мДиалектыSQL Экспорт; // Используется в Обработка.ирКлсПолеёТекстаПрограммы
Перем ЛиРежимСовместимости83 Экспорт;
Перем WScriptShell;
Перем мРегВыражение Экспорт; // ОбработкаОбъект.ирОболочкаРегВыражение
Перем мРегВыражение2 Экспорт; // ОбработкаОбъект.ирОболочкаРегВыражение
Перем мНечеткоеСравнениеСлов;
Перем мТипыВыражений Экспорт;
Перем мФайлОтменыВычислений Экспорт; // Файл, Неопределено
Перем шЛюбой Экспорт;
Перем шБуква Экспорт;
Перем шБукваЦифра Экспорт;
Перем шИмя Экспорт;
Перем шЧисло Экспорт;
Перем шИндекс Экспорт;
Перем шСкобки Экспорт;
Перем шGUID Экспорт;
Перем шКомментарий Экспорт;
Перем шРазделитель Экспорт;
Перем шПустоеНачалоСтроки Экспорт;
Перем шЛитералПрограммы Экспорт;
Перем шЛитералПростой Экспорт;
Перем шЛитералВЗапросе Экспорт;
Перем шИмяВременнойТаблицы Экспорт;
Перем шГиперСсылка Экспорт;
Перем шИнструкцияПрепроцессора Экспорт;
Перем шМетодНачало Экспорт;
Перем шМетодКонец Экспорт;
Перем МаркерОбъектаМетаданных;
Перем МаркерКоллекцииМетаданных;
//#Если Клиент Или ВнешнееСоединение Тогда
Перем ИдентификаторПроцессаОС Экспорт;
Перем VBScript Экспорт;
Перем JavaScript Экспорт;
Перем ДеревоТипов Экспорт;
Перем ТаблицаКонтекстов Экспорт;
Перем ТаблицаОбщихТипов Экспорт;
Перем ТаблицаИменЭлементовКоллекций Экспорт;
Перем ТаблицаРасширенийТипов Экспорт;
Перем ТаблицаТиповМетаданных Экспорт;
Перем ТаблицаСокращенияИменТипов Экспорт;
Перем ТаблицаШаблоновКонтекстов Экспорт;
Перем ТаблицаТиповМетаОбъектов Экспорт;
Перем ТаблицаПараметров Экспорт;
Перем СлужебноеПолеТекста Экспорт;
Перем СлужебноеПолеТекста2 Экспорт;
//Перем СлужебноеПолеHtmlДокумента Экспорт;
Перем МассивОбычныхЭлементовУправления Экспорт;
Перем МассивУправляемыхЭлементовУправления Экспорт;
Перем мМассивТиповЭлементовОбычнойФормы Экспорт;
Перем мМассивТиповЭлементовУправляемойФормы Экспорт;
Перем ТаблицаСтатистикиВыбора Экспорт;
Перем ДатаПоследнегоСохраненияСтатистикиВыбора Экспорт;
Перем мМассивТиповСМетаданными Экспорт;
Перем мТаблицаТипов;
Перем мТаблицаСоответствияВидов;
Перем мТаблицаЗамеров Экспорт;
Перем мИндикаторы Экспорт;
Перем мИменаОсновныхКлассовБиблиотекCOM; // Кэш имен классов, например Exel - Application
Перем мОбразцыCOMОбъектов; // Для вычисления свойств
Перем мADOUtils; // см. ПолучитьADOUtils()
Перем мКэшСловГлобальногоКонтекста;
Перем мКолонкиБД Экспорт;
Перем мСтруктураХраненияБДСРазмерами Экспорт;
Перем мТаблицаРедактируемыхТипов;
Перем мОписаниеТипаМДТабличнаяЧасть;
Перем мОписаниеТипаМДВнешнийИсточникДанных;
Перем мДеревоОбъектовМД;
Перем мТаблицаВсехТаблицБД;
Перем мПоляТекстаПрограммы;
Перем мШаблоныДляАнализаВстроенногоЯзыка;
Перем мСлужебнаяФорма;
Перем COMНавигатор Экспорт; // см. ПолучитьCOMНавигатор()
Перем ТаблицаШаблоновТекста Экспорт;
Перем мКартинкиТипов;
Перем мМассивИсключенийИменКоллекций;
Перем мПассивныеФормы;
Перем мИменаТиповМетаданныхСМенеджерами;
Перем мКэшРазбораВыражений Экспорт;
Перем мПравилаВычисленияФункций Экспорт;
Перем мВсеИменаСобытийЭлементовФормы;
Перем мКэшИменТипов;
Перем ФайлЗапаковщика1С Экспорт;
Перем ФайлБиблиотекиЗапаковщика;
Перем ФайлОткрывателя1С Экспорт;
Перем ФайлФорматераЗапросовБД Экспорт;
Перем ФайлРаспаковщикаZIP Экспорт;
Перем СинтаксПомощник;
Перем Парсеры Экспорт;
Перем БуферыСравнения Экспорт;
Перем ПараметрыОбработчикаОжидания Экспорт;
Перем БазовыйФайлРедактораJSON;
Перем БазовыйФайлРедактораКода;
Перем мМаркерИмениЗапросаПакета Экспорт;
Перем мМаркерИмениЧастиОбъединения Экспорт;
Перем СинтаксическийКонтрольПередЗаписью Экспорт;
Перем ОтложенноеОткрытиеИсточникаОшибки Экспорт;
Перем АвторегистрацияComКомпонент Экспорт;
Перем ЛиКомпонентаFormsTextBoxДоступна;
Перем МодальныеГруппы Экспорт;
Перем мМодулиМетаданных;
Перем мПрямыеВызовыМетодов;
Перем мВызовыВсехСловПоМодулям;
Перем ОткрытыеФормыПодсистемы Экспорт;
Перем ОтслеживаемыеФормы Экспорт;
Перем ПерехватКлавиатурногоВводаВОбычномПриложении Экспорт;
Перем ОтмененныеФоновыеЗадания Экспорт;
Перем ВнутреннийБуферОбмена Экспорт;
Перем ПроверочноеСоединениеЭтойСУБД Экспорт;
Перем ИспользоватьЭмуляциюНажатияКлавиш Экспорт;
Перем ВыделениеРезультатовПоиска Экспорт;
Перем НеИспользоватьУправляемыеФормыИнструментов Экспорт;
Перем мСвязанныйКонфигуратор Экспорт;
Перем мДатаОбновленияКэшаМодулей;
Перем мДобавленныеОбщиеМодули;
Перем мРежимПроверкиМодуля Экспорт;
Перем мРежимПереходаКОпределению Экспорт;
Перем мОчередьСообщенийВнешнемуКлиенту Экспорт; // см. НоваяОчередьСообщенийВнешнемуКлиенту, Неопределено - для накопления важных сообщений в режиме Automation-сервера
Перем мТерминалыЯзыкаЗапросов;
Перем мПроизвольныйКод Экспорт; // Для адаптера
Перем ПеречТипСлова Экспорт; // см. ПеречТипСлова
Перем ПеречИсточникСлова Экспорт; // см. ПеречИсточникСлова
Перем мЭтотОбъектГотов;
Перем КлючСервисаНапарник Экспорт;
Перем КлючСервисаИИ Экспорт;
Перем МаксОжиданиеИИ Экспорт;
Перем МодельИИ Экспорт;
Перем СерверИИ Экспорт;
Перем ЛиЗапросыИИНаСервере Экспорт; // Булево
Перем ПредлагатьОчиститьМенеджерВременныхТаблицЧерезМинут Экспорт; // Структура
// Инициализирует, если необходимо, большие таблицы платформы.
// К ним относятся таблицы методов и свойств.
//
// Параметры:
// Нет.
//
Процедура ИнициацияОписанияМетодовИСвойств() Экспорт
Если ТаблицаКонтекстов <> Неопределено Тогда
Возврат;
КонецЕсли;
#Если Клиент Тогда
Состояние("Инициализация таблицы методов и свойств...");
#КонецЕсли
МассивТаблиц = ЗначениеИзСтрокиВнутр(ПолучитьМакет("ТаблицаМетодовИСвойств").ПолучитьТекст());
ТаблицаКонтекстов = МассивТаблиц.ТаблицаКонтекстов; // см. Обработка.ирПлатформа.Форма.ОписаниеПлатформы.ТаблицаКонтекстов
ТаблицаКонтекстов.Колонки.Добавить("Описание");
ТаблицаКонтекстов.Индексы.Добавить("ТипКонтекста");
ТаблицаКонтекстов.Индексы.Добавить("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка");
ТаблицаКонтекстов.Индексы.Добавить("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка, ТипСлова");
ТаблицаКонтекстов.Индексы.Добавить("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка, НСлово");
ТаблицаКонтекстов.Индексы.Добавить("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка, НСлово, ТипСлова");
ТаблицаШаблоновКонтекстов = МассивТаблиц.ТаблицаШаблоновКонтекстов; // см. Обработка.ирПлатформа.Форма.ОписаниеПлатформы.ТаблицаШаблоновКонтекстов
ТаблицаШаблоновКонтекстов.Колонки.Добавить("Описание"); // Нужно для вирт. таблицы КритерийОтбора.<Имя критерия отбора>()
ТаблицаШаблоновКонтекстов.Индексы.Добавить("ТипКонтекста");
ТаблицаШаблоновКонтекстов.Индексы.Добавить("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка");
ТаблицаШаблоновКонтекстов.Индексы.Добавить("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка, ТипСлова");
ТаблицаПараметров = МассивТаблиц.ТаблицаПараметров; // см. Обработка.ирПлатформа.Форма.ОписаниеПлатформы.ТаблицаПараметров
ТаблицаПараметров.Колонки.Добавить("Описание");
ТаблицаПараметров.Индексы.Добавить("ТипКонтекста, ЯзыкПрограммы, Слово");
//ТаблицаПараметров.Индексы.Добавить("ТипКонтекста, ЯзыкПрограммы, Слово, Номер");
#Если Клиент Тогда
Состояние("");
#КонецЕсли
//мПравилаВычисленияФункций = ирОбщий.НоваяТаблицаЗначенийЛкс("Слово, нСлово, ТипКонтекста, Правило"); // Долго
мПравилаВычисленияФункций = Новый ТаблицаЗначений;
мПравилаВычисленияФункций.Колонки.Добавить("Слово");
мПравилаВычисленияФункций.Колонки.Добавить("нСлово");
мПравилаВычисленияФункций.Колонки.Добавить("ТипКонтекста");
мПравилаВычисленияФункций.Колонки.Добавить("Правило");
мПравилаВычисленияФункций.Индексы.Добавить("Слово, ТипКонтекста");
ТаблицаСтатистикиВыбора = ирОбщий.ВосстановитьЗначениеЛкс("ирПлатформа.ТаблицаСтатистикиВыбора");
ИмяКолонкиХраненияВерсии = "ЯзыкПрограммы";
ВерсияСтатистики = "2";
Если ТаблицаСтатистикиВыбора <> Неопределено Тогда
Если Ложь
Или ТаблицаСтатистикиВыбора.Колонки.Найти(ИмяКолонкиХраненияВерсии) = Неопределено
Или ТаблицаСтатистикиВыбора.Колонки[ИмяКолонкиХраненияВерсии].Заголовок <> ВерсияСтатистики
Тогда
ТаблицаСтатистикиВыбора = Неопределено;
КонецЕсли;
КонецЕсли;
Если ТаблицаСтатистикиВыбора = Неопределено Тогда
ТаблицаСтатистикиВыбора = Новый ТаблицаЗначений;
ТаблицаСтатистикиВыбора.Колонки.Добавить("ТипКонтекста", Новый ОписаниеТипов("Строка"));
ТаблицаСтатистикиВыбора.Колонки.Добавить("Слово", Новый ОписаниеТипов("Строка"));
ТаблицаСтатистикиВыбора.Колонки.Добавить("ЯзыкПрограммы", Новый ОписаниеТипов("Число"));
ТаблицаСтатистикиВыбора.Колонки.Добавить("ЭтоМетод", Новый ОписаниеТипов("Булево"));
ТаблицаСтатистикиВыбора.Колонки.Добавить("Рейтинг", Новый ОписаниеТипов("Число"));
КонецЕсли;
ТаблицаСтатистикиВыбора.Колонки[ИмяКолонкиХраненияВерсии].Заголовок = ВерсияСтатистики;
Если ТаблицаСтатистикиВыбора.Индексы.Количество() > 2 Тогда
ТаблицаСтатистикиВыбора.Индексы.Очистить();
КонецЕсли;
ирОбщий.ДобавитьИндексВТаблицуЛкс(ТаблицаСтатистикиВыбора, "ТипКонтекста, ЯзыкПрограммы");
ирОбщий.ДобавитьИндексВТаблицуЛкс(ТаблицаСтатистикиВыбора, "ТипКонтекста, ЯзыкПрограммы, Слово, ЭтоМетод");
ДатаПоследнегоСохраненияСтатистикиВыбора = ТекущаяДата();
КонецПроцедуры
// Инициализирует, если необходимо, малые таблицы платформы.
// К ним относятся таблицы типов и коллекций.
//
// Параметры:
// Нет.
//
Процедура ИнициализацияОписанияОбщихТипов() Экспорт
Если ТипЗнч(ТаблицаОбщихТипов) = Тип("ТаблицаЗначений") Тогда
Возврат;
КонецЕсли;
МассивТаблиц = ЗначениеИзСтрокиВнутр(ПолучитьМакет("ТаблицаИменЭлементовКоллекций").ПолучитьТекст()); // Структура
ТаблицаИменЭлементовКоллекций = МассивТаблиц.ТаблицаИменЭлементовКоллекций; // см. Обработка.ирПлатформа.Форма.ОписаниеПлатформы.ТаблицаИменЭлементовКоллекций
ТаблицаИменЭлементовКоллекций.Индексы.Добавить("ИмяКоллекции");
ТаблицаИменЭлементовКоллекций.Индексы.Добавить("ИмяЭлементаКоллекции");
ТаблицаИменЭлементовКоллекций.Индексы.Добавить("ИмяОбщегоТипа, ИмяЭлементаКоллекции");
ТаблицаРасширенийТипов = МассивТаблиц.ТаблицаРасширений; // см. Обработка.ирПлатформа.Форма.ОписаниеПлатформы.ТаблицаРасширений
ТаблицаРасширенийТипов.Индексы.Добавить("Расширение");
ТаблицаРасширенийТипов.Индексы.Добавить("ОсновнойТип");
ТаблицаТиповМетаданных = МассивТаблиц.ТаблицаТиповМетаданных; // см. Обработка.ирПлатформа.Форма.ОписаниеПлатформы.ТаблицаТиповМетаданных
Если МассивТаблиц.Свойство("ТаблицаСокращенияИменТипов") Тогда
ТаблицаСокращенияИменТипов = МассивТаблиц.ТаблицаСокращенияИменТипов; // см. Обработка.ирПлатформа.Форма.ОписаниеПлатформы.ТаблицаСокращенияИменТипов
КонецЕсли;
МассивТаблиц = ЗначениеИзСтрокиВнутр(ПолучитьМакет("ТаблицаОбщихТипов").ПолучитьТекст());
ТаблицаОбщихТипов = МассивТаблиц.ТаблицаОбщихТипов; // см. Обработка.ирПлатформа.Форма.ОписаниеПлатформы.ТаблицаОбщихТипов
ТаблицаОбщихТипов.Колонки.Добавить("Описание");
ТаблицаОбщихТипов.Индексы.Добавить("Слово, ЯзыкПрограммы");
ТаблицаОбщихТипов.Индексы.Добавить("Слово, ТипТипа");
//ТаблицаОбщихТипов.Индексы.Добавить("Слово, ЯзыкПрограммы, ТипТипа");
ТаблицаОбщихТипов.Индексы.Добавить("НСлово, ЯзыкПрограммы, ЕстьКонструктор");
ТаблицаОбщихТипов.Индексы.Добавить("Представление, ТипТипа");
ТаблицаОбщихТипов.Индексы.Добавить("ИД");
ТаблицаОбщихТипов.Индексы.Добавить("БазовыйТип, ЯзыкПрограммы");
ПеречТипСлова();
ПеречИсточникСлова();
КонецПроцедуры
// Добавляет дополнительные Свойства для типов контекстов платформы.
Процедура ДобавитьСловоВОписаниеТипаКонтекста(ТипКонтекста, Слово, ТипСлова, ТипЗначения) Экспорт
ИнициацияОписанияМетодовИСвойств();
НоваяСтрока = ТаблицаКонтекстов.Добавить();
НоваяСтрока.ТипКонтекста = ТипКонтекста;
НоваяСтрока.Слово = Слово;
НоваяСтрока.НСлово = НРег(Слово);
НоваяСтрока.ТипСлова = ТипСлова;
НоваяСтрока.ТипЗначения = ТипЗначения;
КонецПроцедуры
// Добавляет в список значений коллекцию объектов метаданных.
//
// Параметры:
// пСписокМетаданных - СписокЗначений - куда добавляем объекты;
// пИмяМетаданных - Строка - имя коллекции объектов метаданных или имя корневого типа;
// *ЛиПолноеИмя - Булево, *Истина - добавлять полные имена, иначе краткие;
// *ЛиДобавлятьКартинки - Булево, *Истина - добавлять картинки;
// *ОтборПоПраву - Строка, *Неопределено - проверять перед добавлением право текущего пользователя.
//
Процедура ДобавитьВСписокКоллекциюМетаданных(пСписокМетаданных, пИмяМетаданных, ЛиПолноеИмя = Истина, ЛиДобавлятьКартинки = Истина, ОтборПоПраву = Неопределено) Экспорт
Картинка = Неопределено;
СтрокаКорневогоТипа = ОписаниеТипаМетаОбъектов(пИмяМетаданных, , 0);
Если СтрокаКорневогоТипа <> Неопределено Тогда
ИмяКоллекцииМетаданных = СтрокаКорневогоТипа.Множественное;
#Если Клиент Тогда
Если ЛиДобавлятьКартинки Тогда
КорневойТип = пИмяМетаданных;
Картинка = ирКлиент.КартинкаКорневогоТипаМДЛкс(КорневойТип);
КонецЕсли;
#КонецЕсли
Иначе
ИмяКоллекцииМетаданных = пИмяМетаданных;
#Если Клиент Тогда
Если ЛиДобавлятьКартинки Тогда
КорневойТип = ОписаниеТипаМетаОбъектов(, пИмяМетаданных, 0).Единственное;
Картинка = ирКлиент.КартинкаКорневогоТипаМДЛкс(КорневойТип);
КонецЕсли;
#КонецЕсли
КонецЕсли;
Для Каждого Объект ИЗ мМетаданные[ИмяКоллекцииМетаданных] Цикл
Если Истина
И ОтборПоПраву <> Неопределено
И Не ПравоДоступа(ОтборПоПраву, Объект)
Тогда
Продолжить;
КонецЕсли;
Если ЛиПолноеИмя Тогда
ИмяМетаОбъекта = Объект.ПолноеИмя();
Иначе
ИмяМетаОбъекта = Объект.Имя;
КонецЕсли;
пСписокМетаданных.Добавить(ИмяМетаОбъекта, Объект.Представление(), , Картинка);
КонецЦикла;
КонецПроцедуры
// Получает список ключевых слов языка запросов.
//
// Параметры:
// *Расширение - Тип, *Неопределено - для определения расширения языка запросов.
//
// Возвращаемое значение:
// СписокЗначений - где значение содержит слово.
//
Функция КлючевыеСловаЯзыкаЗапросов(Знач РежимКомпоновкиДанных = Ложь, Знач Русские = Истина, Знач Английские = Ложь) Экспорт
Список = Новый СписокЗначений;
Если Русские Тогда
Список.Добавить("АВТОУПОРЯДОЧИВАНИЕ");
Список.Добавить("ВНУТРЕННЕЕ");
Список.Добавить("ВОЗР");
Список.Добавить("ВСЕ");
Список.Добавить("ВЫБРАТЬ");
Список.Добавить("ДОБАВИТЬ");
Список.Добавить("ГДЕ");
Список.Добавить("ДЛЯ");
Список.Добавить("ИЗ");
Список.Добавить("ИЗМЕНЕНИЯ");
Список.Добавить("ИМЕЮЩИЕ");
Список.Добавить("ИНДЕКСИРОВАТЬ");
Список.Добавить("ИТОГИ");
Список.Добавить("КАК");
Список.Добавить("ЛЕВОЕ");
Список.Добавить("НАБОРАМ");
Список.Добавить("ОБЩИЕ");
Список.Добавить("ОБЪЕДИНИТЬ");
Список.Добавить("ПЕРВЫЕ");
Список.Добавить("ПО");
Список.Добавить("ПОЛНОЕ");
Список.Добавить("ПОМЕСТИТЬ");
Список.Добавить("ПРАВОЕ");
Список.Добавить("РАЗЛИЧНЫЕ");
Список.Добавить("РАЗРЕШЕННЫЕ");
Список.Добавить("СГРУППИРОВАТЬ");
Список.Добавить("СОЕДИНЕНИЕ");
Список.Добавить("УБЫВ");
Список.Добавить("УНИКАЛЬНО");
Список.Добавить("УНИЧТОЖИТЬ");
Список.Добавить("УПОРЯДОЧИТЬ");
Список.Добавить("НЕ");
Список.Добавить("И");
Список.Добавить("ИЛИ");
Список.Добавить("ВЫБОР");
Список.Добавить("КОГДА");
Список.Добавить("ТОГДА");
Список.Добавить("ИНАЧЕ");
Список.Добавить("КОНЕЦ");
Список.Добавить("ЕСТЬ");
Список.Добавить("NULL");
Список.Добавить("МЕЖДУ");
Список.Добавить("В");
Список.Добавить("ПОДОБНО");
Список.Добавить("СПЕЦСИМВОЛ");
Список.Добавить("ИЕРАРХИЯ");
Список.Добавить("ИЕРАРХИИ");
Список.Добавить("ССЫЛКА");
Если РежимКомпоновкиДанных Тогда
// Видимо это устаревшие слова
Список.Добавить("ЗНАЧЕНИЕ");
Список.Добавить("ЗНАЧЕНИЯ");
Список.Добавить("ИДЕНТИФИКАТОР");
Список.Добавить("ИМЯ");
Список.Добавить("ОБЪЕКТ");
Список.Добавить("СПИСОК");
Список.Добавить("ТИПЗНАЧЕНИЯ");
Список.Добавить("ХАРАКТЕРИСТИКА");
// Это новые слова
Список.Добавить("ЗНАЧЕНИЯХАРАКТЕРИСТИК");
Список.Добавить("ПОЛЕИМЕНИ");
Список.Добавить("ПОЛЕКЛЮЧА");
Список.Добавить("ПОЛЕЗНАЧЕНИЯ");
Список.Добавить("ПОЛЕВИДА");
Список.Добавить("ПОЛЕТИПАЗНАЧЕНИЯ");
Список.Добавить("ПОЛЕОБЪЕКТА");
Список.Добавить("ВИДЫХАРАКТЕРИСТИК");
КонецЕсли;
КонецЕсли;
Если Английские Тогда
Список.Добавить("AUTOORDER");
Список.Добавить("INNER");
Список.Добавить("ASC");
Список.Добавить("ALL");
Список.Добавить("SELECT");
Список.Добавить("WHERE");
Список.Добавить("FOR");
Список.Добавить("FROM");
Список.Добавить("UPDATE");
Список.Добавить("HAVING");
Список.Добавить("INDEX");
Список.Добавить("TOTALS");
Список.Добавить("AS");
Список.Добавить("LEFT");
Список.Добавить("SETS");
//Список.Добавить("ОБЩИЕ"); // ЗАБЫЛ перевод
Список.Добавить("UNION");
Список.Добавить("FIRST");
Список.Добавить("BY");
Список.Добавить("ON");
Список.Добавить("FULL");
Список.Добавить("INTO");
Список.Добавить("RIGHT");
Список.Добавить("DISTINCT");
Список.Добавить("ALLOWED");
Список.Добавить("GROUP");
Список.Добавить("JOIN");
Список.Добавить("DESC");
Список.Добавить("UNIQUE");
Список.Добавить("DROP");
Список.Добавить("ORDER");
Список.Добавить("NOT");
Список.Добавить("AND");
Список.Добавить("OR");
Список.Добавить("CASE");
Список.Добавить("WHEN");
Список.Добавить("THEN");
Список.Добавить("ELSE");
Список.Добавить("END");
Список.Добавить("IS");
Список.Добавить("NULL");
Список.Добавить("BETWEEN");
Список.Добавить("IN");
Список.Добавить("LIKE");
Список.Добавить("СПЕЦСИМВОЛ");
Список.Добавить("HIERARCHY");
Список.Добавить("REFS");
//Если РежимКомпоновкиДанных Тогда
// // Видимо это устаревшие слова
// Список.Добавить("VALUE");
// Список.Добавить("VALUES");
// Список.Добавить("IDENTIFICATOR");
// Список.Добавить("NAME");
// Список.Добавить("OBJECT");
// Список.Добавить("LIST");
// Список.Добавить("VALUETYPE");
// Список.Добавить("CHARACTERISTIC");
// // Это новые слова
// Список.Добавить("ЗНАЧЕНИЯХАРАКТЕРИСТИК");
// Список.Добавить("ПОЛЕИМЕНИ");
// Список.Добавить("ПОЛЕКЛЮЧА");
// Список.Добавить("ПОЛЕЗНАЧЕНИЯ");
// Список.Добавить("ПОЛЕВИДА");
// Список.Добавить("ПОЛЕТИПАЗНАЧЕНИЯ");
// Список.Добавить("ПОЛЕОБЪЕКТА");
// Список.Добавить("ВИДЫХАРАКТЕРИСТИК");
//КонецЕсли;
КонецЕсли;
Возврат Список;
КонецФункции
// Получает список ключевых встроенного языка.
//
// Параметры:
// Нет.
//
// Возвращаемое значение:
// СписокЗначений - где значение содержит слово.
//
Функция КлючевыеСловаВстроенногоЯзыка(Знач Русские = Истина, Знач Английские = Ложь) Экспорт
Список = Новый СписокЗначений;
Если Русские Тогда
Список.Добавить("Знач");
Список.Добавить("Процедура");
Список.Добавить("Функция");
Список.Добавить("Экспорт");
Список.Добавить("Возврат");
Список.Добавить("ВызватьИсключение");
Список.Добавить("Выполнить");
Список.Добавить("Для");
Список.Добавить("Если");
Список.Добавить("И");
Список.Добавить("Из");
Список.Добавить("Или");
Список.Добавить("Иначе");
Список.Добавить("ИначеЕсли");
Список.Добавить("Исключение");
Список.Добавить("Каждого");
Список.Добавить("КонецЕсли");
Список.Добавить("КонецПопытки");
Список.Добавить("КонецПроцедуры");
Список.Добавить("КонецФункции");
Список.Добавить("КонецЦикла");
Список.Добавить("Не");
Список.Добавить("Новый");
Список.Добавить("Перейти");
Список.Добавить("Перем");
Список.Добавить("По");
Список.Добавить("Пока");
Список.Добавить("Попытка");
Список.Добавить("Прервать");
Список.Добавить("Продолжить");
Список.Добавить("Тогда");
Список.Добавить("Цикл");
Список.Добавить("ДобавитьОбработчик");
Список.Добавить("УдалитьОбработчик");
// 8.3
Список.Добавить("Ждать");
Список.Добавить("Асинх");
КонецЕсли;
Если Английские Тогда
Список.Добавить("Val");
Список.Добавить("Procedure");
Список.Добавить("Function");
Список.Добавить("Export");
Список.Добавить("Return");
Список.Добавить("Raise");
Список.Добавить("Execute");
Список.Добавить("For");
Список.Добавить("If");
Список.Добавить("And");
Список.Добавить("In"); // аналог В (запрос) и ИЗ (встроенный)
Список.Добавить("Or");
Список.Добавить("Else");
Список.Добавить("ElsIf");
Список.Добавить("Except");
Список.Добавить("Each");
Список.Добавить("EndIf");
Список.Добавить("EndTry");
Список.Добавить("EndProcedure");
Список.Добавить("EndFunction");
Список.Добавить("EndDo");
Список.Добавить("Not");
Список.Добавить("New");
Список.Добавить("Goto");
Список.Добавить("Var");
Список.Добавить("To");
Список.Добавить("While");
Список.Добавить("Try");
Список.Добавить("Break");
Список.Добавить("Continue");
Список.Добавить("Then");
Список.Добавить("Do");
Список.Добавить("AddHandler");
Список.Добавить("RemoveHandler");
// 8.3
Список.Добавить("Await");
Список.Добавить("Async");
КонецЕсли;
Возврат Список;
КонецФункции
Функция ЛитералыЗначенияВсехЯзыков1С() Экспорт
Список = Новый СписокЗначений;
Список.Добавить("Истина", "Истина");
Список.Добавить("True", "Истина");
Список.Добавить("Ложь", "Ложь");
Список.Добавить("False", "Ложь");
Список.Добавить("Неопределено", "Неопределено");
Список.Добавить("Undefined", "Неопределено");
Список.Добавить("Null", "Null");
Возврат Список;
КонецФункции
// Размаскирует обращения к временным таблицам в тексте запроса.
//
// Параметры:
// ТекстЗапроса - Строка;
// МассивВременныхТаблиц - Массив - элементами являются имена временных таблиц, замаскированных ранее.
//
// Возвращаемое значение:
// Строка - новые текст запроса.
//
Функция РазмаскироватьВременныеТаблицы(ТекстЗапроса, МассивВременныхТаблиц, выхВсеРазмаскировано = Ложь) Экспорт
Если МассивВременныхТаблиц.Количество() = 0 Тогда
Возврат ТекстЗапроса;
КонецЕсли;
// Допустимы 2 уровня скобок внутри имитатора временной таблицы.
мРегВыражение.Global = Истина;
мРегВыражение.MultiLine = Ложь;
мРегВыражение.IgnoreCase = Истина;
ИмяВременнойТаблицы = "";
Для Каждого ПодмененнаяВременнаяТаблица Из МассивВременныхТаблиц Цикл
ИмяВременнойТаблицы = ИмяВременнойТаблицы + "|" + ПодмененнаяВременнаяТаблица;
КонецЦикла;
ИмяВременнойТаблицы = Сред(ИмяВременнойТаблицы, 2);
НовыйТекстЗапроса = ТекстЗапроса;
// Сначала делаем красивые замены - подзапрос на имя временной таблицы
//мРегВыражение.Pattern = "\(ВЫБРАТЬ(?:" + шСкобки + "|[^$\(\)])*?""ВременнаяТаблица"" = ""(" + ИмяВременнойТаблицы + ")""\)";
мРегВыражение.Pattern = "\(ВЫБРАТЬ(?:[^\(\)]*(?:" + шСкобки + "[^\(\)]*)*)""ВременнаяТаблица"" = ""("
+ ИмяВременнойТаблицы + ")""\s*\)";
НовыйТекстЗапроса = мРегВыражение.Заменить(НовыйТекстЗапроса, "$2");
выхВсеРазмаскировано = Найти(НовыйТекстЗапроса, """ВременнаяТаблица"" = """) = 0;
Если Не выхВсеРазмаскировано Тогда
// А теперь делаем некрасивые замены - оставляем подзапросы но заменяем в них имена полей и временной таблицы
мРегВыражение.Pattern = "\(ВЫБРАТЬ(?:[^\(\)]*(?:" + шСкобки + "[^\(\)]*)*)""ВременнаяТаблица"" = ""("
+ ИмяВременнойТаблицы + ")""";
НовыйТекстЗапроса = мРегВыражение.Заменить(НовыйТекстЗапроса, "(ВЫБРАТЬ Т.* ИЗ $2 КАК Т ГДЕ ИСТИНА");
// и0ие90цаун787
мРегВыражение.Pattern = "ВЫБОР\s+КОГДА\s+""!ИмяПоля!""\s+=\s+""(.+?)""\s+ТОГДА\s+.+?\n\s*(?:КОГДА\s+ЛОЖЬ\s+ТОГДА\s+.+?\n)*\s*КОНЕЦ";
НовыйТекстЗапроса = мРегВыражение.Заменить(НовыйТекстЗапроса, "Т.$1");
выхВсеРазмаскировано = Найти(НовыйТекстЗапроса, """ВременнаяТаблица"" = """) = 0;
КонецЕсли;
Если Не выхВсеРазмаскировано Тогда
ВызватьИсключение "Не удалось размаскировать временные таблицы в тексте запроса. Возможно на них был наложен несовместимый с маскировкой отбор компоновки.";
КонецЕсли;
Возврат НовыйТекстЗапроса;
КонецФункции // РазмаскироватьВременныеТаблицы()
// Получает текст запроса, где каждая временная таблица заменена своим имитатором.
//
// Параметры:
// ОбъектЗапроса - Запрос -
// *ТекстЗапроса - Строка, *Неопределено -
// *МассивВременныхТаблиц - Массив, *Неопределено - все подменяемые таблицы заносятся сюда.
//
// Возвращаемое значение:
// Строка - новый текст запроса.
//
Функция ЗамаскироватьВременныеТаблицы(ОбъектЗапроса, Знач ТекстЗапроса = Неопределено, МассивВременныхТаблиц = Неопределено) Экспорт
Если ТекстЗапроса = Неопределено Тогда
ТекстЗапроса = ОбъектЗапроса.Текст;
КонецЕсли;
ВременныйЗапрос = Новый Запрос;
ВременныйЗапрос.МенеджерВременныхТаблиц = ОбъектЗапроса.МенеджерВременныхТаблиц;
ПроверочныйЗапрос = Новый ПостроительЗапроса;
Если ТипЗнч(МассивВременныхТаблиц) <> Тип("Массив") Тогда
МассивВременныхТаблиц = Новый Массив;
КонецЕсли;
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.УстановитьТекст(ТекстЗапроса);
Пока Истина Цикл
Попытка
ПроверочныйЗапрос.Текст = ТекстЗапроса;
Прервать;
Исключение
ИнформацияОбОшибке = ИнформацияОбОшибке();
//ИмяВременнойТаблицы = ирОбщий.ТекстМеждуМаркерамиЛкс(ИнформацияОбОшибке.Причина.Описание, """", """");
ИмяВременнойТаблицы = ирОбщий.ТекстМеждуМаркерамиЛкс(ИнформацияОбОшибке.Причина.Описание, "Таблица не найдена """, """", Ложь);
Если ЗначениеЗаполнено(ИмяВременнойТаблицы) Тогда
ВременныйЗапрос.Текст = "ВЫБРАТЬ * ИЗ " + ИмяВременнойТаблицы;
Попытка
КолонкиВременнойТаблицы = ВременныйЗапрос.Выполнить().Колонки;
Исключение
Прервать;
КонецПопытки;
КонецЕсли;
// В 8.2.15 такой прием лишен смысла, т.к. движок запросов потом не сможет обработать обращения к дочерним полям
//Если Не ЗначениеЗаполнено(ИмяВременнойТаблицы) Тогда
// ИмяВременнойТаблицы = ирОбщий.ТекстМеждуМаркерамиЛкс(ИнформацияОбОшибке.Причина.Описание, "Неверные параметры """, """", Ложь);
// Если ЗначениеЗаполнено(ИмяВременнойТаблицы) Тогда
// Попытка
// КолонкиВременнойТаблицы = ОбъектЗапроса.Параметры[ИмяВременнойТаблицы].Колонки;
// Исключение
// Попытка
// КолонкиВременнойТаблицы = ВременныйЗапрос.Выполнить().Колонки;
// Исключение
// Прервать;
// КонецПопытки;
// КонецПопытки;
// ИмяВременнойТаблицы = "&" + ИмяВременнойТаблицы;
// КонецЕсли;
//КонецЕсли;
Если Не ЗначениеЗаполнено(ИмяВременнойТаблицы) Тогда
Прервать;
КонецЕсли;
ИмитаторВременнойТаблицы = ирОбщий.ЗапросИмитаторКоллекцииПолейЛкс(КолонкиВременнойТаблицы)
+ " ГДЕ ""ВременнаяТаблица"" = """ + ИмяВременнойТаблицы + """";
КоординатыОбращения = ирОбщий.ТекстМеждуМаркерамиЛкс(ИнформацияОбОшибке.Причина.Описание, "{(", ")}");
НомерСтроки = Число(ирОбщий.ПервыйФрагментЛкс(КоординатыОбращения, ", "));
НомерКолонки = Число(ирОбщий.ПоследнийФрагментЛкс(КоординатыОбращения, ","));
СтрокаЗапроса = ТекстовыйДокумент.ПолучитьСтроку(НомерСтроки);
ТекстПосле = Сред(СтрокаЗапроса, НомерКолонки + СтрДлина(ИмяВременнойТаблицы));
СтрокаКАК = "КАК";
Если Не ирОбщий.СтрокиРавныЛкс(Лев(СокрЛ(ТекстПосле), СтрДлина(СтрокаКАК)), СтрокаКАК) Тогда
ТекстПосле = " КАК " + ИмяВременнойТаблицы + " " + ТекстПосле;
КонецЕсли;
НоваяСтрока = Лев(СтрокаЗапроса, НомерКолонки - 1) + "(" + ИмитаторВременнойТаблицы + ")" + ТекстПосле;
ТекстовыйДокумент.ЗаменитьСтроку(НомерСтроки, НоваяСтрока);
ТекстЗапроса = ТекстовыйДокумент.ПолучитьТекст();
МассивВременныхТаблиц.Добавить(ИмяВременнойТаблицы);
КонецПопытки;
КонецЦикла;
Возврат ТекстЗапроса;
КонецФункции
// Результат - Массив
Функция НайтиВозможныеИменаВременныхТаблиц(ТекстЗапроса, ЛиДиалект1С = Истина) Экспорт
Имена = Новый Соответствие;
мРегВыражение.Global = Истина;
мРегВыражение.pattern = "(?:ИЗ|FROM|СОЕДИНЕНИЕ|JOIN|УНИЧТОЖИТЬ|DROP|,)\s+(" + шИмяВременнойТаблицы + ")(?:\s|$|[^\(\._\d" + шБуква + "])";
РезультатПоиска = мРегВыражение.НайтиВхождения(ТекстЗапроса);
Для Каждого Вхождение Из РезультатПоиска Цикл
Имена.Вставить(Нрег(Вхождение.SubMatches(0)), Вхождение.SubMatches(0));
КонецЦикла;
Результат = Новый Массив();
Для Каждого КлючИЗначение Из Имена Цикл
Если Истина
И ЛиДиалект1С
И (Ложь
Или ирОбщий.СтрокиРавныЛкс(КлючИЗначение.Значение, "Константы")
Или Найти(КлючИЗначение.Значение, ".") > 0)
Тогда
Продолжить;
КонецЕсли;
Результат.Добавить(КлючИЗначение.Значение);
КонецЦикла;
Возврат Результат;
КонецФункции
Функция РазбитьГрубоТекстПакетногоЗапросаНаЗапросы(Знач ТекстПакета, Знач ПозицияКурсора = Неопределено, выхПозиции0 = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
мРегВыражение = Обработки.ирОболочкаРегВыражение.Создать();
#КонецЕсли
МассивТекстовЗапросов = Новый Массив;
Если Не ирКэш.ДоступноРегВыраженияЛкс() Тогда
Если ирКэш.ДоступноСхемаЗапросаЛкс() Тогда
Схема = Вычислить("Новый СхемаЗапроса");
#Если Сервер И Не Сервер Тогда
Схема = Новый СхемаЗапроса;
#КонецЕсли
Попытка
Схема.УстановитьТекстЗапроса(ТекстПакета);
Исключение
ОписаниеОшибки = ОписаниеОшибки(); // Для отладки
Возврат МассивТекстовЗапросов;
КонецПопытки;
Для Каждого ЗапросПакета Из Схема.ПакетЗапросов Цикл
МассивТекстовЗапросов.Добавить(ЗапросПакета.ПолучитьТекстЗапроса());
КонецЦикла;
КонецЕсли;
Возврат МассивТекстовЗапросов;
КонецЕсли;
мРегВыражение.Global = Истина;
мРегВыражение.Multiline = Ложь;
//мРегВыражение.Pattern = "(?:" + шЛитералВЗапросе + ")|" + шКомментарий + "|;(?:\s*\n)*|$";
мРегВыражение.Pattern = "[^^](?:" + шЛитералВЗапросе + ")|" + шКомментарий + "|;|$";
Результат = мРегВыражение.НайтиВхождения(ТекстПакета,, Истина);
НачалоЗапроса = 1;
ОстальнойТекст = ТекстПакета;
ДлинаТекстаПакета = СтрДлина(ТекстПакета);
выхПозиции0 = Новый Массив;
выхПозиции0.Добавить(0);
Для Каждого Match Из Результат Цикл
ПозицияВхождения = Match.FirstIndex;
Если Истина
И Не ирОбщий.СтрНачинаетсяСЛкс(Match.Value, ";")
И ПозицияВхождения <> ДлинаТекстаПакета
Тогда
Продолжить;
КонецЕсли;
ДлинаТекстаЗапроса = ПозицияВхождения + Match.Length;
ТекстЗапроса = Сред(ТекстПакета, НачалоЗапроса, ДлинаТекстаЗапроса - НачалоЗапроса + 1);
Если ПустаяСтрока(ТекстЗапроса) Тогда
Продолжить;
КонецЕсли;
//Если ТекстЗапроса = ";" Тогда
// Продолжить;
//КонецЕсли;
ОстальнойТекст = Сред(ОстальнойТекст, ДлинаТекстаЗапроса + 1);
НачалоЗапроса = НачалоЗапроса + СтрДлина(ТекстЗапроса);
МассивТекстовЗапросов.Добавить(ТекстЗапроса);
выхПозиции0.Добавить(ПозицияВхождения + 1);
Если ПозицияКурсора <> Неопределено И ПозицияКурсора < ПозицияВхождения Тогда
Прервать;
КонецЕсли;
КонецЦикла;
Если МассивТекстовЗапросов.Количество() = 0 Тогда
МассивТекстовЗапросов.Добавить(ТекстПакета);
Иначе
выхПозиции0.Удалить(выхПозиции0.ВГраница());
КонецЕсли;
Возврат МассивТекстовЗапросов;
КонецФункции
// Структура результата пакетного запроса на основе разметки в комментариях.
//
// Параметры:
// ТекстПакетаИлиМассивТекстовЗапросов - -
// ПрефиксКомментария - -
//
// Возвращаемое значение:
// -
//
Функция СтруктураРезультатаПакетногоЗапроса(Знач ТекстПакетаИлиМассивТекстовЗапросов, Знач ПрефиксКомментария = "//") Экспорт
Результат = Новый Структура;
Если Не ирКэш.ДоступноРегВыраженияЛкс() Тогда
Возврат Результат;
КонецЕсли;
Если ТипЗнч(ТекстПакетаИлиМассивТекстовЗапросов) = Тип("Строка") Тогда
МассивТекстовЗапросов = РазбитьГрубоТекстПакетногоЗапросаНаЗапросы(ТекстПакетаИлиМассивТекстовЗапросов);
Иначе
МассивТекстовЗапросов = ТекстПакетаИлиМассивТекстовЗапросов;
КонецЕсли;
мРегВыражение.Global = Ложь;
мРегВыражение.Multiline = Ложь;
мРегВыражение.Pattern = ирОбщий.ТекстДляРегВыраженияЛкс(ПрефиксКомментария + мМаркерИмениЗапросаПакета) + "(" + шИмя + ")(?: |\n|\r)";
Индекс = -1;
Для Каждого ТекстЗапроса Из МассивТекстовЗапросов Цикл
Индекс = Индекс + 1;
Вхождения = мРегВыражение.НайтиВхождения(ТекстЗапроса);
Если Вхождения.Количество() = 0 Тогда
Продолжить;
КонецЕсли;
ИмяЗапроса = Вхождения[0].SubMatches(0);
Если ирОбщий.ЛиИмяПеременнойЛкс(ИмяЗапроса) Тогда
Результат.Вставить(ИмяЗапроса, Индекс);
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
Функция ПреобразоватьЗапросВПодзапрос(Текст, ТекстВыбранныхПолей = "*", ПсевдонимВложенногоЗапроса = "ВложенныйЗапрос",
ОбрезатьНачинаяСУпорядочивания = Ложь, ЭтоРусскийЯзык = Истина, Знач Смещение = "") Экспорт
//ЭтоРусскийЯзык = ЭтоРусскийВариантТекстаЗапроса(ТекстЗапроса);
мРегВыражение.Pattern = "^(?:\s|(" + шКомментарий + "))*((?:ВЫБРАТЬ|SELECT)\s+((?:РАЗРЕШЕННЫЕ|ALLOWED)\s+)?)((?:(?:.|\r|\n)*\s((?:УПОРЯДОЧИТЬ|ORDER)\s+(?:ПО|BY)\s+" + шИмя
+ "(?:\s*,\s*" + шИмя + ")*(?:\s+(?:АВТОУПОРЯДОЧИВАНИЕ|AUTOORDER))?|(?:АВТОУПОРЯДОЧИВАНИЕ|AUTOORDER)))*)((?:.|\r|\n)*)$";
РезультатПоиска = мРегВыражение.НайтиВхождения(Текст)[0];
Если ЭтоРусскийЯзык Тогда
Результат = "ВЫБРАТЬ";
Иначе
Результат = "SELECT";
КонецЕсли;
Если РезультатПоиска.SubMatches(2) <> Неопределено Тогда
Если ЭтоРусскийЯзык Тогда
Результат = Результат + " РАЗРЕШЕННЫЕ";
Иначе
Результат = Результат + " ALLOWED";
КонецЕсли;
КонецЕсли;
Смещение = Смещение + Символы.Таб;
Если ЭтоРусскийЯзык Тогда
Результат = Результат + " " + ТекстВыбранныхПолей + " ИЗ (";
Иначе
Результат = Результат + " " + ТекстВыбранныхПолей + " FROM (";
КонецЕсли;
НачальныйКомментарий = РезультатПоиска.SubMatches(0);
Если ЗначениеЗаполнено(НачальныйКомментарий) Тогда
Результат = Результат + Символы.ПС + Смещение + НачальныйКомментарий;
Иначе
Результат = Результат + Символы.ПС;
КонецЕсли;
Если ЭтоРусскийЯзык Тогда
Результат = Результат + Смещение + "ВЫБРАТЬ ";
Иначе
Результат = Результат + Смещение + "SELECT ";
КонецЕсли;
ТекстДоПоследнегоУПОРЯДОЧИТЬ = РезультатПоиска.SubMatches(3);
Если ЗначениеЗаполнено(ТекстДоПоследнегоУПОРЯДОЧИТЬ) Тогда
ТекстДоПоследнегоУПОРЯДОЧИТЬ = ирОбщий.СтрокаБезКонцаЛкс(ТекстДоПоследнегоУПОРЯДОЧИТЬ, СтрДлина(РезультатПоиска.SubMatches(4)));
ирОбщий.ДобавитьМногострочнуюСтрокуВТекстЛкс(Результат, ТекстДоПоследнегоУПОРЯДОЧИТЬ, Смещение);
Иначе
ирОбщий.ДобавитьМногострочнуюСтрокуВТекстЛкс(Результат, РезультатПоиска.SubMatches(5), Смещение);
КонецЕсли;
Если ЭтоРусскийЯзык Тогда
Результат = Результат + ") КАК ";
Иначе
Результат = Результат + ") AS ";
КонецЕсли;
Результат = Результат + ПсевдонимВложенногоЗапроса;
Если Истина
//И ТекстДоПоследнегоУПОРЯДОЧИТЬ <> Неопределено
И Не ПустаяСтрока(ТекстДоПоследнегоУПОРЯДОЧИТЬ)
И Не ОбрезатьНачинаяСУпорядочивания
Тогда
Результат = Результат + Символы.ПС + РезультатПоиска.SubMatches(4) + РезультатПоиска.SubMatches(5);
КонецЕсли;
Возврат Результат;
КонецФункции // ПолучитьТекстЗапросаДоУпорядочивания()
Функция СоздаваемыеВременныеТаблицыПакетаЗапросов(Знач ТекстПакетаИлиМассивТекстовЗапросов, Знач ТолькоТребующиеУничтоженияНаВходе = Ложь, Знач ВместеСУничтожениями = Ложь,
Знач ВместеСДополнениями = Ложь, Знач БыстрыйАнализ = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
мРегВыражение2 = Обработки.ирОболочкаРегВыражение.Создать();
#КонецЕсли
СозданныеТаблицы = Новый СписокЗначений;
Если ТипЗнч(ТекстПакетаИлиМассивТекстовЗапросов) = Тип("Массив") Тогда
ТекстыЗапросовПакета = ТекстПакетаИлиМассивТекстовЗапросов;
Иначе
Если Не ирКэш.ДоступноРегВыраженияЛкс() Тогда
Если ирКэш.ДоступноСхемаЗапросаЛкс() Тогда
Схема = Вычислить("Новый СхемаЗапроса");
#Если Сервер И Не Сервер Тогда
Схема = Новый СхемаЗапроса;
#КонецЕсли
Попытка
Схема.УстановитьТекстЗапроса(ТекстПакетаИлиМассивТекстовЗапросов);
Исключение
ОписаниеОшибки = ОписаниеОшибки(); // Для отладки
Возврат СозданныеТаблицы;
КонецПопытки;
Для Каждого ЗапросПакета Из Схема.ПакетЗапросов Цикл
ИмяСоздаваемойТаблицы = Неопределено;
Если Истина
И ТипЗнч(ЗапросПакета) = Тип("ЗапросВыбораСхемыЗапроса")
И ЗначениеЗаполнено(ЗапросПакета.ТаблицаДляПомещения)
Тогда
ИмяСоздаваемойТаблицы = ЗапросПакета.ТаблицаДляПомещения;
КонецЕсли;
СозданныеТаблицы.Добавить(НРег(ИмяСоздаваемойТаблицы), ИмяСоздаваемойТаблицы);
КонецЦикла;
КонецЕсли;
Возврат СозданныеТаблицы;
КонецЕсли;
ТекстыЗапросовПакета = РазбитьГрубоТекстПакетногоЗапросаНаЗапросы(ТекстПакетаИлиМассивТекстовЗапросов);
КонецЕсли;
мРегВыражение2.Global = Истина;
// Ищем в каждом запросе пакета предложение ПОМЕСТИТЬ/УНИЧТОЖИТЬ
// Теперь мы работаем с возможно грязным текстом в виде литерала встроенного языка
ШаблонПОМЕСТИТЬИЗ = "(?:(?:" + шРазделитель + "|\|)(?:(ПОМЕСТИТЬ|INTO\s+TABLE|INTO|ДОБАВИТЬ|ADD)|(УНИЧТОЖИТЬ|DROP|DROP\s+TABLE))(?:" + шРазделитель + "|\|)"
+ "+(" + шИмяВременнойТаблицы + ")(" + шРазделитель + "|;|'|"")|\s)|" + шРазделитель;
Если Не БыстрыйАнализ Тогда
ШаблонПОМЕСТИТЬИЗ = ШаблонПОМЕСТИТЬИЗ + "|" + шЛитералВЗапросе;
КонецЕсли;
ШаблонПОМЕСТИТЬИЗ = ШаблонПОМЕСТИТЬИЗ + "|.+?";
мРегВыражение2.Pattern = ШаблонПОМЕСТИТЬИЗ;
СозданныеТаблицыНрег = Новый Массив;
СначалаУничтоженныеТаблицы = Новый Массив;
Для Каждого ТекстЗапроса Из ТекстыЗапросовПакета Цикл
ИмяСозданнойВременнойТаблицы = Неопределено;
СозданиеВременнойТаблицы = мРегВыражение2.Заменить(ТекстЗапроса, "$1");
ИмяВременнойТаблицы = мРегВыражение2.Заменить(ТекстЗапроса, "$3");
Если ирОбщий.СтрокиРавныЛкс(СозданиеВременнойТаблицы, "добавить") Тогда
Если ВместеСДополнениями И Не ТолькоТребующиеУничтоженияНаВходе Тогда
ИмяСозданнойВременнойТаблицы = "*" + ИмяВременнойТаблицы;
КонецЕсли;
ИначеЕсли ЗначениеЗаполнено(СозданиеВременнойТаблицы) Тогда
Если Ложь
Или Не ТолькоТребующиеУничтоженияНаВходе
Или СначалаУничтоженныеТаблицы.Найти(НРег(ИмяВременнойТаблицы)) = Неопределено
Тогда
ИмяСозданнойВременнойТаблицы = ИмяВременнойТаблицы;
Если ИмяСозданнойВременнойТаблицы <> Неопределено Тогда
СозданныеТаблицыНрег.Добавить(НРег(ИмяСозданнойВременнойТаблицы));
КонецЕсли;
КонецЕсли;
ИначеЕсли ЗначениеЗаполнено(ИмяВременнойТаблицы) Тогда
Если ВместеСУничтожениями Тогда
ИмяСозданнойВременнойТаблицы = "-" + ИмяВременнойТаблицы;
КонецЕсли;
ИмяВременнойТаблицы = НРег(ИмяВременнойТаблицы);
Если ТолькоТребующиеУничтоженияНаВходе Тогда
Если СозданныеТаблицыНрег.Найти(ИмяВременнойТаблицы) = Неопределено Тогда
СначалаУничтоженныеТаблицы.Добавить(ИмяВременнойТаблицы);
КонецЕсли;
КонецЕсли;
КонецЕсли;
СозданныеТаблицы.Добавить(НРег(ИмяСозданнойВременнойТаблицы), ИмяСозданнойВременнойТаблицы);
КонецЦикла;
Возврат СозданныеТаблицы;
КонецФункции
////////////////////////////////////////////////////////////////////////////////
// РАБОТА С ТИПАМИ
// Получает чистую внутреннюю таблицу предопределенных слов.
//
// Параметры:
// Нет.
//
// Возвращаемое значение:
// ТаблицаЗначений - с колонками "Слово", "ТипСлова", "ТаблицаТипов".
//
Функция НоваяТаблицаСлов() Экспорт
ВнутрТаблицаСлов = Новый ТаблицаЗначений;
ВнутрТаблицаСлов.Колонки.Добавить("Слово"); // Строка
ВнутрТаблицаСлов.Колонки.Добавить("ТипСлова"); // Строка: см. ПеречТипСлова
ВнутрТаблицаСлов.Колонки.Добавить("ТаблицаТипов"); // см. НоваяТаблицаТипов
ВнутрТаблицаСлов.Колонки.Добавить("ТипЗначения"); // Строка
ВнутрТаблицаСлов.Колонки.Добавить("ТипЗначенияИндекс"); // Строка
ВнутрТаблицаСлов.Колонки.Добавить("Определение"); // Строка: см. ПеречИсточникСлова
ВнутрТаблицаСлов.Колонки.Добавить("МожноУточнитьТип"); // Булево - используется только для частично рассчитанных
ВнутрТаблицаСлов.Индексы.Добавить("Слово, ТипСлова");
Возврат ВнутрТаблицаСлов;
КонецФункции
// Функция - Подобрать вариант синтаксиса метода
//
// Параметры:
// ТаблицаВариантов - - содержимое будет утеряно!
//
// Возвращаемое значение:
// строка - название варианта синтаксиса
//
Функция ПодобратьВариантСинтаксисаМетода(Знач ТаблицаВариантов, Знач КоличествоФактПараметровМетода = 0, Знач ТекущийВариант = "", Знач ТекущийВариантУстановленВручную = Ложь, выхНомер = 0) Экспорт
ТаблицаВариантов.Колонки.Добавить("Количество", Новый ОписаниеТипов("Число"));
ТаблицаВариантов.ЗаполнитьЗначения(1, "Количество");
ТаблицаВариантов.Свернуть("ВариантСинтаксиса", "Количество");
//ТаблицаВариантов.Сортировать("Количество"); // Если закомментировано, то ОткрытьФорму("") правильно показывает и ближе к поведению конфигуратора
НовыйТекущийВариант = "";
Если ТаблицаВариантов.Количество() > 0 Тогда
Для Каждого СтрокаВарианта Из ТаблицаВариантов Цикл
Если ТекущийВариантУстановленВручную И СтрокаВарианта.ВариантСинтаксиса = ТекущийВариант Тогда
НовыйТекущийВариант = ТекущийВариант;
выхНомер = ТаблицаВариантов.Индекс(СтрокаВарианта);
Прервать;
КонецЕсли;
Если СтрокаВарианта.Количество >= КоличествоФактПараметровМетода Тогда
НовыйТекущийВариант = СтрокаВарианта.ВариантСинтаксиса;
выхНомер = ТаблицаВариантов.Индекс(СтрокаВарианта);
Если Не ТекущийВариантУстановленВручную Тогда
Если СтрокаВарианта.ВариантСинтаксиса = ТекущийВариант Тогда
Прервать;
Иначе
Продолжить;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если СтрокаВарианта.Количество < КоличествоФактПараметровМетода Тогда
НовыйТекущийВариант = СтрокаВарианта.ВариантСинтаксиса;
выхНомер = ТаблицаВариантов.Индекс(СтрокаВарианта);
КонецЕсли;
КонецЕсли;
выхНомер = выхНомер + 1;
Возврат НовыйТекущийВариант;
КонецФункции
Функция СинтаксПомощник() Экспорт
Если СинтаксПомощник = Неопределено Тогда
СинтаксПомощник = ирОбщий.СоздатьОбъектПоИмениМетаданныхЛкс("Обработка.ирСинтаксПомощник");
КонецЕсли;
Возврат СинтаксПомощник;
КонецФункции
Функция ДоступныеЗначенияТипа(Знач ИмяТипаИлиТипЗначения) Экспорт
ИнициацияОписанияМетодовИСвойств();
Если ТипЗнч(ИмяТипаИлиТипЗначения) = Тип("Тип") Тогда
ИмяТипаИлиТипЗначения = ИмяОбщегоТипаИзТипа(ИмяТипаИлиТипЗначения);
КонецЕсли;
//Пустышка = Вычислить("Метаданные.СвойстваОбъектов." + ИмяТипаЗначения);
СтрокиЗначений = ТаблицаКонтекстов.НайтиСтроки(Новый Структура("ТипКонтекста, ТипСлова", "ПеречислениеМетаданных" + ИмяТипаИлиТипЗначения, "Свойство"));
Если СтрокиЗначений.Количество() = 0 Тогда
ИмяТипаПеречисления = ИмяТипаИлиТипЗначения;
Если Не ирОбщий.СтрНачинаетсяСЛкс(ИмяТипаИлиТипЗначения, "Перечисление") Тогда
ИмяТипаПеречисления = "Перечисление" + ИмяТипаПеречисления;
КонецЕсли;
СтрокиЗначений = ТаблицаКонтекстов.НайтиСтроки(Новый Структура("ТипКонтекста, ТипСлова", ИмяТипаПеречисления, "Свойство"));
КонецЕсли;
СтрокиЗначений = ТаблицаКонтекстов.Скопировать(СтрокиЗначений);
СписокЗначений = Новый СписокЗначений;
СписокЗначений.ЗагрузитьЗначения(СтрокиЗначений.ВыгрузитьКолонку("Слово"));
Возврат СписокЗначений;
КонецФункции
// Формирует построитель запроса по структуре типа.
//
// Параметры:
// СтруктураТипа - Структура - описатель типа.
//
// Возвращаемое значение:
// ПостроительЗапроса.
//
Функция ПостроительЗапросаПоСтруктуреТипа(Знач СтрокаОбщегоТипа, ВиртуальнаяТаблица = Неопределено)
МетаданныеРодителя = СтрокаОбщегоТипа.Метаданные;
Если ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") Тогда
ПолноеИмя = МетаданныеРодителя.ПолноеИмя();
Иначе
ПолноеИмя = ирОбщий.КорневойТипКонфигурацииЛкс(КэшОбъект(МетаданныеРодителя).ПолноеИмя);
КонецЕсли;
МассивФрагментов = ирОбщий.СтрРазделитьЛкс(ПолноеИмя);
КорневойТипРодителя = МассивФрагментов[0];
Если ОписаниеТипаМетаОбъектов(КорневойТипРодителя, , 0) <> Неопределено Тогда
Если Ложь
Или (Истина
И МассивФрагментов.Количество() = 2
И МассивФрагментов[0] <> "ВнешнийИсточникДанных")
Или (Истина
И МассивФрагментов.Количество() = 4
И (Ложь
Или МассивФрагментов[2] = "ТабличнаяЧасть"
Или МассивФрагментов[2] = "Перерасчет"))
Тогда
ПостроительЗапроса = Новый Структура("ДоступныеПоля", Новый Массив);
Если СтрокаОбщегоТипа.ИмяОбщегоТипа = "Константы.<Имя константы>" Тогда
ИмяТаблицы = "Константы." + МассивФрагментов[1];
Иначе
ИмяТаблицы = ирКэш.ИмяТаблицыИзМетаданныхЛкс(ПолноеИмя, Ложь, ВиртуальнаяТаблица = Неопределено);
КонецЕсли;
Если ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") Тогда
Если Ложь
Или ВиртуальнаяТаблица = Неопределено
Или Найти(ВиртуальнаяТаблица.Выражение, "(") = 0
Тогда
ТаблицаРезультата = ирКэш.ПоляТаблицыБДЛкс(ИмяТаблицы + ВиртуальнаяТаблица.Выражение);
ТаблицаРезультата = ТаблицаРезультата.Скопировать(, "Имя, ТипЗначения"); // Делаем копию, т.к. будем ее модифицировать
//Для Каждого СтрокаПоля Из ТаблицаРезультата Цикл
// Если Ложь
// Или Не ЗначениеЗаполнено(СтрокаПоля.Метаданные)
// Или (Истина
// И СтрокаПоля.ТипЗначения <> "Строка"
// И СтрокаПоля.ТипЗначения <> "ХранилищеЗначения")
// Тогда
// Продолжить;
// КонецЕсли;
// МетаРеквизит = Метаданные.НайтиПоПолномуИмени(СтрокаПоля.Метаданные); // ОбъектМетаданныхРеквизит
// Если МетаРеквизит.Тип.КвалификаторыСтроки.Длина > 0 Тогда
// Продолжить;
// КонецЕсли;
// ИмяВложенногоТипа = ирОбщий.ПервыйФрагментЛкс(ирОбщий.ПервыйФрагментЛкс(МетаРеквизит.Комментарий, " "));
// Попытка
// ТипВложенный = Тип(ИмяВложенногоТипа);
// Исключение
// Продолжить;
// КонецПопытки;
// СтрокаПоля.ТипЗначения = ТаблицаТиповИзОписанияТипов(МетаРеквизит.Тип);
// СтрокаПоля.ТипЗначения[0].Метаданные = ДобавитьВТаблицуТипов(, СтруктураТипаИзКонкретногоТипа(ТипВложенный));
//КонецЦикла;
//ТаблицаРезультата.Колонки.Удалить("Метаданные");
ПостроительЗапроса = Новый Структура("ДоступныеПоля", ТаблицаРезультата);
Иначе
Если СтрокаОбщегоТипа.ИмяОбщегоТипа = "Константы.<Имя константы>" Тогда
ОпределениеТаблицы = "ВЫБРАТЬ " + ИмяТаблицы;
Иначе
УникальноеИмяТаблицы = "______________________";
ОпределениеТаблицы = "ВЫБРАТЬ * ИЗ " + ИмяТаблицы ;
Если ВиртуальнаяТаблица <> Неопределено Тогда
ОпределениеТаблицы = ОпределениеТаблицы + ВиртуальнаяТаблица.Выражение;
КонецЕсли;
ОпределениеТаблицы = ОпределениеТаблицы + " КАК " + УникальноеИмяТаблицы;
КонецЕсли;
Попытка
//ПостроительЗапроса.Текст = ОпределениеТаблицы;
ТаблицаРезультата = ирОбщий.ПустаяТаблицаЗначенийИзТекстаЗапросаЛкс(ОпределениеТаблицы,,, Ложь);
Исключение
Успех = Ложь;
Если ВиртуальнаяТаблица <> Неопределено Тогда
ПозицияСкобки = Найти(ВиртуальнаяТаблица.Выражение, "(");
Если ПозицияСкобки > 0 Тогда
ОпределениеТаблицы = "ВЫБРАТЬ * ИЗ " + ИмяТаблицы ;
ОпределениеТаблицы = ОпределениеТаблицы + Лев(ВиртуальнаяТаблица.Выражение, ПозицияСкобки - 1);
ОпределениеТаблицы = ОпределениеТаблицы + " КАК " + УникальноеИмяТаблицы;
Попытка
//ПостроительЗапроса.Текст = ОпределениеТаблицы;
ТаблицаРезультата = ирОбщий.ПустаяТаблицаЗначенийИзТекстаЗапросаЛкс(ОпределениеТаблицы);
Успех = Истина;
Исключение
КонецПопытки;
КонецЕсли;
КонецЕсли;
Если Не Успех Тогда
ВызватьИсключение "ОшибкаВычисленияВиртуальнойТаблицы";
КонецЕсли;
КонецПопытки;
ТаблицаРезультата = ирОбщий.ТаблицаЗначенийВТаблицуПолейБДЛкс(ТаблицаРезультата);
ПостроительЗапроса = Новый Структура("ДоступныеПоля", ТаблицаРезультата);
КонецЕсли;
ТаблицаРезультата.Колонки.Добавить("НИмя");
ирОбщий.ОбновитьКопиюКолонкиВНижнемРегистреЛкс(ТаблицаРезультата);
ирОбщий.ДополнитьТаблицуПолейТаблицыБДВиртуальнымиПолямиЛкс(ПостроительЗапроса.ДоступныеПоля, ирОбщий.ОписаниеТаблицыБДЛкс(ИмяТаблицы));
Иначе
// Внешние метаданные
ПостроительЗапроса = Новый ПостроительЗапроса;
ЗапросРеквизитов = Новый Запрос("ВЫБРАТЬ Имя, ТипыСтрокой ИЗ Справочник.СвойстваМетаданных ГДЕ Владелец = &СсылкаМД");
ЗапросРеквизитов.УстановитьПараметр("СсылкаМД", МетаданныеРодителя);
ТаблицаРеквизитов = ЗапросРеквизитов.Выполнить().Выгрузить();
Для Каждого СтрокаРеквизита Из ТаблицаРеквизитов Цикл
ДоступноеПоле = ПостроительЗапроса.ДоступныеПоля.Добавить(СтрокаРеквизита.Имя, СтрокаРеквизита.Имя);
Для Каждого СтрокаТипа Из СтрокаРеквизита.Типы Цикл
МассивТипов = Новый Массив;
ОбъектМД = КэшОбъект(СтрокаТипа.Объект);
МассивТипов.Добавить(Тип(ОбъектМД.Наименование));
КонецЦикла;
ДоступноеПоле.ТипЗначения = Новый ОписаниеТипов(МассивТипов);
КонецЦикла;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат ПостроительЗапроса;
КонецФункции
// Получает массив общих типов, дополняя исходный тип расширениями.
//
// Параметры:
// СтруктураТипа - Структура.
//
// Возвращаемое значение:
//
Функция РазвернутаяТаблицаТиповИзСтруктурыТипа(Знач СтруктураТипа, Знач ЭтоЛокальныйКонтекст, Знач ДляФиксированныхСлов = Истина, Знач ДоступноКэширование = Ложь) Экспорт
МассивОбщихТипов = НоваяТаблицаДополнительныхТипов();
Если СтруктураТипа.ТипЯзыка <> "" Тогда
ЗаполнитьЗначенияСвойств(МассивОбщихТипов.Добавить(), СтруктураТипа);
Возврат МассивОбщихТипов;
КонецЕсли;
Если Ложь
Или (Истина
И ТипЗнч(СтруктураТипа.Метаданные) <> Тип("COMОбъект")
И (Ложь
Или СтруктураТипа.ИмяОбщегоТипа = "Локальный" // Для подстраховки
Или ЭтоЛокальныйКонтекст И СтруктураТипа.ИмяОбщегоТипа <> "Глобальный"))
Или СтруктураТипа.ИмяОбщегоТипа = "AutomationСервер"
Или СтруктураТипа.ИмяОбщегоТипа = "ВнешнееСоединение"
Тогда
// Должен идти первым в списке чтобы кэширование глобального контекста работало!
НоваяСтрока = МассивОбщихТипов.Добавить();
//ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа,, "ИмяОбщегоТипа, Метаданные");
НоваяСтрока.ИмяОбщегоТипа = "Глобальный";
КонецЕсли;
НоваяСтрока = МассивОбщихТипов.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа);
Если СтруктураТипа.ИмяОбщегоТипа = "УправляемаяФорма" Тогда
СтруктураТипа.ИмяОбщегоТипа = "ФормаКлиентскогоПриложения";
КонецЕсли;
Если Найти(СтруктураТипа.ИмяОбщегоТипа, "ТабличнаяЧасть.") > 0 Тогда
НоваяСтрока = МассивОбщихТипов.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа, "Метаданные");
НоваяСтрока.ИмяОбщегоТипа = "ТабличнаяЧасть";
ИначеЕсли Найти(СтруктураТипа.ИмяОбщегоТипа, "ТабличнаяЧастьСтрока.") > 0 Тогда
НоваяСтрока = МассивОбщихТипов.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа, "Метаданные");
НоваяСтрока.ИмяОбщегоТипа = "СтрокаТабличнойЧасти";
ИначеЕсли Ложь
Или СтруктураТипа.ИмяОбщегоТипа = "ПолеТекстовогоДокумента"
//Или СтруктураТипа.ИмяОбщегоТипа = "РасширениеПоляФормыДляПоляТекстовогоДокумента" // В управляемой форме нет полного отражения ТекстовыйДокумент
Тогда
НоваяСтрока = МассивОбщихТипов.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа, "Метаданные");
НоваяСтрока.ИмяОбщегоТипа = "ТекстовыйДокумент";
ИначеЕсли СтруктураТипа.ИмяОбщегоТипа = "ПолеГрафическойСхемы" Тогда
НоваяСтрока = МассивОбщихТипов.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа, "Метаданные");
НоваяСтрока.ИмяОбщегоТипа = "ГрафическаяСхема";
ИначеЕсли СтруктураТипа.ИмяОбщегоТипа = "ПолеТабличногоДокумента" Тогда
НоваяСтрока = МассивОбщихТипов.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа, "Метаданные");
НоваяСтрока.ИмяОбщегоТипа = "ТабличныйДокумент";
ИначеЕсли СтруктураТипа.ИмяОбщегоТипа = "ЭлементТелоHTML" Тогда
НоваяСтрока = МассивОбщихТипов.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа, "Метаданные");
НоваяСтрока.ИмяОбщегоТипа = "ЭлементHTML";
ИначеЕсли Найти(СтруктураТипа.ИмяОбщегоТипа, МаркерКоллекцииМетаданных) > 0 Тогда
Если ДляФиксированныхСлов Тогда
НоваяСтрока = МассивОбщихТипов.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа, "Метаданные");
НоваяСтрока.ИмяОбщегоТипа = "КоллекцияОбъектовМетаданных";
КонецЕсли;
ИначеЕсли СтруктураТипа.ИмяОбщегоТипа = "ОбъектМетаданных" Тогда
Если ДоступноКэширование Тогда
Для Каждого СтрокаТипа Из ТаблицаТиповМетаОбъектов Цикл
НоваяСтрока = МассивОбщихТипов.Добавить();
//ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа, "Метаданные");
НоваяСтрока.ИмяОбщегоТипа = "ОбъектМетаданных" + СтрокаТипа.Единственное;
КонецЦикла;
КонецЕсли;
ИначеЕсли СтруктураТипа.ИмяОбщегоТипа = "ЛюбаяСсылка" Тогда
Отбор = Новый Структура;
Отбор.Вставить("Слово", "ПолучитьСсылку");
Для Каждого СтрокаСлова Из ТаблицаКонтекстов.НайтиСтроки(Отбор) Цикл
НоваяСтрока = МассивОбщихТипов.Добавить();
НоваяСтрока.ИмяОбщегоТипа = СтрокаСлова.ТипЗначения;
КонецЦикла;
ИначеЕсли СтруктураТипа.ИмяОбщегоТипа = "СсылочныйОбъект" Тогда
Отбор = Новый Структура;
Отбор.Вставить("Слово", "ПолучитьОбъект");
Для Каждого СтрокаСлова Из ТаблицаКонтекстов.НайтиСтроки(Отбор) Цикл
Если Найти(СтрокаСлова.ТипКонтекста, "Ссылка.") = 0 Тогда
Продолжить;
КонецЕсли;
НоваяСтрока = МассивОбщихТипов.Добавить();
НоваяСтрока.ИмяОбщегоТипа = ирОбщий.ПервыйФрагментЛкс(СтрокаСлова.ТипЗначения, ",");
КонецЦикла;
//ИначеЕсли Найти(СтруктураТипа.ИмяОбщегоТипа, "РасширениеФормы") > 0 Тогда
// НоваяСтрока = МассивОбщихТипов.Добавить();
// ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа, "Метаданные");
// НоваяСтрока.ИмяОбщегоТипа = "Форма";
//Иначе
// ОбщийТипМетаданных = ирОбщий.ТекстМеждуМаркерамиЛкс(СтруктураТипа.ИмяОбщегоТипа, , ": ", Ложь);
// //Если ОбщийТипМетаданных <> "" Тогда
// Если ЗначениеЗаполнено(ОбщийТипМетаданных) Тогда
// НоваяСтрока = МассивОбщихТипов.Добавить();
// ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа, "Метаданные");
// НоваяСтрока.ИмяОбщегоТипа = ОбщийТипМетаданных;
// КонецЕсли;
КонецЕсли;
// TODO добавить расширения управляемой формы Мультиметка638663811
// Расширения, образованные элементом управления и типом связанных с ним данных
СтрокаРасширения = ТаблицаРасширенийТипов.Найти(СтруктураТипа.ИмяОбщегоТипа, "Расширение");
Если Истина
И СтрокаРасширения <> Неопределено
И ЗначениеЗаполнено(СтрокаРасширения.ОсновнойТип)
Тогда
Если Истина
И СтрокаРасширения.ОсновнойТип = "Форма"
//И СтруктураТипа.ДополнительныеТипы = Неопределено
Тогда
НоваяСтрока = МассивОбщихТипов.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа, "Метаданные");
НоваяСтрока.ИмяОбщегоТипа = СтрокаРасширения.РасширяющийТип;
#Если Клиент Тогда
Если ТипЗнч(СтруктураТипа.Метаданные) = Тип("Форма") Тогда
СтруктураТипаОбъекта = СтруктураТипаОбъектаОбычнойФормы(СтруктураТипа.Метаданные);
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипаОбъекта);
КонецЕсли;
#КонецЕсли
КонецЕсли;
Если СтрокаРасширения.ОсновнойТип = "ТаблицаФормы" Тогда
НоваяСтрока = МассивОбщихТипов.Вставить(0); // Важно вставлять в начало для кэшируемых типов
Иначе
НоваяСтрока = МассивОбщихТипов.Добавить();
КонецЕсли;
Если Истина
И ирОбщий.СтрНачинаетсяСЛкс(СтруктураТипа.ИмяОбщегоТипа, "РасширениеФормы")
И Не ирОбщий.ЛиФормаИлиИмитаторЛкс(СтруктураТипа.Метаданные)
Тогда
// Нужно для вычисления параметров ненатуральной формы
НоваяСтрока.Метаданные = СтруктураТипа.ИмяОбщегоТипа;
Иначе
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа, "Метаданные");
КонецЕсли;
НоваяСтрока.ИмяОбщегоТипа = СтрокаРасширения.ОсновнойТип;
КонецЕсли;
// Общие расширения элементов управления
Для Счетчик = 1 По Мин(2, МассивОбщихТипов.Количество()) Цикл // Для поля табличного документа будет 2 типа https://www.hostedredmine.com/issues/956247
ИмяПоследнегоОбщегоТипа = МассивОбщихТипов[МассивОбщихТипов.Количество() - Счетчик].ИмяОбщегоТипа;
Если СтруктураТипа.Метаданные = Неопределено И ДоступноКэширование Тогда
// Расширяемому типу без метаданных добавляем сразу все расширения
Для Каждого СтрокаТипа Из ТаблицаРасширенийТипов.НайтиСтроки(Новый Структура("ОсновнойТип", СтруктураТипа.ИмяОбщегоТипа)) Цикл
НоваяСтрока = МассивОбщихТипов.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа, "Метаданные");
НоваяСтрока.ИмяОбщегоТипа = СтрокаТипа.Расширение;
КонецЦикла;
КонецЕсли;
Если МассивОбычныхЭлементовУправления.Найти(ИмяПоследнегоОбщегоТипа) <> Неопределено Тогда
НоваяСтрока = МассивОбщихТипов.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа, "Метаданные");
НоваяСтрока.ИмяОбщегоТипа = "РасширениеЭлементовУправленияРасположенныхВФорме";
НоваяСтрока = МассивОбщихТипов.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа, "Метаданные");
НоваяСтрока.ИмяОбщегоТипа = "РасширениеЭлементовУправленияРасположенныхНаПанели";
//ИначеЕсли МассивУправляемыхЭлементовУправления.Найти(ИмяПоследнегоОбщегоТипа) <> Неопределено Тогда
// // http://www.hostedredmine.com/issues/882998
// НоваяСтрока = МассивОбщихТипов.Добавить();
// ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа, "Метаданные");
// НоваяСтрока.ИмяОбщегоТипа = "РасширениеЭлементовУправленияРасположенныхВФорме";
КонецЕсли;
КонецЦикла;
//Если СтруктураТипа.ДополнительныеТипы <> Неопределено Тогда
// ирОбщий.ЗагрузитьВТаблицуЗначенийЛкс(СтруктураТипа.ДополнительныеТипы, МассивОбщихТипов);
//КонецЕсли;
Возврат МассивОбщихТипов;
КонецФункции
Процедура ОчиститьКэшАнализатораЯзыка() Экспорт
мПустойМодуль = Неопределено;
мПоляТекстаПрограммы = Неопределено;
мВызовыВсехМетодовПоМодулям = Неопределено;
мМодулиМетаданных.Очистить();
мКэшСловГлобальногоКонтекста.Очистить();
мПассивныеФормы.Очистить();
мПрямыеВызовыМетодов.Очистить();
КонецПроцедуры
Процедура ПроверитьОбновитьКэш() Экспорт
НоваяДатаОбновленияКэшаМодулей = ирОбщий.ДатаОбновленияКэшаМодулейЛкс();
Если мДатаОбновленияКэшаМодулей <> НоваяДатаОбновленияКэшаМодулей Тогда
ОчиститьКэшАнализатораЯзыка();
мДатаОбновленияКэшаМодулей = НоваяДатаОбновленияКэшаМодулей;
КонецЕсли;
КонецПроцедуры
// Получает внутреннюю таблицу предопределенных слов заданного родительского типа.
// Параметры:
// РодительскаяСтруктураТипа - см. НоваяСтруктураТипа() -
// ПараметрыЗаполнения - см. НовыеПараметрыЗаполненияСлов -
// КлючКэширования - выходной, Неопределено - не использовать кэш, Истина - полная таблица взята из кэша -
// выходной, Неопределено - не использовать кэш, Истина - полная таблица взята из кэша
// Возвращаемое значение:
// см. НоваяТаблицаСлов -
Функция СловаКонтекстаПредопределенные(Знач РодительскаяСтруктураТипа, Знач ПараметрыЗаполнения, КлючКэширования = Неопределено) Экспорт
ТаблицаСлов = ПараметрыЗаполнения.ТаблицаСлов;
Если Истина
И Не РодительскаяСтруктураТипа.Конструктор
И Не ЗначениеЗаполнено(РодительскаяСтруктураТипа.ИмяОбщегоТипа)
И РодительскаяСтруктураТипа.ТипЯзыка = ""
Тогда
// родительский контекст является Процедурой
Если ТаблицаСлов = Неопределено Тогда
ТаблицаСлов = НоваяТаблицаСлов();
КонецЕсли;
Возврат ТаблицаСлов;
КонецЕсли;
БазовоеРасширениеКонфигурации = ПараметрыЗаполнения.БазовоеРасширениеКонфигурации;
ВычислятьТипы = ПараметрыЗаполнения.ВычислятьТипы;
ДляЗаписи = ПараметрыЗаполнения.ДляЗаписи;
ЗапретГлобальногоКонтекста = ПараметрыЗаполнения.ЗапретГлобальногоКонтекста;
НаборыСлов = ПараметрыЗаполнения.НаборыСлов;
СловоФильтр = ПараметрыЗаполнения.СловоФильтр;
ТипСловаФильтр = ПараметрыЗаполнения.ТипСловаФильтр;
ТолькоСоЗначениями = ПараметрыЗаполнения.ТолькоСоЗначениями;
ФлагиКомпиляции = ПараметрыЗаполнения.ФлагиКомпиляции;
ЭтоЛокальныйКонтекст = ПараметрыЗаполнения.ЭтоЛокальныйКонтекст;
ЯзыкПрограммы = ПараметрыЗаполнения.ЯзыкПрограммы;
Если РодительскаяСтруктураТипа.ТипЯзыка = "ЗначениеВЗапросе" Тогда
ЯзыкПрограммы = 1;
КонецЕсли;
КлючПоискаКонструктора = Новый Структура;
Если РодительскаяСтруктураТипа.Конструктор Тогда
КлючПоискаКонструктора = Новый Структура("ЕстьКонструктор, ЯзыкПрограммы, НСлово", Истина, ЯзыкПрограммы);
КонецЕсли;
ИмяОбщегоТипаРодителяБезДеталей = РодительскаяСтруктураТипа.ИмяОбщегоТипа;
Если Найти(ИмяОбщегоТипаРодителяБезДеталей, " {") > 0 Тогда
НИмяОбщегоТипаРодителя = НРег(ИмяОбщегоТипаРодителяБезДеталей);
Если Найти(НИмяОбщегоТипаРодителя, " {v") > 0 Тогда
ЧистоеИмяТипа = ирОбщий.ПервыйФрагментЛкс(НИмяОбщегоТипаРодителя, " ");
Если Найти(ЧистоеИмяТипа, НРег("IV8COMConnector")) = 1 Тогда
РодительскаяСтруктураТипа.ИмяОбщегоТипа = "МенеджерCOMСоединений";
ИначеЕсли Найти(ЧистоеИмяТипа, НРег("IServerAgentConnection")) = 1 Тогда
РодительскаяСтруктураТипа.ИмяОбщегоТипа = "Соединение с агентом сервера";
ИначеЕсли Найти(ЧистоеИмяТипа, НРег("IWorkingProcessConnection")) Тогда
РодительскаяСтруктураТипа.ИмяОбщегоТипа = "Соединение с рабочим процессом";
ИначеЕсли Найти(ЧистоеИмяТипа, НРег("Application")) Тогда
РодительскаяСтруктураТипа.ИмяОбщегоТипа = "AutomationСервер";
КонецЕсли;
КонецЕсли;
КонецЕсли;
ЛиПолныйКонтрольУникальности = Неопределено;
МассивОбщихТипов = РазвернутаяТаблицаТиповИзСтруктурыТипа(РодительскаяСтруктураТипа, ЭтоЛокальныйКонтекст, Истина, Не ЗначениеЗаполнено(ТаблицаСлов));
ПроверятьДоступностьВКонтекстеКомпиляции = ПроверятьДоступностьВКонтекстеКомпиляции(ФлагиКомпиляции, РодительскаяСтруктураТипа, ЭтоЛокальныйКонтекст);
Для Каждого СтрокаОбщегоТипа Из МассивОбщихТипов Цикл
ИмяОбщегоТипаРодителяБезДеталей = ирОбщий.ПервыйФрагментЛкс(СтрокаОбщегоТипа.ИмяОбщегоТипа, "[");
ИспользоватьКэширование = Ложь;
Если ЗапретГлобальногоКонтекста И ИмяОбщегоТипаРодителяБезДеталей = "Глобальный" Тогда
Продолжить;
КонецЕсли;
Если Ложь
Или ИмяОбщегоТипаРодителяБезДеталей = "Глобальный"
Или ИмяОбщегоТипаРодителяБезДеталей = "БиблиотекаКартинок"
//Или ИмяОбщегоТипаРодителяБезДеталей = "ОбъектМетаданных" И РодительскаяСтруктураТипа.ТипЯзыка = "" // 60 видов
Или (Истина
И РодительскаяСтруктураТипа.ИмяОбщегоТипа = ИмяОбщегоТипаРодителяБезДеталей // Это первая компонента типа
И РодительскаяСтруктураТипа.ТипЯзыка = "" // Нужно для ОбъектМетаданных
И МассивОбщихТипов.Количество() > 10
//И (Ложь
// Или ИмяОбщегоТипаРодителяБезДеталей = "Форма" // 37 расширений
// Или ИмяОбщегоТипаРодителяБезДеталей = "ТабличноеПоле" // 78 расширений
// Или ИмяОбщегоТипаРодителяБезДеталей = "ПолеВвода" // 28 расширений
// Или ИмяОбщегоТипаРодителяБезДеталей = "КолонкаТабличногоПоля" // 22 расширений
// Или ИмяОбщегоТипаРодителяБезДеталей = "ФормаКлиентскогоПриложения" // 15 расширений
// Или ИмяОбщегоТипаРодителяБезДеталей = "ТаблицаФормы" // 40 расширений
// Или ИмяОбщегоТипаРодителяБезДеталей = "ПолеФормы" // 40 расширений
// )
)
Или Найти(ИмяОбщегоТипаРодителяБезДеталей, " {") > 0 // COM
Или ИмяОбщегоТипаРодителяБезДеталей = "" // ИмяТипа
Тогда
КлючКэширования = КлючКэшированияСловИзОбщегоТипа(ИмяОбщегоТипаРодителяБезДеталей);
ИспользоватьКэширование = Истина
И СловоФильтр = Неопределено
И Не ДляЗаписи
И Не ЗапретГлобальногоКонтекста;
Если ИспользоватьКэширование И ЗначениеЗаполнено(ТаблицаСлов) Тогда
Если Найти(ИмяОбщегоТипаРодителяБезДеталей, " {") > 0 Тогда // COM
ИспользоватьКэширование = Ложь;
Иначе
// Мультметка8530527831
ВызватьИсключение "Для кэшируемого контекста нельзя передавать таблицу-приемник"; // Обычно помогает ОбработкаОбъект.ирКлсПолеТекстаПрограммы.ПодготовитьТаблицуТиповКЗаполнениюТаблицыСлов
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ИспользоватьКэширование Тогда
Если Ложь
Или ИмяОбщегоТипаРодителяБезДеталей = "Глобальный"
Или ИмяОбщегоТипаРодителяБезДеталей = ""
Тогда
// Мультиметка3398476724
ЛиСеансТолстогоКлиентаУП = ирКэш.ЛиСеансТолстогоКлиентаУПЛкс();
НаСервере = ирОбщий.СвойствоСтруктурыЛкс(ФлагиКомпиляции, "Сервер", Истина);
КлиентОбычноеПриложение = ирОбщий.СвойствоСтруктурыЛкс(ФлагиКомпиляции, "КлиентОбычноеПриложение", Не ЛиСеансТолстогоКлиентаУП);
КлиентУправляемоеПриложение = ирОбщий.СвойствоСтруктурыЛкс(ФлагиКомпиляции, "КлиентУправляемоеПриложение", ЛиСеансТолстогоКлиентаУП);
ЛиПолноеКэширование = Ложь;
КлючКэширования = ИмяОбщегоТипаРодителяБезДеталей + ";" + ЯзыкПрограммы + ";" + ПараметрыЗаполнения.Конфигурация + ";" + ВычислятьТипы + ";" + ТипСловаФильтр + ";" + НаСервере + ";" + КлиентОбычноеПриложение + ";"
+ КлиентУправляемоеПриложение + ";" + РодительскаяСтруктураТипа.ТипЯзыка + ";" + БазовоеРасширениеКонфигурации + ";" + РодительскаяСтруктураТипа.Конструктор + ";" + ДляЗаписи + ";" + ПараметрыЗаполнения.ТолькоСоЗначениями;
Иначе
ЛиПолноеКэширование = Истина;
КонецЕсли;
ТаблицаСловИзКэша = мКэшСловГлобальногоКонтекста[КлючКэширования];
Если ТаблицаСловИзКэша <> Неопределено Тогда
#Если Сервер И Не Сервер Тогда
ТаблицаСловИзКэша = Новый ТаблицаЗначений;
#КонецЕсли
Если НаборыСлов <> Неопределено Тогда
НаборыСлов.Вставить(КлючКэширования, ТаблицаСловИзКэша);
ТаблицаСлов = НоваяТаблицаСлов();
Иначе
ТаблицаСлов = ТаблицаСловИзКэша.Скопировать();
КонецЕсли;
Если ЛиПолноеКэширование Тогда
КлючКэширования = Истина;
Прервать;
Иначе
КлючКэширования = Неопределено;
Продолжить;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ТаблицаСлов = Неопределено Тогда
ТаблицаСлов = НоваяТаблицаСлов();
КонецЕсли;
Если Истина
И ИмяОбщегоТипаРодителяБезДеталей <> "Глобальный"
И ФлагиКомпиляции <> Неопределено
И ФлагиКомпиляции.БезКонтекста
И ЭтоЛокальныйКонтекст
Тогда
Продолжить;
КонецЕсли;
Если ЛиПолныйКонтрольУникальности = Неопределено Тогда
ЛиПолныйКонтрольУникальности = ИспользоватьКэширование Или ТаблицаСлов.Количество() > 0;
КонецЕсли;
МетаданныеРодителя = СтрокаОбщегоТипа.Метаданные;
Если Истина
И ТипЗнч(МетаданныеРодителя) = Тип("Структура")
И ирОбщий.СвойствоСтруктурыЛкс(МетаданныеРодителя, "Форма") <> Неопределено
Тогда
МетаданныеРодителя = МетаданныеРодителя.Форма;
КонецЕсли;
ЛиРодительЕстьУпрФормаИлиИмитатор = ирОбщий.ЛиФормаИлиИмитаторЛкс(МетаданныеРодителя, Ложь);
КорневойТипРодителя = Неопределено;
ПостроительЗапросаРодителя = Неопределено;
ТипМетаданныхРодителя = ТипЗнч(МетаданныеРодителя);
Если Истина
И ТипМетаданныхРодителя = Тип("ОбъектМетаданных")
И РодительскаяСтруктураТипа.ТипЯзыка <> "ИмяТипа"
Тогда
Если ТипМетаданныхРодителя = Тип("ОбъектМетаданных") Тогда
КорневойТипРодителя = ирОбщий.КорневойТипКонфигурацииЛкс(МетаданныеРодителя);
Иначе
КорневойТипРодителя = ирОбщий.КорневойТипКонфигурацииЛкс(КэшОбъект(МетаданныеРодителя).ПолноеИмя);
КонецЕсли;
ПостроительЗапросаРодителя = ПостроительЗапросаПоСтруктуреТипа(СтрокаОбщегоТипа, РодительскаяСтруктураТипа.ВиртуальнаяТаблица);
КонецЕсли;
Если ИмяОбщегоТипаРодителяБезДеталей = "Локальный" Тогда
НайденныеСтроки = Новый Массив;
ИначеЕсли ТипСловаФильтр = "Конструктор" Тогда
НайденныеСтроки = Новый Массив;
Если ИмяОбщегоТипаРодителяБезДеталей = "Глобальный" Тогда
СтруктураКлюча = Новый Структура("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка, ТипСлова",
СловоФильтр, ЯзыкПрограммы, РодительскаяСтруктураТипа.ТипЯзыка, ТипСловаФильтр);
НайденныеСтроки = ТаблицаКонтекстов.НайтиСтроки(СтруктураКлюча);
КонецЕсли;
Иначе
// Состав полей совпадает с индексом
СтруктураКлюча = Новый Структура("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка",
ИмяОбщегоТипаРодителяБезДеталей, ЯзыкПрограммы, РодительскаяСтруктураТипа.ТипЯзыка);
Если СловоФильтр <> Неопределено Тогда
СтруктураКлюча.Вставить("НСлово", НРег(СловоФильтр));
Если Истина
И ЯзыкПрограммы = 0 // В языке запросов может быть неоднозначность между типами слов Таблица и Поле. Поэтому для них жертвуем попаданием в индекс
И ТипСловаФильтр = Неопределено
Тогда
//ирОбщий.СообщитьЛкс("Использован медленный поиск по таблице контекстов");
ТипСловаФильтр = "Свойство"; // Так будем всегда попадать в индекс
КонецЕсли;
КонецЕсли;
Если ТипСловаФильтр <> Неопределено Тогда
СтруктураКлюча.Вставить("ТипСлова", ТипСловаФильтр);
КонецЕсли;
Если ЯзыкПрограммы <> 0 Тогда
ирОбщий.ДобавитьИндексВТаблицуЛкс(ТаблицаКонтекстов, СтруктураКлюча); // спасает в случае языка запросов, где ТипСловаФильтр не используется
КонецЕсли;
НайденныеСтроки = ТаблицаКонтекстов.НайтиСтроки(СтруктураКлюча);
КонецЕсли;
ПредыдущаяСтрокаСлова = Неопределено; // Для регистра бухгалтерии
ВычислятьТипыЦикл = ВычислятьТипы Или НайденныеСтроки.Количество() < 100;
Для Каждого СтрокаСлова Из НайденныеСтроки Цикл
СловоЦикл = СтрокаСлова.Слово;
ТипСловаЦикл = СтрокаСлова.ТипСлова;
Если Ложь
Или (Истина
И ТолькоСоЗначениями
И ПустаяСтрока(СтрокаСлова.ТипЗначения)
И СтрокаСлова.ТипСлова <> "Свойство")
Или ДляЗаписи И Не СтрокаСлова.Запись
Или (Истина
И ПредыдущаяСтрокаСлова <> Неопределено
И ПредыдущаяСтрокаСлова.НСлово = СтрокаСлова.НСлово
И ПредыдущаяСтрокаСлова.ТипСлова = ТипСловаЦикл)
Или СтрокаСлова.НомерВерсииПлатформы > мНомерВерсииПлатформы
Или (Истина
И ТипСловаЦикл = ПеречТипСлова.Метод
И СтрокаОбщегоТипа.НеВключатьМетоды)
Или (Истина
И ТипСловаФильтр = Неопределено
И (Ложь
Или ТипСловаЦикл = "Событие"
Или ТипСловаЦикл = "Параметр"
Или ТипСловаЦикл = "Конструктор"))
Или (Истина
И ПроверятьДоступностьВКонтекстеКомпиляции
И (Ложь
Или ФлагиКомпиляции.Сервер И СтрокаСлова.НеСервер
Или ФлагиКомпиляции.КлиентОбычноеПриложение И СтрокаСлова.НеТолстыйКлиент
Или ФлагиКомпиляции.КлиентУправляемоеПриложение И Не ФлагиКомпиляции.КлиентОбычноеПриложение И СтрокаСлова.НеТонкийКлиент))
Тогда
Продолжить;
КонецЕсли;
ПредыдущаяСтрокаСлова = СтрокаСлова;
Если РодительскаяСтруктураТипа.Конструктор Тогда
КлючПоискаКонструктора.НСлово = НРег(СловоЦикл);
Если ТаблицаОбщихТипов.НайтиСтроки(КлючПоискаКонструктора).Количество() = 0 Тогда
Продолжить;
КонецЕсли;
КонецЕсли;
МожноУточнитьТип = СловоЦикл = "ВладелецФормы";
ЛиТипСКвалификаторами = Истина
И ТипСловаЦикл = "Свойство"
И ирОбщий.ЛиИмяТипаСКвалификаторамиЛкс(СтрокаСлова.ТипЗначения)
И Не ирОбщий.СтрНачинаетсяСЛкс(РодительскаяСтруктураТипа.ИмяОбщегоТипа, "ОбъектМетаданных");
ТаблицаТипов = Неопределено;
Если ВычислятьТипыЦикл Тогда
ТаблицаТипов = НоваяТаблицаТипов();
ЛиДобавляемСлово = Истина;
Если Найти(СтрокаСлова.ТипЗначения, "[") > 0 Тогда
МассивТиповЗначения = ирОбщий.ЗначенияВМассивЛкс(СтрокаСлова.ТипЗначения);
Иначе
МассивТиповЗначения = ирОбщий.СтрРазделитьЛкс(СтрокаСлова.ТипЗначения, ", ");
КонецЕсли;
СтруктураТипаШаблон = НоваяСтруктураТипа();
СтруктураТипаШаблон.СтрокаОписания = СтрокаСлова;
ЗаполнитьЗначенияСвойств(СтруктураТипаШаблон, РодительскаяСтруктураТипа, , "ИмяОбщегоТипа, СтрокаОписания, Метаданные, МетаданныеСвойства, ВиртуальнаяТаблица");
Если Истина
И ЛиИмяТипаЭлементаУправляемойФормы(ИмяОбщегоТипаРодителяБезДеталей)
И ТипЗнч(МетаданныеРодителя) <> Тип(ИмяОбщегоТипаРодителяБезДеталей)
И ТипЗнч(МетаданныеРодителя) <> Тип("Структура")
Тогда
СтруктураТипаШаблон.Метаданные = НовыйИмитаторЭлементаФормы();
СтруктураТипаШаблон.Метаданные.Тип = Тип(ИмяОбщегоТипаРодителяБезДеталей);
Если ИмяОбщегоТипаРодителяБезДеталей <> РодительскаяСтруктураТипа.ИмяОбщегоТипа Тогда
СтруктураТипаШаблон.Метаданные.Вставить("ИмяТипаРасширения", РодительскаяСтруктураТипа.ИмяОбщегоТипа);
КонецЕсли;
ИначеЕсли Истина
И ТипСловаФильтр = ПеречТипСлова.Метод
И ИмяОбщегоТипаРодителяБезДеталей = "РасширениеЭлементовУправленияРасположенныхВФорме"
Тогда
СоздатьИмитатор = Ложь;
Если ирОбщий.ЛиФормаИлиИмитаторЛкс(МетаданныеРодителя) Тогда
СтруктураТипаШаблон.ДержательМетаданных = МетаданныеРодителя;
СоздатьИмитатор = Истина;
ИначеЕсли ТипЗнч(МетаданныеРодителя) = Тип("Неопределено") Тогда
СоздатьИмитатор = Истина;
КонецЕсли;
Если СоздатьИмитатор Тогда
СтруктураТипаШаблон.Метаданные = НовыйИмитаторЭлементаФормы();
СтруктураТипаШаблон.Метаданные.Тип = РодительскаяСтруктураТипа.ИмяОбщегоТипа;
Иначе
СтруктураТипаШаблон.Метаданные = МетаданныеРодителя;
КонецЕсли;
ИначеЕсли Истина
//И ТипЗнч(МетаданныеРодителя) <> Тип("COMОбъект")
//И ТипСловаЦикл = "Свойство"
И СловоЦикл <> "ВладелецФормы"
И ИмяОбщегоТипаРодителяБезДеталей <> "КлючИЗначение" // Для проверки выражений
И ИмяОбщегоТипаРодителяБезДеталей <> "ЭлементСпискаЗначений" // Для проверки выражений
//И Не ирОбщий.СтрНачинаетсяСЛкс(ИмяОбщегоТипаРодителяБезДеталей, "КоллекцияКолонок") // Закомментировал, т.к. ломает расчет возможных значений ТаблицаЗначений.Колоонки.Удалить("")
И Не (Истина
// Исключаем общее описание значений элементов структуры (МетаданныеРодителя = ТаблицаЗначений)
И ИмяОбщегоТипаРодителяБезДеталей = "Структура"
И ТипЗнч(МетаданныеРодителя) = Тип("ТаблицаЗначений"))
И Не (Истина
// Для ЭлементУправления.УстановитьДействие("")
И ИмяОбщегоТипаРодителяБезДеталей = "КолонкаТабличногоПоля"
И ТипЗнч(МетаданныеРодителя) = Тип("ТабличноеПоле"))
Тогда
СтруктураТипаШаблон.Метаданные = СтрокаОбщегоТипа.Метаданные;
КонецЕсли;
Для Каждого ИмяОбщегоТипаСлова Из МассивТиповЗначения Цикл
Если МассивТиповЗначения.Количество() = 1 Тогда
СтруктураТипа = СтруктураТипаШаблон;
Иначе
СтруктураТипа = НоваяСтруктураТипа();
ЗаполнитьЗначенияСвойств(СтруктураТипа, СтруктураТипаШаблон,, "ВиртуальнаяТаблица");
Если Истина
И Не ЛиТипСКвалификаторами
И ТипСловаЦикл = "Свойство"
Тогда
ЛиТипСКвалификаторами = ирОбщий.ЛиИмяТипаСКвалификаторамиЛкс(ИмяОбщегоТипаСлова);
КонецЕсли;
КонецЕсли;
Если ИмяОбщегоТипаСлова = "ОбъектМетаданныхКонфигурация" Тогда
//СтруктураТипа.Метаданные = Конфигурация;
Если ПараметрыЗаполнения.Конфигурация <> Неопределено Тогда
СтруктураТипа.Метаданные = ПараметрыЗаполнения.Конфигурация;
Иначе
СтруктураТипа.Метаданные = Неопределено;
КонецЕсли;
ИначеЕсли ИмяОбщегоТипаСлова = "Отбор" Тогда
Если Истина
И ТипЗнч(СтрокаОбщегоТипа.Метаданные) = Тип("ОбъектМетаданных")
И (Ложь
//Или Найти(НРег(СтрокаОбщегоТипа.ИмяОбщегоТипа), "объект.") > 0
Или Найти(НРег(СтрокаОбщегоТипа.ИмяОбщегоТипа), "наборзаписей.") > 0)
Тогда
ИмяТаблицыБД = ирКэш.ИмяТаблицыИзМетаданныхЛкс(СтрокаОбщегоТипа.Метаданные.ПолноеИмя());
СтруктураОбъекта = ирОбщий.ОбъектБДПоКлючуЛкс(ИмяТаблицыБД);
СтруктураТипа.Метаданные = СтруктураОбъекта.Методы;
ИначеЕсли Ложь
Или ирОбщий.СтрНачинаетсяСЛкс(СтрокаОбщегоТипа.ИмяОбщегоТипа, "РасширениеТабличногоПоля")
Тогда
Если ТипЗнч(СтрокаОбщегоТипа.Метаданные) = Тип("ТабличноеПоле") Тогда
СтруктураТипа.Метаданные = Метаданные.НайтиПоТипу(ТипЗнч(СтрокаОбщегоТипа.Метаданные.Значение));
КонецЕсли;
Иначе
КонкретныйТип = ИмяТипаИзСтруктурыТипа(СтрокаОбщегоТипа);
Если Истина
И Найти(КонкретныйТип, "<") = 0
И ТипЗнч(СтруктураТипа.Метаданные) <> Тип(КонкретныйТип)
Тогда
Попытка
Образователь = Новый (КонкретныйТип);
СтруктураТипа.Метаданные = Образователь;
Исключение
// Срабатывает для табличных полей
КонецПопытки;
КонецЕсли;
КонецЕсли;
КонецЕсли;
СтруктураТипа.ИмяОбщегоТипа = ИмяОбщегоТипаСлова;
Если ПараметрыЗаполнения.ВиртуальнаяТаблица <> Неопределено Тогда
ЗаполнитьЗначенияСвойств(СтруктураТипа.ВиртуальнаяТаблица, ПараметрыЗаполнения.ВиртуальнаяТаблица);
КонецЕсли;
Если РодительскаяСтруктураТипа.ТипЯзыка = "ИмяТипа" Тогда
СтруктураТипа.ИмяОбщегоТипа = СловоЦикл;
Если СтрокаСлова.ТипКонтекста <> "" Тогда
СтруктураТипа.ИмяОбщегоТипа = СтрокаСлова.ТипКонтекста + "." + СтруктураТипа.ИмяОбщегоТипа;
КонецЕсли;
КонецЕсли;
Если Истина
И Найти(СтруктураТипа.ИмяОбщегоТипа, "СтрокаТабличнойЧасти") > 0
И Найти(РодительскаяСтруктураТипа.ИмяОбщегоТипа, "ТабличнаяЧасть.") > 0
Тогда
ИмяТипаСтрокиТЧ = СтрЗаменить(РодительскаяСтруктураТипа.ИмяОбщегоТипа, "ТабличнаяЧасть.", "ТабличнаяЧастьСтрока.");
СтруктураТипа.ИмяОбщегоТипа = СтрЗаменить(СтруктураТипа.ИмяОбщегоТипа, "СтрокаТабличнойЧасти", ИмяТипаСтрокиТЧ);
КонецЕсли;
#Если Клиент Тогда
Если Истина
И ТипЗнч(МетаданныеРодителя) = Тип("ТабличноеПоле")
И ИмяОбщегоТипаСлова = "КолонкаТабличногоПоля"
Тогда
ИмяОбщегоТипаРасширения = ИмяТипаРасширенияЭлементаФормы(ИмяОбщегоТипаСлова, МетаданныеРодителя);
Если ИмяОбщегоТипаРасширения <> Неопределено Тогда
СтруктураТипа.ИмяОбщегоТипа = ИмяОбщегоТипаРасширения;
КонецЕсли;
КонецЕсли;
#КонецЕсли
МаркерРасширений = "Расширение";
Если Истина
И Лев(РодительскаяСтруктураТипа.ИмяОбщегоТипа, СтрДлина(МаркерРасширений)) = МаркерРасширений
И СловоЦикл = "Значение"
Тогда
Если МетаданныеРодителя <> Неопределено Тогда
ЭлементФормы = МетаданныеРодителя; // ПолеВвода
СтруктураТипа = СтруктураТипаИзЗначения(ЭлементФормы.Значение);
Иначе
СтрокаРасширения = ТаблицаРасширенийТипов.Найти(РодительскаяСтруктураТипа.ИмяОбщегоТипа, "Расширение");
//Если СтрокаРасширения <> Неопределено Тогда
СтруктураТипа.ИмяОбщегоТипа = СтрокаРасширения.РасширяющийТип;
//КонецЕсли;
КонецЕсли;
МожноУточнитьТип = Истина;
ИначеЕсли Истина
И РодительскаяСтруктураТипа.ИмяОбщегоТипа = "ТабличноеПоле"
И СловоЦикл = "Значение"
Тогда
Если ТипЗнч(МетаданныеРодителя) = Тип("ТабличноеПоле") Тогда
СтруктураТипа = СтруктураТипаИзЗначения(МетаданныеРодителя.Значение);
Иначе
ДобавитьВТаблицуТипов(ТаблицаТипов, НоваяСтруктураТипа("ДеревоЗначений"));
ДобавитьВТаблицуТипов(ТаблицаТипов, НоваяСтруктураТипа("ТаблицаЗначений"));
ДобавитьВТаблицуТипов(ТаблицаТипов, НоваяСтруктураТипа("ТабличнаяЧасть"));
КонецЕсли;
КонецЕсли;
Если Истина
И МетаданныеРодителя <> Неопределено
И ТипСловаЦикл = "Свойство"
Тогда
Если Ложь
Или ТипЗнч(МетаданныеРодителя) = Тип("ПостроительЗапроса")
Или (Истина // Нельзя допускать неявного выполнения запроса при обращении к свойству "Результат" построителя
И СтруктураТипа.ИмяОбщегоТипа = "РезультатЗапроса"
И ТипЗнч(МетаданныеРодителя) = Тип("ПостроительЗапроса"))
Или (Истина // Здесь свойство есть у объекта метаданных, но имеет другой смысл
И СловоЦикл = "ВидыСубконто"
И СтруктураТипа.ИмяОбщегоТипа = "ПланСчетовВидыСубконто.<Имя плана счетов>")
Тогда
ЗначениеСвойства = МетаданныеРодителя;
Иначе
Если Истина
#Если Клиент Тогда
И ТипЗнч(МетаданныеРодителя) = Тип("ТабличноеПоле")
#Иначе
И Ложь
#КонецЕсли
И СловоЦикл = "ТекущийРодитель"
Тогда
// Антибаг платформы 8.2.16. Вывести в чистом виде не удалось. Падает при вычислении свойства ТекущийРодитель в форме списка РС.ООП_ВаучерыТез
ЗначениеСвойства = Неопределено;
Иначе
ПроверяемыеМетаданные = ?(МетаданныеРодителя = Неопределено, мМетаданные, МетаданныеРодителя);
Попытка
ЗначениеСвойства = ПроверяемыеМетаданные[СловоЦикл];
Исключение
ЗначениеСвойства = Неопределено;
КонецПопытки;
КонецЕсли;
КонецЕсли;
Если ЗначениеСвойства <> Неопределено Тогда
Если Истина
И ТипЗнч(ЗначениеСвойства) = Тип("ТаблицаЗначений")
И ЗначениеСвойства.Колонки.Найти(ИмяКолонкиФлагаТаблицыТипов()) <> Неопределено
Тогда
// Мультиметка241116_130557 Например КлючИЗначение, ЭлементСпискаЗначений, ПараметрыПеретаскивания и имитаторы описанные в типизирующих комментариях
ТаблицаТипов = ЗначениеСвойства;
ТаблицаТипов.ЗаполнитьЗначения(СтрокаСлова, "СтрокаОписания");
МожноУточнитьТип = Истина;
Прервать;
ИначеЕсли мМассивТиповСМетаданными.Найти(ТипЗнч(ЗначениеСвойства)) <> Неопределено Тогда
Если СтрокаСлова.ТипЗначения = "ВсеЭлементыФормы" Тогда
// Для имитатора формы
Иначе
СтруктураТипа.Метаданные = ЗначениеСвойства;
КонецЕсли;
Если ЛиРодительЕстьУпрФормаИлиИмитатор Тогда
СтруктураТипа.ДержательМетаданных = МетаданныеРодителя;
КонецЕсли;
ИначеЕсли ПустаяСтрока(СтрокаСлова.ТипЗначения) Тогда
// Например ПолеВвода.Значение
СтруктураТипа = СтруктураТипаИзЗначения(ЗначениеСвойства);
МожноУточнитьТип = Истина;
КонецЕсли;
КонецЕсли;
КонецЕсли;
// Для методов метаданных нужна специфическая обработка для усечения типов
Если Истина
И СловоЦикл = "Родитель"
И ТипСловаЦикл = ПеречТипСлова.Метод
И ирОбщий.СтрНачинаетсяСЛкс(ИмяОбщегоТипаСлова, МаркерОбъектаМетаданных)
Тогда
Родитель = Неопределено;
Если ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") Тогда
Родитель = МетаданныеРодителя.Родитель();
КонецЕсли;
Если Родитель <> Неопределено Тогда
МассивФрагментов = ирОбщий.СтрРазделитьЛкс(Родитель.ПолноеИмя());
СтруктураТипа.ИмяОбщегоТипа = МаркерОбъектаМетаданных + МассивФрагментов[МассивФрагментов.ВГраница() - 1];
Иначе
СтруктураТипа.ИмяОбщегоТипа = ИмяОбщегоТипаОбъектаМетаданных();
КонецЕсли;
СтруктураТипа.Метаданные = Родитель;
ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа);
Прервать;
ИначеЕсли Истина
И ТипСловаЦикл = ПеречТипСлова.Метод
И Лев(ИмяОбщегоТипаСлова, СтрДлина(МаркерОбъектаМетаданных)) = МаркерОбъектаМетаданных
И (Ложь
Или СловоЦикл = "Найти"
Или СловоЦикл = "Получить")
Тогда
СтруктураКлюча = Новый Структура("БазовыйТип, ЯзыкПрограммы", РодительскаяСтруктураТипа.ИмяОбщегоТипа, ЯзыкПрограммы);
НайденныеСтроки = ТаблицаОбщихТипов.НайтиСтроки(СтруктураКлюча);
СтруктураТипа.ИмяОбщегоТипа = НайденныеСтроки[0].ТипЭлементаКоллекции;
ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа);
Продолжить;
ИначеЕсли Истина
И СтрокаСлова.ТипКонтекста = "ОтчетОбъект.<Имя отчета>"
И СловоЦикл = "СхемаКомпоновкиДанных"
И ТипСловаЦикл = "Свойство"
И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных")
Тогда
СхемаКомпоновкиДанных = ирКэш.ОсновнаяСхемаКомпоновкиОтчетаЛкс(МетаданныеРодителя.ПолноеИмя());
Если СхемаКомпоновкиДанных <> Неопределено Тогда
СтруктураТипа.Метаданные = СхемаКомпоновкиДанных;
КонецЕсли;
ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа);
Прервать;
ИначеЕсли Истина
И СтрокаСлова.ТипКонтекста = "ОтчетОбъект.<Имя отчета>"
И СловоЦикл = "КомпоновщикНастроек"
И ТипСловаЦикл = "Свойство"
И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных")
Тогда
СхемаКомпоновкиДанных = ирКэш.ОсновнаяСхемаКомпоновкиОтчетаЛкс(МетаданныеРодителя.ПолноеИмя());
Если СхемаКомпоновкиДанных <> Неопределено Тогда
СтруктураТипа.Метаданные = ирОбщий.КомпоновщикПоСхемеКомпоновкиЛкс(СхемаКомпоновкиДанных);
КонецЕсли;
ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа);
Прервать;
ИначеЕсли Истина
И ТипЗнч(МетаданныеРодителя) = Тип("ОписаниеТипов")
И СтрокаСлова.ТипКонтекста = "ОписаниеТипов"
И СловоЦикл = "ПривестиЗначение"
Тогда
Если МетаданныеРодителя.Типы().Количество() = 1 Тогда
ДобавитьВТаблицуТипов(ТаблицаТипов, МетаданныеРодителя);
КонецЕсли;
Прервать;
ИначеЕсли Истина
И ТипЗнч(МетаданныеРодителя) = Тип("ТекстовыйДокумент")
И ИмяОбщегоТипаРодителяБезДеталей = "ТекстовыйДокумент"
И СловоЦикл = "ПолучитьТекст"
Тогда
СтруктураТипа = НоваяСтруктураТипа("Строка");
СтруктураТипа.Метаданные = МетаданныеРодителя.ПолучитьТекст();
ИначеЕсли Истина
И РодительскаяСтруктураТипа.ИмяОбщегоТипа = "Массив"
И ТипСловаЦикл = ПеречТипСлова.Метод
И (Ложь
Или СловоЦикл = "Количество"
Или СловоЦикл = "ВГраница")
И ТипЗнч(МетаданныеРодителя) = Тип("ТаблицаЗначений")
И МетаданныеРодителя.Количество() > 0
И ТипЗнч(МетаданныеРодителя[0].Метаданные) = Тип("ПостроительЗапроса")
Тогда
// Мультиметка6091573442
КоличествоЗапросов = РазбитьГрубоТекстПакетногоЗапросаНаЗапросы(МетаданныеРодителя[0].Метаданные.Текст).Количество();
Если СловоЦикл = "Количество" Тогда
СтруктураТипа.Метаданные = КоличествоЗапросов;
Иначе
СтруктураТипа.Метаданные = КоличествоЗапросов - 1;
КонецЕсли;
ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа);
Прервать;
ИначеЕсли Истина
И ирОбщий.СтрНачинаетсяСЛкс(ИмяОбщегоТипаСлова, "Массив[")
И МетаданныеРодителя <> Неопределено
Тогда
ПолеТекстаПрограммы = ирКэш.ПолеТекстаПрограммы();
ТаблицаТиповИзТекста = ПолеТекстаПрограммы.ТаблицаТиповИзТекста(ИмяОбщегоТипаСлова);
//! ТаблицаТиповИзТекста[0].Метаданные = 0 // см. НоваяТаблицаТипов
ТаблицаТиповИзТекста[0].Метаданные.ЗаполнитьЗначения(МетаданныеРодителя, "Метаданные"); // TODO проверить подобные места, чтобы там обновлялась детальность
ТаблицаТиповИзТекста[0].Метаданные.ЗаполнитьЗначения(РодительскаяСтруктураТипа.ДержательМетаданных, "ДержательМетаданных"); // Для Запрос.ВыполнитьПакет()
Для Каждого СтрокаТипаЭлемента Из ТаблицаТиповИзТекста[0].Метаданные Цикл
ОбновитьДетальностьСтруктурыТипа(СтрокаТипаЭлемента);
КонецЦикла;
ДобавитьВТаблицуТипов(ТаблицаТипов, ТаблицаТиповИзТекста[0]);
ТаблицаТипов.ЗаполнитьЗначения(СтрокаСлова, "СтрокаОписания");
Прервать;
ИначеЕсли Истина
И ИмяОбщегоТипаРодителяБезДеталей = "КлючИЗначение"
И ТипЗнч(МетаданныеРодителя) = Тип("Структура")
И СловоЦикл = "Ключ"
// Опасно, но более надежного простого способа отличить "Соответствие" не нашел
И Не (Истина
И МетаданныеРодителя.Количество() = 2
И МетаданныеРодителя.Свойство("Значение")
И МетаданныеРодителя.Свойство("Ключ"))
Тогда
СтруктураТипа = НоваяСтруктураТипа("Строка");
// Мультиметка241116_130557 перенес выше
//ИначеЕсли Истина
// И (Ложь
// Или ИмяОбщегоТипаРодителяБезДеталей = "ПараметрыПеретаскивания"
// Или ИмяОбщегоТипаРодителяБезДеталей = "КлючИЗначение"
// Или ИмяОбщегоТипаРодителяБезДеталей = "ЭлементСпискаЗначений")
// И ТипЗнч(МетаданныеРодителя) = Тип("Структура")
// И МетаданныеРодителя.Свойство(СловоЦикл)
//Тогда
// ТаблицаТипов = МетаданныеРодителя[СловоЦикл];
// Если ТаблицаТипов <> Неопределено Тогда
// ТаблицаТипов.ЗаполнитьЗначения(СтрокаСлова, "СтрокаОписания");
// МожноУточнитьТип = Истина;
// Прервать;
// КонецЕсли;
//ИначеЕсли Истина
// И ИмяОбщегоТипаРодителяБезДеталей = "КлючИЗначение"
// И ТипЗнч(МетаданныеРодителя) = Тип("ТаблицаЗначений")
// И СловоЦикл = "Значение"
//Тогда
// ТаблицаТипов = МетаданныеРодителя;
// ТаблицаТипов.ЗаполнитьЗначения(СтрокаСлова, "СтрокаОписания");
// МожноУточнитьТип = Истина;
ИначеЕсли Истина
И ИмяОбщегоТипаРодителяБезДеталей = "Соответствие"
И СловоЦикл = "Получить"
И ТипЗнч(МетаданныеРодителя) = Тип("Структура")
Тогда
ТаблицаТипов = МетаданныеРодителя.Значение;
Если ТаблицаТипов <> Неопределено Тогда
ТаблицаТипов.ЗаполнитьЗначения(СтрокаСлова, "СтрокаОписания");
МожноУточнитьТип = Истина;
Прервать;
КонецЕсли;
ИначеЕсли Истина
И ИмяОбщегоТипаРодителяБезДеталей = "ХранилищеЗначения"
И СловоЦикл = "Получить"
И ТипЗнч(МетаданныеРодителя) = Тип("ТаблицаЗначений")
Тогда
ТаблицаТипов = МетаданныеРодителя;
Если ТаблицаТипов <> Неопределено Тогда
ТаблицаТипов.ЗаполнитьЗначения(СтрокаСлова, "СтрокаОписания");
МожноУточнитьТип = Истина;
Прервать;
КонецЕсли;
ИначеЕсли Истина
И ИмяОбщегоТипаРодителяБезДеталей = "ФабрикаXDTO"
И СловоЦикл = "ЭкспортМоделиXDTO"
И ТипСловаЦикл = ПеречТипСлова.Метод
Тогда
ДанныеИзТекста = ФабрикаXDTO.Создать(ФабрикаXDTO.Тип("http://v8.1c.ru/8.1/xdto", "Model"));
СтруктураТипа = СтруктураТипаИзЗначения(ДанныеИзТекста);
ИначеЕсли Истина
И ИмяОбщегоТипаРодителяБезДеталей = "Запрос"
И ИмяОбщегоТипаСлова = "МенеджерВременныхТаблиц"
Тогда
МенеджерВременныхТаблиц = РодительскаяСтруктураТипа.ДержательМетаданных;
Если Истина
И ТипЗнч(МенеджерВременныхТаблиц) = Тип("Структура")
//И МенеджерВременныхТаблиц.Тип = Тип("МенеджерВременныхТаблиц")
//И МенеджерВременныхТаблиц.Активен
Тогда
//СтруктураТипа = СтруктураТипаИзКонкретногоТипа(Тип("МенеджерВременныхТаблиц"));
СтруктураТипа.Метаданные = МенеджерВременныхТаблиц;
//ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа);
Иначе
СтруктураТипа.Метаданные = Неопределено;
КонецЕсли;
ИначеЕсли Истина
И (Ложь
Или РодительскаяСтруктураТипа.ИмяОбщегоТипа = "ЭлементыФормы"
Или РодительскаяСтруктураТипа.ИмяОбщегоТипа = "ВсеЭлементыФормы")
И ТипСловаЦикл = ПеречТипСлова.Метод
И (Ложь
Или СловоЦикл = "Добавить"
Или СловоЦикл = "Получить"
Или СловоЦикл = "Найти")
Тогда
ТаблицаТипов = ТаблицаТиповЭлементовКоллекции(РодительскаяСтруктураТипа,, ЯзыкПрограммы);
ТаблицаТипов.ЗаполнитьЗначения(СтрокаСлова, "СтрокаОписания");
Прервать;
ИначеЕсли Истина
И СловоЦикл = "ИсходныйКлючЗаписи"
//И ТипЗнч(МетаданныеРодителя) = Тип("ДанныеФормыСтруктура") // Такое условие будет часто не давать срабатывать ветке и потому это редко полезное свойство будет неоправданно добавляться
Тогда
ЛиДобавляемСлово = Истина
И ТипЗнч(МетаданныеРодителя) = Тип("ДанныеФормыСтруктура")
И ЗначениеСвойства <> Неопределено;
Если ЛиДобавляемСлово Тогда
СтруктураТипа = СтруктураТипаИзЗначения(ЗначениеСвойства, СтруктураТипа);
КонецЕсли;
Прервать;
ИначеЕсли Ложь
Или СловоЦикл = "ЭтотОбъект"
Или СловоЦикл = "ЭтаФорма"
Тогда
ЛиДобавляемСлово = Истина;
Если ирОбщий.ЛиИмяТипаФормыЛкс(ИмяОбщегоТипаРодителяБезДеталей, СловоЦикл = "ЭтаФорма", Истина) Тогда
СтруктураТипа = РодительскаяСтруктураТипа;
КонецЕсли;
Прервать;
ИначеЕсли Истина
И ТипСловаЦикл = "Свойство"
И СловоЦикл = "ТекущаяСтрока"
И (Ложь
Или ТипЗнч(МетаданныеРодителя) = Тип("ТаблицаФормы")
Или ТипЗнч(МетаданныеРодителя) = Тип("Структура") И МетаданныеРодителя.Тип = Тип("ТаблицаФормы"))
Тогда
Форма = РодительскаяСтруктураТипа.ДержательМетаданных;
ДанныеЭлементаФормы = ирОбщий.ДанныеЭлементаФормыЛкс(МетаданныеРодителя, , Форма);
СтруктураТипа.ИмяОбщегоТипа = "Число";
Если ТипЗнч(ДанныеЭлементаФормы) = Тип("ДинамическийСписок") Тогда
СтруктураТипаСписка = 0; // см. НоваяСтруктураТипа
ирОбщий.ОбщийТипДанныхТабличногоПоляЛкс(МетаданныеРодителя,, СтруктураТипаСписка, ИмяТаблицыБД);
Если ирОбщий.ЛиКорневойТипСсылкиЛкс(ИмяТаблицыБД) Тогда
СтруктураТипа.ИмяОбщегоТипа = ирОбщий.ИмяТипаИзПолногоИмениТаблицыБДЛкс(ИмяТаблицыБД);
СтруктураТипа.Метаданные = СтруктураТипаСписка.Метаданные;
КонецЕсли;
КонецЕсли;
ИначеЕсли Истина
И СловоЦикл = "ПолучитьСтруктуруХраненияБазыДанных"
И ТипСловаЦикл = ПеречТипСлова.Метод
И Метаданные.Справочники.Количество() > 0
Тогда
Отбор = Новый Массив;
Отбор.Добавить(Метаданные.Справочники[0]);
Образователь = ПолучитьСтруктуруХраненияБазыДанных(Отбор);
СтруктураТипа = СтруктураТипаИзЗначения(Образователь);
ИначеЕсли Истина
И СловоЦикл = "ВыбратьВерсии"
И ТипСловаЦикл = ПеречТипСлова.Метод
И Метаданные.Справочники.Количество() > 0
И ирКэш.ДоступноИсторияДанныхЛкс()
Тогда
Отбор = Новый Структура("Данные", Справочники[Метаданные.Справочники[0].Имя].ПолучитьСсылку());
Образователь = ирОбщий.ИсторияДанныхЛкс().ВыбратьВерсии(Отбор);
СтруктураТипа = СтруктураТипаИзЗначения(Образователь);
ИначеЕсли Истина
И СловоЦикл = "НайтиПоСсылкам"
И ТипСловаЦикл = ПеречТипСлова.Метод
Тогда
Образователь = НайтиПоСсылкам(Новый Массив);
СтруктураТипа = СтруктураТипаИзЗначения(Образователь);
ИначеЕсли Истина
И СловоЦикл = "ПроверитьЦиклическиеСсылкиВстроенногоЯзыка"
И ТипСловаЦикл = ПеречТипСлова.Метод
Тогда
СтруктураЦиклическая = Новый Структура;
СтруктураЦиклическая.Вставить("я", СтруктураЦиклическая); // Создаем цикл ссылок
Образователь = ирОбщий.ПроверитьЦиклическиеСсылкиВстроенногоЯзыкаЛкс(СтруктураЦиклическая); // Платформа создает колонки только при добавлении первой строки
СтруктураЦиклическая.я = Неопределено; // Разрываем цикл ссылок
СтруктураТипа = СтруктураТипаИзЗначения(Образователь);
ИначеЕсли Истина
И СловоЦикл = "ВыгрузитьЖурналРегистрации"
И ТипСловаЦикл = ПеречТипСлова.Метод
Тогда
Образователь = ирКэш.ПустаяТаблицаЖурналРегистрацииЛкс();
СтруктураТипа = СтруктураТипаИзЗначения(Образователь);
#Если Не Сервер Тогда
ИначеЕсли Истина
И СловоЦикл = "ПользователиОС"
И ТипСловаЦикл = ПеречТипСлова.Метод
Тогда
Образователь = ПользователиОС();
СтруктураТипа = СтруктураТипаИзЗначения(Образователь);
#КонецЕсли
#Если Клиент Тогда
ИначеЕсли Ложь
Или (Истина
И ТипСловаЦикл = ПеречТипСлова.Метод
И СловоЦикл = "ДанныеСтроки"
И (Ложь
Или ТипЗнч(МетаданныеРодителя) = Тип("ТаблицаФормы")
Или ТипЗнч(МетаданныеРодителя) = Тип("ТабличноеПоле")
Или ТипЗнч(МетаданныеРодителя) = Тип("Структура") И МетаданныеРодителя.Тип = Тип("ТаблицаФормы")))
Или (Истина
И ТипСловаЦикл = "Свойство"
И (Ложь
Или (Истина
И (Ложь
Или СловоЦикл = "ТекущиеДанные"
Или СловоЦикл = "ОформленияЯчеекДинамическогоСписка")
И (Ложь
Или ТипЗнч(МетаданныеРодителя) = Тип("ТаблицаФормы")
Или ТипЗнч(МетаданныеРодителя) = Тип("Структура") И МетаданныеРодителя.Тип = Тип("ТаблицаФормы")))
Или (Истина
И ТипЗнч(МетаданныеРодителя) = Тип("ТабличноеПоле")
И (Ложь
Или СловоЦикл = "ДанныеСтроки"
Или СловоЦикл = "ТекущаяСтрока"
Или СловоЦикл = "ТекущиеДанные"))))
Тогда
НоваяТаблицаТипов = ТаблицаТиповСтрокиТабличногоПоля(РодительскаяСтруктураТипа, МетаданныеРодителя, СловоЦикл, СтрокаСлова.ТипЗначения, СтруктураТипа.Метаданные);
Если НоваяТаблицаТипов <> Неопределено Тогда
ТаблицаТипов = НоваяТаблицаТипов;
ТаблицаТипов.ЗаполнитьЗначения(СтрокаСлова, "СтрокаОписания");
Прервать;
КонецЕсли;
#КонецЕсли
ИначеЕсли Истина
// Опасно широкое условие. Не подходит для Соответствие
И КорневойТипРодителя = Неопределено
И ТипСловаЦикл = ПеречТипСлова.Метод
И СловоЦикл = "Получить"
И СтрокаСлова.ТипЗначения = "Произвольный"
И ТипЗнч(МетаданныеРодителя) <> Тип("ПостроительЗапроса")
Тогда
ТаблицаТипов = ТаблицаТиповЭлементовКоллекции(РодительскаяСтруктураТипа,, ЯзыкПрограммы);
ТаблицаТипов.ЗаполнитьЗначения(СтрокаСлова, "СтрокаОписания");
Прервать;
КонецЕсли;
Если Истина
И КорневойТипРодителя <> Неопределено
И РодительскаяСтруктураТипа.ТипЯзыка <> "ЗначениеВЗапросе"
Тогда
ДоступноеПолеСлова = Неопределено;
Если ПостроительЗапросаРодителя <> Неопределено Тогда
ДоступноеПолеСлова = ПостроительЗапросаРодителя.ДоступныеПоля.Найти(НРег(СловоЦикл));
КонецЕсли;
// Частные случаи
Если Истина
И ПостроительЗапросаРодителя <> Неопределено
И ТипСловаЦикл <> ПеречТипСлова.Метод
И (Ложь
Или ЯзыкПрограммы > 0 И ТипСловаЦикл = "Свойство"
Или СловоЦикл = "Активность"
Или СловоЦикл = "Владелец"
Или СловоЦикл = "ВидДвижения"
Или СловоЦикл = "Код"
Или СловоЦикл = "МоментВремени"
Или СловоЦикл = "Представление"
Или СловоЦикл = "НомерСтроки"
Или СловоЦикл = "Период"
Или СловоЦикл = "Регистратор"
//Или СловоЦикл = "СубконтоДт" // Закомментировано 14.04.2012
//Или СловоЦикл = "СубконтоКт" // Закомментировано 14.04.2012
Или СловоЦикл = "СчетДт"
Или СловоЦикл = "СчетКт"
Или ЛиТипСКвалификаторами И ДоступноеПолеСлова <> Неопределено)
Тогда
Если ДоступноеПолеСлова = Неопределено Тогда
ЛиДобавляемСлово = Ложь;
Иначе
ОписаниеТиповСлова = ДоступноеПолеСлова.ТипЗначения;
// Мультиметка73777324
Для Каждого ТипЗначенияСлова Из ОписаниеТиповСлова.Типы() Цикл
ШаблонСтруктурыТипа = Новый Структура("СтрокаОписания, ТипЯзыка, Квалификаторы");
ШаблонСтруктурыТипа.СтрокаОписания = СтрокаСлова;
ШаблонСтруктурыТипа.Квалификаторы = ОписаниеТиповСлова;
ЗаполнитьЗначенияСвойств(ШаблонСтруктурыТипа, РодительскаяСтруктураТипа, "ТипЯзыка");
СтруктураТипа = СтруктураТипаИзКонкретногоТипа(ТипЗначенияСлова, ЯзыкПрограммы, ШаблонСтруктурыТипа);
ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа);
КонецЦикла;
КонецЕсли;
Прервать;
ИначеЕсли Ложь
Или (Истина
И ИмяОбщегоТипаРодителяБезДеталей = "КонстантаМенеджер.<Имя константы>"
И СловоЦикл = "Получить")
Или (Истина
И ИмяОбщегоТипаРодителяБезДеталей = "КонстантаМенеджерЗначения.<Имя константы>"
И СловоЦикл = "Значение")
Тогда
//: МетаданныеРодителя = 0 // ОбъектМетаданныхКонстанта
ОписаниеТиповСлова = МетаданныеРодителя.Тип;
// Мультиметка73777324
Для Каждого ТипЗначенияСлова Из ОписаниеТиповСлова.Типы() Цикл
ШаблонСтруктурыТипа = Новый Структура("СтрокаОписания, ТипЯзыка, Квалификаторы");
ШаблонСтруктурыТипа.СтрокаОписания = СтрокаСлова;
ШаблонСтруктурыТипа.Квалификаторы = ОписаниеТиповСлова;
ЗаполнитьЗначенияСвойств(ШаблонСтруктурыТипа, РодительскаяСтруктураТипа, "ТипЯзыка");
СтруктураТипа = СтруктураТипаИзКонкретногоТипа(ТипЗначенияСлова, ЯзыкПрограммы, ШаблонСтруктурыТипа);
ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа);
КонецЦикла;
ИначеЕсли Истина
И ТипСловаЦикл = ПеречТипСлова.Метод
И (Ложь
Или СловоЦикл = "Выгрузить"
Или СловоЦикл = "ВыгрузитьКолонки")
И ТипЗнч(СтрокаОбщегоТипа.Метаданные) = Тип("ОбъектМетаданных")
Тогда
Образователь = МетаКолонкиФункцииВыгрузитьКолонки(СтрокаОбщегоТипа);
Если Образователь <> Неопределено Тогда
СтруктураТипа.Метаданные = Образователь;
КонецЕсли;
ИначеЕсли Истина
И (Ложь
Или СловоЦикл = "СрезПервых"
Или СловоЦикл = "СрезПоследних")
И КорневойТипРодителя = "РегистрСведений"
И МетаданныеРодителя.ПериодичностьРегистраСведений = мМетаданные.СвойстваОбъектов.ПериодичностьРегистраСведений.Непериодический
Тогда
ЛиДобавляемСлово = Ложь;
Прервать;
ИначеЕсли Истина
И (Ложь
Или СловоЦикл = "Остатки"
Или СловоЦикл = "ОстаткиИОбороты")
И КорневойТипРодителя = "РегистрНакопления"
И МетаданныеРодителя.ВидРегистра = мМетаданные.СвойстваОбъектов.ВидРегистраНакопления.Обороты
Тогда
ЛиДобавляемСлово = Ложь;
Прервать;
ИначеЕсли Истина
И СловоЦикл = "ОборотыДтКт"
И КорневойТипРодителя = "РегистрБухгалтерии"
И Не МетаданныеРодителя.Корреспонденция
Тогда
ЛиДобавляемСлово = Ложь;
Прервать;
ИначеЕсли Истина
И СловоЦикл = "ФактическийПериодДействия"
И КорневойТипРодителя = "РегистрРасчета"
И Не МетаданныеРодителя.ПериодДействия
Тогда
ЛиДобавляемСлово = Ложь;
Прервать;
ИначеЕсли Истина
И СловоЦикл = "ДанныеГрафика"
И КорневойТипРодителя = "РегистрРасчета"
И МетаданныеРодителя.График = Неопределено
Тогда
ЛиДобавляемСлово = Ложь;
Прервать;
Иначе
ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа);
КонецЕсли;
ИначеЕсли Истина
И СловоЦикл = "Выполнить"
И ТипСловаЦикл = ПеречТипСлова.Метод
И ТипЗнч(МетаданныеРодителя) = Тип("Запрос")
Тогда
ПостроительЗапроса = ПостроительЗапросаИзТекстаДляТипа(МетаданныеРодителя.Текст);
СтруктураТипа.Метаданные = ПостроительЗапроса;
ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа, Ложь);
ИначеЕсли Истина
И СловоЦикл = "Выгрузить"
И ТипСловаЦикл = ПеречТипСлова.Метод
И (Ложь
Или ТипЗнч(МетаданныеРодителя) = Тип("Запрос")
Или ТипЗнч(МетаданныеРодителя) = Тип("ПостроительЗапроса"))
Тогда
ПостроительЗапроса = МетаданныеРодителя;
Если ТипЗнч(ПостроительЗапроса) = Тип("Запрос") Тогда
ПостроительЗапроса = ПостроительЗапросаИзТекстаДляТипа(ПостроительЗапроса.Текст);
КонецЕсли;
ПодготовитьМетаданныеПостроителяЗапроса(ПостроительЗапроса, РодительскаяСтруктураТипа.ДержательМетаданных);
СтруктураТипа.Метаданные = ПустаяТаблицаЗначенийИзПостроителя(ПостроительЗапроса);
ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа, Ложь);
ИначеЕсли Истина
И СловоЦикл = "Выгрузить"
И ТипСловаЦикл = ПеречТипСлова.Метод
И (Ложь
Или ТипЗнч(СтрокаОбщегоТипа.Метаданные) = Тип("ДанныеФормыКоллекция")
Или ТипЗнч(СтрокаОбщегоТипа.Метаданные) = Тип("ДанныеФормыСтруктураСКоллекцией"))
Тогда
#Если Клиент Тогда
ТаблицаЗначений = Новый ТаблицаЗначений;
Для Каждого КлючИЗначение Из ДочерниеСвойстваДанныхФормы(МетаданныеРодителя,, РодительскаяСтруктураТипа.ДержательМетаданных, СловоФильтр) Цикл
ТаблицаЗначений.Колонки.Добавить(КлючИЗначение.Ключ, КлючИЗначение.Значение);
КонецЦикла;
СтруктураТипа.Метаданные = ТаблицаЗначений;
ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа, Ложь);
#КонецЕсли
ИначеЕсли Истина
И СловоЦикл = "ВыгрузитьЗначения"
И ТипСловаЦикл = ПеречТипСлова.Метод
И ТипЗнч(МетаданныеРодителя) = Тип("Структура")
Тогда
СтруктураТипа.Метаданные = МетаданныеРодителя.Значение;
ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа, Ложь);
ИначеЕсли Истина
И СловоЦикл = "Значение"
И ТипСловаЦикл = "Свойство"
И ТипЗнч(СтрокаОбщегоТипа.Метаданные) = Тип("СписокЗначений")
И СтрокаОбщегоТипа.Метаданные.ТипЗначения.Типы().Количество() = 1
Тогда
СтруктураТипа = СтруктураТипаИзКонкретногоТипа(СтрокаОбщегоТипа.Метаданные.ТипЗначения.Типы()[0]);
ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа, Ложь);
ИначеЕсли Истина
И ИмяОбщегоТипаРодителяБезДеталей = "ОбъектМетаданныхКонфигурация"
И ТипСловаЦикл = "Свойство"
И ирОбщий.СтрНачинаетсяСЛкс(ИмяОбщегоТипаСлова, МаркерКоллекцииМетаданных)
Тогда
СтруктураТипа.Метаданные = Метаданные[СловоЦикл];
ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа, Ложь);
Иначе
Если Истина
И ИмяОбщегоТипаСлова = "Форма" // TODO возможно нужно заменить на ирОбщий.ЛиИмяТипаФормыЛкс()
И СловоЦикл = "ЭтаФорма"
Тогда
// Эта пока не несет пользы, но возможно дополнительные типы потом снова начну использовать
ДобавитьВТаблицуТипов(ТаблицаТипов, РодительскаяСтруктураТипа, Истина);
Иначе
ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа, Ложь);
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если Не ЛиДобавляемСлово Тогда
Продолжить;
КонецЕсли;
Если ТаблицаТипов.Количество() = 0 Тогда
ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа);
КонецЕсли;
ТаблицаТипов.ЗаполнитьЗначения(СтрокаСлова, "СтрокаОписания");
КонецЕсли;
ТипЗначенияИндекс = СтрокаСлова.ТипЗначения;
Если ЛиТипСКвалификаторами Или МожноУточнитьТип Тогда
ТипЗначения = "??," + ТипЗначенияИндекс;
Иначе
ТипЗначения = ТипЗначенияИндекс;
КонецЕсли;
ДобавитьВТаблицуСлов(ТаблицаСлов, СловоЦикл, ТипСловаЦикл, ТаблицаТипов, ТипЗначения, "Предопределенный",,,, ЛиПолныйКонтрольУникальности, ТипЗначенияИндекс);
КонецЦикла;
Если ИспользоватьКэширование И Не ЛиПолноеКэширование Тогда
СтруктураТипаГлобальный = НоваяСтруктураТипа(ИмяОбщегоТипаРодителяБезДеталей);
СтруктураТипаГлобальный.Метаданные = МетаданныеРодителя;
СтруктураТипаГлобальный.Конструктор = РодительскаяСтруктураТипа.Конструктор;
СтруктураТипаГлобальный.ТипЯзыка = РодительскаяСтруктураТипа.ТипЯзыка;
ПараметрыЗаполнения.ТаблицаСлов = ТаблицаСлов;
СловаКонтекстаМетаданные(СтруктураТипаГлобальный, ПараметрыЗаполнения);
ДобавитьТаблицуСловВГлобальныйКэш(ТаблицаСлов, КлючКэширования, НаборыСлов);
КлючКэширования = Неопределено;
КонецЕсли;
// Ускорение
Если Истина
И РодительскаяСтруктураТипа.ИмяОбщегоТипа = "ОбъектМетаданных"
И ЗначениеЗаполнено(СловоФильтр)
И ТаблицаСлов.Количество() > 0
Тогда
Прервать;
КонецЕсли;
// Удаляем перегрузку метода глобального контекста методом объекта
// Например ОбработкаОбъект.ПолучитьФорму(), Форма.ПодключитьОбработчикОжидания()
Пока Истина
И ЗначениеЗаполнено(СловоФильтр)
И ТаблицаСлов.Количество() > 1
И ТаблицаСлов[0].ТипСлова = ТаблицаСлов[1].ТипСлова
Цикл
ТаблицаСлов.Удалить(0);
КонецЦикла;
КонецЦикла;
Возврат ТаблицаСлов;
КонецФункции
Функция МетаКолонкиФункцииВыгрузитьКолонки(Знач СтруктураТипа, Знач ИменаКолонок = Неопределено) Экспорт
ИмяКонкретногоТипа = ИмяТипаИзСтруктурыТипа(СтруктураТипа);
Образователь = Неопределено;
Если Ложь
Или НРег(ИмяКонкретногоТипа) = Нрег("ТабличнаяЧасть") // СтрокаОбщегоТипа
Или Найти(ИмяКонкретногоТипа, "ТабличнаяЧасть.") > 0
Тогда
Образователь = ирОбщий.УстановитьМетаданныеКоллекцииЛкс(СтруктураТипа.Метаданные,, ИменаКолонок);
ИменаКолонок = Неопределено;
ИначеЕсли НРег(СтруктураТипа.ИмяОбщегоТипа) = Нрег("ПланСчетовВидыСубконто.<Имя плана счетов>") Тогда
МассивФрагментов = ирОбщий.СтрРазделитьЛкс(СтруктураТипа.Метаданные.ПолноеИмя());
СтруктураОбъекта = ирОбщий.ОбъектБДПоКлючуЛкс(МассивФрагментов[0] + "." + МассивФрагментов[1]);
РеквизитыСчета = СтруктураОбъекта.Данные; // ПланСчетовОбъект
Образователь = РеквизитыСчета.ВидыСубконто;
ИначеЕсли Ложь
Или НРег(СтруктураТипа.ИмяОбщегоТипа) = Нрег("ВытесняющиеВидыРасчета.<Имя плана видов расчета>")
Или НРег(СтруктураТипа.ИмяОбщегоТипа) = Нрег("БазовыеВидыРасчета.<Имя плана видов расчета>")
Или НРег(СтруктураТипа.ИмяОбщегоТипа) = Нрег("ВедущиеВидыРасчета.<Имя плана видов расчета>")
Тогда
МассивФрагментов = ирОбщий.СтрРазделитьЛкс(СтруктураТипа.Метаданные.ПолноеИмя());
СтруктураОбъекта = ирОбщий.ОбъектБДПоКлючуЛкс(МассивФрагментов[0] + "." + МассивФрагментов[1]);
ИмяТЧ = ирОбщий.ПервыйФрагментЛкс(СтруктураТипа.ИмяОбщегоТипа);
Попытка
Образователь = СтруктураОбъекта.Данные[ИмяТЧ];
Исключение
КонецПопытки;
ИначеЕсли Найти(ИмяКонкретногоТипа, "<") = 0 Тогда
СтруктураОбъекта = ирОбщий.ОбъектБДПоКлючуЛкс(ирКэш.ИмяТаблицыИзМетаданныхЛкс(СтруктураТипа.Метаданные.ПолноеИмя()));
Образователь = СтруктураОбъекта.Данные;
КонецЕсли;
Если Образователь <> Неопределено Тогда
Если ТипЗнч(Образователь) <> Тип("ТаблицаЗначений") Тогда
//! Образователь = 0; // ТабличнаяЧасть
Попытка
Образователь = Образователь.ВыгрузитьКолонки(ИменаКолонок);
Исключение
КонецПопытки;
ИначеЕсли ЗначениеЗаполнено(ИменаКолонок) Тогда
Попытка
Образователь = Образователь.СкопироватьКолонки(ИменаКолонок);
Исключение
КонецПопытки;
КонецЕсли;
КонецЕсли;
Возврат Образователь;
КонецФункции
Функция НовыйИмитаторЭлементаФормы() Экспорт
Возврат Новый Структура("Тип, ПутьКДанным, Значение, Имя");
КонецФункции
Функция ПроверятьДоступностьВКонтекстеКомпиляции(Знач ФлагиКомпиляции, Знач РодительскаяСтруктураТипа, Знач ЭтоЛокальныйКонтекст) Экспорт
Результат = ФлагиКомпиляции <> Неопределено
И Не (Истина
// В таких модулях часто применяют инструкции препроцессора, которые анализатор пока не учитывает
И ФлагиКомпиляции.Сервер
И ФлагиКомпиляции.КлиентОбычноеПриложение
И Не (Истина
И ирОбщий.ЛиИмяТипаФормыЛкс(РодительскаяСтруктураТипа.ИмяОбщегоТипа)
И ЭтоЛокальныйКонтекст))
И Не (Истина // Чтобы СправочникОбъект в реквизите имитатора упр. формы на клиенте показывал дочерние свойства
И ТипЗнч(РодительскаяСтруктураТипа.ДержательМетаданных) = Тип("Структура")
И ирОбщий.ЛиФормаИлиИмитаторЛкс(РодительскаяСтруктураТипа.ДержательМетаданных, Ложь)
И ТипЗнч(РодительскаяСтруктураТипа.СтрокаОписания) = Тип("СтрокаТаблицыЗначений")
И РодительскаяСтруктураТипа.СтрокаОписания.Владелец().Колонки.Найти("Слово") <> Неопределено // Защита от переменной модуля
И (Ложь
Или РодительскаяСтруктураТипа.СтрокаОписания.Слово = "<Имя реквизита>"
Или РодительскаяСтруктураТипа.СтрокаОписания.Слово = "<Имя табличной части>")
И (Ложь
Или Не ФлагиКомпиляции.Сервер
Или ФлагиКомпиляции.БезКонтекста // чтобы в &НаКлиентеНаСервереБезКонтекста работало после ЭтаФорма.Объект.
));
Возврат Результат;
КонецФункции
//.
// Параметры:
// ИмяОбщегоТипа - Строка -
// Возвращаемое значение:
// Строка, Неопределено - выходной, Неопределено - не использовать кэш, Истина - полная таблица взята из кэша
Функция КлючКэшированияСловИзОбщегоТипа(Знач ИмяОбщегоТипа) Экспорт
Возврат ИмяОбщегоТипа;
КонецФункции
//.
// Параметры:
// ТаблицаСлов - ТаблицаЗначений -
// КлючКэширования - Строка -
// НаборыСлов - -
Процедура ДобавитьТаблицуСловВГлобальныйКэш(Знач ТаблицаСлов, Знач КлючКэширования, Знач НаборыСлов) Экспорт
ТаблицаСловИзКэша = ТаблицаСлов.Скопировать();
мКэшСловГлобальногоКонтекста[КлючКэширования] = ТаблицаСловИзКэша;
Если НаборыСлов <> Неопределено Тогда
НаборыСлов.Вставить(КлючКэширования, ТаблицаСловИзКэша);
ТаблицаСлов.Очистить();
КонецЕсли;
КонецПроцедуры
//.
// Параметры:
// ПостроительЗапроса - ПостроительЗапроса -
// Возвращаемое значение:
// ТаблицаЗначений, Неопределено -
Функция ПустаяТаблицаЗначенийИзПостроителя(Знач ПостроительЗапроса) Экспорт
ТаблицаЗначений = Новый ТаблицаЗначений;
Для Каждого ВыбранноеПоле Из ПостроительЗапроса.ВыбранныеПоля Цикл
ТаблицаЗначений.Колонки.Добавить(ВыбранноеПоле.Имя, ПостроительЗапроса.ДоступныеПоля[ВыбранноеПоле.Имя].ТипЗначения);
КонецЦикла;
Возврат ТаблицаЗначений;
КонецФункции
Функция МаксРазмерТаблицыТиповДляЗаполненияТаблицыСлов() Экспорт
// У группы общих модулей БСП.ОбщегоНазначения* - 11шт
Возврат 15;
КонецФункции
// Получает внутреннюю таблицу метаданных слов заданного родительского типа.
// Параметры:
// РодительскаяСтруктураТипа - см. НоваяСтруктураТипа -
// ПараметрыЗаполнения - см. НовыеПараметрыЗаполненияСлов -
// КлючКэширования - -
// Возвращаемое значение:
// см. НоваяТаблицаСлов -
Функция СловаКонтекстаМетаданные(Знач РодительскаяСтруктураТипа, Знач ПараметрыЗаполнения, КлючКэширования = Неопределено) Экспорт
ТаблицаСлов = ПараметрыЗаполнения.ТаблицаСлов;
Если ТаблицаСлов = Неопределено Тогда
ТаблицаСлов = НоваяТаблицаСлов();
КонецЕсли;
ТипСловаФильтр = ПараметрыЗаполнения.ТипСловаФильтр;
Если Ложь
Или ТипСловаФильтр = "Конструктор"
Или РодительскаяСтруктураТипа.Конструктор
Или Не ЗначениеЗаполнено(РодительскаяСтруктураТипа.ИмяОбщегоТипа) // родительский контекст является процедурой
Или РодительскаяСтруктураТипа.ИмяОбщегоТипа = "Произвольный"
Или РодительскаяСтруктураТипа.ИмяОбщегоТипа = "Неопределено"
Тогда
Возврат ТаблицаСлов;
КонецЕсли;
БазовоеРасширениеКонфигурации = ПараметрыЗаполнения.БазовоеРасширениеКонфигурации;
ВнутриГруппыОбщихМодулей = ПараметрыЗаполнения.ВнутриГруппыОбщихМодулей;
ВычислятьТипы = ПараметрыЗаполнения.ВычислятьТипы;
ВычислятьТипыМетодовМодулей = ПараметрыЗаполнения.ВычислятьТипыМетодовМодулей;
ДляЗаписи = ПараметрыЗаполнения.ДляЗаписи;
ДляСвойства = ПараметрыЗаполнения.ДляСвойства;
ЗапретГлобальногоКонтекста = ПараметрыЗаполнения.ЗапретГлобальногоКонтекста;
ЛиВместеСЛокальнымКонтекстом = ПараметрыЗаполнения.ЛиВместеСЛокальнымКонтекстом;
НаборыСлов = ПараметрыЗаполнения.НаборыСлов;
СловоФильтр = ПараметрыЗаполнения.СловоФильтр;
ТекущийИндекс = ПараметрыЗаполнения.ТекущийИндекс;
ТолькоСоЗначениями = ПараметрыЗаполнения.ТолькоСоЗначениями;
ФлагиКомпиляции = ПараметрыЗаполнения.ФлагиКомпиляции;
ЭтоЛокальныйКонтекст = ПараметрыЗаполнения.ЭтоЛокальныйКонтекст;
ЯзыкПрограммы = ПараметрыЗаполнения.ЯзыкПрограммы;
Если РодительскаяСтруктураТипа.ТипЯзыка = "ЗначениеВЗапросе" Тогда
ЯзыкПрограммы = 1;
КонецЕсли;
// Мультиметка3398476724
ЛиСеансТолстогоКлиентаУП = ирКэш.ЛиСеансТолстогоКлиентаУПЛкс();
НаСервере = ирОбщий.СвойствоСтруктурыЛкс(ФлагиКомпиляции, "Сервер", Истина);
КлиентОбычноеПриложение = ирОбщий.СвойствоСтруктурыЛкс(ФлагиКомпиляции, "КлиентОбычноеПриложение", Не ЛиСеансТолстогоКлиентаУП);
КлиентУправляемоеПриложение = ирОбщий.СвойствоСтруктурыЛкс(ФлагиКомпиляции, "КлиентУправляемоеПриложение", ЛиСеансТолстогоКлиентаУП);
БезКонтекста = ирОбщий.СвойствоСтруктурыЛкс(ФлагиКомпиляции, "БезКонтекста", ЛиСеансТолстогоКлиентаУП);
ПредставлениеМетаданных = ирОбщий.ПредставлениеЗначенияЛкс(РодительскаяСтруктураТипа.Метаданные);
ЭтоМетаданныеТабличнойЧастиВнешнейОбработки = ирОбщий.ПервыйФрагментЛкс(ПредставлениеМетаданных) = "ВнешняяОбработкаТабличнаяЧасть";
//Если Не ирОбщий.СтрНачинаетсяСЛкс(ПредставлениеМетаданных, "Внешн") Тогда // Не подходит для незаписанной внешней обработки
Если Не ирОбщий.СтрНачинаетсяСЛкс(РодительскаяСтруктураТипа.ИмяОбщегоТипа, "Внешн") Тогда
КонкретныйТип = ИмяТипаИзСтруктурыТипа(РодительскаяСтруктураТипа);
Если Найти(ирОбщий.ПервыйФрагментЛкс(КонкретныйТип, "["), "<") > 0 Тогда
// Такой конкретный тип не разрешен
Возврат ТаблицаСлов;
КонецЕсли;
КонецЕсли;
ЛиВместеСЛокальнымКонтекстом = ЛиВместеСЛокальнымКонтекстом Или ЭтоЛокальныйКонтекст;
Если ВычислятьТипыМетодовМодулей = Неопределено Тогда
ВычислятьТипыМетодовМодулей = СловоФильтр <> Неопределено;
КонецЕсли;
Если СловоФильтр <> Неопределено И ТекущийИндекс <> Неопределено Тогда
ЛиСтруктура = Ложь
Или РодительскаяСтруктураТипа.ИмяОбщегоТипа = "Структура"
Или РодительскаяСтруктураТипа.ИмяОбщегоТипа = "ФиксированнаяСтруктура";
Если Не ЛиСтруктура Тогда
ОписаниеОбщегоТипа = ОписаниеОбщегоТипа(РодительскаяСтруктураТипа.ИмяОбщегоТипа, ЯзыкПрограммы);
Если Истина
И ОписаниеОбщегоТипа <> Неопределено
И ОписаниеОбщегоТипа.ТипЭлементаКоллекции = "КлючИЗначение"
Тогда
Если Истина
И ТипЗнч(РодительскаяСтруктураТипа.Метаданные) = Тип("Соответствие")
И Лев(СловоФильтр, 1) = """"
Тогда
ТаблицаТипов = ТаблицаТиповИзЗначения(РодительскаяСтруктураТипа.Метаданные[ирОбщий.ТекстБезКрайнихСимволовЛкс(СловоФильтр)]);
Иначе
ТаблицаТиповЭлементов = ТаблицаТиповЭлементовКоллекции(РодительскаяСтруктураТипа, СловоФильтр, ЯзыкПрограммы);
СтруктураСвойств = ТаблицаТиповЭлементов[0].Метаданные;
ТаблицаТипов = ДобавитьВТаблицуТипов(ТаблицаТипов, НоваяСтруктураТипа("Неопределено"));
Если Истина
И ТипЗнч(СтруктураСвойств) = Тип("Структура")
И СтруктураСвойств.Значение <> Неопределено
Тогда
ТаблицаТипов = ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураСвойств.Значение);
КонецЕсли;
КонецЕсли;
ДобавитьВТаблицуСлов(ТаблицаСлов, "*", "Свойство", ТаблицаТипов,, "Метаданные1");
Возврат ТаблицаСлов;
КонецЕсли;
КонецЕсли;
ЛиИндексИдентификатор = Ложь;
мРегВыражение.Pattern = "^""(" + шИмя + ")""$";
РезультатСтроковойКонстанты = мРегВыражение.НайтиВхождения(СловоФильтр);
Если РезультатСтроковойКонстанты.Количество() > 0 Тогда
СловоФильтр = РезультатСтроковойКонстанты[0].SubMatches(0);
ЛиИндексИдентификатор = Истина;
КонецЕсли;
Если ЛиСтруктура Тогда
// у них значениями именованных свойств являются произвольные типы. Их вычисляем дальше.
Иначе
Если Не ЛиИндексИдентификатор Тогда
ТаблицаТипов = ТаблицаТиповЭлементовКоллекции(РодительскаяСтруктураТипа, СловоФильтр, ЯзыкПрограммы);
ДобавитьВТаблицуСлов(ТаблицаСлов, "*", "Свойство", ТаблицаТипов,, "Метаданные1");
Возврат ТаблицаСлов;
КонецЕсли;
КонецЕсли;
КонецЕсли;
ЭтоГруппаОбщихМодулей = Ложь;
ПолноеИмяПодсистемыИР = ирОбщий.ИмяПродуктаЛкс();
МаксЧислоТиповДляАнализа = МаксЧислоТиповДляАнализа();
ИмяКолонкиФлагаТаблицыТипов = ИмяКолонкиФлагаТаблицыТипов();
ТаблицаОбщихТиповСтруктурыТипа = РазвернутаяТаблицаТиповИзСтруктурыТипа(РодительскаяСтруктураТипа, ЭтоЛокальныйКонтекст, Ложь);
ЕдинственнаяСтрокаВида = Неопределено;
ПроверятьДоступностьВКонтекстеКомпиляции = ПроверятьДоступностьВКонтекстеКомпиляции(ФлагиКомпиляции, РодительскаяСтруктураТипа, ЭтоЛокальныйКонтекст);
Для Каждого СтрокаОбщегоТипа Из ТаблицаОбщихТиповСтруктурыТипа Цикл
ИмяОбщегоТипаРодителя = СтрокаОбщегоТипа.ИмяОбщегоТипа;
Если ЗапретГлобальногоКонтекста И ИмяОбщегоТипаРодителя = "Глобальный" Тогда
Продолжить;
КонецЕсли;
Если Истина
И ИмяОбщегоТипаРодителя = "Глобальный"
И РодительскаяСтруктураТипа.ИмяОбщегоТипа <> "Глобальный" // пропускаем вызов для заполнения кэша
И СловоФильтр = Неопределено
И ТекущийИндекс = Неопределено
Тогда
// Подразумеваем, что в ТаблицаСлов уже помещен кэш Предопределенные+Метаданные
Продолжить;
КонецЕсли;
Если ирОбщий.СтрокиРавныЛкс(ИмяОбщегоТипаРодителя, "ISWbemObject {WbemScripting.SwbemLocator}") Тогда
Если ТипЗнч(СтрокаОбщегоТипа.Метаданные) = Тип("COMОбъект") Тогда
СтруктураЦикла = Новый Структура();
Попытка
СтруктураЦикла.Вставить("Свойство", СтрокаОбщегоТипа.Метаданные.Properties_);
СтруктураЦикла.Вставить("Метод", СтрокаОбщегоТипа.Метаданные.Methods_);
Исключение
КонецПопытки;
Для Каждого КлючИЗначение Из СтруктураЦикла Цикл
КоллекцияСвойств = КлючИЗначение.Значение;
ТипСловаЧленаКласса = КлючИЗначение.Ключ;
Если Истина
И ТипСловаФильтр <> Неопределено
И Не ирОбщий.СтрокиРавныЛкс(ТипСловаЧленаКласса, ТипСловаФильтр)
Тогда
Продолжить;
КонецЕсли;
Для Каждого Свойство Из КоллекцияСвойств Цикл
ИмяСвойства = Свойство.Name;
Если Истина
И СловоФильтр <> Неопределено
И Не ирОбщий.СтрокиРавныЛкс(ИмяСвойства, СловоФильтр)
Тогда
Продолжить;
КонецЕсли;
ТаблицаТипов = НоваяТаблицаТипов();
СтруктураТипа = ТаблицаТипов.Добавить();
СтруктураТипа.СтрокаОписания = Свойство;
СтруктураТипа.ИмяОбщегоТипа = ирОбщий.ИмяТипаИзКвалификаторовWMIЛкс(Свойство);
СтруктураТипа.Метаданные = РодительскаяСтруктураТипа.Метаданные;
ДобавитьВТаблицуСлов(ТаблицаСлов, ИмяСвойства, ТипСловаЧленаКласса, ТаблицаТипов,, "Метаданные");
КонецЦикла;
КонецЦикла;
КонецЕсли;
КонецЕсли;
МетаданныеРодителя = СтрокаОбщегоТипа.Метаданные;
Если Ложь
Или ИмяОбщегоТипаРодителя = "Локальный"
Или (Истина
И ИмяОбщегоТипаРодителя <> "Глобальный"
И ФлагиКомпиляции <> Неопределено
И ФлагиКомпиляции.БезКонтекста
И ЭтоЛокальныйКонтекст)
Тогда
НайденныеСтроки = Новый Массив;
Иначе
КорневойТипРодителя = Неопределено;
ПостроительЗапросаРодителя = Неопределено;
Если РодительскаяСтруктураТипа.ТипЯзыка <> "ИмяТипа" Тогда
ТипМетаданныхРодителя = ТипЗнч(МетаданныеРодителя);
Если Ложь
Или ТипМетаданныхРодителя = Тип("ОбъектМетаданных")
Или (Истина
И ЭтоИнтеграция
И (Ложь
Или ТипМетаданныхРодителя = Тип("СправочникСсылка.МетаданныеИис")
Или ТипМетаданныхРодителя = Тип("СправочникСсылка.СвойстваМетаданныхИис")))
Тогда
Если ТипМетаданныхРодителя = Тип("ОбъектМетаданных") Тогда
КорневойТипРодителя = ирОбщий.КорневойТипКонфигурацииЛкс(МетаданныеРодителя);
Иначе
КорневойТипРодителя = ирОбщий.КорневойТипКонфигурацииЛкс(КэшОбъект(МетаданныеРодителя).ПолноеИмя);
КонецЕсли;
ПостроительЗапросаРодителя = ПостроительЗапросаПоСтруктуреТипа(СтрокаОбщегоТипа, РодительскаяСтруктураТипа.ВиртуальнаяТаблица);
КонецЕсли;
КонецЕсли;
Если Истина
И ЯзыкПрограммы = 2
И ИмяОбщегоТипаРодителя = "Глобальный"
И ПараметрыЗаполнения.ВнешниеФункцииКомпоновкиДанных
Тогда
СтруктураКлюча = Новый Структура("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка, НСлово", ИмяОбщегоТипаРодителя, 0, РодительскаяСтруктураТипа.ТипЯзыка, НРег("<Имя общего модуля>"));
Иначе
СтруктураКлюча = Новый Структура("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка", ИмяОбщегоТипаРодителя, ЯзыкПрограммы, РодительскаяСтруктураТипа.ТипЯзыка);
КонецЕсли;
Если ТипСловаФильтр <> Неопределено Тогда
СтруктураКлюча.Вставить("ТипСлова", ТипСловаФильтр);
КонецЕсли;
НайденныеСтроки = ТаблицаШаблоновКонтекстов.НайтиСтроки(СтруктураКлюча);
КонецЕсли;
ПредыдущаяСтрокаВида = Неопределено; // см. НайденныеСтроки[0] - для регистра бухгалтерии
Для Каждого СтрокаСлова Из НайденныеСтроки Цикл
Если Ложь
Или (Истина
И ТолькоСоЗначениями
И ПустаяСтрока(СтрокаСлова.ТипЗначения)
И СтрокаСлова.ТипСлова <> "Свойство")
Или ДляЗаписи И Не СтрокаСлова.Запись
Или (Истина
// Для регистра бухгалтерии и ЭлементыФормы (первым идет управляемый вариант)
И ПредыдущаяСтрокаВида <> Неопределено
И ПредыдущаяСтрокаВида.НСлово = СтрокаСлова.НСлово
И ПредыдущаяСтрокаВида.ТипСлова = СтрокаСлова.ТипСлова)
Или СтрокаСлова.НомерВерсииПлатформы > мНомерВерсииПлатформы
Или СтрокаСлова.ТипСлова = "Событие"
Или (Истина
И ПроверятьДоступностьВКонтекстеКомпиляции
И (Ложь
Или ФлагиКомпиляции.Сервер И СтрокаСлова.НеСервер
Или ФлагиКомпиляции.КлиентОбычноеПриложение И СтрокаСлова.НеТолстыйКлиент
Или ФлагиКомпиляции.КлиентУправляемоеПриложение И Не ФлагиКомпиляции.КлиентОбычноеПриложение И СтрокаСлова.НеТонкийКлиент))
Тогда
Продолжить;
КонецЕсли;
// Нельзя делать переход, т.к. не будет работать перегрузка свойств, например "Параметры" в модуле конструктора запросов
//Если Истина
// И ЗначениеЗаполнено(СловоФильтр)
// И СтрокаСлова.Слово = "<Имя реквизита>"
// И ИмяОбщегоТипаРодителя = "Форма"
// И ТаблицаСлов.Количество() > 0
//Тогда
// Продолжить;
//КонецЕсли;
Если ЕдинственнаяСтрокаВида = Неопределено Тогда
ЕдинственнаяСтрокаВида = СтрокаСлова;
Иначе
ЕдинственнаяСтрокаВида = Null;
КонецЕсли;
Если СловоФильтр = "?" Тогда
Продолжить;
КонецЕсли;
ПредыдущаяСтрокаВида = СтрокаСлова;
ЛиТипСКвалификаторами = ирОбщий.ЛиИмяТипаСКвалификаторамиЛкс(СтрокаСлова.ТипЗначения);
СхемаКоллекции = Новый Соответствие;
МетаданныеЭлементов = Новый Соответствие;
КоллекцияЗначений = Неопределено;
ИмяЭлементаКоллекции = ирОбщий.ТекстМеждуМаркерамиЛкс(СтрокаСлова.Слово, "<", ">", Ложь, Истина);
КлючПоиска = Новый Структура("ИмяОбщегоТипа, ИмяЭлементаКоллекции", ИмяОбщегоТипаРодителя, ИмяЭлементаКоллекции);
СтрокаОписанияВида = Неопределено;
НайденныеСтрокиКоллекций = ТаблицаИменЭлементовКоллекций.НайтиСтроки(КлючПоиска);
Если НайденныеСтрокиКоллекций.Количество() > 0 Тогда
СтрокаОписанияВида = НайденныеСтрокиКоллекций[0];
Если НайденныеСтрокиКоллекций.Количество() > 1 Тогда
#Если Клиент Тогда
Если Истина
И СтрокаОписанияВида.ИмяКоллекции = "ПодчиненныеЭлементы"
И ТипЗнч(РодительскаяСтруктураТипа.Метаданные) = Тип("Форма")
Тогда
// Устранение неоднозначности одноименных типов "ЭлементыФормы" обычной и упрвляемой формы
СтрокаОписанияВида = НайденныеСтрокиКоллекций[1];
КонецЕсли;
#КонецЕсли
КонецЕсли;
КонецЕсли;
Если СтрокаОписанияВида = Неопределено Тогда
КлючПоиска.Удалить("ИмяОбщегоТипа");
НайденныеСтрокиКоллекций = ТаблицаИменЭлементовКоллекций.НайтиСтроки(КлючПоиска);
Если НайденныеСтрокиКоллекций.Количество() > 0 Тогда
СтрокаОписанияВида = НайденныеСтрокиКоллекций[0];
КонецЕсли;
КонецЕсли;
//// Исправление кривоты платформенной справки (неуникальные имена шаблона элемента коллекции между разными типами коллекций)
//Если ИмяЭлементаКоллекции = "<Имя элемента управления>" Тогда
// СтруктураОтбора = Новый Структура("ИмяЭлементаКоллекции, ИмяКоллекции", ИмяЭлементаКоллекции);
// Если ИмяОбщегоТипа = "ВсеЭлементыФормы" Тогда
// СтруктураОтбора.ИмяКоллекции = "Элементы";
// Иначе//Если ИмяОбщегоТипа = "ЭлементыФормы" Тогда
// СтруктураОтбора.ИмяКоллекции = "ЭлементыФормы";
// КонецЕсли;
// СтрокаОписанияВида = ТаблицаИменЭлементовКоллекций.НайтиСтроки(СтруктураОтбора)[0];
//ИначеЕсли ИмяЭлементаКоллекции = "<Имя колонки>" Тогда
// СтруктураОтбора = Новый Структура("ИмяЭлементаКоллекции, ИмяКоллекции", ИмяЭлементаКоллекции);
// Если ИмяОбщегоТипа = "Ячейки" Тогда
// СтруктураОтбора.ИмяКоллекции = "ОформленияЯчеек";
// Иначе//Если ИмяОбщегоТипа = "СтрокаТаблицыЗначений" Тогда
// СтруктураОтбора.ИмяКоллекции = "Колонки";
// КонецЕсли;
// СтрокаОписанияВида = ТаблицаИменЭлементовКоллекций.НайтиСтроки(СтруктураОтбора)[0];
//КонецЕсли;
Если СловоФильтр <> Неопределено Тогда
МассивФрагментов = ирОбщий.СтрРазделитьЛкс(СтрокаСлова.Слово, ИмяЭлементаКоллекции);
НачалоТекущегоСлова = Лев(СловоФильтр, СтрДлина(МассивФрагментов[0]));
КонецТекущегоСлова = Прав(СловоФильтр, СтрДлина(МассивФрагментов[1]));
ИмяТекущегоСлова = Сред(СловоФильтр, СтрДлина(НачалоТекущегоСлова) + 1,
СтрДлина(СловоФильтр) - СтрДлина(КонецТекущегоСлова));
Если НачалоТекущегоСлова + ИмяЭлементаКоллекции + КонецТекущегоСлова <> СтрокаСлова.Слово Тогда
Продолжить;
КонецЕсли;
КонецЕсли;
Если СтрокаОписанияВида = Неопределено Тогда
// Имя элемента коллекции не внесено в служебную таблицу
Продолжить;
КонецЕсли;
Если Истина
И СтрокаОписанияВида.ИмяКоллекции = "Предопределенные"
И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") //
Тогда
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ Т.Ссылка ИЗ " + МетаданныеРодителя.ПолноеИмя() + " КАК Т ГДЕ Т.Предопределенный";
Результат = Запрос.Выполнить().Выгрузить();
МенеджерТипа = ирОбщий.ПолучитьМенеджерЛкс(МетаданныеРодителя);
Для Каждого СтрокаРезультата Из Результат Цикл
СхемаКоллекции.Вставить(МенеджерТипа.ПолучитьИмяПредопределенного(СтрокаРезультата.Ссылка), Новый ОписаниеТипов(ирОбщий.ЗначенияВМассивЛкс(ТипЗнч(СтрокаРезультата.Ссылка))));
КонецЦикла;
ИначеЕсли Истина
И СтрокаОписанияВида.ИмяКоллекции = "Структура"
И ТипЗнч(МетаданныеРодителя) = Тип("Структура")
Тогда
КоллекцияЗначений = МетаданныеРодителя;
Если Истина
И ЗначениеЗаполнено(СловоФильтр)
И МетаданныеРодителя.Свойство(СловоФильтр)
Тогда
ТаблицаТиповСлова = МетаданныеРодителя[СловоФильтр];
Если Истина
И ТипЗнч(ТаблицаТиповСлова) = Тип("ТаблицаЗначений")
И ТаблицаТиповСлова.Колонки.Найти(ИмяКолонкиФлагаТаблицыТипов) <> Неопределено
И ТаблицаТиповСлова.Количество() > 0
И ТипЗнч(ТаблицаТиповСлова[0].СтрокаОписания) = Тип("Структура")
Тогда
ОписаниеСвойства = ТаблицаТиповСлова[0].СтрокаОписания; // см. ОбработкаОбъект.ирКлсПолеТекстаПрограммы.НовоеОписаниеДинамическогоСвойства
ОписаниеСвойства = ирОбщий.СкопироватьКоллекциюЛкс(ОписаниеСвойства);
ОписаниеСвойства.СтрокаОписания = СтрокаСлова;
КоллекцияЗначений = ирОбщий.СкопироватьКоллекциюЛкс(КоллекцияЗначений);
ТаблицаТиповСлова = КоллекцияЗначений[СловоФильтр].Скопировать();
ТаблицаТиповСлова.ЗаполнитьЗначения(ОписаниеСвойства, "СтрокаОписания");
КоллекцияЗначений[СловоФильтр] = ТаблицаТиповСлова;
КонецЕсли;
КонецЕсли;
ИначеЕсли Ложь
Или (Истина
И (Ложь
Или СтрокаОписанияВида.ИмяКоллекции = "Колонки"
Или СтрокаОписанияВида.ИмяКоллекции = "Поля")
И (Ложь
Или ТипЗнч(МетаданныеРодителя) = Тип("Структура")
Или ТипЗнч(МетаданныеРодителя) = Тип("РезультатЗапроса")
Или ТипЗнч(МетаданныеРодителя) = Тип("ТаблицаЗначений")
Или ТипЗнч(МетаданныеРодителя) = Тип("ДеревоЗначений")
Или ТипЗнч(МетаданныеРодителя) = Тип("ВыборкаИзРезультатаЗапроса")
Или ТипЗнч(МетаданныеРодителя) = Тип("СтрокаТаблицыЗначений")
Или ТипЗнч(МетаданныеРодителя) = Тип("СтрокаДереваЗначений")
))
Или (Истина
И СтрокаОписанияВида.ИмяЭлементаКоллекции = "<Имя колонки списка>"
И ТипЗнч(МетаданныеРодителя) = Тип("ТабличноеПоле"))
Тогда
Если ТипЗнч(МетаданныеРодителя) = Тип("Структура") Тогда
ОписаниеСвойства = Неопределено;
Если Истина
И ЗначениеЗаполнено(СловоФильтр)
И МетаданныеРодителя.Свойство(СловоФильтр)
И ЗначениеЗаполнено(МетаданныеРодителя[СловоФильтр])
И ТипЗнч(МетаданныеРодителя[СловоФильтр][0].СтрокаОписания) = Тип("Структура")
Тогда
ОписаниеСвойства = МетаданныеРодителя[СловоФильтр][0].СтрокаОписания; // см. ОбработкаОбъект.ирКлсПолеТекстаПрограммы.НовоеОписаниеДинамическогоСвойства
ОписаниеСвойства = ирОбщий.СкопироватьКоллекциюЛкс(ОписаниеСвойства);
ОписаниеСвойства.СтрокаОписания = СтрокаСлова;
КонецЕсли;
Если Ложь
Или СтрокаСлова.ТипЗначения = "КолонкаТаблицыЗначений"
Или СтрокаСлова.ТипЗначения = "КолонкаДереваЗначений"
Тогда
СхемаКоллекции = Новый Структура;
ОписаниеТиповКолонки = Новый ОписаниеТипов(СтрокаСлова.ТипЗначения);
Для Каждого КлючИЗначение Из МетаданныеРодителя Цикл
СхемаКоллекции.Вставить(КлючИЗначение.Ключ, ОписаниеТиповКолонки);
КонецЦикла;
Если ОписаниеСвойства <> Неопределено Тогда
ТаблицаТиповСлова = ТаблицаТиповИзОписанияТипов(ОписаниеТиповКолонки);
ТаблицаТиповСлова.ЗаполнитьЗначения(ОписаниеСвойства, "СтрокаОписания");
СхемаКоллекции[СловоФильтр] = ТаблицаТиповСлова;
КонецЕсли;
//
//Для Каждого КлючИЗначение Из МетаданныеРодителя Цикл
// СхемаКоллекции.Вставить(КлючИЗначение.Ключ); // Так всегда напрямую передаются метаданные родителя и потому в описании слова в свойствах появляется список всех колонок
//КонецЦикла;
Иначе
КоллекцияЗначений = МетаданныеРодителя;
Если ОписаниеСвойства <> Неопределено Тогда
КоллекцияЗначений = ирОбщий.СкопироватьКоллекциюЛкс(КоллекцияЗначений);
ТаблицаТиповСлова = КоллекцияЗначений[СловоФильтр].Скопировать();
ТаблицаТиповСлова.ЗаполнитьЗначения(ОписаниеСвойства, "СтрокаОписания");
КоллекцияЗначений[СловоФильтр] = ТаблицаТиповСлова;
КонецЕсли;
КонецЕсли;
ИначеЕсли Найти(ИмяОбщегоТипаРодителя, "Колон") = 0 Тогда // %%%% Некрасиво, но работает
Если СтрокаОписанияВида.ИмяЭлементаКоллекции = "<Имя колонки списка>" Тогда
ДинамическийСписок = МетаданныеРодителя.Значение;
ПостроительСписка = ПостроительЗапросаПоСтруктуреТипа(СтруктураТипаИзЗначения(ДинамическийСписок));
КоллекцияКолонок = ДинамическийСписок.Колонки;
Для Каждого Колонка Из КоллекцияКолонок Цикл
Если Колонка.Имя = "" Тогда
// Антибаг платформы 8.2.16
Продолжить;
КонецЕсли;
СхемаКоллекции.Вставить(Колонка.Имя, ПостроительСписка.ДоступныеПоля[Колонка.Имя].ТипЗначения);
КонецЦикла;
Иначе
Если Ложь
Или ТипЗнч(МетаданныеРодителя) = Тип("ВыборкаИзРезультатаЗапроса")
Или ТипЗнч(МетаданныеРодителя) = Тип("СтрокаТаблицыЗначений")
Или ТипЗнч(МетаданныеРодителя) = Тип("СтрокаДереваЗначений")
Тогда
Попытка
МетаОбъект = МетаданныеРодителя.Владелец();
Исключение
// Строка была удалена
МетаОбъект = Неопределено;
КонецПопытки;
Если МетаОбъект <> Неопределено Тогда
Для Каждого Колонка Из МетаОбъект.Колонки Цикл
Если Колонка.Имя = "" Тогда
// Строка таблицы/дерева при перетаскивании имеет такую колонку (вероятно ошибка платформы)
Продолжить;
КонецЕсли;
ТипЗначенияКолонки = Колонка.ТипЗначения;
Если ТипЗначенияКолонки.Типы().Количество() = 0 Тогда
ТипЗначенияКолонки = МетаданныеРодителя[Колонка.Имя];
КонецЕсли;
СхемаКоллекции.Вставить(Колонка.Имя, ТипЗначенияКолонки);
КонецЦикла;
КонецЕсли;
Иначе
Для Каждого Колонка Из МетаданныеРодителя.Колонки Цикл
СхемаКоллекции.Вставить(Колонка.Имя, Колонка.ТипЗначения);
КонецЦикла;
КонецЕсли;
КонецЕсли;
Иначе
Если Ложь
Или ТипЗнч(МетаданныеРодителя) = Тип("ВыборкаИзРезультатаЗапроса")
Или ТипЗнч(МетаданныеРодителя) = Тип("СтрокаТаблицыЗначений")
Или ТипЗнч(МетаданныеРодителя) = Тип("СтрокаДереваЗначений")
Тогда
КоллекцияЗначений = МетаданныеРодителя.Владелец().Колонки;
Иначе
КоллекцияЗначений = МетаданныеРодителя.Колонки;
КонецЕсли;
КонецЕсли;
ИначеЕсли Истина
И СтрокаОписанияВида.ИмяКоллекции = "Колонки"
И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных")
Тогда
СхемаКоллекции = МетаданныеРодителя.Реквизиты;
ИначеЕсли Истина
И СтрокаОписанияВида.ИмяКоллекции = "Колонки"
И ЭтоМетаданныеТабличнойЧастиВнешнейОбработки
Тогда
//! МетаданныеРодителя = 0 // ТабличнаяЧасть
Для Каждого Колонка Из МетаданныеРодителя.ВыгрузитьКолонки().Колонки Цикл
Если Колонка.Имя = "НомерСтроки" Тогда
Продолжить;
КонецЕсли;
СхемаКоллекции.Вставить(Колонка.Имя, Колонка.ТипЗначения);
КонецЦикла;
ИначеЕсли Истина
И ТипЗнч(МетаданныеРодителя) = Тип("ПостроительЗапроса")
И СтрокаОписанияВида.ИмяКоллекции = "Колонки"
Тогда
ПодготовитьМетаданныеПостроителяЗапроса(МетаданныеРодителя, РодительскаяСтруктураТипа.ДержательМетаданных);
Если СтрокаСлова.ТипЗначения <> "Произвольный" Тогда
Попытка
ОписаниеТиповЭлемента = Новый ОписаниеТипов(СтрокаСлова.ТипЗначения);
Исключение
ОписаниеТиповЭлемента = Неопределено;
КонецПопытки;
КонецЕсли;
Для Каждого ВыбранноеПоле Из МетаданныеРодителя.ВыбранныеПоля Цикл
лДоступноеПоле = МетаданныеРодителя.ДоступныеПоля.Найти(ВыбранноеПоле.Имя);
Если СтрокаСлова.ТипЗначения = "Произвольный" Тогда
ОписаниеТиповЭлемента = лДоступноеПоле.ТипЗначения;
КонецЕсли;
СхемаКоллекции.Вставить(ВыбранноеПоле.Имя, ОписаниеТиповЭлемента);
КонецЦикла;
ИначеЕсли Истина
И ТипЗнч(МетаданныеРодителя) = Тип("ПостроительЗапроса")
И СтрокаОписанияВида.ИмяКоллекции = "Поля"
Тогда
ПодготовитьМетаданныеПостроителяЗапроса(МетаданныеРодителя, РодительскаяСтруктураТипа.ДержательМетаданных);
Для Каждого ДоступноеПоле Из МетаданныеРодителя.ДоступныеПоля Цикл
ТипЗначения = ДоступноеПоле.ТипЗначения;
Если Истина
И ТипЗначения.СодержитТип(Тип("ТаблицаЗначений"))
И ИмяОбщегоТипаРодителя = "ВыборкаИзРезультатаЗапроса"
Тогда
ТипЗначения = Новый ОписаниеТипов("РезультатЗапроса");
КонецЕсли;
СхемаКоллекции.Вставить(ДоступноеПоле.Имя, ТипЗначения);
КонецЦикла;
ИначеЕсли Истина
И ТипЗнч(МетаданныеРодителя) = Тип("ПостроительЗапроса")
И СтрокаОписанияВида.ИмяКоллекции = "Структура"
Тогда
// Вроде бы мертвая ветка, т.к. для свойства "Параметры" всегда передается готовая структура вместо построителя
Для Каждого КлючИЗначение Из МетаданныеРодителя.Параметры Цикл
СхемаКоллекции.Вставить(ДоступноеПоле.Имя, ДоступноеПоле.ТипЗначения);
КонецЦикла;
ИначеЕсли Ложь
Или (Истина
И СтрокаОписанияВида.ИмяКоллекции = "Структура"
И ТипЗнч(МетаданныеРодителя) = Тип("Структура"))
Или (Истина
И СтрокаОписанияВида.ИмяКоллекции = "ФиксированнаяСтруктура"
И (Ложь
Или ТипЗнч(МетаданныеРодителя) = Тип("Структура")
Или ТипЗнч(МетаданныеРодителя) = Тип("ФиксированнаяСтруктура")))
Или (Истина
И СтрокаОписанияВида.ИмяКоллекции = "НастройкаОформления"
И ТипЗнч(МетаданныеРодителя) = Тип("НастройкаОформления"))
Или (Истина
И СтрокаОписанияВида.ИмяКоллекции = "Отбор"
И ТипЗнч(МетаданныеРодителя) = Тип("Отбор"))
Тогда
КоллекцияЗначений = МетаданныеРодителя;
// Теперь это делается в конце метода более универсально
//ИначеЕсли Истина
// И СтрокаОписанияВида.ИмяКоллекции = "Структура"
// И ТипЗнч(МетаданныеРодителя) = Тип("ТаблицаЗначений")
// И ЗначениеЗаполнено(СловоФильтр)
//Тогда
// СхемаКоллекции.Вставить(СловоФильтр, МетаданныеРодителя);
ИначеЕсли Истина
И СтрокаОписанияВида.ИмяКоллекции = "Колонки"
И (Ложь
Или ТипЗнч(МетаданныеРодителя) = Тип("ДоступноеПолеКомпоновкиДанных")
Или ТипЗнч(МетаданныеРодителя) = Тип("ДоступноеПолеОтбораКомпоновкиДанных"))
Тогда
Для Каждого ДоступноеПоле Из МетаданныеРодителя.Элементы Цикл
СхемаКоллекции.Вставить(ирОбщий.ПоследнийФрагментЛкс("" + ДоступноеПоле.Поле), ДоступноеПоле.ТипЗначения);
КонецЦикла;
ИначеЕсли Истина
И СтрокаОписанияВида.ИмяКоллекции = "ОбщиеРеквизиты"
И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных")
Тогда
Попытка
ОбщиеРеквизиты = Метаданные.ОбщиеРеквизиты;
Исключение
// Платформа 8.2.13 и ниже
ОбщиеРеквизиты = Новый Массив;
КонецПопытки;
СхемаКоллекции = Новый Массив();
Для Каждого ОбщийРеквизит Из ОбщиеРеквизиты Цикл
Если ирОбщий.ЛиОбщийРеквизитИспользуетсяВОбъектеМетаданныхЛкс(ОбщийРеквизит, МетаданныеРодителя) Тогда
СхемаКоллекции.Добавить(ОбщийРеквизит);
КонецЕсли;
КонецЦикла;
ИначеЕсли Истина
И СтрокаОписанияВида.ИмяКоллекции = "Картинки"
И ТипЗнч(МетаданныеРодителя) = Тип("Неопределено")
Тогда
Если ЗначениеЗаполнено(СловоФильтр) Тогда
МетаКартинка = Метаданные.ОбщиеКартинки.Найти(СловоФильтр);
Если МетаКартинка <> Неопределено Тогда
СхемаКоллекции.Вставить(МетаКартинка.Имя, МетаКартинка);
КонецЕсли;
Иначе
// Долго
СхемаКоллекции = Новый Структура;
Для Каждого МетаКартинка Из Метаданные.ОбщиеКартинки Цикл
СхемаКоллекции.Вставить(МетаКартинка.Имя, МетаКартинка);
КонецЦикла;
КонецЕсли;
ИначеЕсли Истина //
И СтрокаОписанияВида.ИмяКоллекции = "Свойства"
И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектXDTO")
Тогда
КоллекцияЗначений = Новый Структура;
ОбъектXDTO = МетаданныеРодителя;
Для Каждого Свойство Из ОбъектXDTO.Свойства() Цикл
Если Истина
И ЗначениеЗаполнено(Свойство.Имя)
//И ОбъектXDTO.Установлено(Свойство.Имя)
Тогда
Если Свойство.ВерхняяГраница > 1 Или Свойство.ВерхняяГраница = -1 Тогда
ЗначениеСвойства = ОбъектXDTO.ПолучитьСписок(Свойство.Имя);
Иначе
ЗначениеСвойства = ОбъектXDTO.Получить(Свойство.Имя);
КонецЕсли;
КоллекцияЗначений.Вставить(Свойство.Имя, ЗначениеСвойства);
КонецЕсли;
КонецЦикла;
ИначеЕсли Истина //
И СтрокаОписанияВида.ИмяКоллекции = "Свойства"
И ТипЗнч(МетаданныеРодителя) = Тип("ТипОбъектаXDTO")
Тогда
СхемаКоллекции = Новый Структура;
Для Каждого Свойство Из МетаданныеРодителя.Свойства Цикл
Если Не ЗначениеЗаполнено(Свойство.Имя) Тогда
Продолжить;
КонецЕсли;
ТаблицаТиповСлова = Неопределено;
Если ТипЗнч(Свойство.Тип) = Тип("ТипОбъектаXDTO") Тогда
СтруктураТипаСлова = НоваяСтруктураТипа("ОбъектXDTO");
СтруктураТипаСлова.Метаданные = Свойство.Тип;
ТаблицаТиповСлова = ДобавитьВТаблицуТипов(, СтруктураТипаСлова);
Иначе
ТипЗначения = СериализаторXDTO.ИзXMLТипа(Свойство.Тип.БазовыйТип.Имя, Свойство.Тип.БазовыйТип.URIПространстваИмен);
Если ТипЗначения <> Неопределено Тогда
ТаблицаТиповСлова = Новый ОписаниеТипов(ирОбщий.ЗначенияВМассивЛкс(ТипЗначения));
КонецЕсли;
КонецЕсли;
СхемаКоллекции.Вставить(Свойство.Имя, ТаблицаТиповСлова);
КонецЦикла;
ИначеЕсли Истина
И СтрокаОписанияВида.ИмяКоллекции = "Свойства"
И ТипЗнч(МетаданныеРодителя) = Тип("СвойствоXDTO")
И МетаданныеРодителя.ОбъектВладелец <> Неопределено
Тогда
КоллекцияЗначений = Новый Структура;
ОбъектXDTO = МетаданныеРодителя.ОбъектВладелец;
Свойство = МетаданныеРодителя;
Если ОбъектXDTO.Установлено(Свойство.Имя) Тогда
Если Свойство.ВерхняяГраница > 1 Или Свойство.ВерхняяГраница = -1 Тогда
ЗначениеСвойства = ОбъектXDTO.ПолучитьСписок(Свойство.Имя);
Иначе
ЗначениеСвойства = ОбъектXDTO.Получить(Свойство.Имя);
КонецЕсли;
КоллекцияЗначений.Вставить(Свойство.Имя, ЗначениеСвойства);
КонецЕсли;
ИначеЕсли Истина
И СтрокаОписанияВида.ИмяКоллекции = "Параметры"
И ТипЗнч(МетаданныеРодителя) = Тип("ТабличныйДокумент")
И МетаданныеРодителя.ВысотаТаблицы * МетаданныеРодителя.ШиринаТаблицы < 20000
Тогда
КоллекцияЗначений = Новый Структура;
СписокПараметров = ирОбщий.ПараметрыТабличногоДокументаЛкс(МетаданныеРодителя);
Для Каждого ЭлементСписка Из СписокПараметров Цикл
Попытка
КоллекцияЗначений.Вставить(ЭлементСписка.Значение);
Исключение
// Имена параметров могут содержать запрещенные символы
КонецПопытки;
КонецЦикла;
ИначеЕсли Истина
И СтрокаОписанияВида.ИмяКоллекции = "Свойства" // коллекция упр. формы
И (Ложь
Или ТипЗнч(МетаданныеРодителя) = Тип("ТаблицаЗначений")
Или ТипЗнч(МетаданныеРодителя) = Тип("ДеревоЗначений"))
Тогда
СхемаКоллекции = МетаданныеРодителя.Колонки;
ИначеЕсли Истина
И СтрокаОписанияВида.ИмяКоллекции = "Свойства" // коллекция упр. формы
И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных")
Тогда
ПолноеИмяМД = МетаданныеРодителя.ПолноеИмя();
Если Ложь
Или Найти(ПолноеИмяМД, "Обработка.")
Или Найти(ПолноеИмяМД, "Отчет.")
Тогда
Для Каждого ОбъектМетаданныхРеквизит Из МетаданныеРодителя.Реквизиты Цикл
СхемаКоллекции.Вставить(ОбъектМетаданныхРеквизит.Имя, ОбъектМетаданныхРеквизит);
КонецЦикла;
// TODO Пока дальше тип не дозревает Мультиметка240813_080918
Для Каждого ОбъектМетаданныхТабличнаяЧасть Из МетаданныеРодителя.ТабличныеЧасти Цикл
СхемаКоллекции.Вставить(ОбъектМетаданныхТабличнаяЧасть.Имя, ОбъектМетаданныхТабличнаяЧасть);
КонецЦикла;
Иначе
СхемаКоллекции = ирКэш.ПоляТаблицыБДЛкс(ирКэш.ИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД), Истина);
КонецЕсли;
ИначеЕсли Истина
И СтрокаОписанияВида.ИмяКоллекции = "Свойства" // коллекция упр. формы
И ТипЗнч(МетаданныеРодителя) = Тип("Структура")
И ирОбщий.СвойствоСтруктурыЛкс(МетаданныеРодителя, "Тип") <> ирОбщий.ТипУправляемаяФормаЛкс()
Тогда
СхемаКоллекции = МетаданныеРодителя;
#Если Клиент Тогда
ИначеЕсли Истина
И СтрокаОписанияВида.ИмяКоллекции = "Структура"
И ТипЗнч(МетаданныеРодителя) = Тип("Форма")
Тогда
КоллекцияЗначений = МетаданныеРодителя[РодительскаяСтруктураТипа.СтрокаОписания.Слово];
ИначеЕсли Истина
И СтрокаОписанияВида.ИмяКоллекции = "Реквизиты"
И ирОбщий.ЛиФормаИлиИмитаторЛкс(МетаданныеРодителя)
Тогда
Если ЗначениеЗаполнено(СловоФильтр) Тогда
ИмитаторФормы = МетаданныеРодителя;
Если ТипЗнч(МетаданныеРодителя) = ирОбщий.ТипУправляемаяФормаЛкс() Тогда
Попытка
ЗначениеРеквизита = МетаданныеРодителя[СловоФильтр];
Исключение
ИмитаторФормы = ирОбщий.СлужебныеДанныеФормыЛкс(МетаданныеРодителя);
КонецПопытки;
КонецЕсли;
Если ТипЗнч(ИмитаторФормы) = Тип("Структура") Тогда
СтруктураИмен = ИменаРеквизитовФормы(ИмитаторФормы, "").Все;
Если СтруктураИмен.Свойство(СловоФильтр) Тогда
ЗначениеСлова = СтруктураИмен[СловоФильтр];
СхемаКоллекции.Вставить(СловоФильтр, ЗначениеСлова);
ИначеЕсли Не ЛиВместеСЛокальнымКонтекстом Тогда
ДобавитьОтсутствиеЭлементаФормы(ИмитаторФормы, "Реквизит:" + СловоФильтр);
КонецЕсли;
Иначе
// Для ускорения особенно для управляемой формы
КоллекцияЗначений = Новый Структура;
Попытка
ЗначениеРеквизита = МетаданныеРодителя[СловоФильтр];
Исключение
ЗначениеРеквизита = Null;
КонецПопытки;
Если Истина
И ЗначениеРеквизита <> Null
И ТипЗнч(МетаданныеРодителя) = Тип("Форма")
И Не ИменаРеквизитовФормы(ИмитаторФормы, "").Все.Свойство(СловоФильтр)
Тогда
// Это реквизит объекта, а не формы
ЗначениеРеквизита = Null;
КонецЕсли;
Если ЗначениеРеквизита <> Null Тогда
КоллекцияЗначений.Вставить(СловоФильтр, ЗначениеРеквизита);
КонецЕсли;
КонецЕсли;
Иначе
Если ТипЗнч(МетаданныеРодителя) = Тип("Форма") Тогда
ПутьКРодителю = Неопределено;
Иначе
ПутьКРодителю = "";
КонецЕсли;
СтруктураИмен = ИменаРеквизитовФормы(МетаданныеРодителя, ПутьКРодителю).Все;
Если ТипЗнч(МетаданныеРодителя) = Тип("Структура") Тогда
СхемаКоллекции = СтруктураИмен;
Иначе
КоллекцияЗначений = Новый Структура;
Для Каждого КлючИЗначение Из СтруктураИмен Цикл
Попытка
ЗначениеРеквизита = МетаданныеРодителя[КлючИЗначение.Ключ];
Исключение
Если КлючИЗначение.Значение <> Неопределено Тогда
// Добавленный реквизит был получен через буфер обмена, но пока отсутствует в натуральной форме
ЗначениеРеквизита = ТаблицаТиповИзОписанияТипов(КлючИЗначение.Значение);
Иначе
ЗначениеРеквизита = Неопределено;
КонецЕсли;
КонецПопытки;
КоллекцияЗначений.Вставить(КлючИЗначение.Ключ, ЗначениеРеквизита);
КонецЦикла;
КонецЕсли;
КонецЕсли;
ИначеЕсли Истина
И СтрокаОписанияВида.ИмяКоллекции = "Реквизиты"
И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных")
И ТипЗнч(РодительскаяСтруктураТипа.Метаданные) = Тип("Форма")
И ЗначениеЗаполнено(СловоФильтр)
И Метаданные.Обработки.Индекс(МетаданныеРодителя) <> -1
И МетаданныеРодителя.Реквизиты.Найти(СловоФильтр) <> Неопределено
Тогда
// Нужно для подготовки реквизита обработки, видимой в ее форме (Обработка.ирКонсольЗапросов.Реквизит.ДеревоЗапросов)
Попытка
ЗначениеРеквизита = РодительскаяСтруктураТипа.Метаданные[СловоФильтр];
Исключение
ЗначениеРеквизита = Неопределено;
КонецПопытки;
Если ЗначениеРеквизита <> Неопределено Тогда
КоллекцияЗначений = Новый Структура(СловоФильтр, ЗначениеРеквизита);
Иначе
СхемаКоллекции = МетаданныеРодителя.Реквизиты;
КонецЕсли;
ИначеЕсли Истина
И СтрокаОписанияВида.ИмяКоллекции = "Команды"
И ирОбщий.ЛиФормаИлиИмитаторЛкс(РодительскаяСтруктураТипа.ДержательМетаданных, Ложь)
Тогда
Форма = РодительскаяСтруктураТипа.ДержательМетаданных;
СлужебныеДанные = ирОбщий.СлужебныеДанныеФормыЛкс(Форма);
Если СлужебныеДанные <> Неопределено И СлужебныеДанные.Свойство("Команды") Тогда
СхемаКоллекции = СлужебныеДанные.Команды;
Если ЗначениеЗаполнено(СловоФильтр) И Не СхемаКоллекции.Свойство(СловоФильтр) Тогда
ДобавитьОтсутствиеЭлементаФормы(Форма, "Команда:" + СловоФильтр);
КонецЕсли;
Иначе
Если ТипЗнч(Форма) = ирОбщий.ТипУправляемаяФормаЛкс() Тогда
СхемаКоллекции = Форма.Команды;
КонецЕсли;
КонецЕсли;
ИначеЕсли Истина
И ИмяОбщегоТипаРодителя = "ДанныеФормыСтруктура"
И ТипЗнч(РодительскаяСтруктураТипа.СтрокаОписания) = Тип("СтрокаТаблицыЗначений")
И РодительскаяСтруктураТипа.СтрокаОписания.ТипКонтекста = "ФормаКлиентскогоПриложения"
И РодительскаяСтруктураТипа.СтрокаОписания.Слово = "Параметры"
Тогда
СхемаКоллекции = СхемаКоллекцииПараметровФормы(РодительскаяСтруктураТипа, СловоФильтр);
ИначеЕсли ирОбщий.ЛиДанныеФормыССериализациейЛкс(МетаданныеРодителя) Тогда
Форма = РодительскаяСтруктураТипа.ДержательМетаданных;
ЛиКоллекция = Ложь
Или ирОбщий.ЛиКоллекцияЛкс(МетаданныеРодителя)
Или ТипЗнч(МетаданныеРодителя) = Тип("ДанныеФормыДерево");
СтруктураИмен = ДочерниеСвойстваДанныхФормы(МетаданныеРодителя, ЛиКоллекция, Форма, СловоФильтр);
СхемаКоллекции = СтруктураИмен;
Если Не ЛиКоллекция Тогда
Для Каждого КлючИЗначение Из СтруктураИмен Цикл
ЗначениеСвойства = КлючИЗначение.Значение; // ОписаниеТипов, см. НоваяТаблицаТипов
Если ТипЗнч(ЗначениеСвойства) = Тип("ТаблицаЗначений") Тогда
//
ИначеЕсли Истина
И ТипЗнч(ЗначениеСвойства) = Тип("ОписаниеТипов")
И ЗначениеСвойства.Типы().Количество() > 0
Тогда
ЗначениеСвойства = ТаблицаТиповИзОписанияТипов(ЗначениеСвойства);
Иначе
Попытка
ЗначениеСвойства = МетаданныеРодителя[КлючИЗначение.Ключ];
Исключение
// Может быть ошибка "Поле объекта недоступно для чтения" https://www.hostedredmine.com/issues/985380
ЗначениеСвойства = Неопределено;
КонецПопытки;
ЗначениеСвойства = ТаблицаТиповИзЗначения(ЗначениеСвойства); // Мультиметка250303_191432
КонецЕсли;
ЗначениеСвойства.ЗаполнитьЗначения(Форма, "ДержательМетаданных");
Если КоллекцияЗначений = Неопределено Тогда
КоллекцияЗначений = Новый Структура;
КонецЕсли;
КоллекцияЗначений.Вставить(КлючИЗначение.Ключ, ЗначениеСвойства);
КонецЦикла;
КонецЕсли;
ИначеЕсли Истина
И ИмяОбщегоТипаРодителя = "ЭлементыФормы"
И ТипЗнч(МетаданныеРодителя) = Тип("Структура")
И ТипЗнч(РодительскаяСтруктураТипа.СтрокаОписания) = Тип("СтрокаТаблицыЗначений")
И РодительскаяСтруктураТипа.СтрокаОписания.ТипКонтекста = "Форма"
Тогда
СхемаКоллекции = МетаданныеРодителя;
ИначеЕсли Ложь
Или (Истина
И СтрокаОписанияВида.ИмяКоллекции = "ЭлементыФормы"
И ТипЗнч(МетаданныеРодителя) = Тип("Форма"))
Или (Истина
И СтрокаОписанияВида.ИмяКоллекции = "Элементы"
И ирОбщий.ЛиФормаИлиИмитаторЛкс(МетаданныеРодителя, Ложь))
Или (Истина
И СтрокаОписанияВида.ИмяКоллекции = "Страницы"
И ТипЗнч(МетаданныеРодителя) = Тип("Панель"))
Или (Истина
И СтрокаОписанияВида.ИмяКоллекции = "Колонки"
И (Ложь
//Или ТипЗнч(МетаданныеРодителя) = Тип("КолонкиТабличногоПоля")
Или ТипЗнч(МетаданныеРодителя) = Тип("ТабличноеПоле")))
Или (Истина
И СтрокаОписанияВида.ИмяКоллекции = "Кнопки"
И (Ложь
Или ТипЗнч(МетаданныеРодителя) = Тип("КнопкаКоманднойПанели")
//Или ТипЗнч(МетаданныеРодителя) = Тип("КнопкиКоманднойПанели")
Или ТипЗнч(МетаданныеРодителя) = Тип("КоманднаяПанель")))
Тогда
СловаКонтекстаМетаданныеФормы(СловоФильтр, ИмяОбщегоТипаРодителя, МетаданныеРодителя, СтрокаОписанияВида, КоллекцияЗначений, СхемаКоллекции);
ИначеЕсли СтрокаОписанияВида.ИмяКоллекции = "ПодчиненныеЭлементы" Тогда
ФормаИлиИмитатор = РодительскаяСтруктураТипа.ДержательМетаданных;
Если ФормаИлиИмитатор = Неопределено Тогда
ФормаИлиИмитатор = МетаданныеРодителя;
КонецЕсли;
Если ирОбщий.ЛиФормаИлиИмитаторЛкс(ФормаИлиИмитатор, Ложь) Тогда
ЭлементыФормы = Неопределено;
Если ТипЗнч(ФормаИлиИмитатор) = ирОбщий.ТипУправляемаяФормаЛкс() Тогда
ЭлементыФормы = ФормаИлиИмитатор.Элементы;
КонецЕсли;
КоллекцияЗначений = Новый Структура;
СлужебныеДанные = ирОбщий.СлужебныеДанныеФормыЛкс(ФормаИлиИмитатор);
Если СлужебныеДанные.Свойство("Элементы") Тогда
Если ирОбщий.ЛиФормаИлиИмитаторЛкс(МетаданныеРодителя, Ложь) Тогда
ИмяРодителя = Неопределено;
Иначе
ИмяРодителя = МетаданныеРодителя.Имя;
КонецЕсли;
ИмитаторыЭлементов = ирОбщий.ОтобратьКоллекциюЛкс(СлужебныеДанные.Элементы, "Э.Значение.ИмяРодителя = П1", "Э.Значение", ИмяРодителя);
Для Каждого СтруктураЭлемента Из ИмитаторыЭлементов Цикл
ДочернийЭлемент = Неопределено;
Если ЭлементыФормы <> Неопределено Тогда
ДочернийЭлемент = ЭлементыФормы.Найти(СтруктураЭлемента.Имя);
КонецЕсли;
Если ДочернийЭлемент = Неопределено Тогда
СхемаКоллекции["_"] = 1; // Чтобы описания типов в значении считались как тип элемента
ДочернийЭлемент = ТаблицаТиповИзИмитатораЭлементаФормы(СтруктураЭлемента, ИмитаторФормы, СловоФильтр);
КонецЕсли;
КоллекцияЗначений.Вставить(СтруктураЭлемента.Имя, ДочернийЭлемент);
КонецЦикла;
КонецЕсли;
КонецЕсли;
#КонецЕсли
ИначеЕсли ТипЗнч(МетаданныеРодителя) = Тип("НаборыДанныхСхемыКомпоновкиДанных") Тогда
КоллекцияЗначений = МетаданныеРодителя;
//ИначеЕсли СтрокаОписанияВида.ИмяКоллекции = "Оформление" Тогда
// Для Каждого МетаОбщийМодуль Из МетаданныеРодителя[СтрокаОписанияВида.ИмяКоллекции] Цикл
// Если МетаОбщийМодуль.Глобальный Тогда
// Продолжить;
// КонецЕсли;
// СхемаКоллекции.Вставить(МетаОбщийМодуль.Имя);
// КонецЦикла;
ИначеЕсли Истина
И СтрокаОписанияВида.ИмяКоллекции = "ОбщиеМодули"
И ИмяОбщегоТипаРодителя = "Глобальный"
И ТипЗнч(МетаданныеРодителя) = Тип("Неопределено") //
Тогда
СхемаКоллекции = ирКэш.ДоступныеОбщиеМодулиЛкс(НаСервере, КлиентОбычноеПриложение, КлиентУправляемоеПриложение);
Если мДобавленныеОбщиеМодули.Количество() > 0 Тогда
СхемаКоллекции = ирОбщий.СкопироватьКоллекциюЛкс(СхемаКоллекции); // Структура
ирОбщий.СкопироватьКоллекциюЛкс(мДобавленныеОбщиеМодули, СхемаКоллекции);
КонецЕсли;
Если Прав(СловоФильтр, 1) = "_" Тогда
ЭтоГруппаОбщихМодулей = Истина;
НачальныйФрагмент = НРег(ирОбщий.СтрокаБезКонцаЛкс(СловоФильтр));
СловоФильтр = Неопределено;
ТаблицаСлов.Очистить();
НоваяСхема = Новый Структура;
Для Каждого КлючИЗначение Из СхемаКоллекции Цикл
Если Не ирОбщий.СтрНачинаетсяСЛкс(КлючИЗначение.Ключ, НачальныйФрагмент) Тогда
Продолжить;
КонецЕсли;
ОстатокИмени = Сред(КлючИЗначение.Ключ, СтрДлина(НачальныйФрагмент) + 1);
Если СтрДлина(ОстатокИмени) > 1 И ВРег(Лев(ОстатокИмени, 2)) = Лев(ОстатокИмени, 2) Тогда
Продолжить;
КонецЕсли;
НоваяСхема.Вставить(КлючИЗначение.Ключ, КлючИЗначение.Значение);
КонецЦикла;
Если НоваяСхема.Количество() > МаксРазмерТаблицыТиповДляЗаполненияТаблицыСлов() Тогда
НоваяСхема.Очистить();
КонецЕсли;
СхемаКоллекции = НоваяСхема;
ИначеЕсли Не ЗначениеЗаполнено(СловоФильтр) Тогда
СписокЗначений = Новый СписокЗначений;
НоваяСхема = Новый Структура;
Для Каждого КлючИЗначение Из СхемаКоллекции Цикл
СписокЗначений.Добавить(КлючИЗначение.Значение, КлючИЗначение.Ключ);
НоваяСхема.Вставить(КлючИЗначение.Ключ, КлючИЗначение.Значение);
КонецЦикла;
СписокЗначений.СортироватьПоПредставлению();
СхемаКоллекции = НоваяСхема;
ИмяГруппы = Неопределено;
ЧленыГруппы = Новый Массив;
ГруппыМодулей = Новый Структура;
МассивМетаМодулей = СписокЗначений.ВыгрузитьЗначения();
// для 400 модулей 30мс
//РегВыражение = мРегВыражение;
//РегВыражение.Global = Ложь;
//РегВыражение.IgnoreCase = Ложь;
//РегВыражение.Pattern = "(.+?)(?:Вызов|Клиент|Сервер|ПовтИсп|Кэш)";
//Для Каждого МодульМД Из МассивМетаМодулей Цикл
// Найденные = РегВыражение.НайтиВхождения(МодульМД.Имя);
// Если Найденные.Количество() > 0 Тогда
// ИмяГруппы = Найденные[0].SubMatches(0);
// Если ГруппыМодулей.Свойство(ИмяГруппы) Тогда
// ГруппыМодулей[ИмяГруппы] = 2;
// Иначе
// ГруппыМодулей.Вставить(ИмяГруппы, 1);
// КонецЕсли;
// КонецЕсли;
//КонецЦикла;
//РегВыражение.IgnoreCase = Истина;
//
// для 400 модулей 2мс
СуффиксыМодулей = Новый Массив;
СуффиксыМодулей.Добавить("Вызов");
СуффиксыМодулей.Добавить("Клиент");
СуффиксыМодулей.Добавить("Сервер");
СуффиксыМодулей.Добавить("ПовтИсп");
СуффиксыМодулей.Добавить("Кэш");
_РежимОтладки = Ложь;
Если _РежимОтладки Тогда // Можно менять на Истина в точке останова, например условием ирОбщий.Пр(_РежимОтладки, 1, 1)
// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
Для Каждого МодульМД Из МассивМетаМодулей Цикл
ИмяМодуля = МодульМД.Имя;
Для Каждого Суффикс Из СуффиксыМодулей Цикл
Позиция = Найти(ИмяМодуля, Суффикс);
Если Позиция > 1 Тогда
Прервать;
КонецЕсли;
КонецЦикла;
Если Позиция > 1 Тогда
ИмяГруппы = Лев(ИмяМодуля, Позиция - 1);
Если ГруппыМодулей.Свойство(ИмяГруппы) Тогда
ГруппыМодулей[ИмяГруппы] = 2;
Иначе
ГруппыМодулей.Вставить(ИмяГруппы, 1);
КонецЕсли;
КонецЕсли;
КонецЦикла;
Иначе
// Однострочный код использован для ускорения при разрешенной отладке. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика"
Для Каждого МодульМД Из МассивМетаМодулей Цикл   ИмяМодуля = МодульМД.Имя;   Для Каждого Суффикс Из СуффиксыМодулей Цикл   Позиция = Найти(ИмяМодуля, Суффикс);   Если Позиция > 1 Тогда   Прервать;   КонецЕсли;   КонецЦикла;   Если Позиция > 1 Тогда   ИмяГруппы = Лев(ИмяМодуля, Позиция - 1);   Если ГруппыМодулей.Свойство(ИмяГруппы) Тогда   ГруппыМодулей[ИмяГруппы] = 2;   Иначе   ГруппыМодулей.Вставить(ИмяГруппы, 1);   КонецЕсли;   КонецЕсли;   КонецЦикла;  
КонецЕсли;
Для Каждого КлючИЗначение Из ГруппыМодулей Цикл
Если Ложь
Или КлючИЗначение.Значение > 1
Или СхемаКоллекции.Свойство(КлючИЗначение.Ключ)
Тогда
СхемаКоллекции.Вставить(КлючИЗначение.Ключ + "_");
КонецЕсли;
КонецЦикла;
КонецЕсли;
ИначеЕсли Истина
И СтрокаОписанияВида.ИмяКоллекции = "ВидыСубконто"
И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных")
Тогда
//! МетаданныеРодителя = 0; // ОбъектМетаданныхРегистрБухгалтерии
Для Счетчик = 1 По МетаданныеРодителя.ПланСчетов.МаксКоличествоСубконто Цикл
СхемаКоллекции.Вставить(Строка(Счетчик), МетаданныеРодителя.ПланСчетов.ВидыСубконто);
КонецЦикла;
ИначеЕсли СтрокаОписанияВида.ИмяКоллекции = "Движения" Тогда
Если ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") Тогда
//! МетаданныеРодителя = 0; // ОбъектМетаданныхДокумент
Для Каждого МетаРегистр Из МетаданныеРодителя.Движения Цикл
МассивФрагментов = ирОбщий.СтрРазделитьЛкс(МетаРегистр.ПолноеИмя());
СхемаКоллекции.Вставить(МетаРегистр.Имя, Новый ОписаниеТипов(МассивФрагментов[0] + "НаборЗаписей." + МассивФрагментов[1]));
КонецЦикла;
ИначеЕсли ТипЗнч(МетаданныеРодителя) = Тип("КоллекцияДвижений") Тогда
Для Каждого НаборЗаписейРегистра Из МетаданныеРодителя Цикл // РегистрСведенийНаборЗаписей.КурсыВалют
СхемаКоллекции.Вставить(НаборЗаписейРегистра.Метаданные().Имя, НаборЗаписейРегистра);
КонецЦикла;
ИначеЕсли Истина
И СловоФильтр <> Неопределено
И ТипЗнч(МетаданныеРодителя) = Тип("Неопределено") //
Тогда
МетаданныеРегистра = Метаданные.РегистрыСведений.Найти(СловоФильтр);
Если МетаданныеРегистра = Неопределено Тогда
МетаданныеРегистра = Метаданные.РегистрыНакопления.Найти(СловоФильтр);
КонецЕсли;
Если МетаданныеРегистра = Неопределено Тогда
МетаданныеРегистра = Метаданные.РегистрыБухгалтерии.Найти(СловоФильтр);
КонецЕсли;
Если МетаданныеРегистра = Неопределено Тогда
МетаданныеРегистра = Метаданные.РегистрыРасчета.Найти(СловоФильтр);
КонецЕсли;
Если МетаданныеРегистра <> Неопределено Тогда
МассивФрагментов = ирОбщий.СтрРазделитьЛкс(МетаданныеРегистра.ПолноеИмя());
СхемаКоллекции.Вставить(МассивФрагментов[1], Новый ОписаниеТипов(МассивФрагментов[0] + "НаборЗаписей." + МассивФрагментов[1]));
КонецЕсли;
КонецЕсли;
ИначеЕсли Истина
И СтрокаОписанияВида.ИмяКоллекции = "БазовыеВидыРасчета"
И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных")
Тогда
Для Каждого БазовыйПлан Из МетаданныеРодителя.ПланВидовРасчета.БазовыеВидыРасчета Цикл
Для Каждого БазовыйРегистрРасчета Из Метаданные.РегистрыРасчета Цикл
Если БазовыйРегистрРасчета.ПланВидовРасчета = БазовыйПлан Тогда
СхемаКоллекции.Вставить(БазовыйРегистрРасчета.Имя, БазовыйРегистрРасчета);
КонецЕсли;
КонецЦикла;
КонецЦикла;
ИначеЕсли Истина
И СтрокаОписанияВида.ИмяКоллекции = "ТочкиМаршрута"
И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных")
Тогда
КоллекцияЗначений = ирОбщий.ПолучитьМенеджерЛкс(МетаданныеРодителя)[СтрокаОписанияВида.ИмяКоллекции];
ИначеЕсли Истина
И СтрокаОписанияВида.ИмяКоллекции = "<Имя коллекции метаданных>"
И (Ложь
Или ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных")
Или ТипЗнч(МетаданныеРодителя) = Тип("КоллекцияОбъектовМетаданных")
Или ТипЗнч(МетаданныеРодителя) = Тип("Неопределено"))
Тогда
Если ТипЗнч(МетаданныеРодителя) = Тип("КоллекцияОбъектовМетаданных") Тогда
КоллекцияЗначений = МетаданныеРодителя;
Иначе
ИмяКоллекцииОбъектовМетаданных = ирОбщий.ТекстМеждуМаркерамиЛкс(ИмяОбщегоТипаРодителя, МаркерКоллекцииМетаданных, , Ложь);
Если ЗначениеЗаполнено(ИмяКоллекцииОбъектовМетаданных) Тогда
СтрокаКорневогоТипа = ОписаниеТипаМетаОбъектов(, ИмяКоллекцииОбъектовМетаданных);
Если СтрокаКорневогоТипа <> Неопределено Тогда
ПроверяемыеМетаданные = ?(МетаданныеРодителя = Неопределено, мМетаданные, МетаданныеРодителя);
//КоллекцияЗначений = ПроверяемыеМетаданные[ИмяКоллекцииОбъектовМетаданных];
Попытка
КоллекцияЗначений = ПроверяемыеМетаданные[РодительскаяСтруктураТипа.СтрокаОписания.Слово];
Исключение
ИнформацияОбОшибке = ИнформацияОбОшибке(); // Для отладки
КонецПопытки;
КонецЕсли;
КонецЕсли;
КонецЕсли;
ИначеЕсли Истина
//И СтрокаОписанияВида.ИмяКоллекции = "<Имя коллекции метаданных>"
И ЭтоИнтеграция
И (Ложь
Или ТипЗнч(МетаданныеРодителя) = Тип("СправочникСсылка.КонфигурацииМетаданныхИис")
Или ТипЗнч(МетаданныеРодителя) = Тип("СправочникСсылка.МетаданныеИис"))
Тогда
Если СтрокаОписанияВида.ИмяКоллекции = "<Имя коллекции метаданных>" Тогда
ИмяКоллекцииОбъектовМетаданных = ирОбщий.ТекстМеждуМаркерамиЛкс(ИмяОбщегоТипаРодителя, МаркерКоллекцииМетаданных, , Ложь);
Иначе
ИмяКоллекцииОбъектовМетаданных = СтрокаОписанияВида.ИмяКоллекции;
КонецЕсли;
Если ЗначениеЗаполнено(ИмяКоллекцииОбъектовМетаданных) Тогда
СтрокаКорневогоТипа = ОписаниеТипаМетаОбъектов(, ИмяКоллекцииОбъектовМетаданных);
Запрос = Новый Запрос;
Если СтрокаКорневогоТипа <> Неопределено Тогда
//лИмяКоллекции = РодительскаяСтруктураТипа.СтрокаОписания.Слово;
Если ИмяКоллекцииОбъектовМетаданных = "Реквизиты" Тогда
ТекстЗапроса = "ВЫБРАТЬ Наименование КАК Имя, Типы Как Значение ИЗ Справочник.СвойстваМетаданныхИис
|ГДЕ КонфигурацияМетаданных = &Владелец И Вид <> ЗНАЧЕНИЕ(Перечисление.ВидыСвойствМетаданныхИис.Свойство)";
Запрос.Текст = ТекстЗапроса;
Запрос.УстановитьПараметр("Владелец", МетаданныеРодителя);
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
СхемаКоллекции[Выборка.Имя] = Выборка.Значение.Выгрузить().ВыгрузитьКолонку("Тип");
КонецЦикла;
Иначе
ТекстЗапроса = "ВЫБРАТЬ Имя, Ссылка КАК Значение ИЗ Справочник.МетаданныеИис
|ГДЕ КонфигурацияМетаданных = &Владелец И ТипМетаданных.ИмяМножественное = &ИмяРодителя";
Запрос.УстановитьПараметр("ИмяРодителя", ИмяКоллекцииОбъектовМетаданных);
Запрос.Текст = ТекстЗапроса;
Запрос.УстановитьПараметр("Владелец", МетаданныеРодителя);
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
СхемаКоллекции[Выборка.Имя] = Выборка.Значение;
КонецЦикла;
КонецЕсли;
КонецЕсли;
Иначе
//КоллекцияЗначений = МетаданныеРодителя;
КонецЕсли;
ИначеЕсли Истина
И ТипЗнч(МетаданныеРодителя) = Тип("ОбщийМодуль")
Тогда
// Платформа пока не дает узнать имя модуля
Иначе
Если мМассивИсключенийИменКоллекций.НайтиПоЗначению(СтрокаОписанияВида.ИмяКоллекции) <> Неопределено Тогда
Продолжить;
КонецЕсли;
СхемаКоллекции = МетаданныеРодителя;
Если ТипЗнч(МетаданныеРодителя) <> Тип("КоллекцияОбъектовМетаданных") Тогда
ЦелевойТип = Неопределено;
Если Найти(СтрокаОбщегоТипа.ИмяОбщегоТипа, "<") = 0 Тогда
Попытка
ЦелевойТип = Тип(СтрокаОбщегоТипа.ИмяОбщегоТипа);
Исключение
КонецПопытки;
КонецЕсли;
Если ТипЗнч(МетаданныеРодителя) = ЦелевойТип Тогда
СхемаКоллекции = МетаданныеРодителя;
Иначе
ПроверяемыеМетаданные = ?(МетаданныеРодителя = Неопределено, мМетаданные, МетаданныеРодителя);
Попытка
СхемаКоллекции = ПроверяемыеМетаданные[СтрокаОписанияВида.ИмяКоллекции];
Исключение
Продолжить;
КонецПопытки;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если КоллекцияЗначений = Неопределено Тогда
КоллекцияЗначений = СхемаКоллекции;
Если СловоФильтр <> Неопределено Тогда
ЭлементСхемы = Неопределено;
Если Ложь
Или ТипЗнч(КоллекцияЗначений) = Тип("ФиксированнаяСтруктура")
Или ТипЗнч(КоллекцияЗначений) = Тип("ФиксированноеСоответствие")
Или ТипЗнч(КоллекцияЗначений) = Тип("Структура")
Или ТипЗнч(КоллекцияЗначений) = Тип("Соответствие")
Тогда
//Для Каждого ЭлементКоллекции Из КоллекцияЗначений Цикл
// Если ЭлементКоллекции.Ключ = ИмяТекущегоСлова Тогда
// ЭлементСхемы = ЭлементКоллекции.Значение;
// Прервать;
// КонецЕсли;
//КонецЦикла;
Попытка
ЭлементСхемы = КоллекцияЗначений[ИмяТекущегоСлова];
Исключение
КонецПопытки;
Иначе
ЭлементСхемы = Null;
Если ТипЗнч(КоллекцияЗначений) <> Тип("Массив") Тогда
Попытка
ЭлементСхемы = КоллекцияЗначений.Найти(ИмяТекущегоСлова);
Исключение
КонецПопытки;
КонецЕсли;
Если ЭлементСхемы = Null Тогда
ЭлементСхемы = Неопределено;
Для Каждого ЭлементКоллекции Из КоллекцияЗначений Цикл
Если ЭлементКоллекции.Имя = ИмяТекущегоСлова Тогда
ЭлементСхемы = ЭлементКоллекции;
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЕсли;
КоллекцияЗначений = Новый Соответствие;
Если ЭлементСхемы <> Неопределено Тогда
КоллекцияЗначений.Вставить(ИмяТекущегоСлова, ЭлементСхемы);
КонецЕсли;
КонецЕсли;
Иначе
Если СловоФильтр <> Неопределено Тогда
Попытка
ЭлементСхемы = КоллекцияЗначений[ИмяТекущегоСлова];
Исключение
ЭлементСхемы = Null;
КонецПопытки;
КоллекцияЗначений = Новый Соответствие;
Если ЭлементСхемы <> Null Тогда
КоллекцияЗначений.Вставить(ИмяТекущегоСлова, ЭлементСхемы);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если КоллекцияЗначений = Неопределено Тогда
КоллекцияЗначений = Новый Массив();
КонецЕсли;
//! СхемаКоллекции = Неопределено; // Соответствие, Структура
ЭтоСубконто = Найти(СтрокаСлова.Слово, "Субконто") = 1;
ПредыдущаяТаблицаТипов = Неопределено;
ВычислятьТипыЦикл = ВычислятьТипы Или КоллекцияЗначений.Количество() < 100;
Если ЗначениеЗаполнено(СтрокаСлова.ТипЗначения) Тогда
ТипЗначенияСлова = ", " + СтрокаСлова.ТипЗначения;
ТипЗначенияСлова = СтрЗаменить(ТипЗначенияСлова, ", Произвольный", "");
Иначе
ТипЗначенияСлова = "";
КонецЕсли;
Для Каждого ЭлементКоллекции Из КоллекцияЗначений Цикл
Если ЭлементКоллекции = Неопределено Тогда
// ПараметрыМакетаТабличногоДокумента
Продолжить;
КонецЕсли;
Если ТипЗнч(ЭлементКоллекции) = Тип("КлючИЗначение") Тогда
ИмяСвойства = ЭлементКоллекции.Ключ;
ЗначениеСвойства = ЭлементКоллекции.Значение;
Иначе
ИмяСвойства = ЭлементКоллекции.Имя;
ЗначениеСвойства = ЭлементКоллекции;
КонецЕсли;
КонечноеСлово = СтрЗаменить(СтрокаСлова.Слово, ИмяЭлементаКоллекции, ИмяСвойства);
ТаблицаТипов = Неопределено;
Если ВычислятьТипыЦикл Тогда
Если ЭтоСубконто И ПредыдущаяТаблицаТипов <> Неопределено Тогда
ТаблицаТипов = ПредыдущаяТаблицаТипов;
ИначеЕсли Истина
И ТипЗнч(ЗначениеСвойства) = Тип("ТаблицаЗначений")
И ЗначениеСвойства.Количество() > 0
И ЗначениеСвойства.Колонки.Найти(ИмяКолонкиФлагаТаблицыТипов) <> Неопределено
//И ЗначениеСвойства.Колонки.Найти("ИмяОбщегоТипа") <> Неопределено
Тогда
ТаблицаТипов = ЗначениеСвойства;
Иначе
ТаблицаТипов = НоваяТаблицаТипов();
ПредыдущаяТаблицаТипов = ТаблицаТипов;
МассивТипов = Новый Массив;
Квалификаторы = Неопределено;
ОписаниеТиповЗначения = Неопределено;
Если Истина
И РодительскаяСтруктураТипа.ТипЯзыка <> "ИмяТипа"
И СхемаКоллекции.Количество() > 0
И (Ложь
Или СтрокаСлова.ТипЗначения = ""
Или Найти(СтрокаСлова.ТипЗначения + ",", "Произвольный,") > 0
Или СтрокаСлова.ТипЗначения = "НаборЗаписейРегистра"
Или Найти(СтрокаСлова.ТипЗначения, "<") > 0
Или ЛиТипСКвалификаторами)
Тогда
Если ТипЗнч(ЗначениеСвойства) = Тип("ОписаниеТипов") Тогда
ОписаниеТиповЗначения = ЗначениеСвойства;
КонецЕсли;
Если Истина
И ЯзыкПрограммы = 1
И РодительскаяСтруктураТипа.ТипЯзыка <> "ЗначениеВЗапросе"
//И КорневойТипРодителя <> Неопределено
//И КорневойТипРодителя <> "ВнешнийИсточникДанных"
И СтрокаСлова.Слово <> "<Имя перерасчета>"
И СтрокаСлова.Слово <> "База<Имя базового регистра расчета>"
И ПостроительЗапросаРодителя <> Неопределено
Тогда
ДоступноеПолеСлова = ПостроительЗапросаРодителя.ДоступныеПоля.Найти(НРег(КонечноеСлово));
Если ДоступноеПолеСлова = Неопределено Тогда
Продолжить;
КонецЕсли;
Если ДоступноеПолеСлова.ТипЗначения <> Новый ОписаниеТипов("ТаблицаЗначений") Тогда
ОписаниеТиповЗначения = ДоступноеПолеСлова.ТипЗначения;
КонецЕсли;
КонецЕсли;
Если Истина
И ОписаниеТиповЗначения = Неопределено
И СтрокаОписанияВида.ИмяКоллекции <> "КритерииОтбора"
И СтрокаОписанияВида.ИмяКоллекции <> "ПланыВидовХарактеристик"
И ИмяОбщегоТипаРодителя <> "Константа"
Тогда
СвойстваСТипом = Новый Структура("Тип, ТипЗначения");
Попытка
ЗаполнитьЗначенияСвойств(СвойстваСТипом, ЗначениеСвойства); // Длительность равна одному выбросу исключения
Исключение
// Не объектное значение
КонецПопытки;
Если ТипЗнч(СвойстваСТипом.Тип) = Тип("ОписаниеТипов") Тогда
ОписаниеТиповЗначения = СвойстваСТипом.Тип;
ИначеЕсли ТипЗнч(СвойстваСТипом.ТипЗначения) = Тип("ОписаниеТипов") Тогда
ОписаниеТиповЗначения = СвойстваСТипом.ТипЗначения;
КонецЕсли;
Если Истина
И ТипЗнч(ЗначениеСвойства) = Тип("ОбъектМетаданных")
И ОписаниеТиповЗначения <> Неопределено
Тогда
ИмяВложенногоТипа = ЗначениеСвойства.Комментарий;
Если ОписаниеТиповЗначения.Типы().Количество() = 0 Тогда
// реквизит обработки с типом Произвольный
ИмяТипа = ирОбщий.ПервыйФрагментЛкс(ИмяВложенногоТипа, " "); // Типизация реквизита из свойства "Комментарий"
Фрагменты = ирОбщий.СтрРазделитьЛкс(ИмяТипа, ":", Истина);
Попытка
ОписаниеТиповЗначения = Новый ОписаниеТипов(Фрагменты[0]);
Исключение
//
КонецПопытки;
Если Фрагменты.Количество() > 1 Тогда
ИмяВложенногоТипа = Фрагменты[1];
КонецЕсли;
КонецЕсли;
Если Ложь
Или ОписаниеТиповЗначения.СодержитТип(Тип("ХранилищеЗначения"))
Или ОписаниеТиповЗначения.СодержитТип(Тип("Строка")) И ОписаниеТиповЗначения.КвалификаторыСтроки.Длина = 0
Тогда
ЕстьВложенныйТип = ЛиВСтрокеТиповЕстьКонструктор(ИмяВложенногоТипа);
Если Не ЕстьВложенныйТип Тогда
ИмяВложенногоТипа = ирОбщий.ПервыйФрагментЛкс(ИмяВложенногоТипа, " "); // Типизация реквизита из свойства "Комментарий"
Попытка
ТипВложенный = Тип(ИмяВложенногоТипа);
ЕстьВложенныйТип = Истина;
Исключение
КонецПопытки;
КонецЕсли;
Если ЕстьВложенныйТип Тогда
ТаблицаТиповВложенная = ирКэш.ПолеТекстаПрограммы(0).ТаблицаТиповИзТекста(ИмяВложенногоТипа);
Если ТаблицаТиповВложенная.Количество() Тогда
ТаблицаТипов = ТаблицаТиповИзОписанияТипов(ОписаниеТиповЗначения);
ТаблицаТипов[0].Метаданные = ТаблицаТиповВложенная[0].Метаданные;
ОписаниеТиповЗначения = Неопределено;
МассивТипов.Очистить();
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ТипЗнч(ОписаниеТиповЗначения) = Тип("ОписаниеТипов") Тогда
МассивТипов = ОписаниеТиповЗначения.Типы();
Квалификаторы = ОписаниеТиповЗначения;
ИначеЕсли ТипЗнч(ЗначениеСвойства) = Тип("Массив") Тогда
МассивТипов = ЗначениеСвойства;
КонецЕсли;
КонецЕсли;
Если Истина
И МассивТипов.Количество() = 0
И (Ложь
Или СхемаКоллекции.Количество() = 0
//Или ОписаниеТиповЗначения = Неопределено И СтрокаСлова.ТипЗначения = "Произвольный"
)
Тогда
МассивТипов.Добавить(ТипЗнч(ЗначениеСвойства));
КонецЕсли;
ПередаватьМетаданныеСвойства = ТипЗнч(ЗначениеСвойства) = Тип("ОбъектМетаданных") И СтрокаСлова.ТипСлова = ПеречТипСлова.Свойство;
Если Истина
//И ОписаниеТиповЗначения <> Неопределено
И МассивТипов.Количество() > 0
И СтрокаОписанияВида.ИмяКоллекции <> "<Имя коллекции метаданных>"
И (Ложь
Или СтрокаОписанияВида.ИмяКоллекции <> "Константы"
Или ЯзыкПрограммы = 1)
Тогда
ШаблонСтруктурыТипа = Новый Структура("СтрокаОписания, ТипЯзыка, Метаданные, МетаданныеСвойства, ДержательМетаданных, Квалификаторы");
ШаблонСтруктурыТипа.СтрокаОписания = СтрокаСлова;
ШаблонСтруктурыТипа.ТипЯзыка = РодительскаяСтруктураТипа.ТипЯзыка;
Если ирОбщий.ЛиФормаИлиИмитаторЛкс(МетаданныеРодителя) Тогда
ШаблонСтруктурыТипа.ДержательМетаданных = МетаданныеРодителя;
Иначе
ШаблонСтруктурыТипа.ДержательМетаданных = РодительскаяСтруктураТипа.ДержательМетаданных;
КонецЕсли;
ШаблонСтруктурыТипа.Квалификаторы = Квалификаторы;
//ШаблонСтруктурыТипа.Метаданные = МетаданныеРодителя;
ПередаватьМетаданные = Ложь
Или МассивТипов.Количество() <> 1
Или МассивТипов[0] <> Тип("ТаблицаЗначений");
ПередаватьМетаданныеРодителя = Истина
И ИмяОбщегоТипаРодителя <> "ВсеЭлементыФормы" // Иначе в метаданные элемента формы запишется имитатор формы
И ИмяОбщегоТипаРодителя <> "СтрокаДереваЗначений"
И ИмяОбщегоТипаРодителя <> "СтрокаТаблицыЗначений" // Иначе у таблицы вложенной в другую таблицу будут наследоваться колонки
И НЕ (ИмяОбщегоТипаРодителя = "Структура" И ТипЗнч(МетаданныеРодителя) = Тип("Структура"))
//И (Ложь // У этого типа бывают свои метаданные Мультиметка62766134
// Или МассивТипов.Количество() <> 1
// Или МассивТипов[0] <> Тип("Строка"))
;
Если ПередаватьМетаданныеСвойства Тогда
ШаблонСтруктурыТипа.МетаданныеСвойства = ЗначениеСвойства;
КонецЕсли;
Если МассивТипов.Количество() > МаксЧислоТиповДляАнализа Тогда
СтруктураТипаСвойства = СтруктураТипаИзКонкретногоТипа(МассивТипов[0], ЯзыкПрограммы, ШаблонСтруктурыТипа);
СтруктураОбщегоТипа = НоваяСтруктураТипа(СтруктураТипаСвойства.ИмяОбщегоТипа);
ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураОбщегоТипа);
Иначе
МассивНакопления = Новый Массив;
Для Каждого Тип Из МассивТипов Цикл
Если Истина
И Тип = ТипЗнч(ЗначениеСвойства)
//И (Ложь
// Или мМассивТиповСМетаданными.Найти(Тип) <> Неопределено
// Или мМассивТиповЭлементовОбычнойФормы.Найти(Тип) <> Неопределено)
Тогда
МетаданныеЭлемента = МетаданныеЭлементов[ИмяСвойства];
Если МетаданныеЭлемента = Неопределено Тогда
МетаданныеЭлемента = ЗначениеСвойства;
КонецЕсли;
ШаблонСтруктурыТипа.Метаданные = МетаданныеЭлемента;
СтруктураТипаСвойства = СтруктураТипаИзЗначения(ЗначениеСвойства, ЯзыкПрограммы, ШаблонСтруктурыТипа);
Иначе
Если ПередаватьМетаданные Тогда
Если ПередаватьМетаданныеСвойства Тогда
ШаблонСтруктурыТипа.Метаданные = ЗначениеСвойства;
ИначеЕсли ПередаватьМетаданныеРодителя Тогда
ШаблонСтруктурыТипа.Метаданные = МетаданныеРодителя;
КонецЕсли;
КонецЕсли;
СтруктураТипаСвойства = СтруктураТипаИзКонкретногоТипа(Тип, ЯзыкПрограммы, ШаблонСтруктурыТипа);
КонецЕсли;
МассивНакопления.Добавить(СтруктураТипаСвойства);
КонецЦикла;
ДобавитьВТаблицуТипов(ТаблицаТипов, МассивНакопления);
КонецЕсли;
Иначе
СтруктураТипаСвойства = НоваяСтруктураТипа();
ЗаполнитьЗначенияСвойств(СтруктураТипаСвойства, РодительскаяСтруктураТипа, "ТипЯзыка");
Если ТипЗнч(МетаданныеРодителя) = ирОбщий.ТипУправляемаяФормаЛкс() Тогда
СтруктураТипаСвойства.ДержательМетаданных = МетаданныеРодителя;
Иначе
СтруктураТипаСвойства.ДержательМетаданных = РодительскаяСтруктураТипа.ДержательМетаданных;
КонецЕсли;
Если РодительскаяСтруктураТипа.ТипЯзыка = "ИмяТипа" Тогда
СтруктураТипаСвойства.ИмяОбщегоТипа = СтрокаСлова.Слово;
Если СтрокаСлова.ТипКонтекста <> "" Тогда
СтруктураТипаСвойства.ИмяОбщегоТипа = СтрокаСлова.ТипКонтекста + "." + СтруктураТипаСвойства.ИмяОбщегоТипа;
КонецЕсли;
Иначе
СтруктураТипаСвойства.ИмяОбщегоТипа = СтрокаСлова.ТипЗначения;
СтруктураТипаСвойства.СтрокаОписания = СтрокаСлова;
КонецЕсли;
СтруктураТипаСвойства.Метаданные = ЗначениеСвойства;
//Если ПустаяСтрока(СтруктураТипаСвойства.ИмяОбщегоТипа) Тогда
//КонецЕсли;
Если ПередаватьМетаданныеСвойства Тогда
СтруктураТипаСвойства.МетаданныеСвойства = ЗначениеСвойства;
КонецЕсли;
ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипаСвойства);
КонецЕсли;
КонецЕсли;
Иначе
//
КонецЕсли;
ДобавитьВТаблицуСлов(ТаблицаСлов, КонечноеСлово, СтрокаСлова.ТипСлова, ТаблицаТипов, "??" + ТипЗначенияСлова, "Метаданные",,,,, ТипЗначенияСлова);
КонецЦикла;
Если ЭтоГруппаОбщихМодулей Тогда
Прервать;
КонецЕсли;
КонецЦикла;
Если ЭтоГруппаОбщихМодулей Тогда
Прервать;
КонецЕсли;
// Модуль
Если Истина
И Не ирОбщий.СтрНачинаетсяСЛкс(СтрокаОбщегоТипа.ИмяОбщегоТипа, "РасширениеФормы")
И (Ложь
Или РодительскаяСтруктураТипа.ТипЯзыка = ""
Или СтрокаОбщегоТипа.ИмяОбщегоТипа <> "Глобальный")
И (Ложь
Или ЯзыкПрограммы = 0
Или ЯзыкПрограммы = 2)
Тогда
Если СтрокаОбщегоТипа.ИмяОбщегоТипа = "Глобальный" Тогда
ДобавитьВТаблицуСловЭлементыГлобальныхМодулей(СтрокаОбщегоТипа, СловоФильтр, ТипСловаФильтр, ВычислятьТипы, ВычислятьТипыМетодовМодулей, Не ЭтоЛокальныйКонтекст,
КлиентОбычноеПриложение, КлиентУправляемоеПриложение, НаСервере, ТаблицаСлов,, ТолькоСоЗначениями);
Иначе
МодульМетаданныхКомпонента = ПараметрыЗаполнения.МодульМетаданных;
Если Истина
И МодульМетаданныхКомпонента = Неопределено
И ИмяОбщегоТипаРодителя <> "НеизвестныйКонтекст"
И ТипЗнч(МетаданныеРодителя) <> Тип("Неопределено")
И ТипЗнч(МетаданныеРодителя) <> Тип("Строка")
Тогда
Если ирОбщий.СтрНачинаетсяСЛкс(ИмяОбщегоТипаРодителя, "Форма") Тогда
ИмяОбщегоТипаРодителя = РодительскаяСтруктураТипа.ИмяОбщегоТипа;
КонецЕсли;
СтруктураТипаМодуля = НоваяСтруктураТипа(ИмяОбщегоТипаРодителя);
СтруктураТипаМодуля.ДержательМетаданных = РодительскаяСтруктураТипа.ДержательМетаданных; // Имя расширения конфигурации
СтруктураТипаМодуля.Метаданные = МетаданныеРодителя;
МодульМетаданныхКомпонента = ПодготовитьМодульМетаданных(СтруктураТипаМодуля);
КонецЕсли;
Если МодульМетаданныхКомпонента <> Неопределено Тогда
РасширениеМодуля = "";
Если Истина
И МодульМетаданныхКомпонента.СтруктураТипа <> Неопределено
И ТипЗнч(МодульМетаданныхКомпонента.СтруктураТипа.ДержательМетаданных) = Тип("Строка")
И ЗначениеЗаполнено(МодульМетаданныхКомпонента.СтруктураТипа.ДержательМетаданных)
Тогда
РасширениеМодуля = МодульМетаданныхКомпонента.СтруктураТипа.ДержательМетаданных;
КонецЕсли;
Если Ложь
Или Не ЗначениеЗаполнено(РасширениеМодуля) // методы конфигурации всегда видны расширению
Или БазовоеРасширениеКонфигурации = "*" // методы конфигурации всегда видны внешнему модулю
Или РасширениеМодуля = БазовоеРасширениеКонфигурации
Или РасширениеМодуля = ПолноеИмяПодсистемыИР // расширение ИР видно всем
Или ФлагиКомпиляции <> Неопределено И ФлагиКомпиляции.Свойство("Динамический")
Тогда
ТолькоЭкспорт = Не ЭтоЛокальныйКонтекст Или СтрокаОбщегоТипа.Метаданные <> РодительскаяСтруктураТипа.Метаданные;
ТаблицаСлов = ДобавитьВТаблицуСловЭлементыМодуляМетаданных(СтрокаОбщегоТипа, СловоФильтр, ТипСловаФильтр, ТаблицаСлов, МодульМетаданныхКомпонента, ВычислятьТипыМетодовМодулей, ВычислятьТипы, ТолькоЭкспорт,
ФлагиКомпиляции, ВнутриГруппыОбщихМодулей, ДляСвойства, ЛиВместеСЛокальнымКонтекстом,, ТолькоСоЗначениями, ПараметрыЗаполнения.СтрогийФильтр);
КонецЕсли;
ВидимыеРасширения = Новый Массив;
Если Истина
И ТипЗнч(РасширениеМодуля) = Тип("Строка")
И ЗначениеЗаполнено(РасширениеМодуля)
И (Ложь
Или ТипЗнч(МетаданныеРодителя) <> Тип("ОбъектМетаданных")
Или МетаданныеРодителя.РасширениеКонфигурации() = Неопределено)
Тогда
// Для расширения модуля добавляем базовый модуль
ВидимыеРасширения.Добавить(Неопределено);
ИначеЕсли БазовоеРасширениеКонфигурации = "*" Тогда
// При вызове из внешнего модуля, добавляем расширение модуля этого расширения
Для Каждого РасширениеКонфигурации Из ирКэш.РасширенияКонфигурацииЛкс() Цикл
ВидимыеРасширения.Добавить(РасширениеКонфигурации.Ключ.Имя);
КонецЦикла;
ИначеЕсли ЗначениеЗаполнено(БазовоеРасширениеКонфигурации) И Не ЗначениеЗаполнено(РасширениеМодуля) Тогда
// При вызове из модуля расширения, добавляем расширение модуля этого расширения
ВидимыеРасширения.Добавить(БазовоеРасширениеКонфигурации);
КонецЕсли;
Для Каждого ВидимоеРасширение Из ВидимыеРасширения Цикл
СтруктураТипаМодуля = НоваяСтруктураТипа(ИмяОбщегоТипаРодителя);
СтруктураТипаМодуля.ДержательМетаданных = ВидимоеРасширение;
СтруктураТипаМодуля.Метаданные = МетаданныеРодителя;
МодульМетаданныхРасширение = ПодготовитьМодульМетаданных(СтруктураТипаМодуля);
Если МодульМетаданныхРасширение <> Неопределено Тогда
ТаблицаСлов = ДобавитьВТаблицуСловЭлементыМодуляМетаданных(СтрокаОбщегоТипа, СловоФильтр, ТипСловаФильтр, ТаблицаСлов, МодульМетаданныхРасширение, ВычислятьТипыМетодовМодулей, ВычислятьТипы, Не ЭтоЛокальныйКонтекст,
ФлагиКомпиляции, ВнутриГруппыОбщихМодулей, ДляСвойства, ЛиВместеСЛокальнымКонтекстом,, ТолькоСоЗначениями);
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЕсли;
#Если Клиент Тогда
ТаблицаСлов = СловаКонтекстаМетаданныеCOM(СловоФильтр, ТипСловаФильтр, ИмяОбщегоТипаРодителя, МетаданныеРодителя, ТаблицаСлов, НаборыСлов, КлючКэширования);
#КонецЕсли
КонецЕсли;
КонецЦикла;
Если Истина
И СловоФильтр <> Неопределено
И Не ПараметрыЗаполнения.СтрогийФильтр
И ТаблицаСлов.Количество() = 0
И ЕдинственнаяСтрокаВида <> Неопределено
И ЕдинственнаяСтрокаВида <> Null
И ЕдинственнаяСтрокаВида.Слово <> "<Имя общего модуля>"
И (Ложь
Или ЕдинственнаяСтрокаВида.ТипЗначения <> "Произвольный" // Иначе проверка модуля не будет обнаруживать ошибки в таких переменных
Или Не ЛиВместеСЛокальнымКонтекстом)
// Иначе при вычислении результата метода модуля менеджера все локальные переменные будут срабатывать
И Найти(ЕдинственнаяСтрокаВида.Слово, "<Имя предопределенного") = 0
И Найти(ЕдинственнаяСтрокаВида.Слово, "<Имя значения перечисления") = 0
Тогда
// Шаблон только один. Берем его даже если имя элемента коллекции не подошло.
МассивТиповЗначения = ирОбщий.СтрРазделитьЛкс(ЕдинственнаяСтрокаВида.ТипЗначения, ", ");
Для Каждого ТипЗначения Из МассивТиповЗначения Цикл
//Если Истина
// И Не ЗначениеЗаполнено(ТипЗначения)
// И ЕдинственнаяСтрокаВида.ТипКонтекста <> "COMОбъект"
//Тогда
// ТипЗначения = "НеизвестныйКонтекст"; // Для ЭлементыФормы[0] // Вредно для проверки ДанныеФормыЭлементКоллекции
//КонецЕсли;
СтруктураТипа = НоваяСтруктураТипа();
СтруктураТипа.ИмяОбщегоТипа = ТипЗначения;
СтруктураТипа.СтрокаОписания = ЕдинственнаяСтрокаВида;
СтруктураТипа.ТипЯзыка = ЕдинственнаяСтрокаВида.ТипЯзыка;
ИмяОбщегоТипаРодителя = СтрЗаменить(ИмяОбщегоТипаРодителя, "Менеджер", ""); // СправочникиМенеджер->Справочники
Если Истина
И ирОбщий.СтрКончаетсяНаЛкс(ИмяОбщегоТипаРодителя, "Структура")
И ТипЗнч(МетаданныеРодителя) = Тип("ТаблицаЗначений")
Тогда
СтруктураТипа = МетаданныеРодителя;
ИначеЕсли Ложь
Или ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных")
Или ирОбщий.ЕдинственноеИмяМДЛкс(ИмяОбщегоТипаРодителя) <> Неопределено
Или ирОбщий.МножественноеИмяМДЛкс(ИмяОбщегоТипаРодителя) <> Неопределено
Или ирОбщий.СтрНачинаетсяСЛкс(ИмяОбщегоТипаРодителя, МаркерКоллекцииМетаданных)
Тогда
// Мультиметка29332671 Чтобы проверка модуля отличила обращение к несуществующему реквизиту ТЧ в языке запросов
СтруктураТипа.Метаданные = Null;
Иначе
СтруктураТипа.Метаданные = МетаданныеРодителя;
КонецЕсли;
ТаблицаТипов = ДобавитьВТаблицуТипов(, СтруктураТипа);
ДобавитьВТаблицуСлов(ТаблицаСлов, ЕдинственнаяСтрокаВида.Слово, ЕдинственнаяСтрокаВида.ТипСлова, ТаблицаТипов,, "Метаданные");
КонецЦикла;
КонецЕсли;
Возврат ТаблицаСлов;
КонецФункции
//.
// Параметры:
// РодительскаяСтруктураТипа - Структура - Структура;
// МетаданныеРодителя - -
// СхемаКоллекции - Соответствие -
// Возвращаемое значение:
// Структура -
Функция СхемаКоллекцииПараметровФормы(Знач РодительскаяСтруктураТипа, Знач Слово = Неопределено) Экспорт
Если Слово = "" Тогда
Слово = Неопределено;
КонецЕсли;
СхемаКоллекции = Новый Структура;
МетаданныеРодителя = РодительскаяСтруктураТипа.Метаданные;
Форма = РодительскаяСтруктураТипа.ДержательМетаданных; // ФормаКлиентскогоПриложения
Если ТипЗнч(Форма) = Тип("Структура") И Форма.Свойство("ИмяОбщегоТипа") Тогда
МетаданныеРодителя = Форма.ИмяОбщегоТипа;
КонецЕсли;
Если ТипЗнч(МетаданныеРодителя) = Тип("ДанныеФормыСтруктура") Тогда
СтруктураТипаФормы = СтруктураТипаИзЗначения(Форма);
// Системные параметры формы
ПараметрыЗаполнения = НовыеПараметрыЗаполненияСлов("Параметр",,,,,,,, Слово);
ТаблицаПараметровФормы = ТаблицаСловИзСтруктурыТипа(СтруктураТипаФормы, ПараметрыЗаполнения);
Для Каждого СтрокаПараметра Из ТаблицаПараметровФормы Цикл
ТаблицаТипов = СтрокаПараметра.ТаблицаТипов;
Если СтрокаПараметра.Слово = "Ключ" Тогда
КлючФормы = ирОбщий.КлючОсновногоОбъектаФормыЛкс(Форма);
ОбъектМД = Метаданные.НайтиПоТипу(ТипЗнч(КлючФормы));
ТаблицаТипов[0].Метаданные = ОбъектМД;
КонецЕсли;
СхемаКоллекции.Вставить(СтрокаПараметра.Слово, ТаблицаТипов);
КонецЦикла;
СлужебныеДанные = ирОбщий.СлужебныеДанныеФормыЛкс(Форма);
Если СлужебныеДанные <> Неопределено И СлужебныеДанные.Свойство("Параметры") Тогда
ирОбщий.СкопироватьКоллекциюЛкс(СлужебныеДанные.Параметры, СхемаКоллекции); // TODO добавить фильтр по Слово
// Параметры часто не описаны в структуре формы
//Если ЗначениеЗаполнено(Слово) И Не СхемаКоллекции.Свойство(Слово) Тогда
// ДобавитьОтсутствиеЭлементаФормы(Форма, "Параметр:" + Слово);
//КонецЕсли;
КонецЕсли;
ИначеЕсли ТипЗнч(МетаданныеРодителя) = Тип("Строка") Тогда
ПараметрыЗаполнения = НовыеПараметрыЗаполненияСлов("Параметр",,,,,,,, Слово);
ТаблицаПараметровФормы = ТаблицаСловИзСтруктурыТипа(НоваяСтруктураТипа(МетаданныеРодителя), ПараметрыЗаполнения);
Для Каждого СтрокаПараметра Из ТаблицаПараметровФормы Цикл
СхемаКоллекции.Вставить(СтрокаПараметра.Слово, СтрокаПараметра.ТаблицаТипов);
КонецЦикла;
ИначеЕсли ТипЗнч(МетаданныеРодителя) = Тип("Структура") Тогда
СхемаКоллекции = МетаданныеРодителя;
КонецЕсли;
Если Истина
И СтруктураТипаФормы = Неопределено
И ТипЗнч(РодительскаяСтруктураТипа.ДержательМетаданных) = Тип("Структура")
Тогда
СтруктураТипаФормы = НоваяСтруктураТипа("ФормаКлиентскогоПриложения");
СтруктураТипаФормы.Метаданные = РодительскаяСтруктураТипа.ДержательМетаданных;
КонецЕсли;
// Ожидаемые в коде формы параметры
Если СтруктураТипаФормы <> Неопределено Тогда
МодульФормы = ПодготовитьМодульМетаданных(СтруктураТипаФормы);
Если МодульФормы <> Неопределено Тогда
МетодМодуля = МодульФормы.Методы.Найти(НРег("ПриСозданииНаСервере"), "НИмя");
Если МетодМодуля <> Неопределено Тогда
АнализаторМодуля = ПолеТекстаМодуля(МодульФормы.Имя);
АнализаторМодуля.ЗагрузитьМетодМодуля(МетодМодуля);
СтарыйРежимПроверкиМодуля = мРежимПроверкиМодуля;
мРежимПроверкиМодуля = Ложь;
СтруктураИзКода = АнализаторМодуля.СобратьСвойстваСтруктуры("Параметры",,,,,, Слово, АнализаторМодуля.ИмяФиктивногоСвойства());
Если СтруктураИзКода <> Неопределено Тогда
мРежимПроверкиМодуля = СтарыйРежимПроверкиМодуля;
ирОбщий.СкопироватьКоллекциюЛкс(СтруктураИзКода, СхемаКоллекции);
АнализаторМодуля.мРодительскийКонтекст = "Параметры";
АнализаторМодуля.ЗаполнитьЛокальныеСвойстваИМетодыПоТексту(,, Истина,,,,, Истина);
Для Каждого СтрокаСлова Из АнализаторМодуля.ТаблицаСлов Цикл
СхемаКоллекции.Вставить(СтрокаСлова.Слово);
КонецЦикла;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат СхемаКоллекции;
КонецФункции
//.
// Параметры:
// СтруктураЭлемента - см. ИмитаторЭлементаФормы -
// ИмитаторФормы - -
// Слово - Строка, Неопределено - Строка, *Неопределено - для отбора;
// Возвращаемое значение:
// -
Функция ТаблицаТиповИзИмитатораЭлементаФормы(Знач СтруктураЭлемента, Знач ИмитаторФормы, Знач Слово) Экспорт
ЗначениеЭлемента = Новый ОписаниеТипов(ирОбщий.ЗначенияВМассивЛкс(СтруктураЭлемента.Тип));
Если ЗначениеЗаполнено(Слово) Тогда
ЗначениеЭлемента = ТаблицаТиповИзОписанияТипов(ЗначениеЭлемента);
ЗначениеЭлемента[0].Метаданные = СтруктураЭлемента;
ЗначениеЭлемента[0].ДержательМетаданных = ИмитаторФормы;
ИмяОбщегоТипаРасширения = ИмяТипаРасширенияЭлементаФормы(ЗначениеЭлемента[0].ИмяОбщегоТипа, СтруктураЭлемента);
Если ИмяОбщегоТипаРасширения <> Неопределено Тогда
ЗначениеЭлемента[0].ИмяОбщегоТипа = ИмяОбщегоТипаРасширения;
КонецЕсли;
КонецЕсли;
Возврат ЗначениеЭлемента;
КонецФункции
// Функция - Слова контекста метаданные COM
//
// Параметры:
// Слово - -
// ТипСлова - -
// ИмяОбщегоТипаРодителя - -
// МетаданныеРодителя - -
// ТаблицаСлов - см. НоваяТаблицаСлов() -
// НаборыСлов - -
// КлючКэширования - -
//
// Возвращаемое значение:
// -
//
Функция СловаКонтекстаМетаданныеCOM(Знач Слово, Знач ТипСлова, Знач ИмяОбщегоТипаРодителя, Знач МетаданныеРодителя, Знач ТаблицаСлов, Знач НаборыСлов, КлючКэширования) Экспорт
Если Истина
И (Ложь
Или ТипЗнч(МетаданныеРодителя) = Тип("COMОбъект")
Или ТипЗнч(МетаданныеРодителя) = Тип("ВнешнийОбъект")
Или Найти(ИмяОбщегоТипаРодителя, " {") > 0)
И ЛиИмяТипаComОбъекта(ИмяОбщегоТипаРодителя)
Тогда
КлючКэширования = КлючКэшированияСловИзОбщегоТипа(ИмяОбщегоТипаРодителя);
ТаблицаСловОтдельная = мКэшСловГлобальногоКонтекста[КлючКэширования];
#Если Сервер И Не Сервер Тогда
ТаблицаСловОтдельная = Новый ТаблицаЗначений;
#КонецЕсли
Если ТаблицаСловОтдельная <> Неопределено Тогда
КлючКэширования = Неопределено;
Иначе
ТаблицаСловОтдельная = НоваяТаблицаСлов();
ИмяБиблиотеки = "";
ИнфоТипа = ПолучитьИнфоТипаCOMОбъекта(МетаданныеРодителя, ИмяОбщегоТипаРодителя, ИмяБиблиотеки);
Если ИнфоТипа = Неопределено Тогда
КлючКэширования = Неопределено;
Иначе
МассивИнфоТипа = ИнтерфейсыCOMОбъекта(ИнфоТипа, ИмяОбщегоТипаРодителя);
Для Каждого ИнфоТипа Из МассивИнфоТипа Цикл
Для Каждого Член Из ИнфоТипа.Members Цикл
Если Член.AttributeMask = 1 Тогда
// Это члены IDispatch
Продолжить;
КонецЕсли;
ИмяЧлена = Член.Name;
Если Член.InvokeKind = 1 Или Член.Parameters.Count > 0 Тогда
ТипСловаЧленаКласса = ПеречТипСлова.Метод;
ИначеЕсли Член.InvokeKind = 2 Тогда //Get
ТипСловаЧленаКласса = "Свойство";
Иначе
Продолжить;
КонецЕсли;
СтруктураТипа = НоваяСтруктураТипа();
СтруктураТипа.ИмяОбщегоТипа = ПолучитьТипЗначенияЧленаИнтерфейса(Член, ИмяБиблиотеки, ИнфоТипа);
СтруктураТипа.СтрокаОписания = Член;
СтруктураТипа.Метаданные = МетаданныеРодителя;
ТаблицаТипов = ДобавитьВТаблицуТипов(, СтруктураТипа);
ДобавитьВТаблицуСлов(ТаблицаСловОтдельная, ИмяЧлена, ТипСловаЧленаКласса, ТаблицаТипов,, "Метаданные");
Если Истина
И ТипСловаЧленаКласса = "Свойство"
И Член.ReturnType.TypeInfo <> Неопределено
Тогда
ТипСловаЧленаКласса = ПеречТипСлова.Метод;
ИнфоТипаЧлена = Член.ReturnType.TypeInfo;
Попытка
ОписаниеЭлементаКоллекции = ИнфоТипаЧлена.GetMember("Item");
Исключение
ОписаниеЭлементаКоллекции = Неопределено;
КонецПопытки;
Если ОписаниеЭлементаКоллекции <> Неопределено Тогда
// Например ADODB.Connection.Properties("DBMS Name").Value
СтруктураТипа = НоваяСтруктураТипа();
СтруктураТипа.ИмяОбщегоТипа = ПолучитьТипЗначенияЧленаИнтерфейса(ОписаниеЭлементаКоллекции, ИмяБиблиотеки, ИнфоТипа);
СтруктураТипа.СтрокаОписания = Член;
СтруктураТипа.Метаданные = МетаданныеРодителя;
ТаблицаТипов = ДобавитьВТаблицуТипов(, СтруктураТипа);
ДобавитьВТаблицуСлов(ТаблицаСловОтдельная, ИмяЧлена, ТипСловаЧленаКласса, ТаблицаТипов,, "Метаданные");
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецЕсли;
КонецЕсли;
Если Ложь
Или ЗначениеЗаполнено(ТипСлова)
Или ЗначениеЗаполнено(Слово)
Тогда
НаборыСлов = Неопределено;
Фильтр = Новый Структура;
Если ЗначениеЗаполнено(Слово) Тогда
Если ТаблицаСловОтдельная.Колонки.Найти("НСлово") = Неопределено Тогда
ирОбщий.ОбновитьКопиюКолонкиВНижнемРегистреЛкс(ТаблицаСловОтдельная, "Слово");
//! ТаблицаСловОтдельная.Колонки.Добавить("НСлово")
КонецЕсли;
Фильтр.Вставить("НСлово", НРег(Слово));
КонецЕсли;
Если Не ЗначениеЗаполнено(Слово) Тогда // Тип слова у КОМ типов может быть неверным
Фильтр.Вставить("ТипСлова", ТипСлова);
КонецЕсли;
КонецЕсли;
Если КлючКэширования <> Неопределено Тогда
ДобавитьТаблицуСловВГлобальныйКэш(ТаблицаСловОтдельная, КлючКэширования, НаборыСлов);
КлючКэширования = Неопределено;
КонецЕсли;
Если Фильтр <> Неопределено Тогда
ТаблицаСловОтдельная = ТаблицаСловОтдельная.Скопировать(Фильтр);
КонецЕсли;
Если ЗначениеЗаполнено(Слово) Тогда
ирОбщий.ЗагрузитьВТаблицуЗначенийЛкс(ТаблицаСловОтдельная, ТаблицаСлов); // Нельзя подменять таблицу слов, т.к. ВычислитьТипДочернегоЭлемента это не поддерживает
Иначе
ТаблицаСлов = СлитьТаблицыСлов(ТаблицаСлов, ТаблицаСловОтдельная);
КонецЕсли;
КонецЕсли;
Возврат ТаблицаСлов;
КонецФункции
// Процедура - Слова контекста метаданные формы
//
// Параметры:
// Слово - -
// ИмяОбщегоТипаРодителя - -
// МетаданныеРодителя - Форма, УправляемаяФорма, Структура, ТабличноеПоле, Панель, КнопкаКоманднойПанели, КнопкиКоманднойПанели -
// СтрокаОписанияВида - -
// КоллекцияЗначений - -
// СхемаКоллекции - -
//
Процедура СловаКонтекстаМетаданныеФормы(Знач Слово, Знач ИмяОбщегоТипаРодителя, Знач МетаданныеРодителя, Знач СтрокаОписанияВида, КоллекцияЗначений = Неопределено, СхемаКоллекции = Неопределено) Экспорт
Если Истина
И ТипЗнч(МетаданныеРодителя) = Тип("Структура")
И Не МетаданныеРодителя.Свойство(СтрокаОписанияВида.ИмяКоллекции)
Тогда
Возврат;
КонецЕсли;
ДочерниеЭлементы = МетаданныеРодителя[СтрокаОписанияВида.ИмяКоллекции];
Если ИмяОбщегоТипаРодителя = "ОформленияЯчеек" Тогда
СхемаКоллекции = ДочерниеЭлементы;
Иначе
ИмитаторФормы = МетаданныеРодителя;
Если ТипЗнч(МетаданныеРодителя) = ирОбщий.ТипУправляемаяФормаЛкс() Тогда
//! ДочерниеЭлементы = 0 // ВсеЭлементыФормы
КоллекцияЗначений = Новый Соответствие;
Если ЗначениеЗаполнено(Слово) Тогда
ЦелевойЭлемент = ДочерниеЭлементы.Найти(Слово);
ДочерниеЭлементы = Новый Массив;
Если ЦелевойЭлемент <> Неопределено Тогда
ДочерниеЭлементы.Добавить(ЦелевойЭлемент);
КонецЕсли;
КонецЕсли;
Для Каждого ЭлементФормы Из ДочерниеЭлементы Цикл
КоллекцияЗначений.Вставить(ЭлементФормы.Имя, ЭлементФормы);
КонецЦикла;
ИмитаторФормы = ирОбщий.СлужебныеДанныеФормыЛкс(МетаданныеРодителя);
ИначеЕсли ТипЗнч(ИмитаторФормы) = Тип("Структура") Тогда
КоллекцияЗначений = Новый Соответствие;
Иначе
КоллекцияЗначений = ДочерниеЭлементы;
КонецЕсли;
Если Истина
И ТипЗнч(ИмитаторФормы) = Тип("Структура")
И ИмитаторФормы.Свойство(СтрокаОписанияВида.ИмяКоллекции)
Тогда
// имитатор формы
ЭлементыИзИмитатора = ИмитаторФормы[СтрокаОписанияВида.ИмяКоллекции]; // Структура
Если ЗначениеЗаполнено(Слово) Тогда
ЭлементыИзИмитатора.Свойство(Слово, ЦелевойЭлемент);
ЭлементыИзИмитатора = Новый Структура;
Если ЦелевойЭлемент <> Неопределено Тогда
ЭлементыИзИмитатора.Вставить(Слово, ЦелевойЭлемент);
КонецЕсли;
КонецЕсли;
Для Каждого КлючИЗначение Из ЭлементыИзИмитатора Цикл
Если КоллекцияЗначений[КлючИЗначение.Ключ] <> Неопределено Тогда
Продолжить;
КонецЕсли;
СтруктураЭлемента = КлючИЗначение.Значение;
СхемаКоллекции["_"] = 1; // Чтобы описания типов в значении считались как тип элемента
КоллекцияЗначений.Вставить(СтруктураЭлемента.Имя, ТаблицаТиповИзИмитатораЭлементаФормы(СтруктураЭлемента, ИмитаторФормы, Слово));
КонецЦикла;
Если ЗначениеЗаполнено(Слово) И КоллекцияЗначений[Слово] = Неопределено Тогда
ДобавитьОтсутствиеЭлементаФормы(ИмитаторФормы, "Элемент:" + Слово);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
// Функция - Добавить в таблицу слов элементы глобальных модулей
//
// Параметры:
// СтрокаОбщегоТипа - см. РазвернутаяТаблицаТиповИзСтруктурыТипа()[0] -
//
Функция ДобавитьВТаблицуСловЭлементыГлобальныхМодулей(Знач СтрокаОбщегоТипа, Знач Слово = Неопределено, Знач ТипСлова = Неопределено, Знач ВычислятьТипы = Истина, Знач ВычислятьТипыМетодовМодулей = Ложь,
Знач ТолькоЭкспорт = Истина, Знач КлиентОбычноеПриложение = Истина, Знач КлиентУправляемоеПриложение = Истина, Знач НаСервере = Ложь, Знач ТаблицаСлов = Неопределено, Знач БезПараметров = Ложь,
Знач ТолькоСоЗначениями = Ложь) Экспорт
Если ТаблицаСлов = Неопределено Тогда
ТаблицаСлов = НоваяТаблицаСлов();
КонецЕсли;
Если ПустаяСтрока(ТипСлова) Или ТипСлова = ПеречТипСлова.Метод Тогда
// Глобальные общие модули
СтруктураТипаМодуля = НоваяСтруктураТипа();
СтруктураТипаМодуля.ИмяОбщегоТипа = "ОбщийМодуль";
Для Каждого ОбщийМодульМД Из ирКэш.ГлобальныеОбщиеМодулиЛкс(НаСервере, КлиентОбычноеПриложение, КлиентУправляемоеПриложение) Цикл
СтруктураТипаМодуля.Метаданные = ОбщийМодульМД;
МодульМетаданныхКомпонента = ПодготовитьМодульМетаданных(СтруктураТипаМодуля);
ДобавитьВТаблицуСловЭлементыМодуляМетаданных(СтрокаОбщегоТипа, Слово, ПеречТипСлова.Метод, ТаблицаСлов, МодульМетаданныхКомпонента, ВычислятьТипыМетодовМодулей, ВычислятьТипы, ТолькоЭкспорт,,,,,
БезПараметров, ТолькоСоЗначениями);
КонецЦикла;
КонецЕсли;
СтруктураТипаМодуля = НоваяСтруктураТипа(СтрокаОбщегоТипа.ИмяОбщегоТипа);
СтруктураТипаМодуля.Метаданные = СтрокаОбщегоТипа.Метаданные;
Если КлиентОбычноеПриложение Тогда
МодульМетаданныхКомпонента = ПодготовитьМодульМетаданных(СтруктураТипаМодуля, "МодульОбычногоПриложения");
ДобавитьВТаблицуСловЭлементыМодуляМетаданных(СтрокаОбщегоТипа, Слово, ТипСлова, ТаблицаСлов, МодульМетаданныхКомпонента, ВычислятьТипыМетодовМодулей, ВычислятьТипы, ТолькоЭкспорт,,,,,
БезПараметров, ТолькоСоЗначениями);
КонецЕсли;
Если КлиентУправляемоеПриложение Тогда
МодульМетаданныхКомпонента = ПодготовитьМодульМетаданных(СтруктураТипаМодуля, "МодульУправляемогоПриложения");
ДобавитьВТаблицуСловЭлементыМодуляМетаданных(СтрокаОбщегоТипа, Слово, ТипСлова, ТаблицаСлов, МодульМетаданныхКомпонента, ВычислятьТипыМетодовМодулей, ВычислятьТипы, ТолькоЭкспорт,,,,,
БезПараметров, ТолькоСоЗначениями);
КонецЕсли;
Возврат ТаблицаСлов;
КонецФункции
Функция ИнтерфейсыCOMОбъекта(Знач ИнфоТипа, Знач ИмяОбщегоТипаРодителя) Экспорт
МассивИнфоТипа = Новый Массив;
Если Найти(ИмяОбщегоТипаРодителя, " {") > 0 Тогда
ИнфоТипа = ИнфоТипа.Parent.TypeInfos.NamedItem(ирОбщий.ПервыйФрагментЛкс(ИмяОбщегоТипаРодителя, " {"));
КонецЕсли;
//Если ИмяCOMКласса = "" Тогда
// Если Описатель.Parent.Name = "V" + ирКэш.НомерИзданияПлатформыЛкс() Тогда
// ИмяОбщегоТипа = "COM-соединитель";
// КонецЕсли;
//КонецЕсли;
Если ИнфоТипа = Неопределено Тогда
//
ИначеЕсли НРег(ИнфоТипа.TypeKindString) = "coclass" Тогда
//! ИнфоТипа = 0 // TypeInfo {TLI.TLIApplication}
МассивИнфоТипа = ИнфоТипа.Interfaces;
ИначеЕсли НРег(ИнфоТипа.TypeKindString) = "enum" Тогда
//
Иначе
//! ИнфоТипа = 0 // InterfaceInfo {TLI.TLIApplication}
МассивИнфоТипа = Новый Массив;
МассивИнфоТипа.Добавить(ИнфоТипа);
Для Каждого ИнтерфейсОбъекта Из ИнфоТипа.ImpliedInterfaces Цикл
МассивИнфоТипа.Добавить(ИнтерфейсОбъекта);
КонецЦикла;
КонецЕсли;
Возврат МассивИнфоТипа;
КонецФункции
// Помогает обновлять кэш управляемой формы из конфигуратора при следующем вызове автодополнения
// Параметры:
// ФормаИлиСтруктура - Форма, Структура -
// Ключ - Строка -
Процедура ДобавитьОтсутствиеЭлементаФормы(Знач ФормаИлиСтруктура, Знач Ключ) Экспорт
СлужебныеДанные = ирОбщий.СлужебныеДанныеФормыЛкс(ФормаИлиСтруктура);
ОтсутствуютЭлементы = Неопределено;
Если Не СлужебныеДанные.Свойство("ОтсутствуютЭлементы", ОтсутствуютЭлементы) Тогда
ОтсутствуютЭлементы = Новый Соответствие;
СлужебныеДанные.Вставить("ОтсутствуютЭлементы", ОтсутствуютЭлементы);
КонецЕсли;
Если ОтсутствуютЭлементы[Ключ] = Неопределено Тогда
ОтсутствуютЭлементы[Ключ] = 1;
СлужебныеДанные.Вставить("ДатаОбновления", Дата(1,1,1));
КонецЕсли;
КонецПроцедуры
Функция ТаблицаТиповЭлементовКоллекции(Знач РодительскаяСтруктураТипа, Знач ТекстИндексаЭлемента = "", Знач ЯзыкПрограммы = 0, Знач ТаблицаТипов = Неопределено) Экспорт
НужнаПроверкаТипов = Истина;
МетаданныеКоллекции = РодительскаяСтруктураТипа.Метаданные; // Массив
Если Истина
И (Ложь
Или ТипЗнч(МетаданныеКоллекции) = Тип("ТаблицаЗначений")
Или ТипЗнч(МетаданныеКоллекции) = Тип("Массив"))
И МетаданныеКоллекции.Количество() > 0
И ирОбщий.СтрКончаетсяНаЛкс(РодительскаяСтруктураТипа.ИмяОбщегоТипа, "Массив") // ирОбщий.ПервыйФрагментЛкс(РодительскаяСтруктураТипа.ИмяОбщегоТипа, "[")
Тогда
Если ТипЗнч(МетаданныеКоллекции) = Тип("ТаблицаЗначений") Тогда
//! МетаданныеКоллекции = 0 // см. НоваяТаблицаТипов
Если Не ЗначениеЗаполнено(ТекстИндексаЭлемента) Тогда
Если ТаблицаТипов = Неопределено Тогда
ТаблицаТипов = МетаданныеКоллекции;
Иначе
ТаблицаТипов = ДобавитьВТаблицуТипов(ТаблицаТипов, МетаданныеКоллекции);
КонецЕсли;
Иначе
Для Каждого СтрокаТипа Из МетаданныеКоллекции Цикл
СтруктураТипаЭлемента = Неопределено;
Если ТипЗнч(СтрокаТипа.Метаданные) = Тип("ПостроительЗапроса") Тогда
Попытка
ИндексВПакете = Число(ТекстИндексаЭлемента);
Исключение
ИндексВПакете = Неопределено;
КонецПопытки;
ПостроительЗапроса = СтрокаТипа.Метаданные;
Если ИндексВПакете <> Неопределено И ЗначениеЗаполнено(ПостроительЗапроса.Текст) Тогда
ТекстыЗапросов = РазбитьГрубоТекстПакетногоЗапросаНаЗапросы(ПостроительЗапроса.Текст);
#Если Сервер И Не Сервер Тогда
ТекстыЗапросов = Новый Массив;
#КонецЕсли
ПостроительЗапроса = ПостроительПакетаЗапросовДоИндекса(ТекстыЗапросов, ИндексВПакете, ПостроительЗапроса.Параметры,, СтрокаТипа.ДержательМетаданных);
Если ПостроительЗапроса <> Неопределено Тогда
СтруктураТипаЭлемента = НоваяСтруктураТипа(СтрокаТипа.ИмяОбщегоТипа);
СтруктураТипаЭлемента.Метаданные = ПостроительЗапроса;
МенеджерВременныхТаблиц = СтрокаТипа.ДержательМетаданных; // см. ОбработкаОбъект.ирКлсПолеТекстаПрограммы.НовыйМенеджерВременныхТаблиц()
ПоследнийПакетЗапросов = МенеджерВременныхТаблиц.ПакетыЗапросов[МенеджерВременныхТаблиц.ПакетыЗапросов.ВГраница()]; // см. ОбработкаОбъект.ирКлсПолеТекстаПрограммы.НовыйПакетЗапросов()
ПоследнийПакетЗапросов = ирОбщий.СкопироватьКоллекциюЛкс(ПоследнийПакетЗапросов);
ПоследнийПакетЗапросов.Вставить("ИндексВПакете", ИндексВПакете);
СтруктураТипаЭлемента.ДержательМетаданных = ПоследнийПакетЗапросов;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если СтруктураТипаЭлемента = Неопределено Тогда
СтруктураТипаЭлемента = СтрокаТипа;
КонецЕсли;
ТаблицаТипов = ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипаЭлемента);
КонецЦикла;
КонецЕсли;
Иначе
ТаблицаТипов = ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипаИзЗначения(МетаданныеКоллекции[0]));
КонецЕсли;
ИначеЕсли Истина
И ТипЗнч(МетаданныеКоллекции) = Тип("ТаблицаЗначений")
И МетаданныеКоллекции.Количество() > 0
И ирОбщий.СтрКончаетсяНаЛкс(РодительскаяСтруктураТипа.ИмяОбщегоТипа, "Структура") // ирОбщий.ПервыйФрагментЛкс(РодительскаяСтруктураТипа.ИмяОбщегоТипа, "[")
Тогда
СтруктураТипаЭлемента = НоваяСтруктураТипа("КлючИЗначение");
СтруктураТипаЭлемента.Метаданные = Новый Структура("Значение", МетаданныеКоллекции);
ТаблицаТипов = ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипаЭлемента);
ИначеЕсли Истина
И ТипЗнч(МетаданныеКоллекции) = Тип("Структура")
И РодительскаяСтруктураТипа.ИмяОбщегоТипа = "Соответствие"
Тогда
СтруктураТипаЭлемента = НоваяСтруктураТипа("КлючИЗначение");
СтруктураТипаЭлемента.Метаданные = МетаданныеКоллекции;
ТаблицаТипов = ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипаЭлемента);
ИначеЕсли РодительскаяСтруктураТипа.ИмяОбщегоТипа = "СтрокиДинамическогоСписка" Тогда
СтруктураТипаЭлемента = НоваяСтруктураТипа("КлючИЗначение");
СтруктураТипаЭлемента.Метаданные = Новый Структура;
СтруктураТипаЭлемента.Метаданные.Вставить("Значение", ТаблицаТиповИзОписанияТипов(Новый ОписаниеТипов("СтрокаДинамическогоСписка")));
ТаблицаТипов = ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипаЭлемента);
ИначеЕсли РодительскаяСтруктураТипа.ИмяОбщегоТипа = "ОформленияЯчеекДинамическогоСписка" Тогда
СтруктураТипаЭлемента = НоваяСтруктураТипа("КлючИЗначение");
СтруктураТипаЭлемента.Метаданные = Новый Структура;
СтруктураТипаЭлемента.Метаданные.Вставить("Значение", ТаблицаТиповИзОписанияТипов(Новый ОписаниеТипов("ОформлениеЯчейкиДинамическогоСписка")));
ТаблицаТипов = ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипаЭлемента);
ИначеЕсли Истина
И ТипЗнч(МетаданныеКоллекции) = Тип("Структура")
И РодительскаяСтруктураТипа.ИмяОбщегоТипа = "СписокЗначений"
Тогда
СтруктураТипаЭлемента = НоваяСтруктураТипа("ЭлементСпискаЗначений");
СтруктураТипаЭлемента.Метаданные = МетаданныеКоллекции;
ТаблицаТипов = ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипаЭлемента);
#Если Клиент Тогда
ИначеЕсли Истина
И ТипЗнч(МетаданныеКоллекции) = Тип("ТабличноеПоле")
И РодительскаяСтруктураТипа.ИмяОбщегоТипа = "ВыделенныеСтрокиТабличногоПоля"
Тогда
НоваяТаблицаТипов = ТаблицаТиповСтрокиТабличногоПоля(РодительскаяСтруктураТипа);
Если ТаблицаТипов = Неопределено Тогда
ТаблицаТипов = НоваяТаблицаТипов;
Иначе
ТаблицаТипов = ДобавитьВТаблицуТипов(ТаблицаТипов, НоваяТаблицаТипов);
КонецЕсли;
#КонецЕсли
Иначе
Если ТаблицаТипов = Неопределено Тогда
ТаблицаТипов = НоваяТаблицаТипов();
КонецЕсли;
ТипыЭлементовКоллекции = ТипыЭлементовКоллекции(РодительскаяСтруктураТипа, ЯзыкПрограммы, НужнаПроверкаТипов);
Если ТипыЭлементовКоллекции.Количество() > 0 Тогда
ТипТип = Тип("Тип");
Для Каждого БазовыйТипЭлемента Из ТипыЭлементовКоллекции Цикл
Если ТипЗнч(БазовыйТипЭлемента) = ТипТип Тогда
КонкретныйТип = БазовыйТипЭлемента;
Иначе
Попытка
КонкретныйТип = Тип(БазовыйТипЭлемента);
Исключение
КонкретныйТип = Неопределено;
КонецПопытки;
КонецЕсли;
Если КонкретныйТип <> Неопределено Тогда
СтруктураТипаЭлемента = СтруктураТипаИзКонкретногоТипа(КонкретныйТип);
Иначе
СтруктураТипаЭлемента = НоваяСтруктураТипа();
СтруктураТипаЭлемента.ИмяОбщегоТипа = БазовыйТипЭлемента;
КонецЕсли;
Если Истина
И ТипЗнч(СтруктураТипаЭлемента.Метаданные) = Тип("Неопределено")
И Не ирОбщий.ЛиФормаИлиИмитаторЛкс(МетаданныеКоллекции)
Тогда
СтруктураТипаЭлемента.Метаданные = МетаданныеКоллекции;
КонецЕсли;
Если ТипЗнч(МетаданныеКоллекции) = ирОбщий.ТипУправляемаяФормаЛкс() Тогда
СтруктураТипаЭлемента.ДержательМетаданных = МетаданныеКоллекции;
Иначе
СтруктураТипаЭлемента.ДержательМетаданных = РодительскаяСтруктураТипа.ДержательМетаданных;
КонецЕсли;
Если КонкретныйТип = Неопределено И НужнаПроверкаТипов Тогда
СтруктураКлюча = Новый Структура("БазовыйТип, ЯзыкПрограммы", БазовыйТипЭлемента, ЯзыкПрограммы);
НайденныеСтроки = ТаблицаОбщихТипов.НайтиСтроки(СтруктураКлюча);
Если НайденныеСтроки.Количество() > 0 Тогда
СтруктураТипаЭлемента.СтрокаОписания = НайденныеСтроки[0];
СтруктураТипаЭлемента.ИмяОбщегоТипа = НайденныеСтроки[0].Слово;
Если ТипЗнч(МетаданныеКоллекции) <> Тип("КоллекцияОбъектовМетаданных") Тогда
СтруктураТипаЭлемента.Метаданные = МетаданныеКоллекции;
КонецЕсли;
КонецЕсли;
КонецЕсли;
ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипаЭлемента);
КонецЦикла;
КонецЕсли;
КонецЕсли;
Возврат ТаблицаТипов;
КонецФункции
Функция ПараметрыИзТекстаЗапроса(Знач ТекстЗапроса, Знач ВВидеСтруктуры = Ложь, Знач СтруктураПриемник = Неопределено) Экспорт
ПараметрыЗапроса = Новый Массив;
Если Найти(ТекстЗапроса, "&") Тогда
Запрос = Новый Запрос(ТекстЗапроса);
Попытка
ПараметрыЗапроса = Запрос.НайтиПараметры();
Исключение
ОписаниеОшибки = ОписаниеОшибки(); // Отладка
КонецПопытки;
КонецЕсли;
Если ВВидеСтруктуры Тогда
Результат = СтруктураПриемник;
Если СтруктураПриемник = Неопределено Тогда
Результат = Новый Структура;
КонецЕсли;
Если ПараметрыЗапроса <> Неопределено Тогда
Для Каждого ОписаниеПараметра Из ПараметрыЗапроса Цикл
ТаблицаТиповСтарая = Неопределено;
Результат.Свойство(ОписаниеПараметра.Имя, ТаблицаТиповСтарая);
Результат.Вставить(ОписаниеПараметра.Имя, ДобавитьВТаблицуТипов(ТаблицаТиповИзОписанияТипов(ОписаниеПараметра.ТипЗначения), ТаблицаТиповСтарая));
КонецЦикла;
КонецЕсли;
Иначе
Результат = ПараметрыЗапроса;
КонецЕсли;
Возврат Результат;
КонецФункции
//.
// Параметры:
// ТекстЗапроса - Строка -
// Возвращаемое значение:
// ПостроительЗапроса -
Функция ПостроительЗапросаИзТекстаДляТипа(Знач ТекстЗапроса, Знач ПостроительЗапроса = Неопределено) Экспорт
Если ПостроительЗапроса = Неопределено Тогда
ПостроительЗапроса = Новый ПостроительЗапроса;
КонецЕсли;
Попытка
ПостроительЗапроса.Текст = ТекстЗапроса;
Исключение
// Даже если текст некорректный, он сохраняется в свойстве
КонецПопытки;
ПараметрыИзТекстаЗапроса(ТекстЗапроса, Истина, ПостроительЗапроса.Параметры);
Возврат ПостроительЗапроса;
КонецФункции
// Функция - Построитель пакета запросов до индекса включительно
//
// Параметры:
// ТекстыЗапросов - Массив -
// ИндексЭлемента - -
// Параметры - Структура -
// ИмяРождаемойТаблицы - -
// ДержательМетаданных - см. ОбработкаОбъект.ирКлсПолеТекстаПрограммы.НовыйМенеджерВременныхТаблиц() - нужен для входящих временных таблиц
//
// Возвращаемое значение:
// -
//
Функция ПостроительПакетаЗапросовДоИндекса(Знач ТекстыЗапросов, Знач ИндексЭлемента, Знач Параметры, Знач ИмяРождаемойТаблицы = "", Знач ДержательМетаданных = Неопределено) Экспорт
ТекстЗапроса = "";
Если ТекстыЗапросов.Количество() <= ИндексЭлемента Тогда
Возврат Неопределено;
КонецЕсли;
ТекстыЗапросов = ирОбщий.СкопироватьКоллекциюЛкс(ТекстыЗапросов);
Если ЗначениеЗаполнено(ИмяРождаемойТаблицы) Тогда
// Построитель сначала ищет последний запрос выборки, а затем создания. Поэтому сделаем последний запрос выборкой.
ТекстЗапроса = ТекстыЗапросов[ИндексЭлемента];
Если Найти(ТекстЗапроса, "ИНДЕКСИРОВАТЬ ПО") = 0 Тогда
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "ПОМЕСТИТЬ " + ИмяРождаемойТаблицы, "");
ТекстыЗапросов[ИндексЭлемента] = ТекстЗапроса;
КонецЕсли;
КонецЕсли;
Пока ТекстыЗапросов.Количество() > ИндексЭлемента + 1 Цикл
ТекстыЗапросов.Удалить(ТекстыЗапросов.ВГраница());
КонецЦикла;
ТекстЗапроса = ирОбщий.СтрСоединитьЛкс(ТекстыЗапросов, Символы.ПС);
Если Лев(ТекстЗапроса, 1) = """" Тогда
ТекстЗапроса = ирОбщий.ТекстИзВстроенногоЯзыкаЛкс(ТекстЗапроса);
КонецЕсли;
ПостроительЗапроса = Новый ПостроительЗапроса;
ирОбщий.СкопироватьКоллекциюЛкс(Параметры, ПостроительЗапроса.Параметры);
Попытка
ПостроительЗапроса.Текст = ТекстЗапроса; // Текст в любом случае установится, но еще может быть выброшено исключение
Исключение
КонецПопытки;
ПодготовитьМетаданныеПостроителяЗапроса(ПостроительЗапроса, ДержательМетаданных, ТекстыЗапросов);
Возврат ПостроительЗапроса;
КонецФункции
// .
// Параметры:
// ТекстЗапроса - Строка -
// Параметры - Структура -
// ТекстыЗапросов - -
// КлючПакета - Строка - передается для устранения пересечения веток создания одноименных временных таблиц
// Возвращаемое значение:
// -
Функция ДобавитьВременныеТаблицыПараметровВТекстЗапроса(Знач ТекстЗапроса, Знач Параметры, Знач ТекстыЗапросов = Неопределено, Знач КлючПакета = 0) Экспорт
Если Не ЗначениеЗаполнено(ТекстЗапроса) Тогда
Возврат "";
КонецЕсли;
ПрефиксСлужебнойТаблицы = "ъ" + КлючПакета + "_";
//Если Найти(ТекстЗапроса, "ПОМЕСТИТЬ " + ПрефиксСлужебнойТаблицы) > 0 Тогда
// Возврат "";
//КонецЕсли;
Если ТекстыЗапросов = Неопределено Тогда
ТекстыЗапросов = ирОбщий.СтрРазделитьЛкс(ТекстЗапроса, ";",,,, Истина); // Грубо
КонецЕсли;
ТекстПоследнегоЗапроса = ТекстыЗапросов[ТекстыЗапросов.ВГраница()];
Если Найти(ТекстПоследнегоЗапроса, "&") > 0 Тогда
Найденные = ирОбщий.НайтиРегВыражениеЛкс(ТекстПоследнегоЗапроса, "[\s|](?:ИЗ|FROM)[\s|]+&("+ шИмя + ")",, Ложь);
Для Каждого Вхождение Из Найденные Цикл
ИмяТаблицыПараметра = Вхождение.Группа0;
Если Не Параметры.Свойство(ИмяТаблицыПараметра) Тогда
Параметры.Вставить(ИмяТаблицыПараметра, Новый ТаблицаЗначений);
КонецЕсли;
КонецЦикла;
КонецЕсли;
СлужебныеЗапросы = Новый Массив;
ИменаСлужебныхЗапросов = Новый Массив;
Для Каждого КлючИЗначение Из Параметры Цикл
ЗначениеПараметра = ПодготовитьЗначениеПараметраЗапроса(КлючИЗначение.Значение);
Если ТипЗнч(ЗначениеПараметра) = Тип("ТаблицаЗначений") Тогда
Если Истина
И Найти(ТекстЗапроса, "&" + КлючИЗначение.Ключ) = 0
И Найти(ТекстЗапроса, "&" + НРег(КлючИЗначение.Ключ)) = 0
Тогда
Продолжить;
КонецЕсли;
Если Истина
И ЗначениеПараметра.Колонки.Количество() = 0
И ирОбщий.СтрокиРавныЛкс(ИмяТаблицыПараметра, КлючИЗначение.Ключ)
Тогда
ИменаПолей = ирОбщий.НайтиРегВыражениеЛкс(ирОбщий.ПервыйФрагментЛкс(ТекстПоследнегоЗапроса, "ИЗ"), "[\s\.]("+ шИмя +")\s*(?:,|$)");
Для Каждого Вхождение Из ИменаПолей Цикл
Если ЗначениеПараметра.Колонки.Найти(Вхождение.Группа0) = Неопределено Тогда
ЗначениеПараметра.Колонки.Добавить(Вхождение.Группа0);
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если ЗначениеПараметра.Колонки.Количество() > 0 Тогда
ТекстСлужебногоЗапроса = ирОбщий.ТекстЗапросаПоместитьИзПараметраЛкс(ПрефиксСлужебнойТаблицы + КлючИЗначение.Ключ, КлючИЗначение.Ключ, Истина, ЗначениеПараметра.Колонки,, Истина);
СлужебныеЗапросы.Добавить(ТекстСлужебногоЗапроса);
ИменаСлужебныхЗапросов.Добавить(КлючИЗначение.Ключ);
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если СлужебныеЗапросы.Количество() > 0 Тогда
НовыйТекст = ТекстЗапроса;
Для Каждого ИмяТаблицы Из ИменаСлужебныхЗапросов Цикл
НовыйТекст = СтрЗаменить(НовыйТекст, "&" + ИмяТаблицы, ПрефиксСлужебнойТаблицы + ИмяТаблицы); // TODO избавиться от чувствительности к регистру
КонецЦикла;
НовыйТекст = ирОбщий.СтрСоединитьЛкс(СлужебныеЗапросы, ";" + Символы.ПС) + ";" + Символы.ПС + НовыйТекст;
КонецЕсли;
Возврат НовыйТекст;
КонецФункции
Функция ПодготовитьЗначениеПараметраЗапроса(Знач ЗначениеПараметра, выхОписаниеТипов = Неопределено) Экспорт
Если Истина
И ТипЗнч(ЗначениеПараметра) = Тип("ТаблицаЗначений")
И ЗначениеПараметра.Колонки.Найти(ИмяКолонкиФлагаТаблицыТипов()) <> Неопределено
Тогда
выхОписаниеТипов = ОписаниеТиповИзТаблицыТипов(ЗначениеПараметра);
ЛучшийТип = Неопределено; // см. НоваяСтруктураТипа()
Если ЛиДетальностьТиповДостаточна(ЗначениеПараметра, 5, Истина, ЛучшийТип) Тогда
ЗначениеПараметра = ЛучшийТип.Метаданные;
Иначе
ЗначениеПараметра = выхОписаниеТипов.ПривестиЗначение();
КонецЕсли;
КонецЕсли;
Если ТипЗнч(ЗначениеПараметра) = Тип("Структура") Тогда
ТаблицаЗначений = Новый ТаблицаЗначений;
Для Каждого ОписаниеКолонки Из ЗначениеПараметра Цикл
ОписаниеТиповКолонки = Неопределено;
Если Истина
И ТипЗнч(ОписаниеКолонки.Значение) = Тип("ТаблицаЗначений")
И ОписаниеКолонки.Значение.Колонки.Найти(ИмяКолонкиФлагаТаблицыТипов()) <> Неопределено
Тогда
ОписаниеТиповКолонки = ОписаниеТиповИзТаблицыТипов(ОписаниеКолонки.Значение);
КонецЕсли;
ТаблицаЗначений.Колонки.Добавить(ОписаниеКолонки.Ключ, ОписаниеТиповКолонки);
КонецЦикла;
ЗначениеПараметра = ТаблицаЗначений;
КонецЕсли;
Возврат ЗначениеПараметра;
КонецФункции
// Процедура - Подготовить выбранные поля построителя
//
// Параметры:
// ПостроительЗапроса - ПостроительЗапроса -
// ДержательМетаданных - см. ОбработкаОбъект.ирКлсПолеТекстаПрограммы.НовыйМенеджерВременныхТаблиц() - нужен для входящих временных таблиц
//
Процедура ПодготовитьМетаданныеПостроителяЗапроса(Знач ПостроительЗапроса, Знач ДержательМетаданных = Неопределено, Знач ТекстыЗапросов = Неопределено) Экспорт
Если ПостроительЗапроса.ВыбранныеПоля.Количество() = 0 Тогда
Попытка
ПостроительЗапроса.ЗаполнитьНастройки();
Исключение
КонецПопытки;
КонецЕсли;
Если ПостроительЗапроса.ВыбранныеПоля.Количество() = 0 И ирКэш.ДоступноСхемаЗапросаЛкс() Тогда
Текст = ПостроительЗапроса.Текст;
НовыйТекст = ДобавитьВременныеТаблицыПараметровВТекстЗапроса(Текст, ПостроительЗапроса.Параметры, ТекстыЗапросов);
Если ЗначениеЗаполнено(НовыйТекст) Тогда
Текст = НовыйТекст;
КонецЕсли;
Если Истина
И ДержательМетаданных <> Неопределено
И ДержательМетаданных.Тип = Тип("МенеджерВременныхТаблиц")
//И ДержательМетаданных.Активен
Тогда
ТекстыПакетов = Новый Массив;
Для Индекс = 0 По ДержательМетаданных.ПакетыЗапросов.ВГраница() - 1 Цикл
ПредПакет = ДержательМетаданных.ПакетыЗапросов[Индекс];
ТекстПредпакета = ДобавитьВременныеТаблицыПараметровВТекстЗапроса(ирОбщий.ТекстИзВстроенногоЯзыкаЛкс(ПредПакет.Текст), ПредПакет.Параметры, ПредПакет.ТекстыЗапросов, Индекс + 1);
Если ЗначениеЗаполнено(ТекстПредпакета) Тогда
ТекстыПакетов.Добавить(ТекстПредпакета);
КонецЕсли;
КонецЦикла;
ТекстыПакетов.Добавить(Текст);
Текст = ирОбщий.СтрСоединитьЛкс(ТекстыПакетов, ";" + Символы.ПС);
КонецЕсли;
Попытка
ПустаяТаблица = ирОбщий.ПустаяТаблицаЗначенийИзТекстаЗапросаЛкс(Текст,, Истина);
Исключение
ОписаниеОшибки = ОписаниеОшибки();
Возврат;
КонецПопытки;
ПостроительЗапроса.ИсточникДанных = Новый ОписаниеИсточникаДанных(ПустаяТаблица);
ПостроительЗапроса.ЗаполнитьНастройки();
КонецЕсли;
КонецПроцедуры
Функция ЛиИмяТипаComОбъекта(ИмяОбщегоТипа) Экспорт
Результат = Ложь
Или ирОбщий.СтрокиРавныЛкс(ИмяОбщегоТипа, "COMОбъект")
Или Найти(ИмяОбщегоТипа, " {") > 0;
Возврат Результат;
КонецФункции
Функция ДобавитьВТаблицуСловЭлементыМодуляМетаданных(Знач СтруктураТипаМини, Знач СловоФильтр = Неопределено, Знач ТипСловаФильтр = Неопределено, Знач ТаблицаСловПриемник = Неопределено,
Знач МодульМетаданных, Знач ВычислятьТипыМетодовМодулей = Ложь, Знач ВычислятьТипы = Истина, Знач ТолькоЭкспорт = Истина, Знач ФлагиКомпиляции = Неопределено,
Знач ВнутриГруппыОбщихМодулей = Ложь, Знач ДляСвойства = "", Знач ЛиВместеСЛокальнымКонтекстом = Ложь, Знач БезПараметров = Ложь, Знач ТолькоСоЗначениями = Ложь, Знач СтрогийФильтр = Ложь) Экспорт
Если Истина
И СтруктураТипаМини.ИмяОбщегоТипа <> "Глобальный"
И Не ВнутриГруппыОбщихМодулей
Тогда
ЛиСеансТолстогоКлиентаУП = ирКэш.ЛиСеансТолстогоКлиентаУПЛкс();
НаСервере = ирОбщий.СвойствоСтруктурыЛкс(ФлагиКомпиляции, "Сервер", Истина);
БезКонтекста = ирОбщий.СвойствоСтруктурыЛкс(ФлагиКомпиляции, "БезКонтекста", Ложь);
КлиентОбычноеПриложение = ирОбщий.СвойствоСтруктурыЛкс(ФлагиКомпиляции, "КлиентОбычноеПриложение", Не ЛиСеансТолстогоКлиентаУП);
КлиентУправляемоеПриложение = ирОбщий.СвойствоСтруктурыЛкс(ФлагиКомпиляции, "КлиентУправляемоеПриложение", ЛиСеансТолстогоКлиентаУП);
КлючКэша = "" + ТолькоЭкспорт + ";" + БезПараметров + ";" + ТолькоСоЗначениями + ";" + НаСервере + ";" + БезКонтекста + ";" + КлиентОбычноеПриложение + ";" + КлиентУправляемоеПриложение;
ТаблицаИзКэша = МодульМетаданных.ТаблицыСлов[КлючКэша]; // см. НоваяТаблицаСлов()
Если Истина
И Не ВычислятьТипыМетодовМодулей
И СловоФильтр = Неопределено
И ТипСловаФильтр = Неопределено
И Не ЗначениеЗаполнено(ДляСвойства)
Тогда
Если ТаблицаИзКэша <> Неопределено Тогда
Возврат СлитьТаблицыСлов(ТаблицаСловПриемник, ТаблицаИзКэша);
КонецЕсли;
Иначе
КлючКэша = Неопределено;
КонецЕсли;
КонецЕсли;
Если ТаблицаСловПриемник = Неопределено Или КлючКэша <> Неопределено Тогда
ТаблицаСлов = НоваяТаблицаСлов();
Если ТаблицаСловПриемник = Неопределено Тогда
ТаблицаСловПриемник = ТаблицаСлов;
КонецЕсли;
Иначе
ТаблицаСлов = ТаблицаСловПриемник;
КонецЕсли;
МетаданныеРодителя = СтруктураТипаМини.Метаданные; // см. Метаданные.ОбщиеМодули[0]
ЛиИмяМодуляФормы = ЛиИмяМодуляФормы(МодульМетаданных.Имя);
ОтборСловМодуля = Новый Структура;
Если ТолькоЭкспорт Тогда
ОтборСловМодуля.Вставить("ЛиЭкспорт", Истина);
КонецЕсли;
Если ЗначениеЗаполнено(СловоФильтр) Тогда
ОтборСловМодуля.Вставить("НИмя", НРег(СловоФильтр));
КонецЕсли;
Если Истина
И Не ТолькоЭкспорт
И ФлагиКомпиляции <> Неопределено
И ЛиИмяМодуляФормы
Тогда
//Если ФлагиКомпиляции.Сервер Тогда
// ОтборСловМодуля.Вставить("Сервер", Истина);
//КонецЕсли;
//Если ФлагиКомпиляции.КлиентОбычноеПриложение Или ФлагиКомпиляции.КлиентУправляемоеПриложение Тогда
// ОтборСловМодуля.Вставить("Клиент", Истина);
//КонецЕсли;
Если Не (ФлагиКомпиляции.КлиентОбычноеПриложение Или ФлагиКомпиляции.КлиентУправляемоеПриложение) Тогда
//ОтборСловМодуля.Вставить("Клиент", Ложь); // - Не учитывает двусторонние методы
ОтборСловМодуля.Вставить("Сервер", Истина);
КонецЕсли;
КонецЕсли;
Если Истина
И (Ложь
Или ФлагиКомпиляции = Неопределено
Или Не ФлагиКомпиляции.БезКонтекста)
И (Ложь
Или ТипСловаФильтр = Неопределено
Или ТипСловаФильтр = "Свойство")
Тогда
ПеременныеМодуля = МодульМетаданных.Переменные;
Если ОтборСловМодуля.Количество() > 0 Тогда
ПодходящиеПеременные = ПеременныеМодуля.НайтиСтроки(ОтборСловМодуля);
Иначе
ПодходящиеПеременные = ПеременныеМодуля;
КонецЕсли;
КомпонентаПодсказки = Неопределено;
ТипСловаЦикл = "Свойство";
Для Каждого ПеременнаяМодуля Из ПодходящиеПеременные Цикл
ТаблицаТипов = Неопределено;
Если ВычислятьТипы Тогда
Если Истина
И ВычислятьТипыМетодовМодулей
//И ПеременнаяМодуля.ПозицияСОписанием > 0 // так отбросим все специальные переменные модуля
Тогда
ТаблицаТипов = ПодготовитьТипЗначенияПеременнойМодуля(ПеременнаяМодуля, МодульМетаданных, КомпонентаПодсказки, ДляСвойства);
КонецЕсли;
ТаблицаТипов = ТаблицаТиповСловаМодуля(ПеременнаяМодуля, МодульМетаданных, ТаблицаТипов);
Иначе
ПодготовитьОписаниеПеременнойМодуля(ПеременнаяМодуля);
КонецЕсли;
ДобавитьВТаблицуСловЭлементМодуляМетаданных(ТаблицаСлов, ПеременнаяМодуля.Имя, ВычислятьТипы, ТаблицаИзКэша, ТаблицаТипов, ПеременнаяМодуля.ТипЗначения, ТипСловаЦикл, ПеременнаяМодуля.ПозицияОпределения <> 0);
КонецЦикла;
КонецЕсли;
Если Истина
И Не ТолькоЭкспорт
И ФлагиКомпиляции <> Неопределено
И ЛиИмяМодуляФормы
Тогда
Если ФлагиКомпиляции.БезКонтекста Тогда
ОтборСловМодуля.Вставить("БезКонтекста", Истина);
КонецЕсли;
КонецЕсли;
Если Ложь
Или ТипСловаФильтр = Неопределено
Или ТипСловаФильтр = ПеречТипСлова.Метод
Тогда
МетодыМодуля = МодульМетаданных.Методы;
Если ОтборСловМодуля.Количество() > 0 Тогда
ПодходящиеМетоды = МетодыМодуля.НайтиСтроки(ОтборСловМодуля);
Если Истина
И Не ЛиВместеСЛокальнымКонтекстом
И ПодходящиеМетоды.Количество() = 0
И ЗначениеЗаполнено(СловоФильтр)
И СтруктураТипаМини.ИмяОбщегоТипа <> "Глобальный"
И Не СтрогийФильтр
Тогда
ОтборСловМодуля.Вставить("НИмя", "<>");
ПодходящиеМетоды = МетодыМодуля.НайтиСтроки(ОтборСловМодуля);
КонецЕсли;
Иначе
ПодходящиеМетоды = МетодыМодуля;
КонецЕсли;
ВычислятьТипы = Ложь
Или ЗначениеЗаполнено(СловоФильтр)
Или ВычислятьТипы;
//Если ЗначениеЗаполнено(СловоФильтр) Тогда
// ВычислятьТипыМетодовМодулей = Истина; // Лишнее при вычислении описания обрамляющего метода для текстового литерала
//КонецЕсли;
Если ВычислятьТипыМетодовМодулей И ПодходящиеМетоды.Количество() > 100 Тогда
Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(ПодходящиеМетоды.Количество(), "Вычисление типов функций");
Иначе
Индикатор = Неопределено;
КонецЕсли;
ТипСловаЦикл = ПеречТипСлова.Метод;
РазделительВариантаКонтекста = РазделительВариантаКонтекста();
Для Каждого МетодМодуля Из ПодходящиеМетоды Цикл
Если Индикатор <> Неопределено Тогда
ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
КонецЕсли;
ИмяМетода = МетодМодуля.Имя;
Если Ложь
Или ТолькоСоЗначениями И ПустаяСтрока(МетодМодуля.ТипЗначения)
Или БезПараметров И ЗначениеЗаполнено(МетодМодуля.Параметры)
Или ИмяМетода = "<>" И ПустаяСтрока(СловоФильтр)
Тогда
Продолжить;
КонецЕсли;
Если ВнутриГруппыОбщихМодулей Тогда
ИмяМетода = ИмяМетода + " - " + МетаданныеРодителя.Имя;
КонецЕсли;
ТаблицаТипов = Неопределено;
Если ВычислятьТипы Тогда
Если ВычислятьТипыМетодовМодулей Тогда
ТаблицаТипов = ПодготовитьТипРезультатаМетода(МетодМодуля, МодульМетаданных,,, ДляСвойства);
КонецЕсли;
ТаблицаТипов = ТаблицаТиповСловаМодуля(МетодМодуля, МодульМетаданных, ТаблицаТипов);
Иначе
ПодготовитьОписаниеРезультатаМетода(МетодМодуля);
КонецЕсли;
ДобавитьВТаблицуСловЭлементМодуляМетаданных(ТаблицаСлов, ИмяМетода, ВычислятьТипы, ТаблицаИзКэша, ТаблицаТипов, МетодМодуля.ТипЗначения, ТипСловаЦикл);
КонецЦикла;
Если Индикатор <> Неопределено Тогда
ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
КонецЕсли;
КонецЕсли;
Если КлючКэша <> Неопределено Тогда
МодульМетаданных.ТаблицыСлов[КлючКэша] = ТаблицаСлов;
ТаблицаСловПриемник = СлитьТаблицыСлов(ТаблицаСловПриемник, ТаблицаСлов);
КонецЕсли;
Возврат ТаблицаСловПриемник;
КонецФункции
//.
// Параметры:
// ТаблицаПриемник - ТаблицаЗначений -
// Таблица2 - ТаблицаЗначений -
Функция СлитьТаблицыСлов(Знач ТаблицаПриемник, Знач Таблица2) Экспорт
Если Таблица2.Количество() > ТаблицаПриемник.Количество() Тогда
ТаблицаИсточник = ТаблицаПриемник;
ТаблицаПриемник = Таблица2.Скопировать();
Иначе
ТаблицаИсточник = Таблица2;
КонецЕсли;
//ирОбщий.ЗагрузитьВТаблицуЗначенийЛкс(ТаблицаИсточник, ТаблицаПриемник);
Для Каждого СтрокаИсточника Из ТаблицаИсточник Цикл
Если СтрокаИсточника.ТипСлова = ПеречТипСлова.Метод Или СтрокаИсточника.МожноУточнитьТип = Ложь Тогда
ЗаполнитьЗначенияСвойств(ТаблицаПриемник.Добавить(), СтрокаИсточника);
Иначе
// Убираем дубли реквизитов продублированных в переменных модуля
ДобавитьВТаблицуСлов(ТаблицаПриемник, СтрокаИсточника.Слово, СтрокаИсточника.ТипСлова, СтрокаИсточника.ТаблицаТипов, СтрокаИсточника.ТипЗначения, СтрокаИсточника.Определение);
КонецЕсли;
КонецЦикла;
Возврат ТаблицаПриемник;
КонецФункции
Функция ДобавитьВТаблицуСловЭлементМодуляМетаданных(Знач ТаблицаСлов, Знач Слово, Знач ВычислятьТипы, Знач ТаблицаИзКэша, Знач ТаблицаТипов, Знач ТипЗначения, Знач ТипСлова,
Знач ВытеснятьСвойство = Истина) Экспорт
Если Слово <> "<>" И ТипЗначения <> Неопределено Тогда
Если Истина
И ВычислятьТипы
И ТаблицаИзКэша <> Неопределено
Тогда
Если ЛиВСтрокеТиповЕстьКонструктор(ТипЗначения) Тогда
ТипЗначения = ПредставлениеМассиваСтруктурТипов(ТаблицаТипов);
КонецЕсли;
ТипЗначенияИндекс = ТипЗначенияИндексИзТипа(ТипЗначения);
Если Не ирОбщий.СтрНачинаетсяСЛкс(ТипЗначения, "??") Тогда
ТипЗначения = "??" + ?(ПустаяСтрока(ТипЗначения), "", ", " + ТипЗначения);
КонецЕсли;
КлючПоиска = Новый Структура("Слово, ТипСлова", Слово, ТипСлова);
Найденные = ТаблицаИзКэша.НайтиСтроки(КлючПоиска);
Если Найденные.Количество() > 0 Тогда
Найденные[0].ТипЗначения = ТипЗначения;
Найденные[0].ТипЗначенияИндекс = ТипЗначенияИндекс;
КонецЕсли;
Иначе
ТипЗначенияИндекс = ТипЗначенияИндексИзТипа(ТипЗначения);
Если Не ирОбщий.СтрНачинаетсяСЛкс(ТипЗначения, "??") Тогда
ТипЗначения = "??" + ?(ПустаяСтрока(ТипЗначения), "", ", " + ТипЗначения);
КонецЕсли;
КонецЕсли;
КонецЕсли;
ДобавитьВТаблицуСлов(ТаблицаСлов, Слово, ТипСлова, ТаблицаТипов, ТипЗначения, "Метаданные", ВытеснятьСвойство,,,, ТипЗначенияИндекс);
Возврат ТипЗначения;
КонецФункции
Функция ТипЗначенияИндексИзТипа(Знач ТипЗначения) Экспорт
ТипЗначенияИндекс = ирОбщий.ПервыйФрагментЛкс(ТипЗначения, "(");
ТипЗначенияИндекс = СтрЗаменить(ТипЗначенияИндекс, ", Неопределено", "");
ТипЗначенияИндекс = СтрЗаменить(ТипЗначенияИндекс, "??, ", "");
Если Лев(ТипЗначенияИндекс, 3) = "см." Тогда
// оставляем только последний фрагмент полного указателя на описание типа, т.к. его достаточно чтобы подбирать подходящие слова
ТипЗначенияИндекс = "см. " + СокрЛП(ирОбщий.ПоследнийФрагментЛкс(ТипЗначенияИндекс));
КонецЕсли;
Возврат ТипЗначенияИндекс;
КонецФункции
Функция РазделительВариантаКонтекста() Экспорт
Возврат " - ";
КонецФункции
//.
// Параметры:
// МетодМодуля - СтрокаТаблицыЗначений -
// Возвращаемое значение:
// ТаблицаЗначений -
Функция ТаблицаТиповСловаМодуля(Знач СловоМодуля, Знач МодульМетаданных, Знач ТаблицаТипов = Неопределено) Экспорт
Если ТаблицаТипов = Неопределено Тогда
ТаблицаТипов = СловоМодуля.ТаблицаТипов;
КонецЕсли;
Если ТаблицаТипов = Неопределено Тогда
ТаблицаТипов = НоваяТаблицаТипов();
ИначеЕсли СловоМодуля.ТаблицаТипов = ТаблицаТипов Тогда
ТаблицаТипов = ТаблицаТипов.Скопировать(); // Мультиметка4529884 против циклической ссылки
КонецЕсли;
Если ТаблицаТипов.Количество() = 0 Тогда
СтруктураТипа = ТаблицаТипов.Добавить();
Если ЗначениеЗаполнено(СловоМодуля.ТипЗначения) Тогда
Если СловоМодуля.Имя = "<>" Тогда
СтруктураТипа.ИмяОбщегоТипа = СловоМодуля.ТипЗначения;
Иначе
СтруктураТипа.ИмяОбщегоТипа = "";
КонецЕсли;
КонецЕсли;
ОбновитьДетальностьСтруктурыТипа(СтруктураТипа);
КонецЕсли;
ТаблицаТипов.ЗаполнитьЗначения(СловоМодуля, "СтрокаОписания"); // Мультиметка4529884 против циклической ссылки
СловоМодуля.ИмяМодуля = МодульМетаданных.Имя;
Возврат ТаблицаТипов;
КонецФункции
Функция ПодготовитьМодульМетаданных(Знач СтруктураТипа, Знач ТипМодуля = "", выхИмяМодуля = "", Знач НовыйТекст = Неопределено, Знач ТекущаяПозиция = Неопределено) Экспорт
ВерсияФормата = ВерсияФорматаКэшаМодулей();
СтрокаСозданияРодителя = "";
ФлагиКомпиляции = Неопределено; // см. НовыеФлагиКомпиляции()
выхИмяМодуля = ИмяМодуляИзСтруктурыТипа(СтруктураТипа, ТипМодуля, СтрокаСозданияРодителя, ФлагиКомпиляции);
Если ЗначениеЗаполнено(выхИмяМодуля) Тогда
МодульМетаданных = МодульМетаданныхИзКэша(выхИмяМодуля); // см. МодульМетаданных - для ускорения расчета типа
Если Ложь
Или МодульМетаданных = Неопределено
Или НовыйТекст <> Неопределено И МодульМетаданных.Текст <> НовыйТекст
Тогда
//ПроверитьСтруктуруФайловогоКэша();
#Если Сервер И Не Сервер Тогда
ПапкаКэшаМодулей = Новый Файл;
#КонецЕсли
ФайлМодуля = ФайлМодуляИзИмениМодуля(выхИмяМодуля);
ТекстовыйДокумент = Новый ТекстовыйДокумент;
СтарыйТекст = Неопределено;
Если НовыйТекст <> Неопределено Тогда
Если МодульМетаданных <> Неопределено Тогда
СтарыйТекст = МодульМетаданных.Текст;
КонецЕсли;
Если СтарыйТекст = Неопределено И ФайлМодуля.Существует() Тогда
ТекстовыйДокумент.Прочитать(ФайлМодуля.ПолноеИмя);
СтарыйТекст = ТекстовыйДокумент.ПолучитьТекст();
КонецЕсли;
Если СтарыйТекст <> НовыйТекст Тогда
ТекстовыйДокумент.УстановитьТекст(НовыйТекст);
//Если Найти(выхИмяМодуля, " ") > 0 Тогда // проверка на расширение
ФайлКаталог = Новый Файл(ФайлМодуля.Путь);
Если Не ФайлКаталог.Существует() Тогда
СоздатьКаталог(ФайлКаталог.ПолноеИмя);
КонецЕсли;
//КонецЕсли;
Если ирКэш.НомерРежимаСовместимостиЛкс() >= 803018 Тогда
ТекстовыйДокумент.ЗаписатьАсинх(ФайлМодуля.ПолноеИмя); // не видим исключения из-за асинхронности!
Иначе
ТекстовыйДокумент.Записать(ФайлМодуля.ПолноеИмя);
КонецЕсли;
КонецЕсли;
КонецЕсли;
ФайлОписанияМодуля = ФайлМодуляИзИмениМодуля(выхИмяМодуля, "ixd");
ОбновитьФайлОписания = Истина;
Если Истина
И МодульМетаданных = Неопределено
//И ФайлОписанияМодуля.Существует()
Тогда
МодульМетаданных = ирОбщий.ЗагрузитьЗначениеИзФайлаЛкс(ФайлОписанияМодуля.ПолноеИмя,, "Внутр", Ложь); // см. МодульМетаданных() - временно читаем без вывода ошибок для перехода XML->JSON
ОбновитьФайлОписания = Ложь
Или МодульМетаданных = Неопределено
Или СтарыйТекст <> НовыйТекст
Или (Истина
И ФайлМодуля.Существует()
И ФайлМодуля.ПолучитьВремяИзменения() > ФайлОписанияМодуля.ПолучитьВремяИзменения());
Если Ложь
Или ТипЗнч(МодульМетаданных) <> Тип("Структура")
Или ирОбщий.СвойствоСтруктурыЛкс(МодульМетаданных, "ВерсияФормата") <> ВерсияФормата
Или МодульМетаданных.Имя <> выхИмяМодуля // Антибаг ИР. В старых версиях где то писалось пустое имя в кэш
Тогда
// Старый формат кэша
ОбновитьФайлОписания = Истина;
МодульМетаданных = Неопределено;
Иначе
// Мультиметка723368140
МодульМетаданных.Текст = СтарыйТекст; // Может установиться Неопределено
ирОбщий.СкопироватьКолонкиКоллекцииЛкс(НоваяТаблицаМетодовМодуля(), МодульМетаданных.Методы);
КонецЕсли;
КонецЕсли;
СтарыйМодуль = Неопределено;
Если ОбновитьФайлОписания Тогда
Если Не ФайлМодуля.Существует() И НовыйТекст = Неопределено Тогда
Если СообщениеОНеобходимостиОбновитьКэшМодулейВыводилось <> Истина Тогда
// Может выводиться неоправданно, если модуль пуст. В этом случае конфигуратор не выгружает файл. Поэтому уведомляем только о полной пустоте кэша
ФайлыМодулей = НайтиФайлы(ПапкаКэшаМодулей.ПолноеИмя, ИмяКонтрольногоФайлаКэшаМодулей());
Если ФайлыМодулей.Количество() = 0 Тогда
#Если Клиент Тогда
ирКлиент.ОткрытьНастройкиПоляПрограммыНаЗаднемПланеЛкс();
#КонецЕсли
КонецЕсли;
СообщениеОНеобходимостиОбновитьКэшМодулейВыводилось = Истина;
КонецЕсли;
МодульМетаданных = МодульМетаданных("", СтруктураТипа, выхИмяМодуля);
Иначе
Если НовыйТекст = Неопределено Тогда
ТекстовыйДокумент.Прочитать(ФайлМодуля.ПолноеИмя);
НовыйТекст = ТекстовыйДокумент.ПолучитьТекст();
МодульМетаданных = МодульМетаданных(НовыйТекст, СтруктураТипа, выхИмяМодуля,,,, ФлагиКомпиляции);
ЗаписатьМодульВКэш(МодульМетаданных);
Иначе
СтарыйМодуль = МодульМетаданных;
МодульМетаданных = МодульМетаданных(НовыйТекст, СтруктураТипа, выхИмяМодуля, Ложь, МодульМетаданных, ТекущаяПозиция, ФлагиКомпиляции);
// Т.к. в этом сценарии часто будет обновление текста модуля происходить, то не будем тратить время на обновление индекса в файле, но удалим его чтобы потом дату изменения не сверять
УдалитьФайлы(ФайлОписанияМодуля.Путь, ФайлОписанияМодуля.ИмяБезРасширения + ".i*"); // Все расширения файлов индексов начинаются с "i"
Если мВызовыВсехСловПоМодулям <> Неопределено Тогда
мВызовыВсехСловПоМодулям[КлючКэшаВызововСловаПоМодулю(выхИмяМодуля, Истина)] = Неопределено;
мВызовыВсехСловПоМодулям[КлючКэшаВызововСловаПоМодулю(выхИмяМодуля, Ложь)] = Неопределено;
КонецЕсли;
КонецЕсли;
//ирОбщий.СообщитьЛкс(ФайлМодуля.ПолноеИмя); // Отладка
//УдалитьФайлы(ФайлМодуля.ПолноеИмя);
КонецЕсли;
КонецЕсли;
мМодулиМетаданных[НРег(выхИмяМодуля)] = МодульМетаданных;
Если МодульМетаданных.ЗапретыКомпиляции.Свойство("ТонкийКлиент") Тогда
ФлагиКомпиляции.КлиентУправляемоеПриложение = Ложь;
КонецЕсли;
МодульМетаданных.СтруктураТипа = СтруктураТипа;
МодульМетаданных.ФлагиКомпиляции = ФлагиКомпиляции;
Если ФлагиКомпиляции.КлиентУправляемоеПриложение И Не ФлагиКомпиляции.КлиентОбычноеПриложение Тогда
// Для видимости толстого контекста в управляемой форме
ФлагиКомпиляции.КлиентОбычноеПриложение = ирОбщий.СтрНачинаетсяСЛкс(СокрЛ(НовыйТекст), "#Если ТолстыйКлиент");
КонецЕсли;
МодульМетаданных.Вставить("СтрокаСоздания", СтрокаСозданияРодителя);
МодульМетаданных.Вставить("ТипМодуля", ТипМодуля);
МодульМетаданных.Вставить("ВерсияФормата", ВерсияФормата);
Если МодульМетаданных <> Неопределено И СтарыйМодуль <> МодульМетаданных Тогда
#Если Сервер И Не Сервер Тогда
МетодыМодуля = Новый ТаблицаЗначений;
#КонецЕсли
БазовыйТип = ирОбщий.ПервыйФрагментЛкс(СтруктураТипа.ИмяОбщегоТипа);
ЛиИмяТипаФормы = ирОбщий.ЛиИмяТипаФормыЛкс(БазовыйТип, Истина);
Если Истина
И МодульМетаданных <> мПустойМодуль
И (Ложь
Или ирОбщий.СтрКончаетсяНаЛкс(БазовыйТип, "Объект")
Или ЛиИмяТипаФормы)
Тогда
// Добавим в переменные модуля реквизиты объекта с изменяемыми метаданными, чтобы уточнять их тип по коду
Для Каждого СтрокаПеременной Из МодульМетаданных.Переменные.НайтиСтроки(Новый Структура("ПозицияСОписанием", 0)) Цикл
МодульМетаданных.Переменные.Удалить(СтрокаПеременной);
КонецЦикла;
ИнициацияОписанияМетодовИСвойств();
ПараметрыЗаполнения = НовыеПараметрыЗаполненияСлов("Свойство",,,,,,,,, ПустойМодульМетаданных());
ТаблицаСлов = СловаКонтекстаМетаданные(СтруктураТипа, ПараметрыЗаполнения);
Если ЛиИмяТипаФормы Тогда
ТаблицаСлов.Добавить().Слово = "ВладелецФормы";
КонецЕсли;
Для Каждого СтрокаСлова Из ТаблицаСлов Цикл // TODO добавить фильтр по типу
Если ЛиДетальностьТиповДостаточна(СтрокаСлова.ТаблицаТипов) Тогда
ИмяОбщегоТипаСлова = СтрокаСлова.ТаблицаТипов[0].ИмяОбщегоТипа;
Если Истина
И ИмяОбщегоТипаСлова <> "ТаблицаЗначений"
И ИмяОбщегоТипаСлова <> "ДеревоЗначений"
И ИмяОбщегоТипаСлова <> "КомпоновщикНастроек"
И ИмяОбщегоТипаСлова <> "ХранилищеЗначения"
И ИмяОбщегоТипаСлова <> "Строка" // Мультиметка62766134
Тогда
Продолжить;
Иначе
// В них часто добавляются неинтерактивные колонки
КонецЕсли;
КонецЕсли;
СтрокаПеременной = МодульМетаданных.Переменные.Добавить();
СтрокаПеременной.Имя = СтрокаСлова.Слово;
СтрокаПеременной.НИмя = Нрег(СтрокаПеременной.Имя);
СтрокаПеременной.ЛиЭкспорт = Истина;
// Нельзя опираться на эти типы, т.к. они очищаются чаще чем сюда приходим
// Изначально использовал, чтобы добавляемые в модуле формы колонки реквизита-таблицы учитывались
//СтрокаПеременной.ТаблицаТипов = СтрокаСлова.ТаблицаТипов;
КонецЦикла;
КонецЕсли;
КонецЕсли;
Иначе
МодульМетаданных.Имя = выхИмяМодуля; // Нужно для единого пустого модуля, чтобы виртуальные методы в нем имели правильное имя модуля
КонецЕсли;
КонецЕсли;
Возврат МодульМетаданных;
КонецФункции
//.
// Возвращаемое значение:
// Структура, Неопределено -
Функция ПустойМодульМетаданных() Экспорт
МодульВременный = МодульМетаданных("",, "кэш");
МодульВременный.Переменные.Очистить(); // Иногда там остаются какие то переменные
Возврат МодульВременный;
КонецФункции
//.
// Возвращаемое значение:
// Число -
Функция ВерсияФорматаКэшаМодулей() Экспорт
Возврат 25; // Мультиметка91237881041 Каждый раз при изменении структуры увеличиваем на 1
КонецФункции
Функция ПеречТипСлова() Экспорт
Если ПеречТипСлова = Неопределено Тогда
ПеречТипСлова = ирОбщий.ПеречТипСловаЛкс();
КонецЕсли;
Возврат ПеречТипСлова;
КонецФункции
Функция ПеречИсточникСлова() Экспорт
Если ПеречИсточникСлова = Неопределено Тогда
ПеречИсточникСлова = ирОбщий.НовоеПеречислениеЛкс("Локальный, Статистический, Метаданные, Предопределенный");
КонецЕсли;
Возврат ПеречИсточникСлова;
КонецФункции
// Возращает таблицу вызовов слова через точку.
// Параметры:
// ИмяМодуля - Строка -
// ТекстовыйДокумент - ТекстовыйДокумент -
// Файл - Файл, Неопределено -
// ПолеТекстаПрограммы - ОбработкаОбъект.ирКлсПолеТекстаПрограммы
// Возвращаемое значение:
// ТаблицаЗначений -
Функция НепрямыеВызовыСловаВМодуле(Знач ИмяМодуля, Знач ТекстовыйДокумент, Знач Файл, Знач ПолеТекстаПрограммы, Знач ИскатьСлово, Знач ЛиМетод = Истина) Экспорт
Если ЛиМетод Тогда
//ШаблонВнешнегоВызова = ПолеТекстаПрограммы.шПредИмяПрямое+"(?:"+ПолеТекстаПрограммы.шИмяСТочками +"\.)("+шИмя+")\s*\(((?:(?:"+ПолеТекстаПрограммы.шВыражениеПрограммы+")?"+шРазделитель+"*(?=[,\)])|,)*)\)";
//ИндексГруппыВШаблоне = 0;
ШаблонВнешнегоВызова = ПолеТекстаПрограммы.шПредИмяПрямое+"(?:"+ПолеТекстаПрограммы.шОбъектноеВыражение+"\.)("+шИмя+")\s*\(((?:(?:"+ПолеТекстаПрограммы.шВыражениеПрограммы+")?"+шРазделитель+"*(?=[,\)])|,)*)\)";
ИндексГруппыВШаблоне = 3;
Расширение = "icl";
Иначе
//ШаблонВнешнегоВызова = ПолеТекстаПрограммы.шПредИмяПрямое+"(?:"+ПолеТекстаПрограммы.шИмяСТочками +"\.)("+шИмя+")(?!\s*[\(])"+ПолеТекстаПрограммы.шПостИмяСвойства;
//ИндексГруппыВШаблоне = 0;
ШаблонВнешнегоВызова = ПолеТекстаПрограммы.шПредИмяПрямое+"(?:"+ПолеТекстаПрограммы.шОбъектноеВыражение+"\.)("+шИмя+")(?!\s*[\(])"+ПолеТекстаПрограммы.шПостИмяСвойства;
ИндексГруппыВШаблоне = 3;
Расширение = "ipr";
КонецЕсли;
Если мВызовыВсехСловПоМодулям = Неопределено Тогда
мВызовыВсехСловПоМодулям = Новый Соответствие;
КонецЕсли;
КлючКэша = КлючКэшаВызововСловаПоМодулю(ИмяМодуля, ЛиМетод);
ИндексВызововМодуля = мВызовыВсехСловПоМодулям[КлючКэша];
Если ИндексВызововМодуля = Неопределено Тогда
Если ИмяМодуля = ИмяДинамическогоМодуля() Тогда
ОбновитьИндекс = Истина;
ИмяФайлаИндекса = Неопределено;
КлючКэша = Неопределено;
Иначе
ВерсияФорматаИндекса = 11;
ИмяФайлаИндекса = ИмяФайлаМодуляИзИмениМодуля(ИмяМодуля, Расширение);
//ОбновитьИндекс = Не ФайлИндекса.Существует(); // Долго
ОбновитьИндекс = Ложь;
Если Не ОбновитьИндекс Тогда
Попытка
ИндексВызововМодуля = ирОбщий.ЗагрузитьЗначениеИзФайлаЛкс(ИмяФайлаИндекса,, "Внутр", Ложь); // - временно читаем без вывода ошибок для перехода XML->JSON->Внутр
Исключение
// Экономим на проверке существования файла
КонецПопытки;
//! ИндексВызововМодуля = Новый Структура(ИменаСвойствИндекса);
Если Ложь
Или ТипЗнч(ИндексВызововМодуля) <> Тип("Структура")
Или ИндексВызововМодуля.ВерсияФормата <> ВерсияФорматаИндекса
Тогда
// Старый формат кэша
ОбновитьИндекс = Истина;
ИндексВызововМодуля = Неопределено;
ИначеЕсли Не ИндексВызововМодуля.Свойство("ДатаИзменения") Тогда
ИндексВызововМодуля.Вставить("ДатаИзменения");
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ОбновитьИндекс Тогда
ТекстМодуля = ТекстовыйДокумент.ПолучитьТекст();
ИндексВызововМодуля = НовыйИндексПоискаВызововСловаВМодуле(, ВерсияФорматаИндекса);
ЗаполнитьИндексПоискаВызововСловаВМодуле(ИндексВызововМодуля, ТекстМодуля, ШаблонВнешнегоВызова,, Истина,, ИндексГруппыВШаблоне);
Если ИмяФайлаИндекса <> Неопределено Тогда
ирОбщий.СохранитьЗначениеВФайлЛкс(ИндексВызововМодуля, ИмяФайлаИндекса,,, "Внутр");
КонецЕсли;
КонецЕсли;
Если Не ЗначениеЗаполнено(ИндексВызововМодуля.ДатаИзменения) И Файл <> Неопределено Тогда
ИндексВызововМодуля.ДатаИзменения = Файл.ПолучитьВремяИзменения(); // - пока не стал использовать, чтобы не замедлять код ради редкого сценария
КонецЕсли;
ирОбщий.ДобавитьИндексВТаблицуЛкс(ИндексВызововМодуля.Вызовы, "НомерСлова");
Если КлючКэша <> Неопределено Тогда
мВызовыВсехСловПоМодулям[КлючКэша] = ИндексВызововМодуля;
КонецЕсли;
КонецЕсли;
НомерСлова = 0;
Результат = Новый Массив;
Если ИндексВызововМодуля.СтруктураСлов.Свойство(ИскатьСлово, НомерСлова) Тогда
Результат = ИндексВызововМодуля.Вызовы.НайтиСтроки(Новый Структура("НомерСлова", НомерСлова));
КонецЕсли;
Возврат Результат;
КонецФункции
//.
// Параметры:
// ТекстМодуля - Строка -
// ШаблонВнешнегоВызова - Строка - регулярное выражение, где в первой группе находится слово
Функция НовыйИндексПоискаВызововСловаВМодуле(Знач Модуль = Неопределено, Знач ВерсияФорматаИндекса = 0, Знач ЛиИскатьОповещения = Неопределено) Экспорт
Если ЛиИскатьОповещения = Неопределено Тогда
ЛиИскатьОповещения = Истина
И Модуль <> Неопределено
И Модуль.СтруктураТипа <> Неопределено
И (Ложь
Или (Истина
И Модуль.ФлагиКомпиляции.КлиентУправляемоеПриложение
И Не Модуль.ФлагиКомпиляции.Сервер)
Или ирОбщий.ЛиИмяТипаФормыЛкс(Модуль.СтруктураТипа.ИмяОбщегоТипа));
КонецЕсли;
ТаблицаВызовов = Новый ТаблицаЗначений;
ТаблицаВызовов.Колонки.Добавить("ПозицияВхождения", Новый ОписаниеТипов("Число"));
ТаблицаВызовов.Колонки.Добавить("ДлинаВхождения", Новый ОписаниеТипов("Число"));
ТаблицаВызовов.Колонки.Добавить("Слово", Новый ОписаниеТипов("Строка"));
ТаблицаВызовов.Колонки.Добавить("НомерСлова", Новый ОписаниеТипов("Число"));
СтруктураСлов = Новый Структура;
Если ЛиИскатьОповещения Тогда
ТаблицаОповещений = Новый ТаблицаЗначений;
ТаблицаОповещений.Колонки.Добавить("ПозицияВхождения", Новый ОписаниеТипов("Число"));
ТаблицаОповещений.Колонки.Добавить("ДлинаВхождения", Новый ОписаниеТипов("Число"));
ТаблицаОповещений.Колонки.Добавить("Слово", Новый ОписаниеТипов("Строка"));
ТаблицаОповещений.Колонки.Добавить("Параметр", Новый ОписаниеТипов("Строка"));
ТаблицаОповещений.Колонки.Добавить("НомерСлова", Новый ОписаниеТипов("Число"));
КонецЕсли;
ИндексВызововМодуля = Новый Структура("ВерсияФормата, Вызовы, СтруктураСлов, Оповещения, ДатаИзменения");
ИндексВызововМодуля.ВерсияФормата = ВерсияФорматаИндекса;
ИндексВызововМодуля.Вызовы = ТаблицаВызовов;
ИндексВызововМодуля.Оповещения = ТаблицаОповещений;
ИндексВызововМодуля.СтруктураСлов = СтруктураСлов;
Возврат ИндексВызововМодуля;
КонецФункции
//.
// Параметры:
// ТекстБлока - Строка -
// ШаблонВнешнегоВызова - Строка - регулярное выражение, где в первой группе находится слово
// ШаблонОповещения - Строка -
// СВложенными - Булево -
// Смещение - Число -
// ТаблицаВызовов - ТаблицаЗначений -
// ТаблицаОповещений - ТаблицаЗначений -
Процедура ЗаполнитьИндексПоискаВызововСловаВМодуле(Знач ИндексВызововМодуля, Знач ТекстБлока, Знач ШаблонВнешнегоВызова, Знач ШаблонОповещения = "", Знач СВложенными = Ложь,
Знач Смещение = 0, Знач ИндексГруппыВШаблоне = 0) Экспорт
Если ТекстБлока = Неопределено Тогда
ВызватьИсключение "Текст модуля не загружен в память";
КонецЕсли;
ТаблицаВызовов = ИндексВызововМодуля.Вызовы;
РегВыражение = ирКэш.ВычислительРегВыраженийЛкс();
РегВыражение.IgnoreCase = Истина;
РегВыражение.Global = Истина;
РегВыражение.Pattern = ШаблонВнешнегоВызова;
Вхождения = РегВыражение.НайтиВхождения(ТекстБлока,, Истина);
ДобавитьВхожденияСловаВИндекс(Вхождения, РегВыражение, ТаблицаВызовов, СВложенными, Смещение, ИндексГруппыВШаблоне);
НумероватьСловаВИндексе(ТаблицаВызовов, ИндексВызововМодуля.СтруктураСлов);
Если ЗначениеЗаполнено(ШаблонОповещения) Тогда
ТаблицаОповещений = ИндексВызововМодуля.Оповещения;
РегВыражение.Pattern = ШаблонОповещения;
Вхождения = РегВыражение.НайтиВхождения(ТекстБлока,, Истина);
Для Каждого Вхождение Из Вхождения Цикл
СтрокаРезультата = ТаблицаОповещений.Добавить();
СтрокаРезультата.ПозицияВхождения = Смещение + Вхождение.FirstIndex;
СтрокаРезультата.ДлинаВхождения = Вхождение.Length;
СтрокаРезультата.Слово = Вхождение.SubMatches(0);
СтрокаРезультата.Параметр = Вхождение.SubMatches(1);
КонецЦикла;
НумероватьСловаВИндексе(ТаблицаОповещений, ИндексВызововМодуля.СтруктураСлов);
КонецЕсли;
КонецПроцедуры
//.
// Параметры:
// Вхождения - Массив из ОбработкаОбъект.ирОболочкаРегВхождение -
// РегВыражение - ОбработкаОбъект.ирОболочкаРегВыражение -
// ТаблицаВызовов - ТаблицаЗначений -
// Смещение - Число -
// _РежимОтладки - Булево -
Процедура ДобавитьВхожденияСловаВИндекс(Знач Вхождения, Знач РегВыражение, Знач ТаблицаВызовов, Знач СВложенными = Ложь, Знач Смещение = 0, Знач ИндексГруппыВШаблоне = 0) Экспорт
ИндексГруппыПараметровВШаблоне = ИндексГруппыВШаблоне + 1;
_РежимОтладки = Ложь;
Если _РежимОтладки Тогда // Можно менять на Истина в точке останова, например условием ирОбщий.Пр(_РежимОтладки, 1, 1)
// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
Для Каждого Вхождение Из Вхождения Цикл
СтрокаРезультата = ТаблицаВызовов.Добавить();
СтрокаРезультата.ПозицияВхождения = Смещение + Вхождение.FirstIndex;
СтрокаРезультата.ДлинаВхождения = Вхождение.Length;
СтрокаРезультата.Слово = Вхождение.SubMatches(ИндексГруппыВШаблоне);
Если СВложенными Тогда
Если Вхождение.SubMatches.Count > ИндексГруппыПараметровВШаблоне Тогда
ПараметрыВызова = Вхождение.SubMatches(ИндексГруппыПараметровВШаблоне);
Если Найти(ПараметрыВызова, "(") > 0 Тогда
ВхожденияВложенные = РегВыражение.НайтиВхождения(" " + ПараметрыВызова,, Истина);
ДобавитьВхожденияСловаВИндекс(ВхожденияВложенные, РегВыражение, ТаблицаВызовов, Истина, Вхождение.FirstIndex + Найти(Вхождение.Value, ПараметрыВызова) - 2, ИндексГруппыВШаблоне);
КонецЕсли;
Иначе
Если Вхождение.FirstIndex > 0 Тогда
Текст = Сред(Вхождение.Value, 2);
СмещениеДлины = 1;
Иначе
Текст = Вхождение.Value;
СмещениеДлины = 0;
КонецЕсли;
ЧислоТочек = СтрЧислоВхождений(Текст, ".");
Пока ЧислоТочек > 0 Цикл
Текст = ирОбщий.СтрокаБезПоследнегоФрагментаЛкс(Текст);
СтрокаВложенная = ТаблицаВызовов.Добавить();
СтрокаВложенная.ПозицияВхождения = СтрокаРезультата.ПозицияВхождения;
СтрокаВложенная.ДлинаВхождения = СтрДлина(Текст) + СмещениеДлины;
СтрокаВложенная.Слово = ирОбщий.ПоследнийФрагментЛкс(Текст);
ЧислоТочек = ЧислоТочек - 1;
КонецЦикла;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Иначе
// Однострочный код использован для ускорения при разрешенной отладке. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика"
Для Каждого Вхождение Из Вхождения Цикл   СтрокаРезультата = ТаблицаВызовов.Добавить();   СтрокаРезультата.ПозицияВхождения = Смещение + Вхождение.FirstIndex;   СтрокаРезультата.ДлинаВхождения = Вхождение.Length;   СтрокаРезультата.Слово = Вхождение.SubMatches(ИндексГруппыВШаблоне);   Если СВложенными Тогда   Если Вхождение.SubMatches.Count > ИндексГруппыПараметровВШаблоне Тогда   ПараметрыВызова = Вхождение.SubMatches(ИндексГруппыПараметровВШаблоне);   Если Найти(ПараметрыВызова, "(") > 0 Тогда   ВхожденияВложенные = РегВыражение.НайтиВхождения(" " + ПараметрыВызова,, Истина);   ДобавитьВхожденияСловаВИндекс(ВхожденияВложенные, РегВыражение, ТаблицаВызовов, Истина, Вхождение.FirstIndex + Найти(Вхождение.Value, ПараметрыВызова) - 2, ИндексГруппыВШаблоне);   КонецЕсли;   Иначе   Если Вхождение.FirstIndex > 0 Тогда   Текст = Сред(Вхождение.Value, 2);   СмещениеДлины = 1;   Иначе   Текст = Вхождение.Value;   СмещениеДлины = 0;   КонецЕсли;   ЧислоТочек = СтрЧислоВхождений(Текст, ".");   Пока ЧислоТочек > 0 Цикл   Текст = ирОбщий.СтрокаБезПоследнегоФрагментаЛкс(Текст);   СтрокаВложенная = ТаблицаВызовов.Добавить();   СтрокаВложенная.ПозицияВхождения = СтрокаРезультата.ПозицияВхождения;   СтрокаВложенная.ДлинаВхождения = СтрДлина(Текст) + СмещениеДлины;   СтрокаВложенная.Слово = ирОбщий.ПоследнийФрагментЛкс(Текст);   ЧислоТочек = ЧислоТочек - 1;   КонецЦикла;   КонецЕсли;   КонецЕсли;   КонецЦикла;  
КонецЕсли;
КонецПроцедуры
//.
// Параметры:
// ТаблицаВызовов - ТаблицаЗначений -
// Слово - Строка(0) -
// _РежимОтладки - Булево -
// Возвращаемое значение:
// Структура -
Функция НумероватьСловаВИндексе(ТаблицаВызовов, СтруктураСлов) Экспорт
_РежимОтладки = Ложь;
ВременныйИндекс = ирОбщий.ДобавитьИндексВТаблицуЛкс(ТаблицаВызовов, "Слово");
МассивСлов = ирОбщий.РазличныеЗначенияКолонкиТаблицыЛкс(ТаблицаВызовов, "Слово");
ПервыйСвободныйНомерСлова = СтруктураСлов.Количество();
СтарыйНомерСлова = 0;
//ТаблицаВызовов.Колонки.Добавить("НомерСлова", Новый ОписаниеТипов("Число")); // Вынес наружу для анализатора кода
Для Каждого Слово Из МассивСлов Цикл
Если Не СтруктураСлов.Свойство(Слово, СтарыйНомерСлова) Тогда
ПервыйСвободныйНомерСлова = ПервыйСвободныйНомерСлова + 1;
СтруктураСлов.Вставить(Слово, ПервыйСвободныйНомерСлова);
НомерСлова = ПервыйСвободныйНомерСлова;
Иначе
НомерСлова = СтарыйНомерСлова;
КонецЕсли;
ВызовыСлова = ТаблицаВызовов.НайтиСтроки(Новый Структура("Слово", Слово));
Если _РежимОтладки Тогда // Можно менять на Истина в точке останова, например условием ирОбщий.Пр(_РежимОтладки, 1, 1)
// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
Для Каждого СтрокаВызова Из ВызовыСлова Цикл
СтрокаВызова.НомерСлова = НомерСлова;
КонецЦикла;
Иначе
// Однострочный код использован для ускорения при разрешенной отладке. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика"
Для Каждого СтрокаВызова Из ВызовыСлова Цикл   СтрокаВызова.НомерСлова = НомерСлова;   КонецЦикла;  
КонецЕсли;
КонецЦикла;
ТаблицаВызовов.Индексы.Удалить(ВременныйИндекс); // Платформа 8.3.27 сама не удаляет почему то
ТаблицаВызовов.Колонки.Удалить("Слово");
Возврат СтруктураСлов;
КонецФункции
Функция КлючКэшаВызововСловаПоМодулю(Знач Модуль, Знач ЛиМетод) Экспорт
Возврат НРег(Модуль) + "." + ЛиМетод;
КонецФункции
// Возвращаемое значение:
// Строка -
Функция ИмяКонтрольногоФайлаКэшаМодулей() Экспорт
Возврат "КонтрольныйФайл.ixd";
КонецФункции
Функция ИмяДинамическогоМодуля() Экспорт
Возврат "Динамический.Модуль";
КонецФункции
Функция ИмяДинамическойФормы() Экспорт
Возврат "ОбщаяФорма.ирДинамический";
КонецФункции
Функция ИмяМодуляПсевдокодаПлатформы() Экспорт
Результат = "Обработка.ирПлатформа.Форма.ПсевдокодПлатформы.Форма.Модуль";
Если ирКэш.ЛиЭтоРасширениеКонфигурацииЛкс() Тогда
Результат = ирКэш.ИмяПродукта() + " " + Результат;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ИмяМетодаИнициация() Экспорт
Возврат "<ВнеМетодов>";
КонецФункции
//.
// Параметры:
// МодульМетаданных - см. ПодготовитьМодульМетаданных -
// ОбнулятьВычисляемое - Булево - немного дольше, но гарантирует успех
Процедура ЗаписатьМодульВКэш(Знач МодульМетаданных, Знач ЧерезКопию = Ложь) Экспорт
Если МодульМетаданных = мПустойМодуль Тогда
Возврат;
КонецЕсли;
ФайлОписанияМодуля = ФайлМодуляИзИмениМодуля(МодульМетаданных.Имя, "ixd");
Если ЧерезКопию Тогда
// Мультиметка723368140
КопияМодуля = ирОбщий.СкопироватьКоллекциюЛкс(МодульМетаданных); // см. ПодготовитьМодульМетаданных - указываем явно, чтобы ДляСвойства применялось на полную глубину.
КопияМодуля.Текст = Неопределено;
КопияМодуля.СтруктураТипа = Неопределено;
КопияМодуля.ТекущийМетод = Неопределено;
КопияМодуля.ТекстПоискаОпределенияСловМодуля = Неопределено;
Если Не ЛиСохранятьОшибкиМодуля(КопияМодуля) Тогда
КопияМодуля.Ошибки = Неопределено;
КонецЕсли;
КопияМодуля.ТаблицыСлов.Очистить();
КопияМодуля.Переменные = КопияМодуля.Переменные.Скопировать();
КопияМодуля.СтарыеТипыПрограммы = Неопределено;
КопияМодуля.Методы = КопияМодуля.Методы.Скопировать();
КопияМодуля.Методы.ЗаполнитьЗначения(Неопределено, "КэшПоиска, ТелоБезВозвратов, СтарыеТипы");
СброситьКэшТиповВыраженийМодуля(КопияМодуля);
МодульМетаданных = КопияМодуля;
КонецЕсли;
МодульМетаданных.Вставить("ВерсияФормата", ВерсияФорматаКэшаМодулей());
Текст = МодульМетаданных.Текст;
СтруктураТипа = МодульМетаданных.СтруктураТипа;
МодульМетаданных.Текст = Неопределено;
МодульМетаданных.СтруктураТипа = Неопределено;
ирОбщий.СохранитьЗначениеВФайлЛкс(МодульМетаданных, ФайлОписанияМодуля.ПолноеИмя,,, "Внутр");
МодульМетаданных.Текст = Текст;
МодульМетаданных.СтруктураТипа = СтруктураТипа;
КонецПроцедуры
// Запускает асинхронную загрузку файлов модулей в памятный кэш ОС Windows
// Параметры:
// МаскаФайлов - Строка -
Процедура ЗагрузитьКэшМодулейВПамятьОС(Знач МаскаФайлов = "*.*") Экспорт
Если ирКэш.ЛиПлатформаWindowsЛкс() Тогда
// Фоновое многопоточное наполнение кэша ОС файлами, в которых будем искать
ИмяФайлаСкрипта = ПолучитьИмяВременногоФайла("ps1");
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.УстановитьТекст(ПолучитьМакет("НаполнительКэшаФайловОС").ПолучитьТекст());
ТекстовыйДокумент.Записать(ИмяФайлаСкрипта, КодировкаТекста.Системная);
//ИмяФайлаСкрипта = """" + ИмяФайлаСкрипта + """ -Directory """ + мПлатформа.ПапкаКэшаМодулей.ПолноеИмя + """ -FileMask """ + МаскаФайлов + """";
ИмяФайлаСкрипта = """" + ИмяФайлаСкрипта + """ """ + ПапкаКэшаМодулей.ПолноеИмя + """ """ + МаскаФайлов + """";
КомандаСистемыЗапускаСкрипта = ирОбщий.КомандаСистемыЗапускаСкриптаPowerShellЛкс(ИмяФайлаСкрипта);
ирОбщий.ВыполнитьКомандуОСЛкс(КомандаСистемыЗапускаСкрипта, Ложь);
// Удалять файл ИмяФайлаСкрипта нельзя, т.к. он выполняется асинхронно
КонецЕсли;
КонецПроцедуры
//.
// Параметры:
// Модуль - Структура -
// Возвращаемое значение:
// Булево -
Функция ЛиСохранятьОшибкиМодуля(Модуль) Экспорт
Результат = Истина
И Модуль.Имя <> ИмяДинамическогоМодуля() // Там типы переменных модуля не очищаем
И Модуль.Ошибки <> Неопределено
И Модуль.Ошибки.Количество() < 50;
Возврат Результат;
КонецФункции
//.
// Параметры:
// ИмяМодуля - Строка -
// Возвращаемое значение:
// см. ПодготовитьМодульМетаданных -
Функция МодульМетаданныхИзКэша(Знач ИмяМодуля) Экспорт
Возврат мМодулиМетаданных[НРег(ИмяМодуля)];
КонецФункции
Процедура СброситьКэшиТиповВыраженийМодулей(Знач КромеМодуля = "") Экспорт
Для Каждого КлючИЗначение Из мМодулиМетаданных Цикл
Если КлючИЗначение.Ключ = НРег(КромеМодуля) Тогда
Продолжить;
КонецЕсли;
СброситьКэшТиповВыраженийМодуля(КлючИЗначение.Значение);
КонецЦикла;
КонецПроцедуры
//.
// Параметры:
// Модуль - см. МодульМетаданных -
Процедура СброситьКэшТиповВыраженийМодуля(Знач Модуль, Знач СбросВМетодах = Истина) Экспорт
Если Модуль.Имя <> ИмяДинамическогоМодуля() Тогда
Переменные = Модуль.Переменные;
Переменные.ЗаполнитьЗначения(, "Вычислено, ТаблицаТипов"); // Чтобы не отслеживать зависимости
КонецЕсли;
Модуль.ТипыВыраженийПрограммы.Очистить();
Модуль.КэшПоискаПрограммы.Очистить();
//Модуль.ТаблицыСлов.Очистить();
Если СбросВМетодах Тогда
Методы = Модуль.Методы;
ирОбщий.ОчиститьКолонкиТаблицыЛкс(Методы, "Вычислено, ТаблицаТипов, ТипыВыражений");
_РежимОтладки = Ложь;
Если _РежимОтладки Тогда // Можно менять на Истина в точке останова, например условием ирОбщий.Пр(_РежимОтладки, 1, 1)
// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
Для Каждого СтрокаМетода Из Методы Цикл
Если ТипЗнч(СтрокаМетода.Параметры) = Тип("ТаблицаЗначений") Тогда
СтрокаМетода.Параметры.ЗаполнитьЗначения(, "Вычислено, ТаблицаТипов");
КонецЕсли;
КонецЦикла;
Иначе
// Однострочный код использован для ускорения при разрешенной отладке. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика"
Для Каждого СтрокаМетода Из Методы Цикл   Если ТипЗнч(СтрокаМетода.Параметры) = Тип("ТаблицаЗначений") Тогда   СтрокаМетода.Параметры.ЗаполнитьЗначения(, "Вычислено, ТаблицаТипов");   КонецЕсли;   КонецЦикла;  
КонецЕсли;
//Для Каждого СтрокаМетода Из Методы Цикл
// Если ТипЗнч(СтрокаМетода.Параметры) = Тип("ТаблицаЗначений") Тогда
// СтрокаМетода.Параметры.ЗаполнитьЗначения(, "ТаблицаТипов");
// КонецЕсли;
// Если СтрокаМетода.ТаблицаТипов <> Неопределено Тогда
// СтрокаМетода.ТаблицаТипов = Неопределено;
// КонецЕсли;
// Если СтрокаМетода.ТипыВыражений <> Неопределено Тогда
// СтрокаМетода.ТипыВыражений = Неопределено;
// КонецЕсли;
//КонецЦикла;
КонецЕсли;
КонецПроцедуры
//.
// Параметры:
// ИмяМодуля - Строка - например "ИнструментыРазработчикаTormozit ОбщийМодуль.ирОбщий.Модуль"
// Расширение - Строка -
// ЗаменитьНедопустимыеСимволы - Булево -
// Возвращаемое значение:
// Файл -
Функция ФайлМодуляИзИмениМодуля(Знач ИмяМодуля, Знач Расширение = "txt", Знач ЗаменитьНедопустимыеСимволы = Ложь) Экспорт
ИмяФайла = ИмяФайлаМодуляИзИмениМодуля(ИмяМодуля, Расширение, ЗаменитьНедопустимыеСимволы);
ФайлМодуля = Новый Файл(ИмяФайла);
Возврат ФайлМодуля;
КонецФункции
//.
// Параметры:
// ИмяМодуля - Строка - например "ИнструментыРазработчикаTormozit ОбщийМодуль.ирОбщий.Модуль"
// Расширение - Строка -
// ЗаменитьНедопустимыеСимволы - Булево -
// Возвращаемое значение:
// Строка -
Функция ИмяФайлаМодуляИзИмениМодуля(Знач ИмяМодуля, Знач Расширение = "txt", Знач ЗаменитьНедопустимыеСимволы = Ложь) Экспорт
ИмяМодуля = СтрЗаменить(ИмяМодуля, " ", "\");
Если ЗаменитьНедопустимыеСимволы Тогда
ИмяМодуля = ирОбщий.ЗаменитьНедопустимыеСимволыВИмениФайлаЛкс(ИмяМодуля, "_");
КонецЕсли;
ИмяФайла = ПапкаКэшаМодулей.ПолноеИмя + ирОбщий.РазделительПутиКФайлуЛкс() + ИмяМодуля + "." + Расширение;
Возврат ИмяФайла;
КонецФункции
// Функция - Имя файла модуля без расширения
//
// Параметры:
// СтруктураТипа - см. НоваяСтруктураТипа() -
// ТипМодуля - Строка - входное значение имеет смысл только для модулей приложения (безобъектных)
// СтрокаСозданияРодителя - Строка -
// ФлагиКомпиляции - Структура - выход, заполняется если ТипМодуля на входе пустой
//
// Возвращаемое значение:
// Строка -
//
Функция ИмяМодуляИзСтруктурыТипа(Знач СтруктураТипа, ТипМодуля = "", СтрокаСозданияРодителя = "", ФлагиКомпиляции = Неопределено) Экспорт
ИмяОбщегоТипа = СтруктураТипа.ИмяОбщегоТипа;
МетаданныеРодителя = СтруктураТипа.Метаданные;
ТипыМетаОбъектов = ирКэш.ТипыМетаОбъектов();
Результат = "";
ФлагиКомпиляции = НовыеФлагиКомпиляции(Ложь, Ложь, Ложь);
Если ТипМодуля = "МодульОбычногоПриложения" Тогда
ФлагиКомпиляции.Вставить("КлиентОбычноеПриложение", Истина);
ИначеЕсли ТипМодуля = "МодульУправляемогоПриложения" Тогда
ФлагиКомпиляции.Вставить("КлиентУправляемоеПриложение", Истина);
ИначеЕсли ТипМодуля = "МодульСеанса" Тогда
ФлагиКомпиляции.Вставить("Сервер", Истина);
Иначе
ФлагиКомпиляции = НовыеФлагиКомпиляции();
КонецЕсли;
Если ИмяОбщегоТипа = "Глобальный" Тогда
//Если ИмяОбщегоТипа = "ОбъектМетаданныхКонфигурация" Тогда
//#Если ТолстыйКлиентОбычноеПриложение Тогда
// ТипМодуля = "МодульОбычногоПриложения";
//#Иначе
// ТипМодуля = "МодульУправляемогоПриложения";
//#КонецЕсли
Если Не ЗначениеЗаполнено(ТипМодуля) Тогда
ВызватьИсключение "Требуется передача типа модуля конфигурации";
КонецЕсли;
ИначеЕсли Ложь
Или ИмяОбщегоТипа = "Команда"
Или ИмяОбщегоТипа = "ОбщаяКоманда"
Тогда
ТипМодуля = "МодульКоманды";
ФлагиКомпиляции.КлиентОбычноеПриложение = Ложь;
ИначеЕсли Ложь
Или ИмяОбщегоТипа = "WebСервис"
Или ИмяОбщегоТипа = "HttpСервис"
Или ИмяОбщегоТипа = "ОбщийМодуль"
Тогда
ТипМодуля = "Модуль";
Если ИмяОбщегоТипа = "ОбщийМодуль" Тогда
Если ТипЗнч(МетаданныеРодителя) = Тип("Строка") Тогда
// Добавленный/переименованный объект метаданных
Фрагменты = ирОбщий.СтрРазделитьЛкс(МетаданныеРодителя);
МетаданныеРодителя = Новый Структура;
МетаданныеРодителя.Вставить("ВызовСервера", Истина);
МетаданныеРодителя.Вставить("Сервер", Истина);
МетаданныеРодителя.Вставить("КлиентУправляемоеПриложение", Истина);
МетаданныеРодителя.Вставить("КлиентОбычноеПриложение", Истина);
МетаданныеРодителя.Вставить("Имя", Фрагменты[1]);
//МетаданныеРодителя.Вставить("ИмяРасширения", СтруктураТипа.ДержательМетаданных);
мДобавленныеОбщиеМодули.Вставить(Фрагменты[1], МетаданныеРодителя);
КонецЕсли;
Если Ложь
Или ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных")
Или ТипЗнч(МетаданныеРодителя) = Тип("Структура")
Тогда
ФлагиКомпиляции.Сервер = МетаданныеРодителя.Сервер;
ФлагиКомпиляции.КлиентОбычноеПриложение = МетаданныеРодителя.КлиентОбычноеПриложение;
ФлагиКомпиляции.КлиентУправляемоеПриложение = МетаданныеРодителя.КлиентУправляемоеПриложение;
СтрокаСозданияРодителя = МетаданныеРодителя.Имя;
Результат = ИмяОбщегоТипа + "." + МетаданныеРодителя.Имя + "." + ТипМодуля;
Иначе
// Если ТипЗнч(МетаданныеРодителя) = Тип("Неопределено") Тогда
// см. ОбработкаОбъект.ирКлсПолеТекстаПрограммы.СтруктураТипаМодуля
КонецЕсли;
Иначе
ФлагиКомпиляции.КлиентОбычноеПриложение = Ложь;
ФлагиКомпиляции.КлиентУправляемоеПриложение = Ложь;
КонецЕсли;
ИначеЕсли ирОбщий.ЛиИмяТипаФормыЛкс(ИмяОбщегоТипа, Истина) Тогда
Если Ложь
#Если Клиент Тогда
Или ТипЗнч(МетаданныеРодителя) = Тип("Форма")
#КонецЕсли
Тогда
СлужебныеДанныеФормы = ирОбщий.СлужебныеДанныеФормыЛкс(МетаданныеРодителя);
Если СлужебныеДанныеФормы.Свойство("ИмяФормы") Тогда
МетаданныеРодителя = СлужебныеДанныеФормы.ИмяФормы;
КонецЕсли;
ФлагиКомпиляции.Сервер = Ложь;
ФлагиКомпиляции.КлиентУправляемоеПриложение = Ложь;
ИначеЕсли ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") Тогда
МетаданныеРодителя = МетаданныеРодителя.ПолноеИмя();
ИначеЕсли ирОбщий.ЛиФормаИлиИмитаторЛкс(МетаданныеРодителя, Истина) Тогда
МетаданныеРодителя = МетаданныеРодителя.ИмяФормы;
ФлагиКомпиляции.КлиентОбычноеПриложение = Ложь;
КонецЕсли;
Если ТипЗнч(МетаданныеРодителя) <> Тип("Строка") Тогда
МетаданныеРодителя = Неопределено;
ИначеЕсли ЗначениеЗаполнено(МетаданныеРодителя) Тогда
ТипМодуля = "Модуль";
Если ТипЗнч(МетаданныеРодителя) = Тип("Строка") Тогда
МетаданныеРодителя = МетаданныеРодителя + ".Форма";
КонецЕсли;
КонецЕсли;
ИначеЕсли Истина
И ТипЗнч(МетаданныеРодителя) = Тип("Структура")
И ирОбщий.ЛиИмяТипаВнешнегоОбъектаМетаданныхЛкс(ИмяОбщегоТипа)
Тогда
// Нужно для некомпилируемых внешних объектов
МетаданныеРодителя = ирОбщий.ПервыйФрагментЛкс(ИмяОбщегоТипа, "Объект.", Ложь) + "." + МетаданныеРодителя.Имя;
ТипМодуля = "МодульОбъекта";
Иначе
КорневойТипОбъекта = ирОбщий.ПервыйФрагментЛкс(ИмяОбщегоТипа, "Объект.", Ложь);
Если ЗначениеЗаполнено(КорневойТипОбъекта) Тогда
ТипМодуля = "МодульОбъекта";
СтрокаТипаМетаОбъекта = ТипыМетаОбъектов.Найти(КорневойТипОбъекта, "Единственное");
Если Истина
И СтрокаТипаМетаОбъекта <> Неопределено
И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных")
Тогда
Множественное = СтрокаТипаМетаОбъекта.Множественное;
Если СтрокаТипаМетаОбъекта.Категория = 1 Тогда
СтрокаСозданияРодителя = Множественное + "." + МетаданныеРодителя.Имя + ".Создать()";
ИначеЕсли СтрокаТипаМетаОбъекта.Категория = 0 Тогда
СтрокаСозданияРодителя = Множественное + "." + МетаданныеРодителя.Имя + ".ПустаяСсылка().ПолучитьОбъект()";
КонецЕсли;
КонецЕсли;
ИначеЕсли ЗначениеЗаполнено(ирОбщий.ПервыйФрагментЛкс(ИмяОбщегоТипа, "НаборЗаписей.", Ложь)) Тогда
ТипМодуля = "МодульНабораЗаписей";
КорневойТип = ирОбщий.ПервыйФрагментЛкс(ИмяОбщегоТипа, "НаборЗаписей");
СтрокаТипаМетаОбъекта = ТипыМетаОбъектов.Найти(КорневойТип, "Единственное");
Если Истина
И СтрокаТипаМетаОбъекта <> Неопределено
И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных")
Тогда
Множественное = СтрокаТипаМетаОбъекта.Множественное;
СтрокаСозданияРодителя = Множественное + "." + МетаданныеРодителя.Имя + ".СоздатьНаборЗаписей()";
КонецЕсли;
ИначеЕсли ЗначениеЗаполнено(ирОбщий.ПервыйФрагментЛкс(ИмяОбщегоТипа, "МенеджерЗначения.", Ложь)) Тогда
ТипМодуля = "МодульМенеджераЗначения";
Если ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") Тогда
СтрокаСозданияРодителя = "Константы." + МетаданныеРодителя.Имя + ".СоздатьМенеджерЗначения()";
КонецЕсли;
ИначеЕсли ЗначениеЗаполнено(ирОбщий.ПервыйФрагментЛкс(ИмяОбщегоТипа, "Менеджер.", Ложь)) Тогда
ТипМодуля = "МодульМенеджера";
КорневойТип = ирОбщий.ПервыйФрагментЛкс(ИмяОбщегоТипа, "Менеджер");
СтрокаТипаМетаОбъекта = ТипыМетаОбъектов.Найти(КорневойТип, "Единственное");
Если Истина
И СтрокаТипаМетаОбъекта <> Неопределено
И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных")
Тогда
Множественное = СтрокаТипаМетаОбъекта.Множественное;
СтрокаСозданияРодителя = Множественное + "." + МетаданныеРодителя.Имя;
КонецЕсли;
Иначе
// Тип объекта не имеет модуля
ТипМодуля = Неопределено;
КонецЕсли;
КонецЕсли;
Если Не ЗначениеЗаполнено(Результат) Тогда
Если ЗначениеЗаполнено(ТипМодуля) Тогда
Если ТипЗнч(МетаданныеРодителя) = Тип("Неопределено") Тогда
Результат = "Конфигурация" + "." + ТипМодуля;
Иначе
Если ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") Тогда
МетаданныеРодителя = МетаданныеРодителя.ПолноеИмя();
КонецЕсли;
Если ТипЗнч(МетаданныеРодителя) = Тип("Строка") Тогда
Результат = МетаданныеРодителя + "." + ТипМодуля;
КонецЕсли;
КонецЕсли;
Если Найти(Результат, ":") > 0 Тогда
ЗапрещенныеСимволы = ".";
Если Найти(Результат, "::") > 0 Тогда
ЗапрещенныеСимволы = ЗапрещенныеСимволы + " "; // Иначе он потом в "/" превратится
КонецЕсли;
Результат = ирОбщий.ЗаменитьНедопустимыеСимволыВИмениФайлаЛкс(Результат, "_", ЗапрещенныеСимволы); // Заменяем точки, чтобы по такому имени модуля не делалось попытки создать форму
КонецЕсли;
ИначеЕсли ТипЗнч(МетаданныеРодителя) = Тип("Строка") Тогда
Результат = МетаданныеРодителя;
КонецЕсли;
КонецЕсли;
Если Истина
И мНомерВерсииПлатформы >= 803008
И СтруктураТипа.ДержательМетаданных = Неопределено
Тогда
Если ТипЗнч(СтруктураТипа.Метаданные) = Тип("ОбъектМетаданных") Тогда
МетаданныеРасширения = СтруктураТипа.Метаданные.РасширениеКонфигурации();
ИначеЕсли ирОбщий.ЛиФормаИлиИмитаторЛкс(СтруктураТипа.Метаданные) Тогда
МетаданныеРасширения = ирОбщий.ОбъектМДПоПолномуИмениЛкс(ирОбщий.ПолноеИмяФормыЛкс(СтруктураТипа.Метаданные));
Если МетаданныеРасширения <> Неопределено Тогда
МетаданныеРасширения = МетаданныеРасширения.РасширениеКонфигурации();
КонецЕсли;
КонецЕсли;
Если МетаданныеРасширения <> Неопределено Тогда
СтруктураТипа.ДержательМетаданных = МетаданныеРасширения.Имя;
КонецЕсли;
КонецЕсли;
Если ТипЗнч(СтруктураТипа.ДержательМетаданных) = Тип("Строка") Тогда
Результат = СтруктураТипа.ДержательМетаданных + " " + Результат;
КонецЕсли;
Возврат Результат;
КонецФункции
// Функция - Обновить кэш структуры формы из буфера
//
// Параметры:
// СлужебныеДанные - см. ирОбщий.СлужебныеДанныеФормыЛкс() -
// ТекстБуфераОбмена - Строка - снимок формы из буфера обмена
// ТекстМодуляФормы - массив из Строка - передается для быстрого удаления текста модуля из снимка формы для повышения надежности разбора структуры
// Форма - Форма, ФормаКлиентскогоПриложения -
//
// Возвращаемое значение:
// -
//
Функция ОбновитьКэшСтруктурыФормыИзБуфера(Знач СлужебныеДанные, Знач ТекстБуфераОбмена, Знач ТекстМодуляФормы = "", Знач Форма = Неопределено) Экспорт
Если СлужебныеДанные.Свойство("КорневыеИменаРеквизитов") Тогда
СлужебныеДанные.Удалить("КорневыеИменаРеквизитов");
КонецЕсли;
ЛиОбычнаяФорма = Ложь;
Попытка
ДвоичныеДанные = Base64Значение(ирОбщий.ТекстМеждуМаркерамиЛкс(ТекстБуфераОбмена, "#base64:", "}"));
Текст = Новый ТекстовыйДокумент;
Текст.Прочитать(ДвоичныеДанные.ОткрытьПотокДляЧтения());
ТекстФайла = Текст.ПолучитьТекст();
ЛиОбычнаяФорма = ЗначениеЗаполнено(ТекстФайла) И Лев(ТекстФайла, 1) <> "{";
Если ЛиОбычнаяФорма Тогда
СлужебныеДанные.Тип = Тип("Форма");
ВызватьИсключение "ОбычнаяФорма";
КонецЕсли;
Если СтрДлина(СокрЛП(ТекстМодуляФормы)) > 300 Тогда
ТекстФайла = СтрЗаменить(ТекстФайла, ирОбщий.ТекстВВыражениеВстроенногоЯзыкаЛкс(ТекстМодуляФормы, Ложь, Ложь), "");
КонецЕсли;
XMLСтрока = ирОбщий.СтрокаВнутрВХМЛТелоЛкс(ТекстФайла); // Если ошибка, то обычная форма
ДокументDOM = ирОбщий.ТекстВДокументDOMЛкс(XMLСтрока); // Если ошибка, то не поддерживаемый формат управляемой формы. Например Обработка.упРМПланированиеРейсов.ФормаРедактированияРейса
Исключение
ОписаниеОшибки = ОписаниеОшибки();
Если Не ЛиОбычнаяФорма Тогда
ИмитаторФормы = ИмитаторУправляемойФормы();
ДополнитьСлужебныеДанныеИзКэшаФормы(СлужебныеДанные, ИмитаторФормы, ТекущаяДата());
КонецЕсли;
Если Не ЛиОбычнаяФорма И ЗначениеЗаполнено(ТекстБуфераОбмена) Тогда
ирОбщий.СообщитьЛкс("Ошибка разбора буферного описания формы " + ирОбщий.ПолноеИмяФормыЛкс(СлужебныеДанные) + ": " + ОписаниеОшибки);
КонецЕсли;
Возврат Ложь;
КонецПопытки;
ФайлФормы = ФайлМодуляИзИмениМодуля(СлужебныеДанные.ИмяФормы, "xml", Истина);
ИмитаторФормы = ИмитаторУправляемойФормыИзДокументаДОМ(ДокументDOM, Форма);
Если Истина
И Найти(СлужебныеДанные.ИмяФормы, ":") > 0
И ЗначениеЗаполнено(ИмитаторФормы.ИмяОсновногоРеквизита)
Тогда
СтрокаРеквизитаОбъект = ИмитаторФормы.Реквизиты.Найти(ИмитаторФормы.ИмяОсновногоРеквизита, "Имя");
Если Не ЗначениеЗаполнено(СтрокаРеквизитаОбъект.ОписаниеТипов) Тогда
ИмяФайла = ирОбщий.СтрРазделитьЛкс(СлужебныеДанные.ИмяФормы, "::")[1];
Попытка
ВнешнийОбъект = ирОбщий.МенеджерВнешнегоОбъектаЛкс(ИмяФайла);
Исключение
ОписаниеОшибки = ОписаниеОшибки(); // Для отладки
ВнешнийОбъект = Неопределено;
КонецПопытки;
Если ВнешнийОбъект <> Неопределено Тогда
СтрокаРеквизитаОбъект.ОписаниеТипов = Новый ОписаниеТипов(ирОбщий.ЗначенияВМассивЛкс(ТипЗнч(ВнешнийОбъект)));
СтрокаРеквизитаОбъект.Значение = ВнешнийОбъект;
КонецЕсли;
КонецЕсли;
Иначе
ирОбщий.СохранитьЗначениеВФайлЛкс(ИмитаторФормы, ФайлФормы.ПолноеИмя); // JSON дает тут больший размер чем XML
КонецЕсли;
ДополнитьСлужебныеДанныеИзКэшаФормы(СлужебныеДанные, ИмитаторФормы, ТекущаяДата());
Возврат Истина;
КонецФункции
//.
// Параметры:
// ДокументDOM - ДокументDOM -
// Форма - УправляемаяФорма -
// Возвращаемое значение:
// Структура -
Функция ИмитаторУправляемойФормыИзДокументаДОМ(Знач ДокументDOM, Знач Форма = Неопределено) Экспорт
ИмитаторФормы = ИмитаторУправляемойФормы();
Разыменователь = Новый РазыменовательПространствИменDOM(Новый Соответствие);
ШаблонУровня = "";
Для Счетчик = 0 По 8 Цикл
Выражение = "/e/e[1]/e/" + ШаблонУровня + "d[text()='02023637-7868-4a5f-8576-835a76e0c9ba']";
ШаблонУровня = ШаблонУровня + "*/";
НаборУзлов = ДокументDOM.ВычислитьВыражениеXPath(Выражение, ДокументDOM, Разыменователь);
УзелDOM = НаборУзлов.ПолучитьСледующий();
Если УзелDOM <> Неопределено Тогда
ИмитаторФормы.ИменаОбработчиков = ИменаОбработчиковИзУзлаФормы(ДокументDOM, УзелDOM.РодительскийУзел.РодительскийУзел.ПредыдущийСоседний.ПредыдущийСоседний.ПредыдущийСоседний, Разыменователь);
Прервать;
КонецЕсли;
КонецЦикла;
// реквизиты
Выражение = "/e/e[2]/e/d[3]/text()";
НаборУзлов = ДокументDOM.ВычислитьВыражениеXPath(Выражение, ДокументDOM, Разыменователь, ТипРезультатаDOMXPath.Строка);
УзелDOM = НаборУзлов.ПолучитьСледующий();
ИмитаторФормы.Реквизиты = НоваяТаблицаРеквизитовФормы();
Пока УзелDOM <> Неопределено Цикл
ИмяРеквизита = ирОбщий.ТекстИзВстроенногоЯзыкаЛкс(УзелDOM.ТекстовоеСодержимое);
Если УзелDOM.РодительскийУзел.РодительскийУзел.ДочерниеУзлы[10].ТекстовоеСодержимое = "1" Тогда
ИмитаторФормы.ИмяОсновногоРеквизита = ИмяРеквизита;
КонецЕсли;
ОписаниеРеквизита = Новый Структура;
РеквизитыКоллекции = НоваяТаблицаРеквизитовФормы();
НомерУзлаВложенных = 13;
ОписаниеТипов = ТипЗначенияИзУзлаФормы(УзелDOM.РодительскийУзел.РодительскийУзел.ДочерниеУзлы[5]);
Если ОписаниеТипов = Новый ОписаниеТипов("ДинамическийСписок") Тогда
ДинамическийСписок = Новый Структура("ОсновнаяТаблица, ТекстЗапроса");
УзелДинамическийСписок = УзелDOM.РодительскийУзел.РодительскийУзел.ДочерниеУзлы[14];
//ДинамическийСписок.ОсновнаяТаблица = УзелДинамическийСписок.ДочерниеУзлы[5].ТекстовоеСодержимое;
УзелДинамическийСписок.ДочерниеУзлы[3].УдалитьДочерний(УзелДинамическийСписок.ДочерниеУзлы[3].ПервыйДочерний);
ДинамическийСписок.ТекстЗапроса = ирОбщий.ТекстИзВстроенногоЯзыкаЛкс(УзелДинамическийСписок.ДочерниеУзлы[3].ТекстовоеСодержимое);
ИмитаторФормы.ДинамическиеСписки.Вставить(ИмяРеквизита, ДинамическийСписок);
Для Каждого ДочернийУзел Из УзелДинамическийСписок.ДочерниеУзлы Цикл
Если ДочернийУзел.ПоследнийДочерний = Неопределено Тогда
Продолжить;
КонецЕсли;
ТекстУзла = ДочернийУзел.ПоследнийДочерний.ТекстовоеСодержимое;
Если Ложь
Или ирОбщий.СтрНачинаетсяСЛкс(ТекстУзла, """FieldsMapItemName")
Или ирОбщий.СтрНачинаетсяСЛкс(ТекстУзла, """FieldsMapItemSecondaryName")
Тогда
ИмяДочернегоРеквизита = ирОбщий.ТекстИзВстроенногоЯзыкаЛкс(ДочернийУзел.СледующийСоседний.ПоследнийДочерний.ТекстовоеСодержимое);
Если Найти(ИмяДочернегоРеквизита, ".") = 0 Тогда
ОписаниеРеквизита = РеквизитыКоллекции.Добавить();
ОписаниеРеквизита.Имя = ИмяДочернегоРеквизита;
ирОбщий.ОбновитьКопиюСвойстваВНижнемРегистреЛкс(ОписаниеРеквизита);
ОписаниеРеквизита.ОписаниеТипов = ТипЗначенияИзУзлаФормы(ДочернийУзел.СледующийСоседний.ПервыйДочерний);
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЕсли;
ЗначениеРеквизита = Неопределено;
КоличествоРеквизитовКоллекции = Число(УзелDOM.РодительскийУзел.РодительскийУзел.ДочерниеУзлы[НомерУзлаВложенных].ТекстовоеСодержимое);
Если КоличествоРеквизитовКоллекции > 0 Тогда
Если Ложь
Или ОписаниеТипов = Новый ОписаниеТипов("ТаблицаЗначений")
Или ОписаниеТипов = Новый ОписаниеТипов("ДеревоЗначений")
Тогда
ЗначениеРеквизита = Новый (ОписаниеТипов.Типы()[0]); // ТаблицаЗначений
Иначе
ЗначениеРеквизита = Новый Структура; // Мультиметка7726614
КонецЕсли;
Для НомерРеквизита = 1 По КоличествоРеквизитовКоллекции Цикл
УзелДочерний = УзелDOM.РодительскийУзел.РодительскийУзел.ДочерниеУзлы[НомерУзлаВложенных + НомерРеквизита].ДочерниеУзлы[3];
ОписаниеРеквизита = РеквизитыКоллекции.Добавить();
ОписаниеРеквизита.Имя = ирОбщий.ТекстИзВстроенногоЯзыкаЛкс(УзелДочерний.ТекстовоеСодержимое);
ирОбщий.ОбновитьКопиюСвойстваВНижнемРегистреЛкс(ОписаниеРеквизита);
ОписаниеРеквизита.Индекс = УзелДочерний.РодительскийУзел.ДочерниеУзлы[1].ПервыйДочерний.ТекстовоеСодержимое;
ОписаниеРеквизита.ОписаниеТипов = ТипЗначенияИзУзлаФормы(УзелДочерний.СледующийСоседний.СледующийСоседний);
Если ТипЗнч(ЗначениеРеквизита) = Тип("Структура") Тогда
ЗначениеРеквизита.Вставить(ОписаниеРеквизита.Имя, ОписаниеРеквизита.ОписаниеТипов);
Иначе
ЗначениеРеквизита.Колонки.Добавить(ОписаниеРеквизита.Имя, ОписаниеРеквизита.ОписаниеТипов);
КонецЕсли;
КонецЦикла;
КонецЕсли;
ОписаниеРеквизита = ИмитаторФормы.Реквизиты.Добавить();
ОписаниеРеквизита.Имя = ИмяРеквизита;
ирОбщий.ОбновитьКопиюСвойстваВНижнемРегистреЛкс(ОписаниеРеквизита);
ОписаниеРеквизита.Индекс = УзелDOM.РодительскийУзел.РодительскийУзел.ДочерниеУзлы[1].ПервыйДочерний.ТекстовоеСодержимое;
ОписаниеРеквизита.ОписаниеТипов = ОписаниеТипов;
ОписаниеРеквизита.Реквизиты = РеквизитыКоллекции;
ОписаниеРеквизита.Значение = ЗначениеРеквизита;
УзелDOM = НаборУзлов.ПолучитьСледующий();
КонецЦикла;
// Элементы
ВсеТипыЭлементов = Новый Соответствие;
ВсеТипыЭлементов.Вставить("1", Тип("ДополнениеЭлементаФормы"));
ВсеТипыЭлементов.Вставить("cd5394d0-7dda-4b56-8927-93ccbe967a01", Тип("ГруппаФормы"));
ВсеТипыЭлементов.Вставить("77ffcc29-7f2d-4223-b22f-19666e7250ba", Тип("ПолеФормы"));
ВсеТипыЭлементов.Вставить("143c00f7-a42d-4cd7-9189-88e4467dc768", Тип("ТаблицаФормы"));
ВсеТипыЭлементов.Вставить("a9f3b1ac-f51b-431e-b102-55a69acdecad", Тип("КнопкаФормы"));
ВсеТипыЭлементов.Вставить("3d3cb80c-508b-41fa-8a18-680cdf5f1712", Тип("ДекорацияФормы"));
ВидыЭлементовПоля = Новый Соответствие;
ВидыЭлементовПоля.Вставить("1", ПолучитьПолноеИмяПредопределенногоЗначения(ВидПоляФормы.ПолеНадписи));
ВидыЭлементовПоля.Вставить("2", ПолучитьПолноеИмяПредопределенногоЗначения(ВидПоляФормы.ПолеВвода));
ВидыЭлементовПоля.Вставить("3", ПолучитьПолноеИмяПредопределенногоЗначения(ВидПоляФормы.ПолеФлажка));
ВидыЭлементовПоля.Вставить("4", ПолучитьПолноеИмяПредопределенногоЗначения(ВидПоляФормы.ПолеКартинки));
ВидыЭлементовПоля.Вставить("5", ПолучитьПолноеИмяПредопределенногоЗначения(ВидПоляФормы.ПолеПереключателя));
ВидыЭлементовПоля.Вставить("6", ПолучитьПолноеИмяПредопределенногоЗначения(ВидПоляФормы.ПолеТабличногоДокумента));
ВидыЭлементовПоля.Вставить("7", ПолучитьПолноеИмяПредопределенногоЗначения(ВидПоляФормы.ПолеТекстовогоДокумента));
ВидыЭлементовПоля.Вставить("8", ПолучитьПолноеИмяПредопределенногоЗначения(ВидПоляФормы.ПолеКалендаря));
ВидыЭлементовПоля.Вставить("9", ПолучитьПолноеИмяПредопределенногоЗначения(ВидПоляФормы.ПолеИндикатора));
ВидыЭлементовПоля.Вставить("10", ПолучитьПолноеИмяПредопределенногоЗначения(ВидПоляФормы.ПолеПолосыРегулирования));
ВидыЭлементовПоля.Вставить("11", ПолучитьПолноеИмяПредопределенногоЗначения(ВидПоляФормы.ПолеДиаграммы));
ВидыЭлементовПоля.Вставить("12", ПолучитьПолноеИмяПредопределенногоЗначения(ВидПоляФормы.ПолеДиаграммыГанта));
ВидыЭлементовПоля.Вставить("14", ПолучитьПолноеИмяПредопределенногоЗначения(ВидПоляФормы.ПолеГрафическойСхемы));
ВидыЭлементовПоля.Вставить("15", ПолучитьПолноеИмяПредопределенногоЗначения(ВидПоляФормы.ПолеHTMLДокумента));
ВидыЭлементовПоля.Вставить("17", ПолучитьПолноеИмяПредопределенногоЗначения(ВидПоляФормы.ПолеФорматированногоДокумента));
ВидыЭлементовПоля.Вставить("18", ПолучитьПолноеИмяПредопределенногоЗначения(ВидПоляФормы.ПолеПериода));
ВидыЭлементовПоля.Вставить("19", ПолучитьПолноеИмяПредопределенногоЗначения(ВидПоляФормы.ПолеПланировщика));
ВидыЭлементовГруппы = Новый Соответствие;
ВидыЭлементовГруппы.Вставить("0", ПолучитьПолноеИмяПредопределенногоЗначения(ВидГруппыФормы.КоманднаяПанель)); // Опасно
ВидыЭлементовГруппы.Вставить("1", ПолучитьПолноеИмяПредопределенногоЗначения(ВидГруппыФормы.Подменю));
ВидыЭлементовГруппы.Вставить("3", ПолучитьПолноеИмяПредопределенногоЗначения(ВидГруппыФормы.Страницы));
ВидыЭлементовГруппы.Вставить("4", ПолучитьПолноеИмяПредопределенногоЗначения(ВидГруппыФормы.Страница));
ВидыЭлементовГруппы.Вставить("5", ПолучитьПолноеИмяПредопределенногоЗначения(ВидГруппыФормы.ОбычнаяГруппа));
ВидыЭлементовГруппы.Вставить("6", ПолучитьПолноеИмяПредопределенногоЗначения(ВидГруппыФормы.ГруппаКнопок));
ВидыЭлементовГруппы.Вставить("8", ПолучитьПолноеИмяПредопределенногоЗначения(ВидГруппыФормы.КонтекстноеМеню));
ВидыЭлементовГруппы.Вставить("9", ПолучитьПолноеИмяПредопределенногоЗначения(ВидГруппыФормы.КоманднаяПанель));
// TODO узнать номера остальных видов групп
//ВидыЭлементовГруппы.Вставить("?", ПолучитьПолноеИмяПредопределенногоЗначения(ВидГруппыФормы.ГруппаКолонок));
ПутиКРодителям = Новый Соответствие;
//Выражение = "/e/e[1]/e/d[6]/text()"; // Корневые элементы
// Антибаг платформы 8.3.23. Просмотр поддерева "//" работает крайне медленно https://www.hostedredmine.com/issues/977092
//Выражение = "/e/e[1]/e//d[(position()=5 or position()=6) and starts-with(text(), '""') and text()!='""""']/text()"; // Все элементы
ШаблонУровня = "";
Для Счетчик = 0 По 8 Цикл
Выражение = "/e/e[1]/e/" + ШаблонУровня + "d[(position()=5 or position()=6) and starts-with(text(), '""') and text()!='""""']/text()"; // Все элементы
ШаблонУровня = ШаблонУровня + "*/";
НаборУзлов = ДокументDOM.ВычислитьВыражениеXPath(Выражение, ДокументDOM, Разыменователь, ТипРезультатаDOMXPath.Строка);
УзелDOM = НаборУзлов.ПолучитьСледующий();
Пока УзелDOM <> Неопределено Цикл
ИмяЭлемента = ирОбщий.ТекстИзВстроенногоЯзыкаЛкс(УзелDOM.ТекстовоеСодержимое);
Если Ложь
Или Не ирОбщий.ЛиИмяПеременнойЛкс(ИмяЭлемента)
Или ирОбщий.СтрНачинаетсяСЛкс(ИмяЭлемента, "Navigator")
Тогда
Перейти ~СледующийЭлемент;
КонецЕсли;
ПутьКДанным = Новый Массив;
Если УзелDOM.РодительскийУзел.РодительскийУзел.ДочерниеУзлы.Количество() <= 12 Тогда
УзлыПутиКДанным = Новый Массив;
Иначе
УзлыПутиКДанным = УзелDOM.РодительскийУзел.РодительскийУзел.ДочерниеУзлы[12].ДочерниеУзлы;
КонецЕсли;
Если УзлыПутиКДанным.Количество() > 1 Тогда
ГлубинаПутиКДанным = Число(УзлыПутиКДанным[0].ТекстовоеСодержимое);
Если ГлубинаПутиКДанным > 0 Тогда
ИдентификаторыРеквизитов = Новый Соответствие;
РеквизитыРодителя = ИмитаторФормы.Реквизиты;
Для Индекс = 1 По ГлубинаПутиКДанным Цикл
ИндексРеквизита = УзлыПутиКДанным[Индекс].ТекстовоеСодержимое;
СтрокаРеквизита = РеквизитыРодителя.Найти(ИндексРеквизита, "Индекс");
Если СтрокаРеквизита <> Неопределено Тогда
ИмяРеквизита = СтрокаРеквизита.Имя;
Иначе
ИмяРеквизита = ИндексРеквизита;
#Если Клиент Тогда
Если Форма <> Неопределено И Найти(ИмяРеквизита, "-") > 0 Тогда
ПутьКРодителю = ирОбщий.СтрСоединитьЛкс(ПутьКДанным, ".");
ИдентификаторыРеквизитов = ПутиКРодителям[ПутьКРодителю];
Если ИдентификаторыРеквизитов = Неопределено Тогда
ИменаРеквизитовФормы(Форма, ПутьКРодителю,, ИдентификаторыРеквизитов);
ПутиКРодителям[ПутьКРодителю] = ИдентификаторыРеквизитов;
КонецЕсли;
Идентификатор = ирОбщий.СтрСоединитьЛкс(УзлыПутиКДанным[Индекс].ДочерниеУзлы, ":",,,, "ТекстовоеСодержимое");
ИмяРеквизита = ИдентификаторыРеквизитов[Идентификатор];
КонецЕсли;
#КонецЕсли
КонецЕсли;
ПутьКДанным.Добавить(ИмяРеквизита);
Если Ложь
Или СтрокаРеквизита = Неопределено
Или СтрокаРеквизита.Реквизиты = Неопределено
Тогда
Прервать;
КонецЕсли;
РеквизитыРодителя = СтрокаРеквизита.Реквизиты;
КонецЦикла;
КонецЕсли;
КонецЕсли;
ПутьКДанным = ирОбщий.СтрСоединитьЛкс(ПутьКДанным, ".");
ТипЭлемента = ВсеТипыЭлементов[УзелDOM.РодительскийУзел.РодительскийУзел.ПредыдущийСоседний.ТекстовоеСодержимое];
ВидЭлемента = Неопределено;
ИменаОбработчиков = Неопределено;
ВидЭлементаИмя = "";
Если ТипЭлемента = Неопределено Тогда
Если ирОбщий.СтрКончаетсяНаЛкс(ИмяЭлемента, "РасширеннаяПодсказка") Тогда
ТипЭлемента = Тип("ДекорацияФормы");
ИначеЕсли ирОбщий.СтрКончаетсяНаЛкс(ИмяЭлемента, "КонтекстноеМеню") Тогда
ТипЭлемента = Тип("ГруппаФормы");
ВидЭлемента = ВидГруппыФормы.КонтекстноеМеню;
ИначеЕсли ирОбщий.СтрКончаетсяНаЛкс(ИмяЭлемента, "КоманднаяПанель") Тогда
ТипЭлемента = Тип("ГруппаФормы");
ВидЭлемента = ВидГруппыФормы.КоманднаяПанель;
Иначе
// Опасно. Можно отсечь что то полезное
Перейти ~СледующийЭлемент;
КонецЕсли;
Если ВидЭлемента <> Неопределено Тогда
ВидЭлементаИмя = ПолучитьПолноеИмяПредопределенногоЗначения(ВидЭлемента);
КонецЕсли;
ИначеЕсли ТипЭлемента = Тип("ПолеФормы") Тогда
ВидЭлементаИмя = ВидыЭлементовПоля[УзелDOM.РодительскийУзел.ПредыдущийСоседний.ТекстовоеСодержимое];
ИначеЕсли ТипЭлемента = Тип("ГруппаФормы") Тогда
ВидЭлементаИмя = ВидыЭлементовГруппы[УзелDOM.РодительскийУзел.ПредыдущийСоседний.ТекстовоеСодержимое];
КонецЕсли;
Если Ложь
Или ТипЭлемента = Тип("ДополнениеЭлементаФормы")
Или ТипЭлемента = Тип("КнопкаФормы")
Или ТипЭлемента = Тип("ГруппаФормы") И ВидЭлемента <> ВидГруппыФормы.Страницы
Тогда
// Ускорение
Иначе
ИменаОбработчиков = ИменаОбработчиковИзУзлаФормы(ДокументDOM, УзелDOM.РодительскийУзел.РодительскийУзел, Разыменователь);
КонецЕсли;
УзлыПоискаРодителя = УзелDOM.РодительскийУзел.РодительскийУзел.РодительскийУзел.ДочерниеУзлы;
Для ИндексУзлаРодителя = 6 По 7 Цикл // Не понял от чего зависит
Попытка
ИмяРодителя = УзлыПоискаРодителя[ИндексУзлаРодителя].ПервыйДочерний.ЗначениеУзла;
Исключение
ИмяРодителя = Неопределено;
КонецПопытки;
Если Лев(ИмяРодителя, 1) <> """" Тогда
// Ускорение
Продолжить;
КонецЕсли;
ИмяРодителя = ирОбщий.ТекстИзВстроенногоЯзыкаЛкс(ИмяРодителя);
Если ЗначениеЗаполнено(ИмяРодителя) Тогда
Прервать;
КонецЕсли;
КонецЦикла;
ИмитаторЭлементаФормы = ИмитаторЭлементаФормы(ИмяЭлемента, ВидЭлементаИмя, ИменаОбработчиков, ИмяРодителя, ПутьКДанным, ТипЭлемента);
ИмитаторФормы.Элементы.Вставить(ИмяЭлемента, ИмитаторЭлементаФормы);
//ИмитаторФормы.Элементы[я].
~СледующийЭлемент:
УзелDOM = НаборУзлов.ПолучитьСледующий();
КонецЦикла;
КонецЦикла;
// параметры
Выражение = "/e/e[3]/e/d[2]/text()"; // Все параметры
НаборУзлов = ДокументDOM.ВычислитьВыражениеXPath(Выражение, ДокументDOM, Разыменователь, ТипРезультатаDOMXPath.Строка);
УзелDOM = НаборУзлов.ПолучитьСледующий();
Пока УзелDOM <> Неопределено Цикл
ИмитаторФормы.Параметры.Вставить(ирОбщий.ТекстИзВстроенногоЯзыкаЛкс(УзелDOM.ТекстовоеСодержимое), ТипЗначенияИзУзлаФормы(УзелDOM.РодительскийУзел.СледующийСоседний));
УзелDOM = НаборУзлов.ПолучитьСледующий();
КонецЦикла;
// команды
Выражение = "/e/e[4]/e/d[2]/text()"; // Все команды
НаборУзлов = ДокументDOM.ВычислитьВыражениеXPath(Выражение, ДокументDOM, Разыменователь, ТипРезультатаDOMXPath.Строка);
УзелDOM = НаборУзлов.ПолучитьСледующий();
Пока УзелDOM <> Неопределено Цикл
ИмитаторФормы.Команды.Вставить(ирОбщий.ТекстИзВстроенногоЯзыкаЛкс(УзелDOM.ТекстовоеСодержимое));
УзелDOM = НаборУзлов.ПолучитьСледующий();
КонецЦикла;
Возврат ИмитаторФормы;
КонецФункции
//.
// Параметры:
// ИмяЭлемента - Строка, Неопределено -
// ВидЭлементаИмя - Строка -
// ИменаОбработчиков - Массив[Неопределено, Строка], Неопределено -
// ИмяРодителя - Строка, Неопределено -
// ПутьКДанным - Строка -
// ТипЭлемента - Тип -
// Возвращаемое значение:
// Структура -
Функция ИмитаторЭлементаФормы(ИмяЭлемента, Знач ВидЭлементаИмя, Знач ИменаОбработчиков, Знач ИмяРодителя, Знач ПутьКДанным, Знач ТипЭлемента) Экспорт
ОписаниеЭлемента = Новый Структура;
ОписаниеЭлемента.Вставить("ИменаОбработчиков", ИменаОбработчиков);
ОписаниеЭлемента.Вставить("ПутьКДанным", ПутьКДанным);
ОписаниеЭлемента.Вставить("Тип", ТипЭлемента);
ОписаниеЭлемента.Вставить("Вид", ВидЭлементаИмя);
ОписаниеЭлемента.Вставить("Имя", ИмяЭлемента);
ОписаниеЭлемента.Вставить("ИмяРодителя", ИмяРодителя);
Возврат ОписаниеЭлемента;
КонецФункции
//.
// Возвращаемое значение:
// Структура -
Функция ИмитаторУправляемойФормы() Экспорт
// Каждый раз при изменении структуры увеличиваем ВерсияФорматаСтруктурыФормы() на 1
ИмитаторФормы = Новый Структура;
ИмитаторФормы.Вставить("ВерсияФормата", ВерсияФорматаСтруктурыФормы());
ИмитаторФормы.Вставить("Элементы", Новый Структура);
ИмитаторФормы.Вставить("Параметры", Новый Структура);
ИмитаторФормы.Вставить("Команды", Новый Структура);
ИмитаторФормы.Вставить("ДинамическиеСписки", Новый Структура);
ИмитаторФормы.Вставить("ИменаОбработчиков", Новый Массив);
ИмитаторФормы.Вставить("ИмяОсновногоРеквизита");
ИмитаторФормы.Вставить("Реквизиты"); // см. НоваяТаблицаРеквизитовФормы
Возврат ИмитаторФормы;
КонецФункции
Функция ВерсияФорматаСтруктурыФормы()
Возврат 4;
КонецФункции
Процедура ДополнитьСлужебныеДанныеИзКэшаФормы(Знач СлужебныеДанные, Знач ИмитаторФормы, Знач ДатаОбновления) Экспорт
Если Ложь
Или Не СлужебныеДанные.Свойство("Элементы")
Или ИмитаторФормы.Элементы.Количество() > 0
Тогда
ирОбщий.СкопироватьКоллекциюЛкс(ИмитаторФормы, СлужебныеДанные);
Для Каждого СтрокаЭлемента Из СлужебныеДанные.Элементы Цикл
Если ЗначениеЗаполнено(СтрокаЭлемента.Значение.Вид) Тогда
СтрокаЭлемента.Значение.Вид = ПредопределенноеЗначение(СтрокаЭлемента.Значение.Вид);
КонецЕсли;
ЗначениеРеквизита = Неопределено;
ОписаниеТипов = Неопределено;
ПутьКДанным = СтрокаЭлемента.Значение.ПутьКДанным;
Если ЗначениеЗаполнено(ПутьКДанным) Тогда
СтрокаРеквизита = ИмитаторФормы.Реквизиты.Найти(ПутьКДанным, "Имя");
Если СтрокаРеквизита <> Неопределено Тогда
ЗначениеРеквизита = СтрокаРеквизита.Значение;
ОписаниеТипов = СтрокаРеквизита.ОписаниеТипов;
КонецЕсли;
КонецЕсли;
СтрокаЭлемента.Значение.Вставить("ОписаниеТипов", ОписаниеТипов);
СтрокаЭлемента.Значение.Вставить("Значение", ЗначениеРеквизита);
КонецЦикла;
КонецЕсли;
//СлужебныеДанные.Вставить("ПутиКДанным", ИмитаторФормы.Элементы);
СлужебныеДанные.Вставить("ДатаОбновления", ДатаОбновления);
СлужебныеДанные.Вставить("Тип", ирОбщий.ТипУправляемаяФормаЛкс());
КонецПроцедуры
//.
// Параметры:
// ДокументDOM - ДокументDOM, ДокументHTML -
// УзелDOM - АтрибутDOM, ДокументDOM, КомментарийDOM, НотацияDOM, ОпределениеТипаДокументаDOM, СекцияCDATADOM, СущностьDOM, ТекстDOM, ФрагментДокументаDOM, ЭлементDOM, ... -
// Разыменователь - РазыменовательПространствИменDOM -
// Возвращаемое значение:
// Массив -
Функция ИменаОбработчиковИзУзлаФормы(Знач ДокументDOM, Знач УзелDOM, Знач Разыменователь)
ОбработчикиСобытий = Новый Массив;
// Тут цикл поиска по глубине давал замедление!
ВыражениеОбработчиков = ".//d[contains(text(),'-') and not(starts-with(text(),'-') or text()='00000000-0000-0000-0000-000000000000')]/following-sibling::d[1][not(text()='0' or contains(text(),'""""') or contains(text(),'-'))]/text()";
НаборУзловОбработчиков = ДокументDOM.ВычислитьВыражениеXPath(ВыражениеОбработчиков, УзелDOM, Разыменователь, ТипРезультатаDOMXPath.Строка); // Долго!
УзелОбработчика = НаборУзловОбработчиков.ПолучитьСледующий();
Пока УзелОбработчика <> Неопределено Цикл
ОбработчикиСобытий.Добавить(ирОбщий.ТекстИзВстроенногоЯзыкаЛкс(УзелОбработчика.ТекстовоеСодержимое));
УзелОбработчика = НаборУзловОбработчиков.ПолучитьСледующий();
КонецЦикла;
Возврат ОбработчикиСобытий;
КонецФункции
// .
// Возвращаемое значение:
// ТаблицаЗначений -
Функция НоваяТаблицаРеквизитовФормы() Экспорт
Реквизиты = Новый ТаблицаЗначений;
Реквизиты.Колонки.Добавить("Индекс");
Реквизиты.Колонки.Добавить("Имя");
Реквизиты.Колонки.Добавить("НИмя");
Реквизиты.Колонки.Добавить("ОписаниеТипов"); // ОписаниеТипов
Реквизиты.Колонки.Добавить("Реквизиты"); // см. НоваяТаблицаРеквизитовФормы
Реквизиты.Колонки.Добавить("Значение");
//Реквизиты.Колонки.Добавить("ЛиДляКоллекции", Новый ОписаниеТипов("Булево"));
Возврат Реквизиты;
КонецФункции
//.
// Параметры:
// УзелТипа - ЭлементDOM -
// Возвращаемое значение:
// ОписаниеТипов -
Функция ТипЗначенияИзУзлаФормы(Знач УзелТипа)
Тип = Неопределено;
Если УзелТипа.ДочерниеУзлы.Количество() > 1 Тогда
ДочерниеУзлы = УзелТипа.ДочерниеУзлы[1].ДочерниеУзлы;
РодТипа = ДочерниеУзлы[0].ДочерниеУзлы[0];
Если РодТипа.ТекстовоеСодержимое = """S""" Тогда
Тип = Тип("Строка");
Если ДочерниеУзлы.Количество() > 1 Тогда
КвалификаторыСтроки = Новый КвалификаторыСтроки(Число(ДочерниеУзлы[1].ТекстовоеСодержимое));
КонецЕсли;
ИначеЕсли РодТипа.ТекстовоеСодержимое = """B""" Тогда
Тип = Тип("Булево");
ИначеЕсли РодТипа.ТекстовоеСодержимое = """N""" Тогда
Тип = Тип("Число");
ИначеЕсли РодТипа.ТекстовоеСодержимое = """D""" Тогда
Тип = Тип("Число");
ИначеЕсли РодТипа.ТекстовоеСодержимое = """#""" Тогда
ИДТипа = ДочерниеУзлы[1].ТекстовоеСодержимое;
Попытка
Тип = ЗначениеИзСтрокиВнутр("{""T""," + ИДТипа + "}");
Исключение
// Например для объекта внешней обработки почему то так не опознается тип
КонецПопытки;
Иначе
Пустышка = 0;
КонецЕсли;
КонецЕсли;
Возврат новый ОписаниеТипов(ирОбщий.ЗначенияВМассивЛкс(Тип),,,, КвалификаторыСтроки);
КонецФункции
// Возвращаемое значение:
// Структура -
Функция НовыеФлагиКомпиляции(Знач Сервер = Истина, Знач КлиентОбычноеПриложение = Истина, Знач КлиентУправляемоеПриложение = Истина, Знач БезКонтекста = Ложь) Экспорт
ФлагиКомпиляции = Новый Структура;
ФлагиКомпиляции.Вставить("Сервер", Сервер);
ФлагиКомпиляции.Вставить("КлиентОбычноеПриложение", КлиентОбычноеПриложение);
ФлагиКомпиляции.Вставить("КлиентУправляемоеПриложение", КлиентУправляемоеПриложение);
ФлагиКомпиляции.Вставить("БезКонтекста", БезКонтекста);
Возврат ФлагиКомпиляции;
КонецФункции
Функция ОписаниеМетодаМодуля(ПолноеИмяМетода) Экспорт
СтруктураТипа = НоваяСтруктураТипа();
СтруктураТипа.ИмяОбщегоТипа = "ОбщийМодуль";
СтруктураТипа.Метаданные = Метаданные.ОбщиеМодули[ирОбщий.ПервыйФрагментЛкс(ПолноеИмяМетода)];
МодульМетаданных = ПодготовитьМодульМетаданных(СтруктураТипа);
Если МодульМетаданных = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
МетодыМодуля = МодульМетаданных.Методы;
ОписаниеМетода = МетодыМодуля.Найти(ирОбщий.ПоследнийФрагментЛкс(ПолноеИмяМетода), "Имя");
Возврат ОписаниеМетода;
КонецФункции
Функция ПолучитьРазделыМодуля1С(Знач ТекстМодуля = "") Экспорт
#Если Сервер И Не Сервер Тогда
мРегВыражение = Обработки.ирОболочкаРегВыражение.Создать();
#КонецЕсли
Шаблоны = ШаблоныДляАнализаВстроенногоЯзыка();
мРегВыражение.IgnoreCase = Истина;
мРегВыражение.MultiLine = Ложь;
мРегВыражение.Global = Истина;
мРегВыражение.Pattern = Шаблоны.ЭлементОбластиМетодов;
ВхожденияМетодов = мРегВыражение.НайтиВхождения(ТекстМодуля);
ПозицияНачалаПервогоМетода = 1;
ПозицияКонцаПоследнегоМетода = 1;
Для Индекс = 0 По ВхожденияМетодов.Количество() - 1 Цикл
Вхождение = ВхожденияМетодов[Индекс];
Если Вхождение.SubMatches(1) <> Неопределено Тогда
ПозицияНачалаПервогоМетода = Вхождение.FirstIndex + 1;
Прервать;
КонецЕсли;
КонецЦикла;
ИндексВхожденияПоследнегоМетода = 0;
Для Индекс = 1 - ВхожденияМетодов.Количество() По 0 Цикл // Обратный обход
Вхождение = ВхожденияМетодов[-Индекс];
Если Вхождение.SubMatches(1) <> Неопределено Тогда
ПозицияКонцаПоследнегоМетода = Вхождение.FirstIndex + Вхождение.Length + 1;
ИндексВхожденияПоследнегоМетода = -Индекс;
Прервать;
КонецЕсли;
КонецЦикла;
Если ПозицияКонцаПоследнегоМетода > 1 Тогда
// захватим областью методов закрывающие инструкции препроцессора после последнего метода. Нужно в консоли кода для конвертации текста в режим "Модуль"
Для Индекс = ИндексВхожденияПоследнегоМетода По ВхожденияМетодов.Количество() - 1 Цикл
Вхождение = ВхожденияМетодов[Индекс];
Аннотация = Вхождение.SubMatches(9);
Если Найти(СокрЛ(Аннотация), "#Конец") = 1 Тогда
Если Не ПустаяСтрока(Сред(ТекстМодуля, ПозицияКонцаПоследнегоМетода, Вхождение.FirstIndex - ПозицияКонцаПоследнегоМетода + 1)) Тогда
Прервать;
КонецЕсли;
ПозицияКонцаПоследнегоМетода = Вхождение.FirstIndex + Вхождение.Length + 1;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если ПозицияКонцаПоследнегоМетода = 1 Тогда
мРегВыражение.Pattern = Шаблоны.ОписаниеСтрокиПеременных;
ВхожденияПеременных = мРегВыражение.НайтиВхождения(ТекстМодуля);
Для Индекс = 1 - ВхожденияПеременных.Количество() По 0 Цикл // Обратный обход
Вхождение = ВхожденияПеременных[-Индекс];
ПозицияНачалаПервогоМетода = Вхождение.FirstIndex + Вхождение.Length + 1;
ПозицияКонцаПоследнегоМетода = ПозицияНачалаПервогоМетода;
Прервать;
КонецЦикла;
КонецЕсли;
Результат = Новый Структура;
Результат.Вставить("ПеременныеТекст", Сред(ТекстМодуля, 1, ПозицияНачалаПервогоМетода - 1));
Результат.Вставить("МетодыТекст", Сред(ТекстМодуля, ПозицияНачалаПервогоМетода, ПозицияКонцаПоследнегоМетода - ПозицияНачалаПервогоМетода));
Если ПозицияНачалаПервогоМетода < ПозицияКонцаПоследнегоМетода Тогда
ПозицияКонцаПоследнегоМетода = ПозицияКонцаПоследнегоМетода + 1;
КонецЕсли;
Результат.Вставить("ПозицияМетодов", ПозицияНачалаПервогоМетода); // начиная с 1
Программа = Сред(ТекстМодуля, ПозицияКонцаПоследнегоМетода);
Результат.Вставить("ПозицияПрограммы", ПозицияКонцаПоследнегоМетода); // начиная с 1
Результат.Вставить("Программа", Программа);
Результат.Вставить("ВхожденияМетодов", ВхожденияМетодов);
Возврат Результат;
КонецФункции
Функция ШаблоныДляАнализаВстроенногоЯзыка() Экспорт
Перем шИмя, шПустоеНачалоСтроки, шКомментарий, шРазделитель, шСтруктураКомментаПарам, шСтруктураКомментаВозвр, шВозврат, шСтруктураКомментаОписаниеПараметров, шКомментМетода, шОписаниеПеременной,
шСтрокаПеременныхБезКомментов, шСтрокаПеременных, шЛитералПрограммы, шПараметрыМетода, шДирективаИлиАннотация, шБлокКомментов, шМетодЧистый, шМетод1, шМетодСПредКомментом, шСтруктураМодуля, шЭлементОбластиМетодов;
Если мШаблоныДляАнализаВстроенногоЯзыка <> Неопределено Тогда
Возврат мШаблоныДляАнализаВстроенногоЯзыка;
КонецЕсли;
// {ОписаниеРегулярногоВыражения.Начало} конструктор из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru)
// {Шаблон.Начало}
// + <шИмя> = [_ЁА-ЯA-Z][_ЁА-ЯA-Z\d]*
// + <шПустоеНачалоСтроки> = (?:\n|^)(?:\t| )*
// + <шКомментарий> = //[^\n]*(?=(?:\n|$))
// + <шРазделитель> = (?:<шКомментарий>|\s|\xa0|$)
// + <шБлокКомментов> = <шКомментарий>(?:<шПустоеНачалоСтроки><шКомментарий>)*(?=(?:\n|$))
// + <шСтруктураКомментаПарам> = Параметры(?:\s*:\s*)?((([^\n]\n)*|.|\n)*)(?:\n\s*Возвращаемое значение\s*\:?\s*\n|$)
// + <шСтруктураКомментаВозвр> = Возвращаемое значение(?:\s*:\s*)?((([^\n]\n)*|.|\n)*)(?:\n\s*Параметры\s*\:?\s*\n|$)
// + <шВозврат> = Возврат\s+(?:Неопределено|Undefined|Null|(<шИмя>))(?:;|\n|\r|$)
// + <шСтруктураКомментаОписаниеПараметров> = (<шИмя>)(?:\s*[-])([^\n]*(?:\n|$)(\s{4}[^\n]*(?:\n|$))*)
// + <шМетодНачало> = (?:Функция|Процедура|Function|Procedure)
// + <шМетодКонец> = (?:Конец|End)(?:Процедуры|Функции|Procedure|Function)
// + <шКомментМетода> = ((?:[ \f\r\t\v]*//[^\n]*\n)+)<шМетодНачало><шРазделитель>*(<шИмя>)
// + <шОписаниеПеременной> = (<шИмя>)(<шРазделитель>+(?:Экспорт|Export))?
// + <шСтрокаПеременныхБезКомментов> = <шПустоеНачалоСтроки>(?:Перем|Var)((?:<шРазделитель>*<шОписаниеПеременной><шРазделитель>*[;,])+)
// + <шСтрокаПеременных> = <шСтрокаПеременныхБезКомментов>([ \f\r\t\v]*<шБлокКомментов>)?
// + <шЛитералПрограммы> = "(?:(?:"")|[^"\n])*(?:<шРазделитель>*\|(?:(?:"")|[^"\n])*)*(?:"|$)
// + <шПараметрыМетода> = <шРазделитель>*(Знач\s)?<шРазделитель>*(<шИмя>)<шРазделитель>*=?((?:<шРазделитель>*|(<шЛитералПрограммы>)|(?:[^,\n]*))+)(?:,|$)
// + <шДирективаИлиАннотация> = (?:<шПустоеНачалоСтроки>)?<шПустоеНачалоСтроки>[#&][^\n]*(?=\n|$)
// + <шМетодЧистый> = ([\t ]*(?:(?:Асинх|Async)\s+)?(<шМетодНачало>)<шРазделитель>*(<шИмя>)<шРазделитель>*\(([^\)]*)\)(<шРазделитель>*(?:Экспорт|Export))?(?:\s*?(?=\n))?(?:\n\s*(?:Перем|Var) .*(?=\n))*)((?:<шБлокКомментов>|\.<шМетодКонец>|(?:\r|\n|.)(?!<шМетодКонец>(?![^\n]*(?:"|\n\s*\|))))*)(?:$|[^а-яё_a-z0-9\."]<шМетодКонец>(?=(?:<шКомментарий>|[^а-яё_a-z0-9\."]|$)))
// + <шМетодСПредКомментом> = (?:(<шБлокКомментов>\n)|\n|^)[\t ]*<шМетодЧистый>
// + <шЭлементОбластиМетодов> = <шМетодСПредКомментом>|(<шБлокКомментов>)|(<шДирективаИлиАннотация>)
// {Шаблон.Конец}
шИмя = ЭтотОбъект.шИмя;
шПустоеНачалоСтроки = ЭтотОбъект.шПустоеНачалоСтроки;
шКомментарий = ЭтотОбъект.шКомментарий;
шРазделитель = ЭтотОбъект.шРазделитель;
шЛитералПрограммы = ЭтотОбъект.шЛитералПрограммы;
шМетодНачало = ЭтотОбъект.шМетодНачало;
шМетодКонец = ЭтотОбъект.шМетодКонец;
шБлокКомментов = "" + шКомментарий + "(?:" + шПустоеНачалоСтроки + "" + шКомментарий + ")*(?=(?:\n|$))";
шСтруктураКомментаПарам = "Параметры(?:\s*:\s*)?((([^\n]\n)*|.|\n)*)(?=\n\s*Возвращаемое значение\s*\:?\s*\n|$)"; // Всегда захватывает блок возвращаемого значения
шСтруктураКомментаВозвр = "Возвращаемое значение(?:\s*:\s*)?((([^\n]\n)*|.|\n)*)(?:\n\s*Параметры\s*\:?\s*\n|$)";
//шВозврат = "Возврат\s+(?:Неопределено|Undefined|Null|(" + шИмя + "))(?:;|\n|\r|$)";
шВозврат = "Возврат\s+(.+?)(?:;| КонецЕсли|\n|\r|$)";
шСтруктураКомментаОписаниеПараметров = "(" + шИмя + ")(?:\s*[-])([^\n]*(?:\n|$)(\s{4}[^\n]*(?:\n|$))*)";
шКомментМетода = "((?:[ \f\r\t\v]*//[^\n]*\n)+)" + шМетодНачало + шРазделитель + "+(" + шИмя + ")";
шОписаниеПеременной = "(" + шИмя + ")(" + шРазделитель + "+(?:Экспорт|Export))?";
шСтрокаПеременныхБезКомментов = "(?:Перем|Var)((?:" + шРазделитель + "*" + шОписаниеПеременной + шРазделитель + "*[;,])+)";
шСтрокаПеременных = "" + шПустоеНачалоСтроки + шСтрокаПеременныхБезКомментов + "([ \f\r\t\v]*" + шБлокКомментов + ")?";
шПараметрыМетода = "" + шРазделитель + "*(Знач\s)?" + шРазделитель + "*(" + шИмя + ")\s*=?((?:\s*(" + шЛитералПрограммы + ")|(?:[^,\n/]*))+)(?:(" + шКомментарий + ")|\n|,|$)";
шДирективаИлиАннотация = "(?:" + шПустоеНачалоСтроки + ")?" + шПустоеНачалоСтроки + "[#&][^\n]*(?=\n|$)";
шМетодЧистый = "([\t ]*(?:(?:Асинх|Async)\s+)?(" + шМетодНачало + ")" + шРазделитель + "+(" + шИмя + ")" + шРазделитель + "*\(([^\)]*)\)(" + шРазделитель + "*(?:Экспорт|Export))?(?:[\t ]*(" + шКомментарий + "))?(?:\s*?(?=\n))?(?:\n\s*(?:Перем|Var) .*(?=\n))*)"
+ "((?:" + шБлокКомментов + "|\." + шМетодКонец + "|(?:\r|\n|.)(?!" + шМетодКонец + "(?![^\n]*(?:""|\n\s*\|))))*)(?:$|[^а-яё_a-z0-9\.""]" + шМетодКонец + "(?=(?:" + шКомментарий + "|[^а-яё_a-z0-9\.""]|$)))";
шМетодСПредКомментом = "(?:((?:\n|^)[\t ]*" + шБлокКомментов + "\n)|\n|^)" + шМетодЧистый + "";
шЭлементОбластиМетодов = "" + шМетодСПредКомментом + "|((?:\n|^)[\t ]*" + шБлокКомментов + ")|(" + шДирективаИлиАннотация + ")";
// {ОписаниеРегулярногоВыражения.Конец}
Результат = Новый Структура;
Результат.Вставить("СтрокаПрограммы", шЛитералПрограммы);
Результат.Вставить("ДирективаПрепроцессора", шДирективаИлиАннотация);
Результат.Вставить("БлокКомментариев", шБлокКомментов);
Результат.Вставить("ОписаниеМетодаСКомментарием", шМетодСПредКомментом);
Результат.Вставить("ОписаниеМетодаЧистое", шМетодЧистый);
Результат.Вставить("ЭлементОбластиМетодов", шЭлементОбластиМетодов);
Результат.Вставить("ОписаниеПеременной", шОписаниеПеременной);
Результат.Вставить("ОписаниеСтрокиПеременных", шСтрокаПеременных);
Результат.Вставить("ОписаниеСтрокиПеременныхБезКомментов", шСтрокаПеременныхБезКомментов);
Результат.Вставить("КомментарийОписаниеМетода", шКомментМетода);
Результат.Вставить("ПараметрыМетода", шПараметрыМетода);
Результат.Вставить("СтруктураКомментарияВозвр", шСтруктураКомментаВозвр);
Результат.Вставить("СтруктураКомментарияПарам", шСтруктураКомментаПарам);
Результат.Вставить("СтруктураКомментарияОписаниеПараметров", шСтруктураКомментаОписаниеПараметров);
Результат.Вставить("Возврат", шВозврат);
Результат.Вставить("ОписаниеПараметра", ".*(?:\n(?://)?(?:[\t ]{8,}|[\t ]+[*-]).*)*");
мШаблоныДляАнализаВстроенногоЯзыка = Результат;
Возврат Результат;
КонецФункции
// Функция - Модуль метаданных. Для пустого текста и НЕ пустого имени возращает единый модуль с именем "<Пустой>"!
//
// Параметры:
// ТекстМодуля - Строка -
// СтруктураТипа - см. НоваяСтруктураТипа() -
// ИмяМодуля - Строка -
// ПодготовитьОписанияРезультатовМетодов - Булево -
// СтарыйМодуль - см. МодульМетаданных() -
// ТекущийМетод - см. НоваяТаблицаМетодовМодуля()[0] -
// ТекущаяПозиция - Число - позиция в модуле
//
// Возвращаемое значение:
// Структура -
//
Функция МодульМетаданных(Знач ТекстМодуля, Знач СтруктураТипа = Неопределено, Знач ИмяМодуля = "", Знач ПодготовитьОписанияРезультатовМетодов = Истина, Знач СтарыйМодуль = Неопределено,
Знач ТекущаяПозиция = 0, Знач ФлагиКомпиляции = Неопределено) Экспорт
РазрешитьЕдиныйПустойМодуль = Истина
И ПустаяСтрока(ТекстМодуля)
И ИмяМодуля <> ИмяДинамическогоМодуля()
И ЗначениеЗаполнено(ИмяМодуля);
Если РазрешитьЕдиныйПустойМодуль И мПустойМодуль <> Неопределено Тогда
// Для ускорения заполнения списка в Обработка.ирКлсПолеТекстаПрограммы.Форма.МетодыМодулей
Возврат мПустойМодуль;
КонецЕсли;
ЭтоМодульФормыУпр = Истина
И ЛиИмяМодуляФормы(ИмяМодуля)
И (Ложь
Или СтруктураТипа = Неопределено
Или ирОбщий.ЛиИмяТипаФормыЛкс(СтруктураТипа.ИмяОбщегоТипа));
ЛиНачальныйДиапазонСовпал = Ложь;
ЛиКонечныйДиапазонСовпал = Ложь;
ПозицияНачалаСтарая = 0;
Если Истина
И Не ПустаяСтрока(ТекстМодуля)
И СтарыйМодуль <> Неопределено
//И СтарыйМодуль.Свойство("Текст")
И ЗначениеЗаполнено(ТекущаяПозиция)
И ирКэш.НомерРежимаСовместимостиЛкс() >= 803006 // СтрНайти()
Тогда
МетодыСтарые = СтарыйМодуль.Методы;
ТекущийМетод = СтарыйМодуль.ТекущийМетод; // см. МетодыСтарые.Добавить()
Если ТекущийМетод <> Неопределено Тогда
Если Ложь
Или МетодыСтарые.Индекс(ТекущийМетод) = -1
Или ТекущийМетод.ПозицияСОписанием - ТекущаяПозиция > 1000
Или ТекущаяПозиция - (ТекущийМетод.ПозицияСОписанием + ТекущийМетод.ДлинаСОписанием) > 1000
Тогда
ТекущийМетод = Неопределено;
КонецЕсли;
КонецЕсли;
ИндексТекущегоМетода = -1;
Если ТекущийМетод <> Неопределено Тогда
ИндексТекущегоМетода = МетодыСтарые.Индекс(ТекущийМетод);
КонецЕсли;
Если ИндексТекущегоМетода = -1 Тогда
ИндексТекущегоМетода = МетодыСтарые.Количество();
Для Каждого Метод Из МетодыСтарые Цикл
Если Метод.ПозицияСОписанием = 0 Тогда
Продолжить;
КонецЕсли;
Если Метод.ПозицияСОписанием + Метод.ДлинаСОписанием + 100 > ТекущаяПозиция Тогда
ИндексТекущегоМетода = МетодыСтарые.Индекс(Метод);
ТекущийМетод = Метод;
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если ТекущийМетод <> Неопределено Тогда
ПозицияНачалаСтарая = ТекущийМетод.ПозицияСОписанием;
ПозицияКонцаСтарая = ПозицияНачалаСтарая + ТекущийМетод.ДлинаСОписанием;
Иначе
ПозицияНачалаСтарая = СтарыйМодуль.ПозицияПрограммы;
ПозицияКонцаСтарая = СтрДлина(СтарыйМодуль.Текст);
ОпределениеСОписанием = Сред(ТекстМодуля, ПозицияНачалаСтарая);
КонецЕсли;
ЧастьДоМетодаСтарая = Лев(СтарыйМодуль.Текст, ПозицияНачалаСтарая);
ЧастьДоМетодаНовая = Лев(ТекстМодуля, ПозицияНачалаСтарая);
Если Истина
И ЧастьДоМетодаСтарая = ЧастьДоМетодаНовая
И Найти(ОпределениеСОписанием, "Перем ") = 0 // Чтобы при вставке строки с переменной модуля обновлялось корректно
Тогда
ЛиНачальныйДиапазонСовпал = Истина;
Если ТекущийМетод <> Неопределено Тогда
Если ТекущийМетод.ТипЗначения = Неопределено Тогда
МаркерКонца = Символы.ПС + "КонецПроцедуры";
Иначе
МаркерКонца = Символы.ПС + "КонецФункции";
КонецЕсли;
ПозицияКонцаНовая = ирОбщий.СтрНайтиЛкс(ТекстМодуля, МаркерКонца,, ПозицияНачалаСтарая) + СтрДлина(МаркерКонца);
Иначе
ПозицияКонцаНовая = СтрДлина(ТекстМодуля);
Если Ложь
Или ирОбщий.СтрНайтиЛкс(ТекстМодуля, "КонецФункции",, ПозицияНачалаСтарая) > 0
Или ирОбщий.СтрНайтиЛкс(ТекстМодуля, "КонецПроцедуры",, ПозицияНачалаСтарая) > 0
Тогда
// в конец модуля вставлен метод
ПозицияКонцаСтарая = 0;
КонецЕсли;
КонецЕсли;
ЧастьПослеМетодаНовая = Сред(ТекстМодуля, ПозицияКонцаНовая);
ЧастьПослеМетодаСтарая = Сред(СтарыйМодуль.Текст, ПозицияКонцаСтарая);
ЛиКонечныйДиапазонСовпал = ЧастьПослеМетодаНовая = ЧастьПослеМетодаСтарая;
СмещениеКонечногоДиапазона = ПозицияКонцаНовая - ПозицияКонцаСтарая;
КонецЕсли;
КонецЕсли;
НачальнаяПозицияДиапазона = 0;
ПоследняяАннотация = "";
ПоследнееОписание = "";
ПоследнееНачалоОписания = Неопределено;
ПоследнееНачалоАннотации = Неопределено;
ОбластиГруппировки = Новый ДеревоЗначений;
ОбластиГруппировки.Колонки.Добавить("Имя");
ОбластиГруппировки.Колонки.Добавить("Начало");
ОбластиГруппировки.Колонки.Добавить("Конец");
ОбластиКомпиляции = Новый ДеревоЗначений;
ОбластиКомпиляции.Колонки.Добавить("Условие");
ОбластиКомпиляции.Колонки.Добавить("Начало");
ОбластиКомпиляции.Колонки.Добавить("Конец");
ТекущаяОбластьГруппировки = Неопределено; // см. ОбластиГруппировки.Строки[0]
ТекущаяОбластьКомпиляции = Неопределено; // см. ОбластиКомпиляции.Строки[0]
ТекущийАдресГруппировки = "";
ТекущийАдресКомпиляции = "";
Если ЛиНачальныйДиапазонСовпал Тогда
Модуль = СтарыйМодуль;
Если Модуль.ОбластиКомпиляции <> Неопределено Тогда
ОбластиКомпиляции = Модуль.ОбластиКомпиляции;
КонецЕсли;
Если Модуль.ОбластиГруппировки <> Неопределено Тогда
ОбластиГруппировки = Модуль.ОбластиГруппировки;
КонецЕсли;
Методы = Модуль.Методы;
Ошибки = Модуль.Ошибки; // ОбработкаТабличнаяЧасть.ирКлсПолеТекстаПрограммы.ОшибкиМодуля
Если Ошибки <> Неопределено Тогда
УдалитьОшибкиМетода(ТекущийМетод, Ошибки);
КонецЕсли;
НачальнаяПозицияДиапазона = ПозицияНачалаСтарая - 1;
Если ЛиКонечныйДиапазонСовпал Тогда
Если ТекущийМетод <> Неопределено Тогда
ТипыВыраженийТекущегоМетода = ТекущийМетод.ТипыВыражений; //Берем старую таблицу строго тут, т.к. дальше последняя ссылка на нее удаляется
Если ТипЗнч(ТекущийМетод.Параметры) = Тип("ТаблицаЗначений") Тогда
ТаблицаПараметровТекущегоМетода = ТекущийМетод.Параметры.Скопировать(); // Опасно. Копирование сохраняет таблицы типов внутри параметров
КонецЕсли;
КонецЕсли;
СброситьКэшТиповВыраженийМодуля(Модуль, Истина);
Если ТекущийМетод = Неопределено Тогда
Модуль.Программа = ОпределениеСОписанием;
ВхожденияМетодов = Новый Массив;
Иначе
// Сброс кэшей текущего метода
ТекущийМетод.ОписаниеРезультата = Неопределено;
ТекущийМетод.ТелоБезВозвратов = Неопределено;
ТекущийМетод.КлючевыеПараметры = Неопределено;
ТекущийМетод.КэшПоиска = Неопределено;
// Оптимизация для ускорения расчета ожидаемого типа при вводе "=" после имени переменной. Может влиять на свежесть расчета в рекурсивных функциях
Если ТекущаяПозиция < 2 Тогда
ПозицияНачалаСтроки = 0;
Иначе
ПозицияНачалаСтроки = ирОбщий.СтрНайтиЛкс(ТекстМодуля, Символы.ПС, Истина, ТекущаяПозиция - 1);
КонецЕсли;
НачалоСтроки = Сред(ТекстМодуля, ПозицияНачалаСтроки + 1, ТекущаяПозиция - ПозицияНачалаСтроки);
ПозицияПроверкиИзменений = ПозицияНачалаСтроки + Найти(НачалоСтроки, "=");
ПозицияВТелеМетода = ПозицияПроверкиИзменений - ТекущийМетод.ПозицияТела;
ДлинаСверяемойЧасти = ТекущийМетод.ПозицияТела + ПозицияВТелеМетода - ТекущийМетод.ПозицияСОписанием - 1;
Если Сред(ТекстМодуля, ПозицияНачалаСтарая, ДлинаСверяемойЧасти) = Сред(СтарыйМодуль.Текст, ПозицияНачалаСтарая, ДлинаСверяемойЧасти) Тогда
// Начало метода совпало
Если ТипыВыраженийТекущегоМетода <> Неопределено Тогда
УдаляемыеКлючи = Новый Массив;
Для Каждого КлючИЗначение Из ТипыВыраженийТекущегоМетода Цикл
ПозицияВыражения = Число(ирОбщий.ПервыйФрагментЛкс(КлючИЗначение.Ключ, ";"));
Если ПозицияВыражения > ПозицияВТелеМетода Тогда
УдаляемыеКлючи.Добавить(КлючИЗначение.Ключ);
КонецЕсли;
КонецЦикла;
Для Каждого УдаляемыеЭлемент Из УдаляемыеКлючи Цикл
ТипыВыраженийТекущегоМетода.Удалить(УдаляемыеЭлемент);
КонецЦикла;
ТекущийМетод.ТипыВыражений = ТипыВыраженийТекущегоМетода;
КонецЕсли;
Иначе
ТаблицаПараметровТекущегоМетода = Неопределено;
ТекущийМетод.ВызывающиеМодули = Неопределено;
КонецЕсли;
ТекущийМетод.Параметры = ТаблицаПараметровТекущегоМетода;
ОпределениеСОписанием = Сред(ТекстМодуля, ПозицияНачалаСтарая, ТекущийМетод.ДлинаСОписанием + СмещениеКонечногоДиапазона);
ВхожденияМетодов = ПолучитьРазделыМодуля1С(ОпределениеСОписанием).ВхожденияМетодов;
_РежимОтладки = Ложь;
Если _РежимОтладки Тогда // Можно менять на Истина в точке останова, например условием ирОбщий.Пр(_РежимОтладки, 1, 1)
// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
Для ИндексМетодаЦикл = ИндексТекущегоМетода + 1 По Методы.Количество() - 1 Цикл
СтрокаМетода = Методы[ИндексМетодаЦикл];
Если СтрокаМетода.ПозицияСОписанием = 0 Тогда
Продолжить; // Возможно даже Прервать
КонецЕсли;
СтрокаМетода.ПозицияСОписанием = СтрокаМетода.ПозицияСОписанием + СмещениеКонечногоДиапазона;
СтрокаМетода.ПозицияОпределения = СтрокаМетода.ПозицияОпределения + СмещениеКонечногоДиапазона;
СтрокаМетода.ПозицияТела = СтрокаМетода.ПозицияТела + СмещениеКонечногоДиапазона;
Если Ошибки <> Неопределено И СтрокаМетода.ЕстьОшибки = Истина Тогда
Для Каждого СтрокаОшибки Из Ошибки.НайтиСтроки(Новый Структура("Метод", СтрокаМетода.Имя)) Цикл
СтрокаОшибки.Позиция = СтрокаОшибки.Позиция + СмещениеКонечногоДиапазона;
КонецЦикла;
КонецЕсли;
КонецЦикла;
Иначе
// Однострочный код использован для ускорения при разрешенной отладке. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика"
Для ИндексМетодаЦикл = ИндексТекущегоМетода + 1 По Методы.Количество() - 1 Цикл   СтрокаМетода = Методы[ИндексМетодаЦикл];   Если СтрокаМетода.ПозицияСОписанием = 0 Тогда   Продолжить;   КонецЕсли;   СтрокаМетода.ПозицияСОписанием = СтрокаМетода.ПозицияСОписанием + СмещениеКонечногоДиапазона;   СтрокаМетода.ПозицияОпределения = СтрокаМетода.ПозицияОпределения + СмещениеКонечногоДиапазона;   СтрокаМетода.ПозицияТела = СтрокаМетода.ПозицияТела + СмещениеКонечногоДиапазона;   Если Ошибки <> Неопределено И СтрокаМетода.ЕстьОшибки = Истина Тогда   Для Каждого СтрокаОшибки Из Ошибки.НайтиСтроки(Новый Структура("Метод", СтрокаМетода.Имя)) Цикл   СтрокаОшибки.Позиция = СтрокаОшибки.Позиция + СмещениеКонечногоДиапазона;   КонецЦикла;   КонецЕсли;   КонецЦикла;  
КонецЕсли;
Модуль.ПозицияПрограммы = Модуль.ПозицияПрограммы + СмещениеКонечногоДиапазона;
КонецЕсли;
ПрямыеВызовыМетодов = ПрямыеВызовыМетодовМодуля(ИмяМодуля, ПозицияНачалаСтарая);
Если ПрямыеВызовыМетодов <> Неопределено Тогда
ОтложенныйСдвиг = НовыйОтложенныйСдвигВызововСловМодуля();
ОтложенныйСдвиг.ПозицияНачалаСтарая = ПозицияНачалаСтарая;
ОтложенныйСдвиг.ПозицияКонцаСтарая = ПозицияКонцаСтарая;
ОтложенныйСдвиг.СмещениеКонечногоДиапазона = СмещениеКонечногоДиапазона;
ОтложенныйСдвиг.ОпределениеСОписанием = ОпределениеСОписанием;
ПрямыеВызовыМетодов.Вставить("ОтложенныйСдвиг", ОтложенныйСдвиг);
//Модуль.ФлагиКомпиляции.
КонецЕсли;
//ИзмененаТолькоОднаСтрока = СтароеНачалоБлока = НовоеНачалоБлока И СтароеКонецБлока = НовоеКонецБлока;
Иначе
СброситьКэшТиповВыраженийМодуля(Модуль, Истина);
Модуль.ТаблицыСлов.Очистить();
КонечныйДиапазон = Сред(ТекстМодуля, ПозицияНачалаСтарая);
РазделыМодуля = ПолучитьРазделыМодуля1С(КонечныйДиапазон);
Модуль.Программа = РазделыМодуля.Программа;
Модуль.ПозицияПрограммы = ПозицияНачалаСтарая + РазделыМодуля.ПозицияПрограммы - 1;
ВхожденияМетодов = РазделыМодуля.ВхожденияМетодов;
Пока Методы.Количество() > ИндексТекущегоМетода Цикл
Если Ошибки <> Неопределено Тогда
УдалитьОшибкиМетода(Методы[ИндексТекущегоМетода], Ошибки);
КонецЕсли;
Методы.Удалить(ИндексТекущегоМетода);
КонецЦикла;
ТекущийМетод = Неопределено;
Если ИндексТекущегоМетода > 0 Тогда
ПредМетод = Методы[ИндексТекущегоМетода - 1];
ТекущийАдресГруппировки = ПредМетод.АдресГруппировки;
Если ЗначениеЗаполнено(ТекущийАдресГруппировки) Тогда
ТекущаяОбластьГруппировки = ирОбщий.Дерево_НайтиПоПутиСтрокойЛкс(ОбластиГруппировки, "", ТекущийАдресГруппировки);
ирОбщий.УдалитьЧастьДереваПослеСтрокиЛкс(ОбластиГруппировки, ТекущаяОбластьГруппировки);
КонецЕсли;
ТекущийАдресКомпиляции = ПредМетод.АдресКомпиляции;
Если ЗначениеЗаполнено(ТекущийАдресКомпиляции) Тогда
ТекущаяОбластьКомпиляции = ирОбщий.Дерево_НайтиПоПутиСтрокойЛкс(ОбластиКомпиляции, "", ТекущийАдресКомпиляции);
ирОбщий.УдалитьЧастьДереваПослеСтрокиЛкс(ОбластиКомпиляции, ТекущаяОбластьКомпиляции);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Модуль.Текст = ТекстМодуля;
Иначе
ТекущийМетод = Неопределено;
Ошибки = Неопределено;
ЗапретыКомпиляции = Новый Структура;
Модуль = ПолучитьРазделыМодуля1С(ТекстМодуля);
УстановитьПрямыеВызовыМетодовМодуля(ИмяМодуля);
// При изменении нужно увеличивать версию формата Мультиметка91237881041
Модуль.Вставить("СтруктураТипа", СтруктураТипа);
Модуль.Вставить("Имя", ИмяМодуля);
Модуль.Вставить("ФлагиКомпиляции"); // см. НовыеФлагиКомпиляции()
Модуль.Вставить("ЗапретыКомпиляции", ЗапретыКомпиляции);
Модуль.Вставить("ТекущийМетод");
Модуль.Вставить("ТипыВыраженийПрограммы", Новый Соответствие);
Модуль.Вставить("СтарыеТипыПрограммы"); // Соответствие
Модуль.Вставить("КэшПоискаПрограммы", Новый Соответствие);
Модуль.Вставить("ТаблицыСлов", Новый Соответствие);
Шаблоны = ШаблоныДляАнализаВстроенногоЯзыка();
мРегВыражение.IgnoreCase = Истина;
мРегВыражение.Multiline = Ложь;
Переменные = НоваяТаблицаПеременныхМодуля();
мРегВыражение.Pattern = Шаблоны.ОписаниеСтрокиПеременных + "|(" + Шаблоны.БлокКомментариев + ")|(" + Шаблоны.ДирективаПрепроцессора + ")";
Вхождения = мРегВыражение.НайтиВхождения(Модуль.ПеременныеТекст);
Для Каждого Вхождение Из Вхождения Цикл
Если Вхождение.SubMatches(0) <> Неопределено Тогда
ПоследняяАннотацияН = НРег(ПоследняяАннотация);
Сервер = ПустаяСтрока(ПоследняяАннотацияН) Или Найти(ПоследняяАннотацияН, "насервере") > 0;
Клиент = Ложь
Или Найти(ПоследняяАннотацияН, "наклиенте") > 0
Или (Истина
И ПустаяСтрока(ПоследняяАннотацияН)
И Не ЭтоМодульФормыУпр);
ТекстСтроки = Вхождение.SubMatches(0);
ОписаниеСтроки = ОчиститьТекстМодуляОтПрефиксаКомментария(Вхождение.SubMatches(3));
ПозицияСОписанием = Вхождение.FirstIndex + 2;
Если Найти(ТекстСтроки, ",") = 0 Тогда
// Одна переменная в строке
ИмяПеременной = ирОбщий.ПервыйФрагментЛкс(Вхождение.SubMatches(1));
ЭкспортПеременной = ?(Вхождение.SubMatches(2) = Неопределено, Ложь, Истина);
ДобавитьПеременную(Переменные, ИмяПеременной, ЭкспортПеременной, ОписаниеСтроки, ПозицияСОписанием, ПоследняяАннотация, Сервер, Клиент);
Иначе
// Несколько переменных в строке
мРегВыражение2.Pattern = Шаблоны.ОписаниеПеременной + "|\s*(?:;|,)";
Результат2 = мРегВыражение2.НайтиВхождения(ТекстСтроки); // тяжелая операция
Для Каждого Вхождение2 Из Результат2 Цикл
Если Вхождение2.SubMatches(0) <> Неопределено Тогда
ИмяПеременной = Вхождение2.SubMatches(0);
ЭкспортПеременной = ?(Вхождение2.SubMatches(1) = Неопределено, Ложь, Истина);
ДобавитьПеременную(Переменные, ИмяПеременной, ЭкспортПеременной, ОписаниеСтроки, ПозицияСОписанием, ПоследняяАннотация, Сервер, Клиент);
КонецЕсли;
КонецЦикла;
КонецЕсли;
ПоследняяАннотация = "";
ПоследнееНачалоОписания = Неопределено;
ПоследнееНачалоАннотации = Неопределено;
ИначеЕсли Вхождение.SubMatches(4) <> Неопределено Тогда
ПоследнееОписание = Вхождение.SubMatches(4);
ПоследнееНачалоОписания = Вхождение.FirstIndex + 1;
ИначеЕсли Вхождение.SubMatches(5) <> Неопределено Тогда
НоваяАннотация = Вхождение.SubMatches(5);
НоваяАннотация = СокрЛП(НоваяАннотация);
Если Истина
И Лев(НоваяАннотация, 1) = "&"
И (Ложь
// отдаем приоритет директиве компиляции
Или ПустаяСтрока(ПоследняяАннотация)
Или Найти(ПоследняяАннотация, "("))
Тогда
ПоследняяАннотация = НоваяАннотация;
ПоследнееНачалоАннотации = Вхождение.FirstIndex + 1;
ИначеЕсли Лев(НоваяАннотация, 1) = "#" Тогда
Если Найти(НоваяАннотация, "Не ТонкийКлиент") > 0 Тогда
ЗапретыКомпиляции.Вставить("ТонкийКлиент");
КонецЕсли;
ОбработатьАннотациюОбласти(НоваяАннотация, Вхождение.FirstIndex, ОбластиГруппировки, ТекущаяОбластьГруппировки, ТекущийАдресГруппировки, ОбластиКомпиляции, ТекущаяОбластьКомпиляции, ТекущийАдресКомпиляции);
КонецЕсли;
КонецЕсли;
КонецЦикла;
Модуль.Удалить("ПеременныеТекст");
Модуль.Вставить("Переменные", Переменные);
Методы = НоваяТаблицаМетодовМодуля();
ВхожденияМетодов = Модуль.ВхожденияМетодов;
Если СтруктураТипа <> Неопределено Тогда
СтрокаМетода = Методы.Добавить();
СтрокаМетода.Сервер = Истина;
СтрокаМетода.Клиент = Истина;
СтрокаМетода.ЛиЭкспорт = Истина;
СтрокаМетода.ЕстьОшибки = Ложь;
СтрокаМетода.Имя = "<>";
СтрокаМетода.ТипЗначения = "НеизвестныйКонтекст";
ирОбщий.ОбновитьКопиюСвойстваВНижнемРегистреЛкс(СтрокаМетода);
КонецЕсли;
КонецЕсли;
ПорогДлиныМаркераТела = 20;
НачальнаяПозицияДиапазона = НачальнаяПозицияДиапазона + 1;
Если ПоследнееНачалоАннотации <> Неопределено Тогда
Модуль.ПозицияМетодов = ПоследнееНачалоАннотации;
КонецЕсли;
Для Каждого Вхождение Из ВхожденияМетодов Цикл
ПозицияВхождения = Вхождение.FirstIndex + НачальнаяПозицияДиапазона;
Если Модуль.ПозицияМетодов > ПозицияВхождения Тогда
Продолжить;
КонецЕсли;
Заголовок = Вхождение.SubMatches(1);
Если Заголовок <> Неопределено Тогда
СброситьПараметры = Истина;
Если ТекущийМетод <> Неопределено Тогда
СтрокаМетода = ТекущийМетод;
СтароеИмя = СтрокаМетода.Имя;
СброситьПараметры = ТаблицаПараметровТекущегоМетода = Неопределено;
Иначе
СтрокаМетода = Методы.Добавить();
КонецЕсли;
ОписаниеМетода = Вхождение.SubMatches(0);
ДлинаОписания = СтрДлина(ОписаниеМетода);
ОпределениеБезОписания = Сред(Вхождение.Value, ДлинаОписания + 1);
Если Лев(ОпределениеБезОписания, 1) = Символы.ПС Тогда
ОпределениеБезОписания = Сред(ОпределениеБезОписания, 2);
ДлинаОписания = ДлинаОписания + 1;
КонецЕсли;
СтрокаМетода.ПозицияСОписанием = ПозицияВхождения;
СтрокаМетода.ДлинаСОписанием = Вхождение.Length;
СтрокаМетода.ПозицияОпределения = СтрокаМетода.ПозицияСОписанием + ДлинаОписания;
СтрокаМетода.ДлинаОпределения = СтрДлина(ОпределениеБезОписания);
//СтрокаМетода.Индекс = Вхождение.FirstIndex + Смещение;
СтрокаМетода.Имя = Вхождение.SubMatches(3);
СтрокаМетода.НИмя = Нрег(СтрокаМетода.Имя);
ТекстПараметров = Вхождение.SubMatches(4);
ТекстЭкспорта = Вхождение.SubMatches(5);
ЛиЭкспорт = ?(ТекстЭкспорта = Неопределено, Ложь, Истина);
Тело = Вхождение.SubMatches(7);
ПерваяСтрокаТела = ирОбщий.ПервыйФрагментЛкс(Тело, Символы.ПС);
ПозицияЭкспортаВТеле = Найти(ПерваяСтрокаТела, ") Экспорт");
ДлинаЗаголовка = СтрДлина(Заголовок);
Если ПозицияЭкспортаВТеле > 0 Тогда
// Сработал ложный конец секции параметров из-за ")" в значении по умолчанию
ДобавкаЗаголовка = ")" + Лев(ПерваяСтрокаТела, ПозицияЭкспортаВТеле - 1);
ТекстПараметров = ТекстПараметров + ДобавкаЗаголовка;
ДлинаЗаголовка = ДлинаЗаголовка + СтрДлина(ДобавкаЗаголовка);
ЛиЭкспорт = Истина;
КонецЕсли;
СтрокаМетода.ЛиЭкспорт = ЛиЭкспорт;
Тело = Сред(Тело, 2); // Мультиметка38422941 Сдвиг добавлен после вынужденного переноса символа "переноса строки" из заголовка в тело
СтрокаМетода.ДлинаТела = СтрДлина(Тело);
Если СтрокаМетода.ДлинаТела = 0 Тогда
// TODO надо полностью перейти на этот способ
СтрокаМетода.ПозицияТела = СтрокаМетода.ПозицияОпределения + ДлинаЗаголовка;
Иначе
МаркерНачалаТела = Тело;
//Если СтрДлина(МаркерНачалаТела) < ПорогДлиныМаркераТела Тогда
// МаркерНачалаТела = МаркерНачалаТела + Символы.ПС;
//КонецЕсли;
МаркерНачалаТела = Лев(МаркерНачалаТела, ПорогДлиныМаркераТела);
СтрокаМетода.ПозицияТела = СтрокаМетода.ПозицияОпределения + Найти(ОпределениеБезОписания, МаркерНачалаТела) - 2; // Мультиметка38422941
КонецЕсли;
Если ЗначениеЗаполнено(ПоследняяАннотация) И Не ЗначениеЗаполнено(ОписаниеМетода) Тогда
ОписаниеМетода = ПоследнееОписание;
КонецЕсли;
ПоследнееОписание = "";
СтрокаМетода.Описание = ОписаниеМетода;
СтрокаМетода.Аннотация = ПоследняяАннотация;
Если СброситьПараметры Или ТекущаяПозиция < СтрокаМетода.ПозицияОпределения + ДлинаЗаголовка Тогда
СтрокаМетода.Параметры = ТекстПараметров; // Сначала тип "Строка". Позже разбираем их в ПараметрыМетодаМодуля()
КонецЕсли;
СтрокаМетода.ОписаниеРезультата = Вхождение.SubMatches(6);
Если НРег(Вхождение.SubMatches(2)) = "функция" Тогда
СтрокаМетода.ТипЗначения = "??";
Если ПодготовитьОписанияРезультатовМетодов Тогда
// очень небольшая экономия времени
ПодготовитьОписаниеРезультатаМетода(СтрокаМетода);
КонецЕсли;
КонецЕсли;
Если ЗначениеЗаполнено(ПоследняяАннотация) Тогда
// TODO Сделать учет случая 2-х аннотаций
СтрокаМетода.РасширяемыйМетод = ирОбщий.ТекстМеждуМаркерамиЛкс(ПоследняяАннотация, "(""", """)", Ложь);
Если ЗначениеЗаполнено(СтрокаМетода.РасширяемыйМетод) Тогда
ПоследняяАннотация = "";
КонецЕсли;
КонецЕсли;
ПоследняяАннотация = НРег(ПоследняяАннотация);
СтрокаМетода.Сервер = ПустаяСтрока(ПоследняяАннотация) Или Найти(ПоследняяАннотация, "насервере") > 0;
СтрокаМетода.Клиент = Ложь
Или Найти(ПоследняяАннотация, "наклиенте") > 0
Или (Истина
И ПустаяСтрока(ПоследняяАннотация)
И Не ЭтоМодульФормыУпр);
СтрокаМетода.БезКонтекста = Найти(ПоследняяАннотация, "безконтекста") > 0;
СтрокаМетода.ЛиАсинх = НРег(Лев(Заголовок, 1)) = "а";
СтрокаМетода.АдресГруппировки = ТекущийАдресГруппировки;
СтрокаМетода.АдресКомпиляции = ТекущийАдресКомпиляции;
Если СтарыйМодуль <> Неопределено Тогда
//СтарыйМетод = СтарыйМодуль.Методы.Найти(СтрокаМетода.НИмя, "НИмя");
//Если Истина
// //И СтарыйМетод.Вычислено
// И ТипЗнч(СтарыйМетод.Параметры) <> Тип("Строка")
// И Сред(СтарыйМодуль.Текст, СтарыйМетод.ПозицияСОписанием, СтарыйМетод.ДлинаСОписанием) = Вхождение.Value
// И СтарыйМетод.Аннотация = СтрокаМетода.Аннотация
//Тогда
// СтрокаМетода.Параметры = СтарыйМетод.Параметры;
// СтрокаМетода.Параметры.ЗаполнитьЗначения(, "ТаблицаТипов");
// СтрокаМетода.ОписаниеРезультата = СтарыйМетод.ОписаниеРезультата;
// СтрокаМетода.ТипЗначения = СтарыйМетод.ТипЗначения;
//КонецЕсли;
КонецЕсли;
Если ТекущийМетод <> Неопределено И СтрокаМетода.Имя <> СтароеИмя Тогда
Модуль.ТаблицыСлов.Очистить();
КонецЕсли;
ПозицияНачалаМетода = ПозицияВхождения;
Если ПоследнееНачалоОписания <> Неопределено Тогда
ПозицияНачалаМетода = Мин(ПозицияНачалаМетода, ПоследнееНачалоОписания);
КонецЕсли;
Если ПоследнееНачалоАннотации <> Неопределено Тогда
ПозицияНачалаМетода = Мин(ПозицияНачалаМетода, ПоследнееНачалоАннотации);
КонецЕсли;
СмещениеНазад = ПозицияВхождения - ПозицияНачалаМетода;
Если СмещениеНазад > 0 Тогда
СтрокаМетода.ПозицияСОписанием = СтрокаМетода.ПозицияСОписанием - СмещениеНазад;
СтрокаМетода.ДлинаСОписанием = СтрокаМетода.ДлинаСОписанием + СмещениеНазад;
КонецЕсли;
ПоследняяАннотация = "";
ПоследнееНачалоОписания = Неопределено;
ПоследнееНачалоАннотации = Неопределено;
ИначеЕсли Вхождение.SubMatches(8) <> Неопределено Тогда
Если Модуль.ПозицияМетодов > ПозицияВхождения Тогда
Продолжить;
КонецЕсли;
ПоследнееОписание = Вхождение.SubMatches(8);
ПоследнееНачалоОписания = Вхождение.FirstIndex + НачальнаяПозицияДиапазона;
ИначеЕсли Вхождение.SubMatches(9) <> Неопределено Тогда
НоваяАннотация = Вхождение.SubMatches(9);
СмещениеПозиции = 0;
Если СтрЧислоСтрок(НоваяАннотация) = 3 Тогда
ПоследнееОписание = "";
СмещениеПозиции = ирОбщий.ДлинаОтступаЛкс(НоваяАннотация, Ложь) - 1;
КонецЕсли;
НоваяАннотация = СокрЛП(НоваяАннотация);
Если Истина
И Лев(НоваяАннотация, 1) = "&"
И (Ложь
// отдаем приоритет директиве компиляции
Или ПустаяСтрока(ПоследняяАннотация)
Или Найти(ПоследняяАннотация, "("))
Тогда
ПоследняяАннотация = НоваяАннотация;
ПоследнееНачалоАннотации = Вхождение.FirstIndex + НачальнаяПозицияДиапазона + СмещениеПозиции;
КонецЕсли;
Если Лев(НоваяАннотация, 1) = "#" Тогда
// TODO Сложность - обновление с середины модуля
ПозицияАннотации = Вхождение.FirstIndex + НачальнаяПозицияДиапазона + СмещениеПозиции;
ОбработатьАннотациюОбласти(НоваяАннотация, ПозицияАннотации, ОбластиГруппировки, ТекущаяОбластьГруппировки, ТекущийАдресГруппировки, ОбластиКомпиляции, ТекущаяОбластьКомпиляции, ТекущийАдресКомпиляции);
КонецЕсли;
КонецЕсли;
КонецЦикла;
Модуль.Удалить("МетодыТекст");
Модуль.Удалить("ВхожденияМетодов");
Если ОбластиКомпиляции.Строки.Количество() = 0 Тогда
ОбластиКомпиляции = Неопределено;
КонецЕсли;
Если ОбластиГруппировки.Строки.Количество() = 0 Тогда
ОбластиГруппировки = Неопределено;
КонецЕсли;
Модуль.Вставить("ОбластиКомпиляции", ОбластиКомпиляции);
Модуль.Вставить("ОбластиГруппировки", ОбластиГруппировки);
// Мультиметка723368140
Модуль.Вставить("Методы", Методы);
Модуль.Вставить("Текст", ТекстМодуля);
Модуль.Вставить("Ошибки", Ошибки);
Модуль.Вставить("ТекстПоискаОпределенияСловМодуля");
ирОбщий.ДобавитьИндексВТаблицуЛкс(Методы, "ЛиЭкспорт");
ирОбщий.ДобавитьИндексВТаблицуЛкс(Методы, "ЛиЭкспорт, НИмя");
ирОбщий.ДобавитьИндексВТаблицуЛкс(Методы, "НИмя");
Если РазрешитьЕдиныйПустойМодуль Тогда
Модуль.Имя = "<Пустой>";
мПустойМодуль = Модуль;
КонецЕсли;
Возврат Модуль;
КонецФункции
Процедура ОбработатьАннотациюОбласти(Знач НоваяАннотация, Знач ПозицияАннотации, Знач ОбластиГруппировки, ТекущаяОбластьГруппировки, ТекущийАдресГруппировки, Знач ОбластиКомпиляции, ТекущаяОбластьКомпиляции, ТекущийАдресКомпиляции)
НоваяАннотация = СокрЛ(Сред(НоваяАннотация, 2));
Если Найти(НоваяАннотация, "Область ") = 1 Тогда
Если ТекущаяОбластьГруппировки = Неопределено Тогда
ТекущаяОбластьГруппировки = ОбластиГруппировки;
КонецЕсли;
ТекущийАдресГруппировки = ?(ПустаяСтрока(ТекущийАдресГруппировки), "", ТекущийАдресГруппировки + ".") + ТекущаяОбластьГруппировки.Строки.Количество();
ТекущаяОбластьГруппировки = ТекущаяОбластьГруппировки.Строки.Добавить();
ТекущаяОбластьГруппировки.Имя = ирОбщий.ПоследнийФрагментЛкс(НоваяАннотация, " ");
ТекущаяОбластьГруппировки.Начало = ПозицияАннотации;
ИначеЕсли Найти(НоваяАннотация, "КонецОбласти") = 1 Тогда
Если Истина
И ТекущаяОбластьГруппировки <> Неопределено
И ТекущаяОбластьГруппировки <> ОбластиГруппировки
Тогда
ТекущаяОбластьГруппировки.Конец = ПозицияАннотации;
ТекущаяОбластьГруппировки = ТекущаяОбластьГруппировки.Родитель;
ТекущийАдресГруппировки = ирОбщий.СтрокаБезПоследнегоФрагментаЛкс(ТекущийАдресГруппировки);
КонецЕсли;
ИначеЕсли Найти(НоваяАннотация, "Если ") = 1 Тогда
Если ТекущаяОбластьКомпиляции = Неопределено Тогда
ТекущаяОбластьКомпиляции = ОбластиКомпиляции;
КонецЕсли;
ТекущийАдресКомпиляции = ?(ПустаяСтрока(ТекущийАдресКомпиляции), "", ТекущийАдресКомпиляции + ".") + ТекущаяОбластьКомпиляции.Строки.Количество();
ТекущаяОбластьКомпиляции = ТекущаяОбластьКомпиляции.Строки.Добавить();
ТекущаяОбластьКомпиляции.Условие = ирОбщий.ТекстМеждуМаркерамиЛкс(НоваяАннотация, " ", " Тогда", Ложь);
ТекущаяОбластьКомпиляции.Начало = ПозицияАннотации;
ИначеЕсли Найти(НоваяАннотация, "КонецЕсли") = 1 Тогда
Если Истина
И ТекущаяОбластьКомпиляции <> Неопределено
И ТекущаяОбластьКомпиляции <> ОбластиКомпиляции
Тогда
ТекущаяОбластьКомпиляции.Конец = ПозицияАннотации;
ТекущаяОбластьКомпиляции = ирОбщий.РодительСтрокиДереваЛкс(ТекущаяОбластьКомпиляции, ОбластиКомпиляции);
ТекущийАдресКомпиляции = ирОбщий.СтрокаБезПоследнегоФрагментаЛкс(ТекущийАдресКомпиляции);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
// Параметры:
// ИмяМодуля - Строка -
// Возвращаемое значение:
// см. НовыйИндексПоискаВызововСловаВМодуле -
Функция ПрямыеВызовыМетодовМодуля(Знач ИмяМодуля, Знач ПозицияНачалаСтарая = Неопределено) Экспорт
ПрямыеВызовыМетодов = мПрямыеВызовыМетодов[НРег(ИмяМодуля)];
Если ПрямыеВызовыМетодов <> Неопределено Тогда
ВыполнитьОтложенноеОбновлениеВызововСловМодуля(ИмяМодуля, ПозицияНачалаСтарая);
КонецЕсли;
Возврат ПрямыеВызовыМетодов;
КонецФункции
//.
// Параметры:
// ИмяМодуля - Строка -
// ПрямыеВызовыМетодов - см. НовыйИндексПоискаВызововСловаВМодуле -
Процедура УстановитьПрямыеВызовыМетодовМодуля(Знач ИмяМодуля, Знач ПрямыеВызовыМетодов = Неопределено) Экспорт
мПрямыеВызовыМетодов[НРег(ИмяМодуля)] = ПрямыеВызовыМетодов;
КонецПроцедуры
//.
// Возвращаемое значение:
// ТаблицаЗначений -
Функция НоваяТаблицаПеременныхМодуля() Экспорт
// При изменении нужно увеличивать версию формата Мультиметка91237881041
Переменные = Новый ТаблицаЗначений;
Переменные.Колонки.Добавить("Имя", Новый ОписаниеТипов("Строка"));
Переменные.Колонки.Добавить("НИмя", Новый ОписаниеТипов("Строка"));
Переменные.Колонки.Добавить("ЛиЭкспорт", Новый ОписаниеТипов("Булево"));
Переменные.Колонки.Добавить("Аннотация", Новый ОписаниеТипов("Строка"));
Переменные.Колонки.Добавить("Сервер", Новый ОписаниеТипов("Булево"));
Переменные.Колонки.Добавить("Клиент", Новый ОписаниеТипов("Булево"));
Переменные.Колонки.Добавить("Вычислено", Новый ОписаниеТипов("Булево")); // вычислено по коду
Переменные.Колонки.Добавить("ПозицияСОписанием", Новый ОписаниеТипов("Число")); // Начиная с 1.
Переменные.Колонки.Добавить("ПозицияОпределения", Новый ОписаниеТипов("Число")); // Начиная с 1.
Переменные.Колонки.Добавить("ТипЗначения", Новый ОписаниеТипов("Строка"));
Переменные.Колонки.Добавить("Описание", Новый ОписаниеТипов("Строка"));
Переменные.Колонки.Добавить("ИмяМодуля", Новый ОписаниеТипов("Строка"));
Переменные.Колонки.Добавить("ТаблицаТипов"); // см. НоваяТаблицаТипов()
Переменные.Индексы.Добавить("НИмя");
Возврат Переменные;
КонецФункции
Функция ЛиИмяМодуляФормы(Знач Имя) Экспорт
Возврат ирОбщий.СтрКончаетсяНаЛкс(Имя, ".Форма.Модуль");
КонецФункции
Функция ЛиПолноеИмяМакета(Знач ПолноеИмя) Экспорт
Результат = Ложь
Или ирОбщий.СтрНайтиЛкс(ПолноеИмя, ".Макет.") > 0
Или ирОбщий.СтрНачинаетсяСЛкс(ПолноеИмя, "ОбщийМакет.") > 0;
Возврат Результат;
КонецФункции
Функция ЛиПолноеИмяФормы(Знач ПолноеИмя) Экспорт
Результат = Ложь
Или ирОбщий.СтрНайтиЛкс(ПолноеИмя, ".Форма") > 0 // Важно учесть ролевые имена форм
Или ирОбщий.СтрНачинаетсяСЛкс(ПолноеИмя, "ОбщаяФорма.") > 0;
Возврат Результат;
КонецФункции
Процедура ВыполнитьОтложенноеОбновлениеВызововСловМодуля(Знач ИмяМодуля, Знач ПозицияНачалаСтарая = Неопределено) Экспорт
ПрямыеВызовыМетодов = мПрямыеВызовыМетодов[НРег(ИмяМодуля)]; // см. НовыйИндексПоискаВызововСловаВМодуле()
Если Ложь
Или ПрямыеВызовыМетодов = Неопределено
Или Не ПрямыеВызовыМетодов.Свойство("ОтложенныйСдвиг")
Тогда
Возврат;
КонецЕсли;
ВыполнитьОтложенныйСдвигВызововСловМодуля(ПрямыеВызовыМетодов);
ОтложенныйСдвиг = ПрямыеВызовыМетодов.ОтложенныйСдвиг; // см. НовыйОтложенныйСдвигВызововСловМодуля()
Если ОтложенныйСдвиг.ПозицияНачалаСтарая = ПозицияНачалаСтарая Тогда
Возврат;
КонецЕсли;
ПрямыеВызовыМетодовВМетоде = НовыйИндексПоискаВызововСловаВМодуле(,, ПрямыеВызовыМетодов.Оповещения <> Неопределено);
ПрямыеВызовыМетодовВМетоде.СтруктураСлов = ПрямыеВызовыМетодов.СтруктураСлов;
ирКэш.ПолеТекстаПрограммы().ЗаполнитьИндексПоискаВызововМетодовВМодуле(ПрямыеВызовыМетодовВМетоде, ОтложенныйСдвиг.ОпределениеСОписанием, ОтложенныйСдвиг.ПозицияНачалаСтарая);
НачальныйИндекс = ОтложенныйСдвиг.НачальныеИндексы[ПрямыеВызовыМетодов.Вызовы];
ирОбщий.ЗагрузитьВТаблицуЗначенийЛкс(ПрямыеВызовыМетодовВМетоде.Вызовы, ПрямыеВызовыМетодов.Вызовы,,,,, НачальныйИндекс);
Если ПрямыеВызовыМетодов.Оповещения <> Неопределено Тогда
НачальныйИндекс = ОтложенныйСдвиг.НачальныеИндексы[ПрямыеВызовыМетодов.Оповещения];
ирОбщий.ЗагрузитьВТаблицуЗначенийЛкс(ПрямыеВызовыМетодовВМетоде.Оповещения, ПрямыеВызовыМетодов.Оповещения,,,,, НачальныйИндекс);
КонецЕсли;
ПрямыеВызовыМетодов.Удалить("ОтложенныйСдвиг");
КонецПроцедуры
Процедура ВыполнитьОтложенныйСдвигВызововСловМодуля(ПрямыеВызовыМетодов) Экспорт
ОтложенныйСдвиг = ПрямыеВызовыМетодов.ОтложенныйСдвиг; // см. НовыйОтложенныйСдвигВызововСловМодуля()
СдвинутьПозицииВТаблицеВызовов(ПрямыеВызовыМетодов.Вызовы, ОтложенныйСдвиг);
Если ПрямыеВызовыМетодов.Оповещения <> Неопределено Тогда
СдвинутьПозицииВТаблицеВызовов(ПрямыеВызовыМетодов.Оповещения, ОтложенныйСдвиг);
КонецЕсли;
КонецПроцедуры
//.
// Возвращаемое значение:
// Структура -
Функция НовыйОтложенныйСдвигВызововСловМодуля() Экспорт
ОтложенныйСдвиг = Новый Структура;
ОтложенныйСдвиг.Вставить("ПозицияНачалаСтарая", 0);
ОтложенныйСдвиг.Вставить("ПозицияКонцаСтарая", 0);
ОтложенныйСдвиг.Вставить("СмещениеКонечногоДиапазона", 0);
ОтложенныйСдвиг.Вставить("ОпределениеСОписанием", "");
ОтложенныйСдвиг.Вставить("НачальныеИндексы", Новый Соответствие);
Возврат ОтложенныйСдвиг;
КонецФункции
//.
// Параметры:
// ТаблицаВызовов - ТаблицаЗначений -
// ПозицияКонцаСтарая - Число -
// ПозицияНачалаСтарая - Число(10,0) -
// СмещениеКонечногоДиапазона - Число, Неопределено -
Процедура СдвинутьПозицииВТаблицеВызовов(Знач ТаблицаВызовов, Знач ОтложенныйСдвиг) Экспорт
ПозицияНачалаСтарая = ОтложенныйСдвиг.ПозицияНачалаСтарая;
ПозицияКонцаСтарая = ОтложенныйСдвиг.ПозицияКонцаСтарая;
СмещениеКонечногоДиапазона = ОтложенныйСдвиг.СмещениеКонечногоДиапазона;
ОпределениеСОписанием = ОтложенныйСдвиг.ОпределениеСОписанием;
_РежимОтладки = Ложь;
Если _РежимОтладки Тогда // Можно менять на Истина в точке останова, например условием ирОбщий.Пр(_РежимОтладки, 1, 1)
// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
Для ИндексВызова = -ТаблицаВызовов.Количество()+1 По 0 Цикл
СтрокаВызова = ТаблицаВызовов[-ИндексВызова];
Если СтрокаВызова.ПозицияВхождения < ПозицияНачалаСтарая Тогда
Прервать;
КонецЕсли;
Если СтрокаВызова.ПозицияВхождения < ПозицияКонцаСтарая Тогда
ТаблицаВызовов.Удалить(СтрокаВызова);
Продолжить;
КонецЕсли;
СтрокаВызова.ПозицияВхождения = СтрокаВызова.ПозицияВхождения + СмещениеКонечногоДиапазона;
КонецЦикла;
Иначе
// Однострочный код использован для ускорения при разрешенной отладке. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика"
Для ИндексВызова = -ТаблицаВызовов.Количество()+1 По 0 Цикл   СтрокаВызова = ТаблицаВызовов[-ИндексВызова];   Если СтрокаВызова.ПозицияВхождения < ПозицияНачалаСтарая Тогда   Прервать;   КонецЕсли;   Если СтрокаВызова.ПозицияВхождения < ПозицияКонцаСтарая Тогда   ТаблицаВызовов.Удалить(СтрокаВызова);   Продолжить;   КонецЕсли;   СтрокаВызова.ПозицияВхождения = СтрокаВызова.ПозицияВхождения + СмещениеКонечногоДиапазона;   КонецЦикла;  
КонецЕсли;
ОтложенныйСдвиг.НачальныеИндексы[ТаблицаВызовов] = -ИндексВызова + 1;
КонецПроцедуры
//.
// Параметры:
// СтрокаМетода - СтрокаТаблицыЗначений -
// Ошибки - ОбработкаТабличнаяЧасть.ирКлсПолеТекстаПрограммы.ОшибкиМодуля -
Процедура УдалитьОшибкиМетода(Знач СтрокаМетода, Знач Ошибки) Экспорт
Если СтрокаМетода = Неопределено Тогда
ИмяМетода = ИмяМетодаИнициация();
Иначе
БылиОшибки = СтрокаМетода.ЕстьОшибки = Истина;
СтрокаМетода.ЕстьОшибки = Неопределено;
Если Не БылиОшибки Тогда
Возврат;
КонецЕсли;
ИмяМетода = СтрокаМетода.Имя;
КонецЕсли;
Для Каждого СтрокаОшибки Из Ошибки.НайтиСтроки(Новый Структура("Метод", ИмяМетода)) Цикл
Ошибки.Удалить(СтрокаОшибки);
КонецЦикла;
КонецПроцедуры
// Функция - Новая таблица методов модуля
//
// Возвращаемое значение:
// ТаблицаЗначений
//
Функция НоваяТаблицаМетодовМодуля() Экспорт
// При добавлении колонок желательно увеличивать версию формата Мультиметка91237881041
Методы = Новый ТаблицаЗначений;
Методы.Колонки.Добавить("Имя", Новый ОписаниеТипов("Строка"));
//Методы.Колонки.Добавить("Тип", Новый ОписаниеТипов("Строка"));
//Методы.Колонки.Добавить("Индекс", Новый ОписаниеТипов("Число"));
Методы.Колонки.Добавить("НИмя", Новый ОписаниеТипов("Строка"));
Методы.Колонки.Добавить("Аннотация", Новый ОписаниеТипов("Строка"));
Методы.Колонки.Добавить("РасширяемыйМетод", Новый ОписаниеТипов("Строка"));
Методы.Колонки.Добавить("Параметры"); // Строка, см. НоваяТаблицаПараметровМетодаМодуля
Методы.Колонки.Добавить("МинЧислоПараметров"); // Число
Методы.Колонки.Добавить("ПозицияСОписанием", Новый ОписаниеТипов("Число")); // Начиная с 1
Методы.Колонки.Добавить("ДлинаСОписанием", Новый ОписаниеТипов("Число"));
Методы.Колонки.Добавить("ПозицияОпределения", Новый ОписаниеТипов("Число")); // Начиная с 1. Может содержать непечатное смещение от начала строки
Методы.Колонки.Добавить("ДлинаОпределения", Новый ОписаниеТипов("Число"));
Методы.Колонки.Добавить("ПозицияТела", Новый ОписаниеТипов("Число")); // Начиная с 1
Методы.Колонки.Добавить("ДлинаТела", Новый ОписаниеТипов("Число"));
Методы.Колонки.Добавить("ТелоБезВозвратов");
Методы.Колонки.Добавить("Описание", Новый ОписаниеТипов("Строка"));
Методы.Колонки.Добавить("ОписаниеРезультата");
Методы.Колонки.Добавить("ПозицияОписанияРезультата", Новый ОписаниеТипов("Число")); // Начиная с 1
Методы.Колонки.Добавить("ТипЗначения"); // - Используем значение Неопределено
Методы.Колонки.Добавить("ТаблицаТипов"); // см. НоваяТаблицаТипов, Неопределено
Методы.Колонки.Добавить("Сервер", Новый ОписаниеТипов("Булево"));
Методы.Колонки.Добавить("Клиент", Новый ОписаниеТипов("Булево"));
Методы.Колонки.Добавить("БезКонтекста", Новый ОписаниеТипов("Булево"));
Методы.Колонки.Добавить("ЛиЭкспорт", Новый ОписаниеТипов("Булево"));
Методы.Колонки.Добавить("ЛиАсинх", Новый ОписаниеТипов("Булево"));
Методы.Колонки.Добавить("Вычислено", Новый ОписаниеТипов("Булево")); // тип значения вычислен по коду
Методы.Колонки.Добавить("ЕстьОшибки"); // Булево
Методы.Колонки.Добавить("ИмяМодуля", Новый ОписаниеТипов("Строка"));
Методы.Колонки.Добавить("КлючевыеПараметры"); // Структура, Неопределено
Методы.Колонки.Добавить("КэшПоиска"); // Соответствие, Неопределено
Методы.Колонки.Добавить("ТипыВыражений"); // Соответствие, Неопределено
Методы.Колонки.Добавить("СтарыеТипы"); // Соответствие, Неопределено
Методы.Колонки.Добавить("ВызывающиеМодули"); // Массив, Неопределено
Методы.Колонки.Добавить("АдресГруппировки"); // Строка
Методы.Колонки.Добавить("АдресКомпиляции"); // Строка
Возврат Методы;
КонецФункции
Функция ПрефиксВременногоКомментирования() Экспорт
Возврат "СлужебноИР ";
КонецФункции
Функция ЗамаскироватьДирективыПрепроцессора(Знач Текст, Знач ВнутриТекстовогоЛитерала = Истина) Экспорт
Префикс = "//" + ПрефиксВременногоКомментирования();
НачалоСтрокиЗамены = "";
НачалоИскомойСтроки = "#";
Если ВнутриТекстовогоЛитерала Тогда
НачалоСтрокиЗамены = "|";
НачалоИскомойСтроки = "#|//"; // - Обычные комментарии маскируем, чтобы отличать их от вложенных в текст литерала
КонецЕсли;
ВхожденияБлоков = ирОбщий.НайтиРегВыражениеЛкс(Текст, шПустоеНачалоСтроки + "#Удаление\s[\S\s]*?" + шПустоеНачалоСтроки + "#КонецУдаления",, Ложь);
Для Каждого Вхождение Из ВхожденияБлоков Цикл
НовыйФрагмент = СтрЗаменить(Вхождение.ТекстВхождения, Символы.ПС, Символы.ПС + НачалоСтрокиЗамены + Префикс);
Текст = СтрЗаменить(Текст, Вхождение.ТекстВхождения, НовыйФрагмент);
КонецЦикла;
ВхожденияБлоков = ирОбщий.НайтиРегВыражениеЛкс(Текст, шПустоеНачалоСтроки + "#Если Сервер И Не Сервер Тогда\s[\S\s]*?" + шПустоеНачалоСтроки + "#КонецЕсли",, Ложь);
Для Каждого Вхождение Из ВхожденияБлоков Цикл
НовыйФрагмент = СтрЗаменить(Вхождение.ТекстВхождения, Символы.ПС, Символы.ПС + НачалоСтрокиЗамены + Префикс);
Текст = СтрЗаменить(Текст, Вхождение.ТекстВхождения, НовыйФрагмент);
КонецЦикла;
Текст = ирОбщий.ЗаменитьРегВыражениеЛкс(Текст, "(\n|^)(\t| )*(" + НачалоИскомойСтроки + ")", "$1" + НачалоСтрокиЗамены + "$2" + Префикс + "$3", Ложь);
Возврат Текст;
КонецФункции
Функция РазмаскироватьДирективыПрепроцессора(Знач Текст) Экспорт
Текст = СтрЗаменить(Текст, Символы.ПС + "|//" + ПрефиксВременногоКомментирования(), Символы.ПС);
Возврат Текст;
КонецФункции
//.
// Параметры:
// Переменные - ТаблицаЗначений -
// ИмяПеременной - ? -
// ЭкспортПеременной - ? -
// ОписаниеСтроки - Строка -
// ПозицияСОписанием - ? -
Процедура ДобавитьПеременную(Переменные, ИмяПеременной, ЭкспортПеременной, Знач ОписаниеСтроки, Знач ПозицияСОписанием, Знач ПоследняяАннотация, Знач Сервер, Знач Клиент) Экспорт
СтрокаПеременной = Переменные.Добавить();
СтрокаПеременной.Имя = ИмяПеременной;
СтрокаПеременной.НИмя = Нрег(СтрокаПеременной.Имя);
СтрокаПеременной.ЛиЭкспорт = ЭкспортПеременной;
СтрокаПеременной.ПозицияСОписанием = ПозицияСОписанием;
СтрокаПеременной.ПозицияОпределения = ПозицияСОписанием;
СтрокаПеременной.Описание = ОписаниеСтроки;
СтрокаПеременной.Аннотация = ПоследняяАннотация;
СтрокаПеременной.Сервер = Сервер;
СтрокаПеременной.Клиент = Клиент;
КонецПроцедуры
//.
// Параметры:
// СтрокаМетода - см. НоваяТаблицаМетодовМодуля()[0] -
// выхБылиИзменения - Булево -
// Возвращаемое значение:
// ТаблицаЗначений, Неопределено -
Функция ПараметрыМетодаМодуля(Знач СтрокаМетода, выхБылиИзменения = Ложь, Знач ДляКонструктора = Ложь) Экспорт
Если СтрокаМетода = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
Результат = СтрокаМетода.Параметры;
Если ТипЗнч(Результат) = Тип("Строка") Тогда
выхБылиИзменения = Истина;
МинЧислоПараметров = 0;
СтрокаМетода.Описание = ОчиститьТекстМодуляОтПрефиксаКомментария(СтрокаМетода.Описание);
Если Не ДляКонструктора И Не ЗначениеЗаполнено(СтрокаМетода.Параметры) Тогда
Результат = Неопределено;
Иначе
Шаблоны = ШаблоныДляАнализаВстроенногоЯзыка();
мРегВыражение2.Global = Истина;
мРегВыражение2.Pattern = Шаблоны.ПараметрыМетода;
РезультатПараметров = мРегВыражение2.НайтиВхождения(СтрокаМетода.Параметры);
Если Не ДляКонструктора И РезультатПараметров.Количество() = 0 Тогда
Результат = Неопределено;
Иначе
Результат = НоваяТаблицаПараметровМетодаМодуля();
Если ДляКонструктора Тогда
Результат.Колонки.Добавить("Виртуальный", Новый ОписаниеТипов("Булево"));
КонецЕсли;
Для Каждого ВхождениеПараметра Из РезультатПараметров Цикл
СтрокаПараметра = Результат.Добавить();
СтрокаПараметра.Имя = ВхождениеПараметра.SubMatches(1);
СтрокаПараметра.НИмя = НРег(СтрокаПараметра.Имя);
СтрокаПараметра.Знач = ?(ВхождениеПараметра.SubMatches(0) = Неопределено, Ложь, Истина);
СтрокаПараметра.Значение = СокрЛП(ВхождениеПараметра.SubMatches(2));
Если СтрокаПараметра.Значение = "" Тогда
МинЧислоПараметров = Результат.Количество();
КонецЕсли;
ОписаниеПараметра = ОчиститьТекстМодуляОтПрефиксаКомментария(ВхождениеПараметра.SubMatches(4));
ПозицияТире = Найти(ОписаниеПараметра, "-");
Если ПозицияТире > 0 Тогда
СтрокаПараметра.ТипЗначения = Лев(ОписаниеПараметра, ПозицияТире - 1);
СтрокаПараметра.Описание = Сред(ОписаниеПараметра, ПозицияТире + 1);
Иначе
СтрокаПараметра.ТипЗначения = ОписаниеПараметра;
КонецЕсли;
КонецЦикла;
Если ЗначениеЗаполнено(СтрокаМетода.Описание) Тогда
ОписанияПараметровЗагружены = Ложь;
Если Найти(СтрокаМетода.Описание, ":") = 0 Тогда
СсылкаНаОписание = ирОбщий.ПоследнийФрагментЛкс(СокрП(СтрокаМетода.Описание), Символы.ПС);
Если УдалитьПрефиксИзТекстаТипов(СсылкаНаОписание) Тогда
// Ссылка на описание друго метода. Параметры сопоставляются по позиции.
//СтрокаМетода.Описание = СтрокаБазовогоМетода.Описание;
Методы = Неопределено;
Если Найти(СсылкаНаОписание, ".") = 0 Тогда
Методы = СтрокаМетода.Владелец();
Иначе
Если Прав(СсылкаНаОписание, 1) = "." Тогда
СсылкаНаОписание = СокрП(ирОбщий.СтрокаБезКонцаЛкс(СсылкаНаОписание));
КонецЕсли;
КраткоеИмяМодуля = ирОбщий.СтрокаБезПоследнегоФрагментаЛкс(СсылкаНаОписание);
Анализатор = ирКэш.ПолеТекстаМодуляБезСтруктурыТипаЛкс("");
ТаблицаТиповМодуля = Анализатор.ВычислитьТипЗначенияВыражения(КраткоеИмяМодуля,,,,,, Ложь);
Если ТаблицаТиповМодуля.Количество() > 0 Тогда
Модуль = ПодготовитьМодульМетаданных(ТаблицаТиповМодуля[0]);
Если Модуль <> Неопределено Тогда
Методы = Модуль.Методы;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Методы <> Неопределено Тогда
ИмяБазовогоМетода = ирОбщий.ПервыйФрагментЛкс(ирОбщий.ПоследнийФрагментЛкс(СсылкаНаОписание), "(");
СтрокаБазовогоМетода = Методы.Найти(НРег(ИмяБазовогоМетода), "НИмя");
Если СтрокаБазовогоМетода <> Неопределено Тогда
ПараметрыБазовогоМетода = ПараметрыМетодаМодуля(СтрокаБазовогоМетода);
Если ПараметрыБазовогоМетода <> Неопределено Тогда
Для Индекс = 0 По Мин(ПараметрыБазовогоМетода.Количество(), Результат.Количество()) - 1 Цикл
Результат[Индекс].Описание = ПараметрыБазовогоМетода[Индекс].Описание;
Результат[Индекс].ТипЗначения = ПараметрыБазовогоМетода[Индекс].ТипЗначения;
КонецЦикла;
КонецЕсли;
СтрокаМетода.ВызывающиеМодули = СтрокаБазовогоМетода.ВызывающиеМодули;
ОписанияПараметровЗагружены = Истина;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Не ОписанияПараметровЗагружены Тогда
ОписаниеПараметров = ирОбщий.ТекстМеждуМаркерамиЛкс(СтрокаМетода.Описание, ЗаголовокРазделаПараметры(), ЗаголовокРазделаВозвращаемоеЗначение(), Ложь,,, Истина);
ВхожденияОписаний = ПараметрыМетодаИзКомментария(ОписаниеПараметров, Шаблоны);
ПозицияОписания = СтрокаМетода.ПозицияСОписанием - СтрокаМетода.ПозицияТела;
Для каждого ВхождениеОписания Из ВхожденияОписаний Цикл
СтрокаПараметра = Результат.Найти(НРег(ВхождениеОписания.Имя));
Если ДляКонструктора И СтрокаПараметра = Неопределено Тогда
СтрокаПараметра = Результат.Добавить();
СтрокаПараметра.Имя = ВхождениеОписания.Имя;
СтрокаПараметра.НИмя = НРег(СтрокаПараметра.Имя);
СтрокаПараметра.Виртуальный = Истина;
КонецЕсли;
Если СтрокаПараметра <> Неопределено Тогда
СтрокаПараметра.Описание = ВхождениеОписания.Описание;
СтрокаПараметра.ПозицияСОписанием = ПозицияОписания + ВхождениеОписания.ПозицияВхождения
+ СтрДлина(ВхождениеОписания.Разделитель1) + СтрДлина(ВхождениеОписания.Имя) + СтрДлина(ВхождениеОписания.Разделитель2);
СтрокаПараметра.ТипЗначения = ВхождениеОписания.ТипЗначения;
Если Истина
//И Не ЗначениеЗаполнено(СтрокаПараметра.ТипЗначения)
И ВхождениеОписания.ТипЗначения = Неопределено
//И Не ДляКонструктора
Тогда
СтрокаПараметра.ТипЗначения = СокрЛП(ГрязныйТипИзОписанияПараметра(СтрокаПараметра.Описание));
КонецЕсли;
ЧастьСоВторойСтроки = ирОбщий.СтрокаБезПервогоФрагментаЛкс(СтрокаПараметра.Описание, Символы.ПС);
Если Истина
И ЗначениеЗаполнено(ЧастьСоВторойСтроки)
И Найти(ЧастьСоВторойСтроки, "-") // хорошо бы и второй вариант тире проверять
Тогда
// Если каждый тип описан с новой строки описания, то нужнен анализ описания https://www.hostedredmine.com/issues/984526
Если ЗначениеЗаполнено(СтрокаПараметра.ТипЗначения) Тогда
ОстатокОписания = ЧастьСоВторойСтроки;
Иначе
ОстатокОписания = ВхождениеОписания.Описание;
КонецЕсли;
ВхожденияТипов = ирОбщий.НайтиРегВыражениеЛкс(ОстатокОписания, шПустоеНачалоСтроки + "-\s*([^\-\:\n]+)");
Если ВхожденияТипов.Количество() > 0 Тогда
Типы = ВхожденияТипов.ВыгрузитьКолонку("Группа0");
Если ЗначениеЗаполнено(СтрокаПараметра.ТипЗначения) Тогда
Типы.Вставить(0, СтрокаПараметра.ТипЗначения);
КонецЕсли;
СтрокаПараметра.ТипЗначения = ирОбщий.СтрСоединитьЛкс(Типы);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЦикла;
// ВызывающиеМодули
шИмяМодуля = "\n[\t ]+(" + шИмяВременнойТаблицы + ")(?=\s)";
ВхожденияОписаний = ирОбщий.НайтиРегВыражениеЛкс(ирОбщий.ТекстМеждуМаркерамиЛкс(СтрокаМетода.Описание + Символы.ПС, ЗаголовокРазделаВызывающиеМодули(), ":", Ложь,,, Истина),
шИмяМодуля,,,, Ложь, Ложь);
Если ВхожденияОписаний.Количество() > 0 Тогда
СтрокаМетода.ВызывающиеМодули = Новый Массив;
Для каждого ВхождениеОписания Из ВхожденияОписаний Цикл
СтрокаМетода.ВызывающиеМодули.Добавить(ВхождениеОписания.Группа0);
КонецЦикла;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Не ДляКонструктора Тогда
Для Каждого СтрокаПараметра Из Результат.НайтиСтроки(Новый Структура("ТипЗначения", "")) Цикл
Если ПустаяСтрока(СтрокаПараметра.Значение) Тогда
Продолжить;
КонецЕсли;
Если ирОбщий.ЛиБулевыйЛитералЛкс(СтрокаПараметра.Значение) Тогда
СтрокаПараметра.ТипЗначения = "Булево";
Иначе
ПервыйСимвол = Лев(СтрокаПараметра.Значение, 1);
Если ПервыйСимвол = """" Тогда
СтрокаПараметра.ТипЗначения = "Строка";
ИначеЕсли Найти("0123456789", ПервыйСимвол) > 0 Тогда
СтрокаПараметра.ТипЗначения = "Число";
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЕсли;
КонецЕсли;
СтрокаМетода.МинЧислоПараметров = МинЧислоПараметров;
Если Не ДляКонструктора Тогда
СтрокаМетода.Параметры = Результат;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ЗаголовокРазделаПараметры() Экспорт
Возврат "Параметры:";
КонецФункции
Функция ЗаголовокРазделаВызывающиеМодули() Экспорт
Возврат "Вызывающие модули:";
КонецФункции
Функция ЗаголовокРазделаВозвращаемоеЗначение() Экспорт
Возврат "Возвращаемое значение:";
КонецФункции
Функция ГрязныйТипИзОписанияПараметра(Знач Описание) Экспорт
Возврат ирОбщий.ТекстМеждуМаркерамиЛкс(Описание, "-", Символы.ПС);
КонецФункции
//.
// Возвращаемое значение:
// ТаблицаЗначений -
Функция НоваяТаблицаПараметровМетодаМодуля() Экспорт
Результат = Новый ТаблицаЗначений;
Результат.Колонки.Добавить("Имя", Новый ОписаниеТипов("Строка"));
Результат.Колонки.Добавить("НИмя", Новый ОписаниеТипов("Строка"));
Результат.Колонки.Добавить("ТипЗначения", Новый ОписаниеТипов("Строка"));
Результат.Колонки.Добавить("Описание", Новый ОписаниеТипов("Строка"));
Результат.Колонки.Добавить("Значение", Новый ОписаниеТипов("Строка"));
Результат.Колонки.Добавить("Знач", Новый ОписаниеТипов("Булево"));
Результат.Колонки.Добавить("ПозицияСОписанием", Новый ОписаниеТипов("Число")); // Начиная с 1
Результат.Колонки.Добавить("Вычислено", Новый ОписаниеТипов("Булево"));
Результат.Колонки.Добавить("ТаблицаТипов"); // см. НоваяТаблицаТипов, Неопределено
Возврат Результат;
КонецФункции
// Вызывается из других конфигураций!
// Параметры:
// ОписаниеМетода - Строка -
// Шаблоны - Структура - для ускорения
// Возвращаемое значение:
// ТаблицаЗначений -
Функция ПараметрыМетодаИзКомментария(Знач ОписаниеМетода, Шаблоны = Неопределено) Экспорт
Если Шаблоны = Неопределено Тогда
Шаблоны = ШаблоныДляАнализаВстроенногоЯзыка();
КонецЕсли;
шТире = "-"; // Здесь 2 разных символа
// Не поддерживает разбивку секции типа значения на 2 строки см. ирОбщий.ОтладитьЛкс Сделать TODO
шОписаниеПараметра = "(\n[\t ]{0,8})(" + шИмя + ")(\*?[\t ]*(?:[" + шТире + "][\t ]*)([^" + шТире + "\n]*?))?([\t ]*[" + шТире + "]\s*?" + Шаблоны.ОписаниеПараметра + ")";
ВхожденияОписаний = ирОбщий.НайтиРегВыражениеЛкс(ОписаниеМетода, шОписаниеПараметра, "Разделитель1, Имя, Разделитель2, ТипЗначения, Описание",,, Ложь, Ложь);
Возврат ВхожденияОписаний;
КонецФункции
Функция ОчиститьТекстМодуляОтПрефиксаКомментария(Знач ТекстМодуля) Экспорт
Если Не ЗначениеЗаполнено(ТекстМодуля) Тогда
Возврат "";
КонецЕсли;
Если Найти(ТекстМодуля, Символы.ПС) = 0 Тогда
Позиция = Найти(ТекстМодуля, "//");
Если Позиция > 0 Тогда
ТекстМодуля = Сред(ТекстМодуля, Позиция + 3);
КонецЕсли;
Возврат ТекстМодуля;
КонецЕсли;
мРегВыражение.Global = Истина;
//мРегВыражение.Pattern = шПустоеНачалоСтроки + "(?:/){2,}";
//Результат = мРегВыражение.Заменить(ТекстМодуля, Символы.ПС);
мРегВыражение.Pattern = "(" + шПустоеНачалоСтроки + ")(?://)";
Результат = мРегВыражение.Заменить(ТекстМодуля, "$1 "); // Сохраняем все позиции
Если Лев(Результат, 1) = Символы.ПС Тогда
Результат = Сред(Результат, 2); // Отрезаем начальный перенос строки
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПодготовитьТипРезультатаМетода(МетодМодуля, ИмяИлиМодуль, ПолеТекстаМодуляКэш = Неопределено, Знач СФактическимиПараметрами = Ложь, Знач ДляСвойства = "") Экспорт
Если МетодМодуля.ТипЗначения = Неопределено Тогда
// тип метода - "процедура"
Возврат Неопределено;
КонецЕсли;
// Отключил 30.03.2025
//Если Истина
// И МетодМодуля.ТаблицаТипов = Неопределено
// И Не МетодМодуля.Вычислено // Временно добавил 30.03.2025
//Тогда
// МетодМодуля.ТаблицаТипов = НоваяТаблицаТипов();
//КонецЕсли;
ПодготовитьОписаниеРезультатаМетода(МетодМодуля);
ПолеТекстаМодуляКэш = ПолеТекстаМодуля(ИмяИлиМодуль, ПолеТекстаМодуляКэш);
ПолеТекстаМодуляКэш.ЗагрузитьМетодМодуля(МетодМодуля, Истина);
ТаблицаТипов = ПодготовитьТипЗначенияСловаМодуля(ПолеТекстаМодуляКэш.ИмяПеременнойВозвращаемогоЗначения(), ПолеТекстаМодуляКэш, МетодМодуля, ИмяИлиМодуль, МетодМодуля,
МетодМодуля.ОписаниеРезультата, СФактическимиПараметрами, Истина, ДляСвойства, МетодМодуля.ПозицияОписанияРезультата);
Возврат ТаблицаТипов;
КонецФункции
//.
// Параметры:
// СтрокаОпределения - СтрокаТаблицыЗначений -
Процедура ПодготовитьОписаниеРезультатаМетода(СтрокаОпределения, Знач ДляКонструктора = Ложь) Экспорт
СыроеОписание = Неопределено;
Если Истина
И ЗначениеЗаполнено(СтрокаОпределения.Описание)
И СтрокаОпределения.ОписаниеРезультата = Неопределено
И (Ложь
Или ДляКонструктора
Или СтрокаОпределения.ТипЗначения <> Неопределено)
Тогда
СыроеОписание = СтрокаОпределения.Описание;
ИначеЕсли Лев(СтрокаОпределения.ОписаниеРезультата, 2) = "//" Тогда
СыроеОписание = СтрЗаменить(СтрокаОпределения.ОписаниеРезультата, "//", "// Результат:");
КонецЕсли;
Если СыроеОписание <> Неопределено Тогда
Шаблоны = ШаблоныДляАнализаВстроенногоЯзыка();
шТире = "-"; // Здесь 2 разных символа
ШаблонОписанияРезультата = "(?:Возвращаемое\s+значение|Результат)\:\s*(?:([^" + шТире + ":\n]+)\s*(?=[" + шТире + ":\n]))?\s*(" + Шаблоны.ОписаниеПараметра + ")";
ВхожденияОписаний = ирОбщий.НайтиРегВыражениеЛкс(СыроеОписание, ШаблонОписанияРезультата, "ТипЗначения, Описание", Ложь,, Ложь, Ложь);
Если ВхожденияОписаний.Количество() > 0 Тогда
ВхождениеОписания = ВхожденияОписаний[ВхожденияОписаний.Количество() - 1];
ОписаниеРезультата = СокрЛП(ВхождениеОписания.Описание);
СтрокаОпределения.ОписаниеРезультата = ОчиститьТекстМодуляОтПрефиксаКомментария(ОписаниеРезультата);
СтрокаОпределения.ПозицияОписанияРезультата = ВхождениеОписания.ПозицияВхождения - СтрДлина(СыроеОписание);
Если СтрокаОпределения.ТипЗначения <> Неопределено Тогда
ТекстТипаЗначения = СокрЛП(СтрЗаменить(ВхождениеОписания.ТипЗначения, "//", ""));
Если ЗначениеЗаполнено(ТекстТипаЗначения) Тогда
КопияТекстТипаЗначения = ТекстТипаЗначения;
Если УдалитьПрефиксИзТекстаТипов(КопияТекстТипаЗначения) Тогда
СтрокаОпределения.ТипЗначения = ТекстТипаЗначения;
Иначе
СтрокаОпределения.ТипЗначения = СтрокаОпределения.ТипЗначения + ", " + ТекстТипаЗначения; // TODO удаление дублей
КонецЕсли;
КонецЕсли;
КонецЕсли;
Иначе
СтрокаОпределения.ОписаниеРезультата = "";
КонецЕсли;
КонецЕсли;
КонецПроцедуры
// Функция - Удалить префикс из текста типов
//
// Параметры:
// Текст - -
//
// Возвращаемое значение:
// Булево - является ли ссылкой на описание (см.)
//
Функция УдалитьПрефиксИзТекстаТипов(Текст) Экспорт
Текст = СокрЛП(Текст);
МаркерСм = "см.";
Если ирОбщий.СтрНачинаетсяСЛкс(Текст, МаркерСм) Тогда
Текст = СокрЛ(Сред(Текст, СтрДлина(МаркерСм) + 1));
Возврат Истина;
КонецЕсли;
Если Найти(Текст, "(") > 0 И Найти(Текст, " ") = 0 Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ПодготовитьТипЗначенияПеременнойМодуля(СтрокаОпределения, ИмяИлиМодуль, Знач ПолеТекстаМодуляКэш = Неопределено, Знач ДляСвойства = "") Экспорт
Если СтрокаОпределения.ТаблицаТипов = Неопределено Тогда
СтрокаОпределения.ТаблицаТипов = НоваяТаблицаТипов();
КонецЕсли;
ПодготовитьОписаниеПеременнойМодуля(СтрокаОпределения);
ПолеТекстаМодуляКэш = ПолеТекстаМодуля(ИмяИлиМодуль, ПолеТекстаМодуляКэш);
ТаблицаТипов = ПодготовитьТипЗначенияСловаМодуля(СтрокаОпределения.Имя, ПолеТекстаМодуляКэш,, ИмяИлиМодуль, СтрокаОпределения, СтрокаОпределения.Описание,,, ДляСвойства);
Если ТаблицаТипов.Количество() > 1 Тогда
ирОбщий.УдалитьСтрокиТаблицыИлиДереваПоЗначениюЛкс(ТаблицаТипов, "ИмяОбщегоТипа", "Произвольный"); // Нужно для проверок выражений
КонецЕсли;
Возврат ТаблицаТипов;
КонецФункции
Процедура ПодготовитьОписаниеПеременнойМодуля(Знач СтрокаОпределения) Экспорт
Если Истина
И ЗначениеЗаполнено(СтрокаОпределения.Описание)
И Не ЗначениеЗаполнено(СтрокаОпределения.ТипЗначения)
Тогда
ТипЗначения = ирОбщий.ПервыйФрагментЛкс(СтрокаОпределения.Описание, "-");
СтрокаОпределения.Описание = Сред(СтрокаОпределения.Описание, СтрДлина(ТипЗначения) + 1);
СтрокаОпределения.ТипЗначения = СокрЛ(ТипЗначения);
КонецЕсли;
КонецПроцедуры
Функция ПодготовитьТипЗначенияСловаМодуля(Знач ИмяПеременной, Знач ПолеТекстаМодуляКэш, Знач МетодМодуля, Знач ИмяИлиМодуль, Знач СтрокаОпределения, Знач ОписаниеТипа = "",
Знач СФактическимиПараметрами = Ложь, Знач ЭтоПрисвоенноеВыражение = Ложь, Знач ДляСвойства = "", Знач ПозицияОписания = 0)
Если ПустаяСтрока(ИмяПеременной) Тогда
ВызватьИсключение "Э";
КонецЕсли;
Если СФактическимиПараметрами Тогда
ТаблицаТипов = ПолеТекстаМодуляКэш.ВычислитьТипЗначенияВыражения(ИмяПеременной,,,,,,, МетодМодуля = Неопределено, НоваяТаблицаТипов(), Истина,,, , ДляСвойства);
Если ТаблицаТипов.Количество() = 0 И ТаблицаТипов.Колонки.Метаданные.Заголовок = "" Тогда
ДобавитьВТаблицуТипов(ТаблицаТипов, НоваяСтруктураТипа("Произвольный"));
КонецЕсли;
ТаблицаТипов.ЗаполнитьЗначения(СтрокаОпределения, "СтрокаОписания");
Иначе
//ТаблицаТипов = СтрокаОпределения.ТаблицаТипов;
Если Ложь
Или СтрокаОпределения.Вычислено
Или СтрокаОпределения.Имя = "<>"
Тогда
ТаблицаТипов = СтрокаОпределения.ТаблицаТипов;
Иначе
СтрокаОпределения.ТаблицаТипов = Неопределено; // На случай рекурсивного обращения до завершения вычисления
СтрокаОпределения.Вычислено = Истина;
Попытка
Если Истина
И ЗначениеЗаполнено(СтрокаОпределения.ТипЗначения)
И (Ложь
Или СтрокаОпределения.ТипЗначения <> "??"
Или ЗначениеЗаполнено(ОписаниеТипа))
И СтрокаОпределения.ТипЗначения <> "?"
Тогда
ПолеТекстаМодуляКэш.ЗагрузитьМетодМодуля(Неопределено);
ТаблицаТиповИзКомментария = ПолеТекстаМодуляКэш.ТаблицаТиповИзТекста(СтрокаОпределения.ТипЗначения, ОписаниеТипа,, ДляСвойства,,,, ПозицияОписания, Истина);
Если ТаблицаТиповИзКомментария.Колонки.Метаданные.Заголовок = "" Тогда
ДобавитьВТаблицуТипов(СтрокаОпределения.ТаблицаТипов, ТаблицаТиповИзКомментария);
КонецЕсли;
КонецЕсли;
УказанКонструктор = ЛиВСтрокеТиповЕстьКонструктор(СтрокаОпределения.ТипЗначения);
Если Истина
И Не УказанКонструктор
И ЗначениеЗаполнено(ТаблицаТиповИзКомментария)
И Лев(СтрокаОпределения.ТипЗначения, 1) = "?"
//И Найти(НРег(СтрокаОпределения.ТипЗначения), " из ") = 0 // Иначе часть после "из" будет потеряна https://turboconf.ru/Tasks/9668
Тогда
СтрокаОпределения.ТипЗначения = ПредставлениеМассиваСтруктурТипов(ТаблицаТиповИзКомментария);
КонецЕсли;
Если Ложь
// Жертвует качеством расчета ради ускорения - дает 10% скорости при проверке модуля ирКлсПолеТекстаПрограммы
Или (Истина
И УказанКонструктор
И Не ЗначениеЗаполнено(ДляСвойства)
И ЛиДетальностьТиповДостаточна(ТаблицаТиповИзКомментария))
Или (Истина
И МетодМодуля = Неопределено // только для переменных
И ЗначениеЗаполнено(СтрокаОпределения.ТипЗначения)
И Не УказанКонструктор
И ЛиДетальностьТиповДостаточна(ТаблицаТиповИзКомментария, 4)) // Мультиметка481662548
Тогда
// Считаем что тип в комментарии описан достаточно подробно
ТаблицаТипов = ТаблицаТиповИзКомментария;
Иначе
ПолеТекстаМодуляКэш.ЗагрузитьМетодМодуля(МетодМодуля);
ТаблицаТипов = ПолеТекстаМодуляКэш.ВычислитьТипЗначенияВыражения(ИмяПеременной,,,,,,, МетодМодуля = Неопределено, НоваяТаблицаТипов(), Истина,,,, ДляСвойства);
Если ТаблицаТипов.Количество() > 0 Тогда
// Мультиметка4529884 против циклической ссылки
Для Каждого СтрокаТипа Из ТаблицаТипов.НайтиСтроки(Новый Структура("СтрокаОписания", СтрокаОпределения)) Цикл
СтрокаТипа.СтрокаОписания = Неопределено;
КонецЦикла;
КонецЕсли;
Если ТаблицаТипов.Колонки.Метаданные.Заголовок = "" Тогда
ДобавитьВТаблицуТипов(СтрокаОпределения.ТаблицаТипов, ТаблицаТипов);
Если Истина
И ТаблицаТиповИзКомментария <> Неопределено
И ТаблицаТиповИзКомментария.Колонки.Метаданные.Заголовок <> ""
Тогда
Если Истина
И СтрокаОпределения.ТаблицаТипов.Количество() > 0
И СтрокаОпределения.ТаблицаТипов[0].Метаданные <> Неопределено // Иначе обрезанная Структура будет считаться полной
Тогда
// Для обогащения НоваяСтруктураТипа().ВиртуальнаяТаблица
ТаблицаТиповИзКомментария.Колонки.Метаданные.Заголовок = ""; // - опасно, т.к. может сломать вычисление результата ОбъектБДПоКлючуЛкс через докОбъектБДПоКлючуСсылочный
КонецЕсли;
ДобавитьВТаблицуТипов(СтрокаОпределения.ТаблицаТипов, ТаблицаТиповИзКомментария);
КонецЕсли;
ТаблицаТипов = СтрокаОпределения.ТаблицаТипов;
КонецЕсли;
Если Истина
И ТаблицаТиповИзКомментария <> Неопределено
И (Ложь
Или ТаблицаТипов.Количество() = 0
Или ТаблицаТипов.Колонки.Метаданные.Заголовок <> "")
Тогда
ДобавитьВТаблицуТипов(ТаблицаТипов, ТаблицаТиповИзКомментария);
КонецЕсли;
КонецЕсли;
Если ТаблицаТипов.Количество() = 0 И ТаблицаТипов.Колонки.Метаданные.Заголовок = "" Тогда
ДобавитьВТаблицуТипов(ТаблицаТипов, НоваяСтруктураТипа("Произвольный"));
КонецЕсли;
//СтрокаОпределения.ТаблицаТипов.ЗаполнитьЗначения(СтрокаОпределения, "СтрокаОписания"); // Мультиметка4529884 Была циклическая ссылка ! Теперь заполняем ссылку позже уже в копии таблицы
Исключение
СтрокаОпределения.Вычислено = Ложь; //
ВызватьИсключение;
КонецПопытки;
Если ТаблицаТипов.Колонки.Метаданные.Заголовок <> "" Тогда
СтрокаОпределения.Вычислено = Ложь;
КонецЕсли;
Если Истина
И МетодМодуля <> Неопределено
И МетодМодуля.КлючевыеПараметры <> Неопределено
Тогда
Если Ложь
Или ЛиДетальностьТиповДостаточна(ТаблицаТиповИзКомментария, 4)
Или Не ЛиНестрогаяТаблицаТипов(ТаблицаТипов, Ложь, МетодМодуля.ТипЗначения)
Тогда
МетодМодуля.КлючевыеПараметры = Неопределено;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат ТаблицаТипов;
КонецФункции
//.
// Параметры:
// ТаблицаТипов - ТаблицаЗначений -
// Возвращаемое значение:
// Булево
Функция ЛиНестрогаяТаблицаТипов(Знач ТаблицаТипов, Знач ЛиВходящий, Знач ОбъявленныйТип) Экспорт
ЛиКлючевойПараметр = Ложь
Или ТаблицаТипов.Количество() - ТаблицаТипов.НайтиСтроки(Новый Структура("ИмяОбщегоТипа", "Неопределено")).Количество() > 1 // Составной тип
Или ТаблицаТипов.Найти("Произвольный", "ИмяОбщегоТипа") <> Неопределено;
Если Не ЛиКлючевойПараметр Тогда
Для Каждого СтрокаТипа Из ТаблицаТипов Цикл
ИмяОбщегоТипа = СтрокаТипа.ИмяОбщегоТипа;
Если ИмяОбщегоТипа = "Неопределено" Тогда
Продолжить;
КонецЕсли;
ИмяОбщегоТипа = ирОбщий.ПервыйФрагментЛкс(ИмяОбщегоТипа, "[");
Попытка
Тип = Тип(ИмяОбщегоТипа);
Исключение
Продолжить;
КонецПопытки;
ЛиКлючевойПараметр = Истина
И (Ложь
Или мМассивТиповСМетаданными.Найти(Тип) <> Неопределено
//Или (Истина
// И ЛиВходящий
// И (Ложь
// Или Тип = Тип("Строка")
// Или Тип = Тип("Число")))
)
И (Ложь
Или СтрокаТипа.Детальность < 4
Или (Истина
И ОбъявленныйТип <> "??"
И ЗначениеЗаполнено(ОбъявленныйТип)
И Не ЛиВСтрокеТиповЕстьКонструктор(ОбъявленныйТип)));
Прервать; // В таблице может быть макс. 2 шт
КонецЦикла;
КонецЕсли;
Возврат ЛиКлючевойПараметр;
КонецФункции
Функция ЛиВСтрокеТиповЕстьКонструктор(Знач ОбъявленныйТип) Экспорт
Возврат Найти(НРег(ОбъявленныйТип), "см.") > 0;
КонецФункции
// Модуль уже должен быть в кэше.
// Параметры:
// ИмяИлиМодуль - Структура -
// ПолеТекстаМодуляКэш - ОбработкаОбъект.ирКлсПолеТекстаПрограммы, Неопределено -
// Возвращаемое значение:
// ОбработкаОбъект.ирКлсПолеТекстаПрограммы, Неопределено -
Функция ПолеТекстаМодуля(Знач ИмяИлиМодуль, ПолеТекстаМодуляКэш = Неопределено) Экспорт
Если ПолеТекстаМодуляКэш = Неопределено Тогда
Если ТипЗнч(ИмяИлиМодуль) = Тип("Строка") Тогда
ИмяМодуля = ИмяИлиМодуль;
Иначе
ИмяМодуля = ИмяИлиМодуль.Имя
КонецЕсли;
ПолеТекстаМодуляКэш = ирКэш.ПолеТекстаМодуляЛкс(ИмяМодуля);
Если ТипЗнч(ИмяИлиМодуль) = Тип("Структура") Тогда
НовыйМодуль = ИмяИлиМодуль; // Точно из кэша
Иначе
НовыйМодуль = МодульМетаданныхИзКэша(ИмяМодуля);
КонецЕсли;
Если НовыйМодуль <> Неопределено Тогда
ПолеТекстаМодуляКэш.ЗагрузитьМодульМетаданных(НовыйМодуль); // Мультиметка250323_114539
КонецЕсли;
ПолеТекстаМодуляКэш = ПолеТекстаМодуляКэш.КопияКомпоненты(); // Иначе при вызовах в рамках одного модуля будет переиспользоваться один объект и портиться контекст
КонецЕсли;
Возврат ПолеТекстаМодуляКэш;
КонецФункции
// Получает представление массива типов.
//
// Параметры:
// ТаблицаТиповКонтекста - ТаблицаЗначений.
//
// Возвращаемое значение:
// Строка - представление массива типов.
//
Функция ПредставлениеМассиваСтруктурТипов(ТаблицаТиповКонтекста, БезДублей = Ложь, МаксКоличествоТипов = 10, Знач Подробное = Истина) Экспорт
#Если Сервер И Не Сервер Тогда
ТаблицаТиповКонтекста = Новый ТаблицаЗначений;
#КонецЕсли
ПредставлениеТипаКонтекста = "";
Если ТаблицаТиповКонтекста <> Неопределено Тогда
Если ТаблицаТиповКонтекста.Количество() = 0 Тогда
ИначеЕсли ТаблицаТиповКонтекста.Количество() = 1 Тогда
ПредставлениеТипаКонтекста = ИмяТипаИзСтруктурыТипа(ТаблицаТиповКонтекста[0], Подробное);
Иначе
СписокОбрезан = Неопределено;
СписокИменТипов = ТаблицаТиповДляПользователя(ТаблицаТиповКонтекста, БезДублей, МаксКоличествоТипов, СписокОбрезан, Подробное);
Если СписокОбрезан Тогда
СписокИменТипов.Добавить().Имя = "...";
КонецЕсли;
ПредставлениеТипаКонтекста = ирОбщий.СтрСоединитьЛкс(СписокИменТипов.ВыгрузитьКолонку("Имя"), ", ");
ПредставлениеТипаКонтекста = СтрЗаменить(ПредставлениеТипаКонтекста, "?, ", "");
КонецЕсли;
КонецЕсли;
Возврат ПредставлениеТипаКонтекста;
КонецФункции
Функция ТаблицаТиповДляПользователя(Знач ТаблицаТиповКонтекста, Знач БезДублей = Истина, Знач МаксКоличествоТипов = 0, выхСписокОбрезан = Ложь, Знач Подробное = Истина) Экспорт
#Если Сервер И Не Сервер Тогда
ТаблицаТиповКонтекста = Новый ТаблицаЗначений;
#КонецЕсли
Счетчик = 0;
выхСписокОбрезан = Ложь;
СписокИменТипов = Новый ТаблицаЗначений;
СписокИменТипов.Колонки.Добавить("Имя");
СписокИменТипов.Колонки.Добавить("СтруктураТипа");
СтруктураТипаНеопределено = Неопределено;
Для Каждого СтруктураТипаКонтекста Из ТаблицаТиповКонтекста Цикл
Счетчик = Счетчик + 1;
Если МаксКоличествоТипов > 0 И Счетчик > МаксКоличествоТипов Тогда
выхСписокОбрезан = Истина;
Прервать;
КонецЕсли;
ИмяТипа = ИмяТипаИзСтруктурыТипа(СтруктураТипаКонтекста, Подробное);
Если Не ЗначениеЗаполнено(ИмяТипа) Тогда
Продолжить;
КонецЕсли;
Если ИмяТипа = "Неопределено" Тогда
СтруктураТипаНеопределено = СтруктураТипаКонтекста;
Продолжить;
КонецЕсли;
СтрокаИменТипов = СписокИменТипов.Добавить();
СтрокаИменТипов.Имя = ИмяТипа;
СтрокаИменТипов.СтруктураТипа = СтруктураТипаКонтекста;
КонецЦикла;
СписокИменТипов.Сортировать("Имя");
Если СтруктураТипаНеопределено <> Неопределено Тогда
// Чтобы Неопределено всегда шло последним
СтрокаИменТипов = СписокИменТипов.Добавить();
СтрокаИменТипов.Имя = "Неопределено";
СтрокаИменТипов.СтруктураТипа = СтруктураТипаНеопределено;
КонецЕсли;
Если БезДублей Тогда
СписокИменТипов.Свернуть("Имя");
КонецЕсли;
Возврат СписокИменТипов;
КонецФункции
// Функция - Отбор параметров метода
//
// Параметры:
// СтрокаОписания - СтрокаТаблицыЗначений - строка таблицы ТаблицаКонтекстов
//
// Возвращаемое значение:
// -
//
Функция ОтборПараметровМетода(Знач СтрокаОписания) Экспорт
ОтборПараметров = Новый Структура;
ОтборПараметров.Вставить("ТипКонтекста", СтрокаОписания.ТипКонтекста);
Если СтрокаОписания.ТипСлова = "Конструктор" Тогда
ОтборПараметров.Вставить("Слово", "<Новый>");
Иначе
ОтборПараметров.Вставить("Слово", СтрокаОписания.Слово);
КонецЕсли;
ОтборПараметров.Вставить("ЯзыкПрограммы", СтрокаОписания.ЯзыкПрограммы);
Возврат ОтборПараметров;
КонецФункции
// Функция - Таблица параметров метода для всех вариантов синтаксиса
//
// Параметры:
// СтрокаОписания - СтрокаТаблицыЗначений, см. ОбработкаОбъект.ирПлатформа.ТаблицаКонтекстов[0] -
// ОтборПараметров - -
//
// Возвращаемое значение:
// -
//
Функция ПараметрыМетодаПлатформы(Знач СтрокаОписания) Экспорт
ОтборПараметров = ОтборПараметровМетода(СтрокаОписания);
КоличествоПараметров = 0;
Если Не ЗначениеЗаполнено(СтрокаОписания.Описание) Тогда // Мультиметка443985642
СинтаксПомощник = СинтаксПомощник();
#Если Сервер И Не Сервер Тогда
СинтаксПомощник = Обработки.ирСинтаксПомощник.Создать();
#КонецЕсли
МассивВариантов = Новый Массив;
Если СтрокаОписания.ТипСлова = "Конструктор" Тогда
Отбор = Новый Структура("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка, ТипСлова"); // индекс
ЗаполнитьЗначенияСвойств(Отбор, СтрокаОписания);
Для Каждого СтрокаВарианта Из ТаблицаКонтекстов.НайтиСтроки(Отбор) Цикл
МассивВариантов.Добавить(СтрокаВарианта);
КонецЦикла;
Иначе
МассивВариантов.Добавить(СтрокаОписания);
КонецЕсли;
Для Каждого ВариантМетода Из МассивВариантов Цикл
ПутьКЭлементуАрхива = ВариантМетода.ПутьКОписанию;
Если Не ЗначениеЗаполнено(ПутьКЭлементуАрхива) Тогда
Продолжить;
КонецЕсли;
НовыйАдрес = СинтаксПомощник.РаспаковатьЭлементАрхиваСинтаксПомощника(ПутьКЭлементуАрхива);
КоличествоПараметров = 100;
Если НовыйАдрес <> Неопределено Тогда
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.Прочитать(ирОбщий.ПервыйФрагментЛкс(НовыйАдрес, "#"));
ТекстДокумента = ТекстовыйДокумент.ПолучитьТекст();
КоличествоПараметров = СинтаксПомощник.ЗагрузитьОписаниеМетода(ВариантМетода.ТипКонтекста, ВариантМетода.Слово, ТекстДокумента, ВариантМетода.ТипСлова, ВариантМетода.ЯзыкПрограммы,,, ВариантМетода);
Иначе
СтрокаОписания.Описание = "<Описание не найдено>"; // Чтобы больше не пытаться загружать
КонецЕсли;
КонецЦикла;
КонецЕсли;
СтрокиПараметров = ТаблицаПараметров.НайтиСтроки(ОтборПараметров);
Пока Истина
И КоличествоПараметров > 0
И КоличествоПараметров < СтрокиПараметров.Количество()
И СтрокиПараметров[0].ВариантСинтаксиса = СтрокиПараметров[КоличествоПараметров].ВариантСинтаксиса
Цикл
// Удаляем дубли параметров виртуальных таблиц регистра бухгалтерии https://www.hostedredmine.com/issues/952173
ТаблицаПараметров.Удалить(СтрокиПараметров[КоличествоПараметров]);
СтрокиПараметров.Удалить(КоличествоПараметров);
КонецЦикла;
СтрокиПараметров = ТаблицаПараметров.Скопировать(СтрокиПараметров);
Возврат СтрокиПараметров;
КонецФункции
Функция ПолучитьТипЗначенияЧленаИнтерфейса(Член, ИмяБиблиотеки = "", ИнфоИнтерфейса = Неопределено) Экспорт
//Тест = ПолучитьИмяТипаCOMVariant(Член);
Попытка
ОписаниеРезультата = Член.ReturnType;
Исключение
// Параметр метода
//: Член = 0 // ParameterInfo {TLI.TLIApplication}
ОписаниеРезультата = Член.VarTypeInfo;
КонецПопытки;
ИнфоТипаРезультата = ОписаниеРезультата.TypeInfo;
Если ИнфоТипаРезультата <> Неопределено Тогда
ТипЗначенияРезультата = ПолноеИмяТипаCOMОбъектаИзИнфоТипа(ИнфоТипаРезультата, ИмяБиблиотеки);
ИначеЕсли Истина
И ИмяБиблиотеки = "VBScript.RegExp"
И ИнфоИнтерфейса.Name = "IRegExp2"
И Член.Name = "Execute"
Тогда
ТипЗначенияРезультата = "MatchCollection {VBScript.RegExp}";
ИначеЕсли Истина
И ИмяБиблиотеки = "VBScript.RegExp"
И ИнфоИнтерфейса.Name = "IMatchCollection2"
И Член.Name = "Item"
Тогда
ТипЗначенияРезультата = "Match {VBScript.RegExp}";
Иначе
НомерТипа = ОписаниеРезультата.VarType;
ТипЗначенияРезультата = "Произвольный" + ", " + НомерТипа;
Если НомерТипа = 0 Тогда
ТипЗначенияРезультата = Неопределено;
ИначеЕсли НомерТипа = 1 Тогда
ТипЗначенияРезультата = Null;
ИначеЕсли НомерТипа >= 2 И НомерТипа <= 5 Тогда
ТипЗначенияРезультата = "Число";
ИначеЕсли НомерТипа = 7 Тогда
ТипЗначенияРезультата = "Дата";
ИначеЕсли НомерТипа = 8 Тогда
ТипЗначенияРезультата = "Строка";
ИначеЕсли НомерТипа = 11 Тогда
ТипЗначенияРезультата = "Булево";
ИначеЕсли НомерТипа = 12 Тогда
ТипЗначенияРезультата = "Строка";
ИначеЕсли НомерТипа >= 14 И НомерТипа <= 23 Тогда
ТипЗначенияРезультата = "Число";
ИначеЕсли НомерТипа = 24 Тогда
// Метод не возвращает значение - Процедура
ТипЗначенияРезультата = "";
ИначеЕсли НомерТипа = 9 Тогда
// Тип этого значения станет известен только при его появлении
//ТипЗначенияРезультата = ПолучитьИмяТипаCOMVariant(ОписаниеРезультата); // Тоже не дает результат
ТипЗначенияРезультата = "Произвольный";
КонецЕсли;
КонецЕсли;
Возврат ТипЗначенияРезультата;
//'OLE Automation VARIANT types
// Enum TliVarType
// VT_EMPTY = 0 '&H0
// VT_NULL = 1 '&H1
// VT_I2 = 2 '&H2
// VT_I4 = 3 '&H3
// VT_R4 = 4 '&H4
// VT_R8 = 5 '&H5
// VT_CY = 6 '&H6
// VT_DATE = 7 '&H7
// VT_BSTR = 8 '&H8
// VT_DISPATCH = 9 '&H9
// VT_ERROR = 10 '&HA
// VT_BOOL = 11 '&HB
// VT_VARIANT = 12 '&HC
// VT_UNKNOWN = 13 '&HD
// VT_DECIMAL = 14 '&HE
// VT_I1 = 16 '&H10
// VT_UI1 = 17 '&H11
// VT_UI2 = 18 '&H12
// VT_UI4 = 19 '&H13
// VT_I8 = 20 '&H14
// VT_UI8 = 21 '&H15
// VT_INT = 22 '&H16
// VT_UINT = 23 '&H17
// VT_VOID = 24 '&H18
// VT_HRESULT = 25 '&H19
// VT_PTR = 26 '&H1A
// VT_SAFEARRAY = 27 '&H1B
// VT_CARRAY = 28 '&H1C
// VT_USERDEFINED = 29 '&H1D
// VT_LPSTR = 30 '&H1E
// VT_LPWSTR = 31 '&H1F
// VT_RECORD = 36 '&H24
// VT_FILETIME = 64 '&H40
// VT_BLOB = 65 '&H41
// VT_STREAM = 66 '&H42
// VT_STORAGE = 67 '&H43
// VT_STREAMED_OBJECT = 68 '&H44
// VT_STORED_OBJECT = 69 '&H45
// VT_BLOB_OBJECT = 70 '&H46
// VT_CF = 71 '&H47
// VT_CLSID = 72 '&H48
// VT_VECTOR = 4096 '&H1000
// VT_ARRAY = 8192 '&H2000
// VT_BYREF = 16384 '&H4000
// VT_RESERVED = 32768 '&H8000
КонецФункции
Функция ПолноеИмяТипаCOMОбъектаИзИнфоТипа(ИнфоИнтерфейса, Знач ИмяБиблиотеки = "") Экспорт
Если Не ЗначениеЗаполнено(ИмяБиблиотеки) Тогда
ИмяБиблиотеки = "COMОбъект";
КонецЕсли;
Результат = ИнфоИнтерфейса.Name + " {" + ИмяБиблиотеки + "}";
Возврат Результат;
КонецФункции
Функция ПолноеИмяТипаCOMОбъекта(COMОбъект, Знач ПолноеИмяОсновногоКласса = "") Экспорт
ИнфоИнтерфейса = ПолучитьИнфоТипаCOMОбъекта(COMОбъект, , ПолноеИмяОсновногоКласса);
Если ИнфоИнтерфейса <> Неопределено Тогда
Результат = ПолноеИмяТипаCOMОбъектаИзИнфоТипа(ИнфоИнтерфейса, ПолноеИмяОсновногоКласса);
Иначе
Результат = "COMОбъект";
КонецЕсли;
Возврат Результат;
КонецФункции
// Функция - Получить инфо типа COMОбъекта
//
// Параметры:
// выхCOMОбъект - -
// ИмяОбщегоТипа - -
// выхПолноеИмяОсновногоКласса - -
//
// Возвращаемое значение:
// TypeInfo {TLI.TLIApplication}, InterfaceInfo {TLI.TLIApplication} -
//
Функция ПолучитьИнфоТипаCOMОбъекта(выхCOMОбъект, Знач ИмяОбщегоТипа = Неопределено, выхПолноеИмяОсновногоКласса = "") Экспорт
ПолучитьCOMНавигатор();
Если COMНавигатор = "Отказ" Тогда
Возврат Неопределено;
КонецЕсли;
Если ТипЗнч(выхCOMОбъект) = Тип("COMОбъект") Тогда
Попытка
COMНавигатор.ResolveAliases = Ложь; // Тут бывает кривой объект без свойств и методов и при выводе строки эта ошибка очень раздражает
//ИнфоКласса = COMНавигатор.TypeLibInfoFromRegistry(); // По ИУД
//ИнфоКласса = COMНавигатор.ClassInfoFromObject(выхCOMОбъект); // Этот способ не поддерживается в большинстве классов
ИнфоИнтерфейса = COMНавигатор.InterfaceInfoFromObject(выхCOMОбъект); // Тут возникает ошибка для некоторых объектов, например V83.Application, ADODB.Recorset.Fields(*).Precision, WindowsInstaller.Installer
Исключение
ОписаниеОшибки = ОписаниеОшибки();
//ирОбщий.СообщитьЛкс(ОписаниеОшибки);
Возврат Неопределено;
КонецПопытки;
КонецЕсли;
Если ЗначениеЗаполнено(ИмяОбщегоТипа) Тогда
выхПолноеИмяОсновногоКласса = ирОбщий.ТекстМеждуМаркерамиЛкс(ИмяОбщегоТипа, "{", "}", Ложь);
ИмяОбщегоТипа = ирОбщий.ПервыйФрагментЛкс(ИмяОбщегоТипа, " ");
КонецЕсли;
Если Не ЗначениеЗаполнено(выхПолноеИмяОсновногоКласса) Тогда
Если ТипЗнч(выхCOMОбъект) = Тип("COMОбъект") Тогда
ИмяБиблиотеки = ИнфоИнтерфейса.Parent.Name;
ИмяОсновногоКласса = мИменаОсновныхКлассовБиблиотекCOM[ИмяБиблиотеки];
Если ИмяОсновногоКласса = Неопределено Тогда
//КаталогПриложений = Новый COMОбъект("COMAdmin.COMAdminCatalog");
//КаталогПриложений.Connect("localhost");
//Компоненты = КаталогПриложений.GetCollection("InprocServers");
//Компоненты.PopulateByKey("" + ИнфоИнтерфейса.Parent.GUID);
//Компоненты.PopulateByKey("{F935DC26-1CF0-11D0-ADB9-00C04FD58A0B}");
//Если Компоненты.Count > 0 Тогда
// ИмяОсновногоКласса = Компоненты.Item(0).Name;
//Иначе
ПробныйОбъект = Неопределено;
Для Каждого Претендент Из ИнфоИнтерфейса.Parent.CoClasses Цикл
Попытка
ПробныйОбъект = Новый COMОбъект(ИмяБиблиотеки + "." + Претендент.Name);
Исключение
Продолжить;
КонецПопытки;
Прервать;
КонецЦикла;
Если ПробныйОбъект <> Неопределено Тогда
ИмяОсновногоКласса = Претендент.Name;
Иначе
ИмяОсновногоКласса = "?";
КонецЕсли;
мИменаОсновныхКлассовБиблиотекCOM[ИмяБиблиотеки] = ИмяОсновногоКласса;
//КонецЕсли;
КонецЕсли;
выхПолноеИмяОсновногоКласса = ИмяБиблиотеки + "." + ИмяОсновногоКласса;
Иначе
Возврат Неопределено;
КонецЕсли;
КонецЕсли;
Если ИнфоИнтерфейса = Неопределено Тогда
выхCOMОбъект = ПолучитьОбразецCOMОбъекта(выхПолноеИмяОсновногоКласса);
Попытка
ИнфоИнтерфейса = COMНавигатор.InterfaceInfoFromObject(выхCOMОбъект);
Исключение
//ирОбщий.СообщитьЛкс(ОписаниеОшибки());
Возврат Неопределено;
КонецПопытки;
лИнфоИнтерфейса = ИнфоИнтерфейса.Parent.TypeInfos.NamedItem(ИмяОбщегоТипа);
Если лИнфоИнтерфейса <> Неопределено Тогда
ИнфоИнтерфейса = лИнфоИнтерфейса;
Иначе
// Например для Shell.Application выполняется
КонецЕсли;
КонецЕсли;
Возврат ИнфоИнтерфейса;
КонецФункции
//.
// Параметры:
// ПолноеИмяОсновногоКлассаCOM - -
// ЧерезНовый - Булево - создавать конструктором COMОбъект, иначе ПолучитьCOMОбъект()
// Возвращаемое значение:
// -
Функция ПолучитьОбразецCOMОбъекта(Знач ПолноеИмяОсновногоКлассаCOM, Знач ЧерезНовый = Истина) Экспорт
КлючКэша = НРеголноеИмяОсновногоКлассаCOM);
Результат = мОбразцыCOMОбъектов[КлючКэша];
// Закомментировал т.к. замедляет работу анализатора кода например для V83.Application
//Если Результат <> Неопределено Тогда
// ИнфоИнтерфейса = ПолучитьИнфоТипаCOMОбъекта(Результат,, ПолноеИмяОсновногоКлассаCOM);
// Если ИнфоИнтерфейса = Неопределено Тогда
// // Объект испорчен
// Результат = Неопределено;
// КонецЕсли;
//КонецЕсли;
Если Результат = Неопределено Тогда
Попытка
Если ЧерезНовый Тогда
Результат = Новый COMОбъект(ПолноеИмяОсновногоКлассаCOM);
Иначе
Результат = ПолучитьCOMОбъект(ПолноеИмяОсновногоКлассаCOM);
КонецЕсли;
Исключение
Возврат Неопределено;
КонецПопытки;
мОбразцыCOMОбъектов[КлючКэша] = Результат;
КонецЕсли;
Возврат Результат;
КонецФункции
// Получает новый экземпляр ком-объекта парсера.
//
// Параметры:
// Нет.
//
// Возвращаемое значение:
// Com-объект, Неопределено.
//
Функция ПолучитьCOMНавигатор() Экспорт
Если COMНавигатор = "НеИнициализирован" Тогда
COMНавигатор = ПолучитьCOMОбъектИзМакета("TLBINF32", "TLI.TLIApplication");
//! COMНавигатор = Новый COMОбъект("TLI.TLIApplication");
КонецЕсли;
Возврат COMНавигатор;
КонецФункции
Функция ТипыЭлементовКоллекции(Знач СтруктураТипаКоллекции, Знач ЯзыкПрограммы = 0, выхНужнаПроверкаТипов = Истина) Экспорт
Результат = Новый Массив;
выхНужнаПроверкаТипов = Истина;
ИмяОбщегоТипаКоллекции = ирОбщий.ПервыйФрагментЛкс(СтруктураТипаКоллекции.ИмяОбщегоТипа, "[");
Если Ложь
Или ИмяОбщегоТипаКоллекции = "Массив"
Или ИмяОбщегоТипаКоллекции = "ФиксированныйМассив"
Тогда
выхНужнаПроверкаТипов = Ложь;
ТекстТипыЭлементов = ирОбщий.ТекстМеждуМаркерамиЛкс(СтруктураТипаКоллекции.ИмяОбщегоТипа, "[", "]", Ложь);
Если ЗначениеЗаполнено(ТекстТипыЭлементов) Тогда
Результат = ирОбщий.СтрРазделитьЛкс(ТекстТипыЭлементов, ", ");
КонецЕсли;
ИначеЕсли ЛиИмяТипаComОбъекта(СтруктураТипаКоллекции.ИмяОбщегоТипа) Тогда
ИмяОбщегоТипа = СтруктураТипаКоллекции.ИмяОбщегоТипа;
ТаблицаСтруктурТипаЭлемента = НоваяТаблицаТипов();
ИмяБиблиотеки = "";
МетаданныеОбъекта = СтруктураТипаКоллекции.Метаданные;
ИнфоТипа = ПолучитьИнфоТипаCOMОбъекта(МетаданныеОбъекта, ИмяОбщегоТипа, ИмяБиблиотеки);
Если ИнфоТипа = Неопределено Тогда
Возврат ТаблицаСтруктурТипаЭлемента;
КонецЕсли;
МассивИнфоТипа = ИнтерфейсыCOMОбъекта(ИнфоТипа, ИмяОбщегоТипа);
Для Каждого ИнфоТипа Из МассивИнфоТипа Цикл
Для Каждого Член Из ИнфоТипа.Members Цикл
Если Истина
//И Член.InvokeKind = 1 // метод // почему то иногда у него стоит 2 (например ADODB.Fields)
И ирОбщий.СтрокиРавныЛкс(Член.Name, "Item")
Тогда
ИмяОбщегоТипаЭлемента = ПолучитьТипЗначенияЧленаИнтерфейса(Член, ИмяБиблиотеки, ИнфоТипа);
Результат.Добавить(ИмяОбщегоТипаЭлемента);
Прервать;
КонецЕсли;
КонецЦикла;
КонецЦикла;
ИначеЕсли Истина
И СтруктураТипаКоллекции.ИмяОбщегоТипа = "ЭлементыФормы"
И ТипЗнч(СтруктураТипаКоллекции.СтрокаОписания) = Тип("СтрокаТаблицыЗначений")
И СтруктураТипаКоллекции.СтрокаОписания.Владелец().Колонки.Найти("ТипКонтекста") <> Неопределено
И СтруктураТипаКоллекции.СтрокаОписания.ТипКонтекста = "Форма"
Тогда
Результат = мМассивТиповЭлементовОбычнойФормы;
ИначеЕсли Ложь
Или СтруктураТипаКоллекции.ИмяОбщегоТипа = "ВсеЭлементыФормы"
Или (Истина
И СтруктураТипаКоллекции.ИмяОбщегоТипа = "ЭлементыФормы"
// Если не обычные ЭлементыФормы, то управляемые
//И ТипЗнч(СтруктураТипаКоллекции.СтрокаОписания) = Тип("СтрокаТаблицыЗначений")
//И СтруктураТипаКоллекции.СтрокаОписания.ТипКонтекста = "ФормаКлиентскогоПриложения"
)
Тогда
// Нужно для типа результата Найти()
Результат.Добавить("ГруппаФормы");
Результат.Добавить("ТаблицаФормы");
Результат.Добавить("ПолеФормы");
Результат.Добавить("КнопкаФормы");
Результат.Добавить("ДекорацияФормы");
Иначе
СтруктураКлюча = Новый Структура("Слово, ЯзыкПрограммы", СтруктураТипаКоллекции.ИмяОбщегоТипа, ЯзыкПрограммы);
НайденныеСтроки = ТаблицаОбщихТипов.НайтиСтроки(СтруктураКлюча);
Если НайденныеСтроки.Количество() > 0 Тогда
Если НайденныеСтроки[0].ТипЭлементаКоллекции <> "" Тогда
Результат = ирОбщий.СтрРазделитьЛкс(НайденныеСтроки[0].ТипЭлементаКоллекции, ",", Истина);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ЛиИмяСистемногоПеречисления(Знач ИмяОбщегоТипа) Экспорт
Если Найти(ИмяОбщегоТипа, ".") > 0 Тогда
Возврат Ложь;
КонецЕсли;
Если ирОбщий.СтрНачинаетсяСЛкс(ИмяОбщегоТипа, "Перечисление") Тогда
Возврат Истина;
КонецЕсли;
СтруктураКлюча = Новый Структура("БазовыйТип, ЯзыкПрограммы", "Перечисление" + ИмяОбщегоТипа, 0);
ЛиИмяСистемногоПеречисления = ТаблицаОбщихТипов.НайтиСтроки(СтруктураКлюча).Количество() > 0;
Возврат ЛиИмяСистемногоПеречисления;
КонецФункции
// Добавляет и заполняет строку в таблицу слов при условии отсутствия там строк по ключу (Слово, ТипСлова)
//
// Параметры:
// ТаблицаСлов - ТаблицаЗначений, ТабличнаяЧасть - обычно см. НоваяТаблицаСлов()
// Слово - Строка -
// ТипСлова - Строка
// ТаблицаТипов - ТаблицаЗначений
// ТипЗначения - -
// Определение - -
// Вытеснять - -
// СтарыеТипы - -
//
// Возвращаемое значение:
// -
//
Функция ДобавитьВТаблицуСлов(Знач ТаблицаСлов, Знач Слово, Знач ТипСлова = "Свойство", Знач ТаблицаТипов = Неопределено, Знач ТипЗначения = "??", Знач Определение = "", Знач Вытеснять = Истина,
Знач СтарыеТипы = Неопределено, Знач УстановитьНСлово = Ложь, Знач ЛиПолныйКонтрольУникальности = Ложь, Знач ТипЗначенияИндекс = "") Экспорт
Если ТипЗначения = "??" И СтарыеТипы <> Неопределено Тогда
СтарыйТип = СтарыеТипы[НРег(Слово)];
Если ЗначениеЗаполнено(СтарыйТип) Тогда
ТипЗначения = ТипЗначения + ", " + СтарыйТип;
КонецЕсли;
КонецЕсли;
Если ТипСлова = ПеречТипСлова.Конструкция Тогда
Если ТипЗначения = "??" Тогда
ТипЗначения = "";
КонецЕсли;
Если Не ЗначениеЗаполнено(Определение) Тогда
Определение = "Локальный";
КонецЕсли;
КонецЕсли;
Если ПустаяСтрока(ТипЗначенияИндекс) Тогда
//ТипЗначенияИндекс = ТипЗначенияИндексИзТипа(ТипЗначения); // Вроде бы здесь это бессмысленно, т.к. тут не бывает скобок. Они появляются позже.
ТипЗначенияИндекс = ТипЗначения;
КонецЕсли;
КлючПоиска = Новый Структура("Слово, ТипСлова", Слово, ТипСлова);
Если Ложь
Или (Истина
И ТипСлова <> ПеречТипСлова.Метод // Для ускорения, т.к. платформа не позволяет перегружать методы
И ТипСлова <> ПеречТипСлова.Конструкция)
Или ЛиПолныйКонтрольУникальности // Но методы могут дублироваться при объединении (например равноправных типов)
Тогда
НайденныеСтроки = ТаблицаСлов.НайтиСтроки(КлючПоиска);
Если НайденныеСтроки.Количество() > 0 Тогда
Если ТаблицаТипов <> Неопределено Тогда
// Например свойство "Параметры" перегружено в модуле конструктора запроса
Если Вытеснять Тогда
НайденныеСтроки[0].ТаблицаТипов = ТаблицаТипов;
НайденныеСтроки[0].ТипЗначения = ТипЗначения;
НайденныеСтроки[0].ТипЗначенияИндекс = ТипЗначенияИндекс;
НайденныеСтроки[0].Определение = Определение;
Иначе
ДобавитьВТаблицуТипов(НайденныеСтроки[0].ТаблицаТипов, ТаблицаТипов);
КонецЕсли;
КонецЕсли;
Возврат НайденныеСтроки[0];
КонецЕсли;
КонецЕсли;
СтрокаСлова = ТаблицаСлов.Добавить();
ЗаполнитьЗначенияСвойств(СтрокаСлова, КлючПоиска);
Если УстановитьНСлово Тогда
СтрокаСлова.НСлово = НРег(Слово);
КонецЕсли;
СтрокаСлова.ТипЗначения = ТипЗначения;
СтрокаСлова.ТипЗначенияИндекс = ТипЗначенияИндекс;
СтрокаСлова.Определение = Определение;
Если ЗначениеЗаполнено(ТаблицаТипов) Тогда
СтрокаСлова.ТаблицаТипов = ТаблицаТипов;
СтрокаОписания = ТаблицаТипов[0].СтрокаОписания;
ТипЗначенияВложенный = Неопределено;
Если СтрокаОписания <> Неопределено Тогда
Попытка
ТипЗначенияВложенный = СтрокаОписания.ТипЗначения;
Исключение
КонецПопытки;
КонецЕсли;
//Если Ложь
// //Или ТипЗначенияВложенный = Неопределено // Отключил, чтобы вычисление представлений примитивных типов не откладывалось
// //Или ТипЗначенияВложенный = "Произвольный"
//Тогда
// ТипЗначенияВложенный = "??";
//КонецЕсли;
СтрокаСлова.МожноУточнитьТип = Ложь
Или (Истина
И ТипЗначенияВложенный <> "??" // Нужно чтобы вычисляемые по коду свойства и функции не вычислялись сразу при заполнении списка автодополнения
И Лев(ТипЗначения, 2) = "??")
Или Найти(ТипЗначения, "<") > 0;
КонецЕсли;
//: Если ТипСлова = "Метод"
//: Если ТипСлова = "Свойство"
//: Если ТипСлова = "Конструкция"
Возврат СтрокаСлова;
КонецФункции
//.
// Параметры:
// ТипСловаФильтр - -
// БазовоеРасширениеКонфигурации - -
// ЯзыкПрограммы - -
// Конфигурация - -
// ВнешниеФункцииКомпоновкиДанных - -
// ВычислятьТипы - -
// ВнутриГруппыОбщихМодулей - -
// ФлагиКомпиляции - см. НовыеФлагиКомпиляции -
// СловоФильтр - -
// МодульМетаданных - см. МодульМетаданных -
// ВычислятьТипыМетодовМодулей - -
// ТаблицаСлов - см. НоваяТаблицаСлов -
// ЭтоЛокальныйКонтекст - -
// НаборыСлов - -
// СтрогийФильтр - -
// ДляЗаписи - -
// ТолькоСоЗначениями - -
// ЗапретГлобальногоКонтекста - -
Функция НовыеПараметрыЗаполненияСлов(Знач ТипСловаФильтр = Неопределено, Знач БазовоеРасширениеКонфигурации = "", Знач ЯзыкПрограммы = 0, Знач Конфигурация = Неопределено,
Знач ВнешниеФункцииКомпоновкиДанных = Истина, Знач ВычислятьТипы = Истина, Знач ВнутриГруппыОбщихМодулей = Ложь, Знач ФлагиКомпиляции = Неопределено, Знач СловоФильтр = Неопределено,
Знач МодульМетаданных = Неопределено, Знач ВычислятьТипыМетодовМодулей = Неопределено, Знач ТаблицаСлов = Неопределено, Знач ЭтоЛокальныйКонтекст = Ложь, Знач НаборыСлов = Неопределено,
Знач СтрогийФильтр = Ложь, Знач ДляЗаписи = Ложь, Знач ТолькоСоЗначениями = Ложь, Знач ЗапретГлобальногоКонтекста = Ложь, Знач ТекущийИндекс = Неопределено, Знач ДляСвойства = "",
Знач ЛиВместеСЛокальнымКонтекстом = Ложь, Знач ВиртуальнаяТаблица = Неопределено, Знач ПрименятьКонтракты = Ложь) Экспорт
Результат = Новый Структура;
Результат.Вставить("БазовоеРасширениеКонфигурации", БазовоеРасширениеКонфигурации);
Результат.Вставить("ВиртуальнаяТаблица", ВиртуальнаяТаблица);
Результат.Вставить("ВнешниеФункцииКомпоновкиДанных", ВнешниеФункцииКомпоновкиДанных);
Результат.Вставить("ВнутриГруппыОбщихМодулей", ВнутриГруппыОбщихМодулей);
Результат.Вставить("ВычислятьТипы", ВычислятьТипы); // - ЗаполнятьТипы
Результат.Вставить("ВычислятьТипыМетодовМодулей", ВычислятьТипыМетодовМодулей);
Результат.Вставить("ДляЗаписи", ДляЗаписи);
Результат.Вставить("ДляСвойства", ДляСвойства);
Результат.Вставить("ЗапретГлобальногоКонтекста", ЗапретГлобальногоКонтекста);
Результат.Вставить("Конфигурация", Конфигурация);
Результат.Вставить("ЛиВместеСЛокальнымКонтекстом", ЛиВместеСЛокальнымКонтекстом);
Результат.Вставить("МодульМетаданных", МодульМетаданных);
Результат.Вставить("НаборыСлов", НаборыСлов);
Результат.Вставить("ПрименятьКонтракты", ПрименятьКонтракты И Не ЭтоЛокальныйКонтекст);
Результат.Вставить("СловоФильтр", СловоФильтр);
Результат.Вставить("СтрогийФильтр", СтрогийФильтр);
Результат.Вставить("ТаблицаСлов", ТаблицаСлов);
Результат.Вставить("ТекущийИндекс", ТекущийИндекс);
Результат.Вставить("ТипСловаФильтр", ТипСловаФильтр);
Результат.Вставить("ТолькоСоЗначениями", ТолькоСоЗначениями);
Результат.Вставить("ФлагиКомпиляции", ФлагиКомпиляции);
Результат.Вставить("ЭтоЛокальныйКонтекст", ЭтоЛокальныйКонтекст);
Результат.Вставить("ЯзыкПрограммы", ЯзыкПрограммы);
//: Если ТипСловаФильтр = "Метод"
//: Если ТипСловаФильтр = "Свойство"
//: Если ТипСловаФильтр = "Конструкция"
Возврат Результат;
КонецФункции
// Получает таблицу слов указанной структуры типа.
//
// Параметры:
// СтруктураТипа - см. НоваяСтруктураТипа - описание типа.
// ПараметрыЗаполнения - см. НовыеПараметрыЗаполненияСлов - "" для основная конфигурация, "*" для все расширения
//
// Возвращаемое значение:
// ТаблицаЗначений - с колонками "Слово", "ТипСлова", "ТаблицаТипов", "Определение".
//
Функция ТаблицаСловИзСтруктурыТипа(Знач СтруктураТипа, Знач ПараметрыЗаполнения = Неопределено) Экспорт
ИнициацияОписанияМетодовИСвойств();
Если ПараметрыЗаполнения = Неопределено Тогда
ПараметрыЗаполнения = НовыеПараметрыЗаполненияСлов();
КонецЕсли;
Если ПараметрыЗаполнения.ФлагиКомпиляции = Неопределено Тогда
ФлагиКомпиляции = НовыеФлагиКомпиляции();
КонецЕсли;
КлючКэширования = Неопределено;
ЭтоКонтракт = Истина
И ПараметрыЗаполнения.ПрименятьКонтракты
И ТипЗнч(СтруктураТипа.Метаданные) = Тип("ОбъектМетаданных")
И ирОбщий.СтрКончаетсяНаЛкс(СтруктураТипа.Метаданные.Имя, "Кнт", Истина);
Если Истина
И Не ПараметрыЗаполнения.ВнутриГруппыОбщихМодулей
И Не ЭтоКонтракт
Тогда
ПараметрыЗаполнения.ТаблицаСлов = СловаКонтекстаПредопределенные(СтруктураТипа, ПараметрыЗаполнения, КлючКэширования);
КонецЕсли;
Если КлючКэширования <> Истина Тогда
Если ЭтоКонтракт Тогда
СтарыйСтрогийФильтр = ПараметрыЗаполнения.СтрогийФильтр;
ПараметрыЗаполнения.СтрогийФильтр = Истина;
КонецЕсли;
ПараметрыЗаполнения.ТаблицаСлов = СловаКонтекстаМетаданные(СтруктураТипа, ПараметрыЗаполнения, КлючКэширования);
Если ЭтоКонтракт Тогда
ПараметрыЗаполнения.СтрогийФильтр = СтарыйСтрогийФильтр;
КонецЕсли;
Если Истина
И ПараметрыЗаполнения.СловоФильтр = Неопределено
И КлючКэширования <> Неопределено
Тогда
ДобавитьТаблицуСловВГлобальныйКэш(ПараметрыЗаполнения.ТаблицаСлов, КлючКэширования, ПараметрыЗаполнения.НаборыСлов);
КонецЕсли;
КонецЕсли;
Возврат ПараметрыЗаполнения.ТаблицаСлов;
КонецФункции
Функция ИмяКолонкиФлагаТаблицыТипов() Экспорт
Возврат "ДержательМетаданных";
КонецФункции
// Получает новую структуру типа.
//
// Параметры:
// Нет.
//
// Возвращаемое значение:
//
Функция НоваяТаблицаДополнительныхТипов() Экспорт
ТаблицаСтруктурТипа = Новый ТаблицаЗначений;
ТаблицаСтруктурТипа.Колонки.Добавить("ИмяОбщегоТипа", Новый ОписаниеТипов("Строка"));
ТаблицаСтруктурТипа.Колонки.Добавить("Метаданные");
//ТаблицаСтруктурТипа.Колонки.Добавить("ВключатьСвойства", Новый ОписаниеТипов("Булево"));
ТаблицаСтруктурТипа.Колонки.Добавить("НеВключатьМетоды", Новый ОписаниеТипов("Булево"));
Возврат ТаблицаСтруктурТипа;
КонецФункции
// Получает допустимые типы (строку) из таблицы структур типа.
//
// Параметры:
// ТаблицаТипов - ТаблицаЗначений.
//
// Возвращаемое значение:
// Строка.
//
Функция ДопустимыеТипыИзТаблицыСтруктурТипа(ТаблицаТипов) Экспорт
СтрокаСериализованныхТипов = "";
Для Каждого СтруктураТипа Из ТаблицаТипов Цикл
СтрокаСериализованныхТипов = СтрокаСериализованныхТипов + ";" + СтруктураТипаВСтрокуВнутр(СтруктураТипа);
КонецЦикла;
СтрокаСериализованныхТипов = Сред(СтрокаСериализованныхТипов, 2);
Возврат СтрокаСериализованныхТипов;
КонецФункции
Функция ДопустимыеТипыИзОписанияТипов(ОписаниеТипов) Экспорт
ТаблицаТипов = ТаблицаТиповИзОписанияТипов(ОписаниеТипов);
ДопустимыеТипы = ДопустимыеТипыИзТаблицыСтруктурТипа(ТаблицаТипов);
Возврат ДопустимыеТипы;
КонецФункции
// Получает представление допустимых типов.
//
// Параметры:
// ДопустимыеТипы - Строка.
//
// Возвращаемое значение:
// СтрокаПредставления - Строка.
//
Функция ПредставлениеДопустимыхТипов(ДопустимыеТипы) Экспорт
ТаблицаТипов = ТаблицаТиповИзДопустимыхТипов(ДопустимыеТипы);
СтрокаПредставления = "";
Для Каждого СтруктураТипа Из ТаблицаТипов Цикл
СтрокаПредставления = СтрокаПредставления + ", " + ИмяТипаИзСтруктурыТипа(СтруктураТипа);
ТипМетаданных = ТипЗнч(СтруктураТипа.Метаданные);
Если ТипМетаданных = Тип("КвалификаторыДаты") Тогда
Квалификаторы = СтруктураТипа.Метаданные;
Если Квалификаторы.ЧастиДаты = ЧастиДаты.Время Тогда
ПредставлениеСоставаДаты = "В";
ИначеЕсли Квалификаторы.ЧастиДаты = ЧастиДаты.Дата Тогда
ПредставлениеСоставаДаты = "Д";
ИначеЕсли Квалификаторы.ЧастиДаты = ЧастиДаты.ДатаВремя Тогда
ПредставлениеСоставаДаты = "ДВ";
КонецЕсли;
СтрокаПредставления = СтрокаПредставления + "(" + ПредставлениеСоставаДаты + ")";
ИначеЕсли ТипМетаданных = Тип("КвалификаторыСтроки") Тогда
Квалификаторы = СтруктураТипа.Метаданные;
СтрокаПредставления = СтрокаПредставления + "("
+ Квалификаторы.Длина + ","
+ ?(Квалификаторы.ДопустимаяДлина = ДопустимаяДлина.Фиксированная, "Ф", "П") + ")";
ИначеЕсли ТипМетаданных = Тип("КвалификаторыЧисла") Тогда
Квалификаторы = СтруктураТипа.Метаданные;
СтрокаПредставления = СтрокаПредставления + "("
+ ?(Квалификаторы.ДопустимыйЗнак = ДопустимыйЗнак.Неотрицательный, "Н", "")
+ Квалификаторы.Разрядность + ","
+ Квалификаторы.РазрядностьДробнойЧасти + ")";
КонецЕсли;
КонецЦикла;
СтрокаПредставления = Сред(СтрокаПредставления, 3);
Возврат СтрокаПредставления;
КонецФункции // ПредставлениеДопустимыхТипов()
// Получает структуру типа из значения.
//
// Параметры:
// Значение - Произвольный;
// *ЯзыкПрограммы - Число, *0;
// *ШаблонСтруктурыТипа - Структура, СтрокаТаблицыЗначений, *Неопределено - содержит значения по умолчанию для новой структуры типа.
//
// Возвращаемое значение:
// см. НоваяСтруктураТипа() -
//
Функция СтруктураТипаИзЗначения(Значение, ЯзыкПрограммы = 0, ШаблонСтруктурыТипа = Неопределено, Знач РазрешитьЛюбойТипВКачествеМетаданных = Ложь) Экспорт
Если Ложь
Или РазрешитьЛюбойТипВКачествеМетаданных
Или мМассивТиповСМетаданными.Найти(ТипЗнч(Значение)) <> Неопределено
Тогда
Если ШаблонСтруктурыТипа = Неопределено Тогда
ШаблонСтруктурыТипа = Новый Структура;
КонецЕсли;
Если ТипЗнч(ШаблонСтруктурыТипа) = Тип("Структура") Тогда
Если ирОбщий.СвойствоСтруктурыЛкс(ШаблонСтруктурыТипа, "Метаданные") = Неопределено Тогда
ШаблонСтруктурыТипа.Вставить("Метаданные", Значение);
КонецЕсли;
КонецЕсли;
КонецЕсли;
СтруктураТипа = СтруктураТипаИзКонкретногоТипа(ТипЗнч(Значение), ЯзыкПрограммы, ШаблонСтруктурыТипа);
Если СтруктураТипа.ИмяОбщегоТипа = "COMОбъект" Тогда
СтруктураТипа.ИмяОбщегоТипа = ПолноеИмяТипаCOMОбъекта(Значение);
//ИначеЕсли СтруктураТипа.ИмяОбщегоТипа = "ПеречислимоеСвойствоОбъектовМетаданных" Тогда
// // Не работает. Оказывается одно ПеречислимоеСвойствоОбъектовМетаданных может иметь много экземпляров
// СтрокиСвойствПеречислений = ТаблицаКонтекстов.НайтиСтроки(Новый Структура("ТипКонтекста", "ПеречислимыеСвойстваОбъектовМетаданных"));
// Для Каждого СтрокиСвойстваПеречисления Из СтрокиСвойствПеречислений Цикл
// Если Метаданные.СвойстваОбъектов[СтрокиСвойстваПеречисления.Слово] = Значение Тогда
// СтруктураТипа.ИмяОбщегоТипа = "ПеречислениеМетаданных" + СтрокиСвойстваПеречисления.Слово;
// Прервать;
// КонецЕсли;
// КонецЦикла;
КонецЕсли;
ИмяОбщегоТипа = СтруктураТипа.ИмяОбщегоТипа;
//Если Ложь
// Или (Истина
// И ИмяОбщегоТипа = "СтрокаТаблицыЗначений"
// И ТипЗнч(СтруктураТипа.Метаданные) <> Тип("ТаблицаЗначений"))
// Или (Истина
// И ИмяОбщегоТипа = "СтрокаДереваЗначений"
// И ТипЗнч(СтруктураТипа.Метаданные) <> Тип("ДеревоЗначений"))
// Или (Истина
// И ИмяОбщегоТипа = "ВыборкаИзРезультатаЗапроса"
// И ТипЗнч(СтруктураТипа.Метаданные) <> Тип("РезультатЗапроса"))
//Тогда
// Попытка
// СтруктураТипа.Метаданные = Значение.Владелец();
// Исключение
// // Строка была удалена из коллекции
// КонецПопытки;
//КонецЕсли;
Если ирОбщий.ЛиИмяТипаВнешнегоОбъектаМетаданныхЛкс(ИмяОбщегоТипа) Тогда
//! Значение = 0 // ВнешняяОбработкаОбъект
МетаданныеЗначения = Значение.Метаданные();
ЛиНеУчитыватьПодтип = (ЯзыкПрограммы <> 0) И СтруктураТипа.ТипЯзыка <> "ЗначениеВЗапросе";
ИмяОбщегоТипа = ИмяОбщегоТипаИзТипаЗначенияСМетаданными(ТипЗнч(Значение), МетаданныеЗначения, ЛиНеУчитыватьПодтип);
СтруктураТипа.Метаданные = МетаданныеЗначения;
СтруктураТипа.ДержательМетаданных = Значение;
КлючПоиска = Новый Структура("Слово", ИмяОбщегоТипа);
НайденныеСтроки = ТаблицаОбщихТипов.НайтиСтроки(КлючПоиска);
Если НайденныеСтроки.Количество() > 0 Тогда
СтруктураТипа.ИмяОбщегоТипа = НайденныеСтроки[0].Слово;
//Если СтруктураТипа.СтрокаОписания = Неопределено Тогда
// СтруктураТипа.СтрокаОписания = НайденныеСтроки[0];
//КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Ложь
Или ИмяОбщегоТипа = "Форма"
Или ИмяОбщегоТипа = "ПолеВвода"
//Или ИмяОбщегоТипа = "КолонкаТабличногоПоля" // в другом месте делаем
Или ИмяОбщегоТипа = "ТабличноеПоле"
Или ИмяОбщегоТипа = "УправляемаяФорма"
Или ИмяОбщегоТипа = "ФормаКлиентскогоПриложения"
Или ЛиИмяТипаЭлементаУправляемойФормы(ИмяОбщегоТипа)
Тогда
ИмяОбщегоТипаРасширения = ИмяТипаРасширенияЭлементаФормы(ИмяОбщегоТипа, Значение);
Если ИмяОбщегоТипаРасширения <> Неопределено Тогда
СтруктураТипа.ИмяОбщегоТипа = ИмяОбщегоТипаРасширения;
КонецЕсли;
КонецЕсли;
Если ИмяОбщегоТипа = "Форма" Тогда
//СтруктураТипа.ДержательМетаданных = Значение; // Для формы тут должно быть имя расширения, а не сама форма
КонецЕсли;
Возврат СтруктураТипа;
КонецФункции
Функция ВсеИменаСобытийЭлементовФормы() Экспорт
Если мВсеИменаСобытийЭлементовФормы = Неопределено Тогда
ВсеИменаСобытий = ТаблицаКонтекстов.НайтиСтроки(Новый Структура("ЯзыкПрограммы, ТипЯзыка, ТипСлова", 0, "", "Событие"));
мВсеИменаСобытийЭлементовФормы = Новый Структура;
Для Каждого СтрокаСобытия Из ВсеИменаСобытий Цикл
Если Ложь
Или СтрокаСобытия.ТипКонтекста = "Глобальный"
Или ирОбщий.СтрНачинаетсяСЛкс(СтрокаСобытия.ТипКонтекста, "Модуль")
Или ирОбщий.ЛиИмяТипаФормыЛкс(СтрокаСобытия.ТипКонтекста, Истина)
Или Найти(СтрокаСобытия.ТипКонтекста, ".")
Тогда
Продолжить;
КонецЕсли;
мВсеИменаСобытийЭлементовФормы.Вставить(СтрокаСобытия.Слово, СтрокаСобытия);
КонецЦикла;
КонецЕсли;
Возврат мВсеИменаСобытийЭлементовФормы;
КонецФункции
Функция ОписаниеОбщегоТипа(Знач ИмяОбщегоТипа, Знач ЯзыкПрограммы = 0) Экспорт
ИмяОбщегоТипа = ирОбщий.ПервыйФрагментЛкс(ИмяОбщегоТипа, "["); // - для результата НайтиФайлы()
СтрокиОбщегоТипа = ТаблицаОбщихТипов.НайтиСтроки(Новый Структура("Слово, ЯзыкПрограммы", ИмяОбщегоТипа, ЯзыкПрограммы));
Если СтрокиОбщегоТипа.Количество() > 0 Тогда
Результат = СтрокиОбщегоТипа[0];
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ЛиИмяТипаЭлементаУправляемойФормы(Знач ИмяОбщегоТипа) Экспорт
Результат = Ложь
Или ИмяОбщегоТипа = "ДекорацияФормы"
Или ИмяОбщегоТипа = "ПолеФормы"
Или ИмяОбщегоТипа = "КнопкаФормы"
Или ИмяОбщегоТипа = "ГруппаФормы"
Или ИмяОбщегоТипа = "ТаблицаФормы";
Возврат Результат;
КонецФункции
// . Мультиметка638663811
//
// Параметры:
// БазовоеИмяОбщегоТипа - -
// ЭлементИлиФорма - Форма, ПолеФормы, ПолеВвода -
//
// Возвращаемое значение:
// -
//
Функция ИмяТипаРасширенияЭлементаФормы(БазовоеИмяОбщегоТипа, ЭлементИлиФорма = Неопределено) Экспорт
ИмяОбщегоТипаРасширения = Неопределено;
РасширяющийТип = Неопределено;
Если Ложь Тогда
#Если Клиент Тогда
ИначеЕсли Ложь
Или БазовоеИмяОбщегоТипа = "УправляемаяФорма"
Или БазовоеИмяОбщегоТипа = "ФормаКлиентскогоПриложения"
Тогда
БазовоеИмяОбщегоТипа = "ФормаКлиентскогоПриложения";
СтруктураРасширяющегоТипа = СтруктураТипаОбъектаОбычнойФормы(ЭлементИлиФорма);
Если СтруктураРасширяющегоТипа <> Неопределено Тогда
РасширяющийТип = СтруктураРасширяющегоТипа.ИмяОбщегоТипа;
Иначе
КлючОсновногоОбъекта = ирОбщий.КлючОсновногоОбъектаФормыЛкс(ЭлементИлиФорма);
Если КлючОсновногоОбъекта <> Неопределено Тогда
СтруктураРасширяющегоТипа = СтруктураТипаИзЗначения(КлючОсновногоОбъекта);
ИмяОбщегоТипаОбъекта = СтруктураРасширяющегоТипа.ИмяОбщегоТипа;
Если Найти(ИмяОбщегоТипаОбъекта, "Ссылка.") > 0 Тогда
Если Ложь
Или ирОбщий.СтрНачинаетсяСЛкс(ИмяОбщегоТипаОбъекта, "Справочник")
Или ирОбщий.СтрНачинаетсяСЛкс(ИмяОбщегоТипаОбъекта, "Документ")
Или ирОбщий.СтрНачинаетсяСЛкс(ИмяОбщегоТипаОбъекта, "ПланВидовХарактеристик")
Или ирОбщий.СтрНачинаетсяСЛкс(ИмяОбщегоТипаОбъекта, "Задача")
Или ирОбщий.СтрНачинаетсяСЛкс(ИмяОбщегоТипаОбъекта, "БизнесПроцесс")
Тогда
РасширяющийТип = СтрЗаменить(ИмяОбщегоТипаОбъекта, "Ссылка.", "Объект.");
Иначе
РасширяющийТип = "СсылочныйОбъект";
КонецЕсли;
Иначе
РасширяющийТип = СтрЗаменить(СтруктураРасширяющегоТипа.ИмяОбщегоТипа, "КлючЗаписи.", "Запись.");
КонецЕсли;
Иначе
Попытка
Пустышка = ЭлементИлиФорма.Параметры.РежимВыбора;
ЭтоФормаДинамическогоСписка = ТипЗнч(ЭлементИлиФорма.Список) = Тип("ДинамическийСписок");
Исключение
ЭтоФормаДинамическогоСписка = Ложь;
КонецПопытки;
Если ЭтоФормаДинамическогоСписка Тогда
РасширяющийТип = "ДинамическийСписок";
КонецЕсли;
КонецЕсли;
КонецЕсли;
ИначеЕсли Ложь
Или БазовоеИмяОбщегоТипа = "ДекорацияФормы"
Или БазовоеИмяОбщегоТипа = "ПолеФормы"
Или БазовоеИмяОбщегоТипа = "ГруппаФормы"
Тогда
Если Ложь
Или ирОбщий.ЛиФормаИлиИмитаторЛкс(ЭлементИлиФорма)
Или ТипЗнч(ЭлементИлиФорма) = Тип("Структура") И Не ЭлементИлиФорма.Свойство("Вид")
Тогда
Пустышка = 0; // TODO Приходим сюда при вводе имени события в ДинамическоеПолеФормы.Установитьдействие("
Иначе
Если Истина
И ТипЗнч(ЭлементИлиФорма.Вид) <> Тип("Строка")
И ЗначениеЗаполнено(ЭлементИлиФорма.Вид)
Тогда
ИмяВида = ПолучитьПолноеИмяПредопределенногоЗначения(ЭлементИлиФорма.Вид);
Иначе
ИмяВида = ЭлементИлиФорма.Вид;
КонецЕсли;
РасширяющийТип = ирОбщий.ПоследнийФрагментЛкс(ИмяВида);
КонецЕсли;
ИначеЕсли БазовоеИмяОбщегоТипа = "ТаблицаФормы" Тогда
РасширяющийТип = ирОбщий.ОбщийТипДанныхТабличногоПоляЛкс(ЭлементИлиФорма);
Если РасширяющийТип = "Список" Тогда
РасширяющийТип = "ДинамическийСписок";
КонецЕсли;
ИначеЕсли БазовоеИмяОбщегоТипа = "Форма" Тогда
СтруктураРасширяющегоТипа = СтруктураТипаОбъектаОбычнойФормы(ЭлементИлиФорма);
Если СтруктураРасширяющегоТипа <> Неопределено Тогда
РасширяющийТип = СтруктураРасширяющегоТипа.ИмяОбщегоТипа;
КонецЕсли;
Иначе
#КонецЕсли
Попытка
ДанныеЭлементаФормы = ЭлементИлиФорма.Значение;
Исключение
// Случается из-за особенностей платформы. Иногда она убирает это свойство из элемента управления.
КонецПопытки;
СтруктураРасширяющегоТипа = СтруктураТипаИзЗначения(ДанныеЭлементаФормы);
РасширяющийТип = СтруктураРасширяющегоТипа.ИмяОбщегоТипа;
Если ирОбщий.СтрКончаетсяНаЛкс(РасширяющийТип, ".<Имя табличной части>") Тогда
РасширяющийТип = "ТабличнаяЧасть";
КонецЕсли;
Если ЛиИмяСистемногоПеречисления(СтруктураРасширяющегоТипа.ИмяОбщегоТипа) Тогда
РасширяющийТип = "Системное перечисление";
КонецЕсли;
КонецЕсли;
Если РасширяющийТип <> Неопределено Тогда
Если РасширяющийТип = "ВнешняяОбработкаОбъект.<Имя внешней обработки>" Тогда
РасширяющийТип = "ОбработкаОбъект.<Имя обработки>";
ИначеЕсли РасширяющийТип = "ВнешнийОтчетОбъект.<Имя внешнего отчета>" Тогда
РасширяющийТип = "ОтчетОбъект.<Имя отчета>";
КонецЕсли;
СтруктураКлюча = Новый Структура("РасширяющийТип, ОсновнойТип", РасширяющийТип, БазовоеИмяОбщегоТипа);
МассивНайденных = ТаблицаРасширенийТипов.НайтиСтроки(СтруктураКлюча);
Если МассивНайденных.Количество() > 0 Тогда
ИмяОбщегоТипаРасширения = МассивНайденных[0].Расширение;
КонецЕсли;
КонецЕсли;
Возврат ИмяОбщегоТипаРасширения;
КонецФункции
Функция ОписаниеРасширенногоТипа(Знач РасширенныйТип) Экспорт
Если ирОбщий.СтрНачинаетсяСЛкс(РасширенныйТип, "ОбъектМетаданных") Тогда
//Результат = Новый Структура(ирОбщий.СтрСоединитьЛкс(ТаблицаРасширенийТипов.Колонки,,,,, "Имя"));
////! Результат = ирОбщий.СтруктураИзСтрокиТаблицыИлиДереваИлиВыборкиЛкс(ТаблицаРасширенийТипов[0])
Результат = Новый Структура("ОсновнойТип, РасширяющийТип, Расширение");
Результат.ОсновнойТип = "ОбъектМетаданных";
Иначе
Результат = ТаблицаРасширенийТипов.Найти(РасширенныйТип, "Расширение");
КонецЕсли;
Возврат Результат;
КонецФункции
Функция УникальныйИдентификаторИзСтроки(Текст) Экспорт
Цифра = "[a-fA-F0-9]";
мРегВыражение.Pattern = "(" + ирОбщий.СтрокаПовторомЛкс(Цифра, 32) + ")|("
+ ирОбщий.СтрокаПовторомЛкс(Цифра, 8) + "-"
+ ирОбщий.СтрокаПовторомЛкс(Цифра, 4) + "-"
+ ирОбщий.СтрокаПовторомЛкс(Цифра, 4) + "-"
+ ирОбщий.СтрокаПовторомЛкс(Цифра, 4) + "-"
+ ирОбщий.СтрокаПовторомЛкс(Цифра, 12) + ")";
Вхождения = мРегВыражение.НайтиВхождения(Текст);
Если Вхождения.Количество() > 0 Тогда
Вхождение = Вхождения[0];
Если Вхождение.SubMatches(1) <> Неопределено Тогда
УникальныйИдентификатор = Новый УникальныйИдентификатор(Вхождение.SubMatches(1));
Иначе
УникальныйИдентификатор = Новый УникальныйИдентификатор(ирОбщий.ПолучитьГУИДПрямойИзИнверсногоЛкс(Вхождение.SubMatches(0)));
КонецЕсли;
КонецЕсли;
Возврат УникальныйИдентификатор;
КонецФункции
// Неполный сериализатор структуры типа.
//
// Параметры:
// СтруктураТипа - Структура.
//
// Возвращаемое значение:
// Строка.
//
Функция СтруктураТипаВСтрокуВнутр(СтруктураТипа) Экспорт
ОписательТипа = Новый Структура("ИмяОбщегоТипа, Метаданные");
ЗаполнитьЗначенияСвойств(ОписательТипа, СтруктураТипа, "ИмяОбщегоТипа");
ТипМетаданных = ТипЗнч(СтруктураТипа.Метаданные);
Если ТипМетаданных = Тип("Неопределено") Тогда
//ОписательТипа.Метаданные = СтруктураТипа.Метаданные.ПолноеИмя();
ИначеЕсли ТипМетаданных = Тип("ОбъектМетаданных") Тогда
ОписательТипа.Метаданные = СтруктураТипа.Метаданные.ПолноеИмя();
ИначеЕсли Ложь
Или ТипМетаданных = Тип("КвалификаторыДаты")
Или ТипМетаданных = Тип("КвалификаторыСтроки")
Или ТипМетаданных = Тип("КвалификаторыЧисла")
Тогда
Поток = Новый ЗаписьXML;
Поток.УстановитьСтроку();
СериализаторXDTO.ЗаписатьXML(Поток, СтруктураТипа.Метаданные);
ОписательТипа.Метаданные = Новый ХранилищеЗначения(Поток.Закрыть());
Иначе
//ОписательТипа.Метаданные = СтруктураТипа.Метаданные;
КонецЕсли;
Результат = ЗначениеВСтрокуВнутр(ОписательТипа);
Возврат Результат;
КонецФункции // СтруктураТипаВСтрокуВнутр()
Функция ИмяОбщегоТипаИзТипа(Знач ТипЭлемента) Экспорт
Если мКэшИменТипов = Неопределено Тогда
мКэшИменТипов = Новый Соответствие;
КонецЕсли;
ИмяОбщегоТипа = мКэшИменТипов[ТипЭлемента];
Если ИмяОбщегоТипа = Неопределено Тогда
ИмяОбщегоТипа = СтруктураТипаИзКонкретногоТипа(ТипЭлемента).ИмяОбщегоТипа;
мКэшИменТипов[ТипЭлемента] = ИмяОбщегоТипа;
КонецЕсли;
Возврат ИмяОбщегоТипа;
КонецФункции
// Зависит от текущего языка системы. Поддерживаются Рус и Анг языки.
//
// Параметры:
// КонкрентыйТип - Тип -
// МетаданныеТипа - ОбъектМетаданных -
// ЛиНеУчитыватьПодтип - Булево -
//
// Возвращаемое значение:
// Строка -
//
Функция ИмяОбщегоТипаИзТипаЗначенияСМетаданными(Знач КонкрентыйТип, Знач МетаданныеТипа, Знач ЛиНеУчитыватьПодтип)
КонкрентыйТип = НРег(КонкрентыйТип);
Если Ложь
Или Найти(КонкрентыйТип, "(точка маршрута)") > 0
Или Найти(КонкрентыйТип, "(route point)") > 0
Тогда
ИмяОбщегоТипа = "ТочкаМаршрутаБизнесПроцессаСсылка.<Имя бизнес-процесса>";
Возврат ИмяОбщегоТипа;
КонецЕсли;
ИмяОбщегоТипа = ирОбщий.КорневойТипКонфигурацииЛкс(МетаданныеТипа);
Подтип = "";
ИмяЭлементаПодтипа = "";
Если ЛиНеУчитыватьПодтип Тогда
Подтип = "";
ИначеЕсли Ложь
Или Найти(КонкрентыйТип, "объект:") > 0
Или Найти(КонкрентыйТип, "object:") > 0
Тогда
//Если Истина
// И Не ИмяОбщегоТипа = "ВнешняяОбработка"
// И Не ИмяОбщегоТипа = "ВнешнийОтчет"
//Тогда
Подтип = "Объект";
//КонецЕсли;
ИначеЕсли Ложь
Или Найти(КонкрентыйТип, "выборка:") > 0
Или Найти(КонкрентыйТип, "selection:") > 0
Тогда
Подтип = "Выборка";
ИначеЕсли Ложь
Или Найти(КонкрентыйТип, "список:") > 0
Или Найти(КонкрентыйТип, "list:") > 0
Тогда
Подтип = "Список";
ИначеЕсли Ложь
Или Найти(КонкрентыйТип, "менеджер:") > 0
Или Найти(КонкрентыйТип, "manager:") > 0
Тогда
Подтип = "Менеджер";
ИначеЕсли Ложь
Или Найти(КонкрентыйТип, "менеджер значения:") > 0
Или Найти(КонкрентыйТип, "value manager:") > 0
Тогда
Подтип = "МенеджерЗначения";
ИначеЕсли Ложь
Или Найти(КонкрентыйТип, "менеджер ws-ссылки:") > 0
Или Найти(КонкрентыйТип, "ws-reference manager:") > 0
Тогда
Подтип = "Менеджер";
ИначеЕсли Ложь
Или Найти(КонкрентыйТип, "табличная часть:") > 0
Или Найти(КонкрентыйТип, "tabular section:") > 0
Тогда
Подтип = "ТабличнаяЧасть";
ИмяЭлементаПодтипа = "<Имя табличной части>";
ИначеЕсли Ложь
Или Найти(КонкрентыйТип, "табличная часть строка:") > 0
Или Найти(КонкрентыйТип, "tabular section row:") > 0
Тогда
Подтип = "ТабличнаяЧастьСтрока";
ИмяЭлементаПодтипа = "<Имя табличной части>";
ИначеЕсли Ложь // Связано со следующим условием!
Или Найти(КонкрентыйТип, "виды субконто:") > 0
Или Найти(КонкрентыйТип, "ext dimension types:") > 0
Тогда
Подтип = "ВидыСубконто";
ИначеЕсли Ложь // Связано со следующим условием!
Или Найти(КонкрентыйТип, "ext dimensions:") > 0
Или Найти(КонкрентыйТип, "субконто:") > 0
Тогда
Подтип = "Субконто";
ИначеЕсли Ложь
Или Найти(КонкрентыйТип, "виды субконто строка:") > 0
Или Найти(КонкрентыйТип, "ext dimension types row:") > 0
Тогда
Подтип = "ВидыСубконтоСтрока";
ИначеЕсли Ложь
Или Найти(КонкрентыйТип, "набор записей:") > 0
Или Найти(КонкрентыйТип, "record set:") > 0
Тогда
Подтип = "НаборЗаписей";
ИначеЕсли Ложь
Или Найти(КонкрентыйТип, "ключ записи:") > 0
Или Найти(КонкрентыйТип, "record key:") > 0
Тогда
Подтип = "КлючЗаписи";
ИначеЕсли Ложь
Или Найти(КонкрентыйТип, "запись:") > 0
Или Найти(КонкрентыйТип, "record:") > 0
Тогда
Подтип = "Запись";
ИначеЕсли Ложь
Или Найти(КонкрентыйТип, "менеджер записи:") > 0
Или Найти(КонкрентыйТип, "record manager:") > 0
Тогда
Подтип = "МенеджерЗаписи";
// Пришлось сделать так из-за изменения представления ссылочных типов в 8.2 http://partners.v8.1c.ru/forum/thread.jsp?id=830683#830683
//ИначеЕсли Найти(КонкрентыйТип, "ссылка:") > 0 Тогда
Иначе//Если Найти(КонкрентыйТип, ":") = 0 Тогда
Подтип = "Ссылка";
КонецЕсли;
СтрокаКорневогоТипа = ОписаниеТипаМетаОбъектов(ИмяОбщегоТипа);
СтрокаВида = ТаблицаИменЭлементовКоллекций.Найти(СтрокаКорневогоТипа.Множественное, "ИмяКоллекции");
Если СтрокаВида <> Неопределено Тогда
Если ИмяОбщегоТипа = "ВнешнийИсточникДанных" Тогда
Если ЛиНеУчитыватьПодтип Тогда
ИмяОбщегоТипа = ИмяОбщегоТипа + "." + СтрокаВида.ИмяЭлементаКоллекции + ".Таблица.<Имя таблицы>"; // Тут другое имя элемента коллекции
Иначе
ИмяОбщегоТипа = ИмяОбщегоТипа + "Таблица" + Подтип + "." + СтрокаВида.ИмяЭлементаКоллекции;
СтрокаВида = ТаблицаИменЭлементовКоллекций.Найти("Таблицы", "ИмяКоллекции");
ИмяОбщегоТипа = ИмяОбщегоТипа + "." + СтрокаВида.ИмяЭлементаКоллекции;
КонецЕсли;
Иначе
ИмяОбщегоТипа = ИмяОбщегоТипа + Подтип + "." + СтрокаВида.ИмяЭлементаКоллекции;
КонецЕсли;
КонецЕсли;
Если ИмяЭлементаПодтипа <> "" Тогда
ИмяОбщегоТипа = ИмяОбщегоТипа + "." + ИмяЭлементаПодтипа;
КонецЕсли;
Возврат ИмяОбщегоТипа;
КонецФункции
//.
// Возвращаемое значение:
// Структура -
Функция ИменаТиповМетаданныхСМенеджерами() Экспорт
Если мИменаТиповМетаданныхСМенеджерами <> Неопределено Тогда
Возврат мИменаТиповМетаданныхСМенеджерами;
КонецЕсли;
мИменаТиповМетаданныхСМенеджерами = Новый Структура;
ИмяДочернегоТипаМД = "МодульМенеджера";
Для Каждого СтрокаТипаМетаОбъекта Из ирКэш.ТипыМетаОбъектов(Истина, Ложь) Цикл
ОтборСвойств = Новый Структура("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка, НСлово, ТипСлова",
"ОбъектМетаданных" + СтрокаТипаМетаОбъекта.Единственное, 0, "", НРег(ИмяДочернегоТипаМД), "Свойство");
Если ТаблицаКонтекстов.НайтиСтроки(ОтборСвойств).Количество() = 0 Тогда
Продолжить;
КонецЕсли;
мИменаТиповМетаданныхСМенеджерами.Вставить(СтрокаТипаМетаОбъекта.Множественное);
КонецЦикла;
Возврат мИменаТиповМетаданныхСМенеджерами;
КонецФункции
// Получает структуру типа из конкретного типа.
//
// Параметры:
// КонкрентыйТип - Тип, Строка - тип либо его представление (для неметаданных типов);
// ЯзыкПрограммы - Число;
// ШаблонСтруктурыТипа - см. НоваяСтруктураТипа, Неопределено - все поля необязательны, содержит значения по умолчанию для новой структуры типа.
//
// Возвращаемое значение:
// см. НоваяСтруктураТипа() -
//
Функция СтруктураТипаИзКонкретногоТипа(КонкрентыйТип, ЯзыкПрограммы = 0, ШаблонСтруктурыТипа = Неопределено) Экспорт
//ШаблонСтруктурыТипа.
СтруктураТипа = НоваяСтруктураТипа();
Если ШаблонСтруктурыТипа <> Неопределено Тогда
ЗаполнитьЗначенияСвойств(СтруктураТипа, ШаблонСтруктурыТипа);
КонецЕсли;
Если ЯзыкПрограммы = 1 И КонкрентыйТип = Тип("ТаблицаЗначений") Тогда
СтруктураТипа.ИмяОбщегоТипа = "ВременнаяТаблица";
// Для ускорения
ИначеЕсли КонкрентыйТип = Тип("Число") Тогда
СтруктураТипа.ИмяОбщегоТипа = "Число";
ИначеЕсли КонкрентыйТип = Тип("Строка") Тогда
СтруктураТипа.ИмяОбщегоТипа = "Строка";
ИначеЕсли КонкрентыйТип = Тип("Булево") Тогда
СтруктураТипа.ИмяОбщегоТипа = "Булево";
ИначеЕсли КонкрентыйТип = Тип("ОписаниеТипов") Тогда
СтруктураТипа.ИмяОбщегоТипа = "ОписаниеТипов";
ИначеЕсли КонкрентыйТип = Тип("Массив") Тогда
СтруктураТипа.ИмяОбщегоТипа = "Массив";
ИначеЕсли КонкрентыйТип = Тип("Структура") Тогда
СтруктураТипа.ИмяОбщегоТипа = "Структура";
ИначеЕсли КонкрентыйТип = Тип("ОбъектМетаданных") Тогда
Если Истина
И ШаблонСтруктурыТипа <> Неопределено // было закомментировано
И ТипЗнч(ШаблонСтруктурыТипа.Метаданные) = Тип("ОбъектМетаданных")
Тогда
МассивФрагментов = ирОбщий.СтрРазделитьЛкс(ШаблонСтруктурыТипа.Метаданные.ПолноеИмя());
// Исключения из общего правила
Если МассивФрагментов[0] = "ОбщаяФорма" Тогда
МассивФрагментов[0] = "Форма";
ИначеЕсли МассивФрагментов[0] = "ОбщийМакет" Тогда
МассивФрагментов[0] = "Макет";
КонецЕсли;
СтруктураТипа.ИмяОбщегоТипа = МаркерОбъектаМетаданных + МассивФрагментов[МассивФрагментов.ВГраница() - 1];
Иначе
СтруктураТипа.ИмяОбщегоТипа = ИмяОбщегоТипаОбъектаМетаданных();
КонецЕсли;
ИначеЕсли Истина
И КонкрентыйТип = Тип("КоллекцияОбъектовМетаданных")
И ШаблонСтруктурыТипа <> Неопределено
И СтруктураТипа.ИмяОбщегоТипа <> "НеизвестныйКонтекст"
Тогда
//
Иначе
Если Истина
И ТипЗнч(КонкрентыйТип) = Тип("Тип")
//И КонкрентыйТип <> Тип("КонстантыНабор") // Антибаг платформы http://partners.v8.1c.ru/forum/thread.jsp?id=876094#876094 . Отключил, т.к. первое вычисление занимает 200мс https://www.hostedredmine.com/issues/995887
И Не (Истина
// Антибаг платформы. При правке внешней обработки во время ее отладки ее тип может становиться "Тип не определен '794a4eb3-0aff-402c-b654-e1670e90df73'" https://www.hostedredmine.com/issues/992088
И Найти(КонкрентыйТип, "'") > 0
И Найти(КонкрентыйТип, ":") = 0)
Тогда
МетаданныеТипа = мМетаданные.НайтиПоТипу(КонкрентыйТип);
КонецЕсли;
Если Ложь
Или МетаданныеТипа = Неопределено
Или ТипЗнч(МетаданныеТипа) = Тип("ОбъектМетаданныхКонфигурация")
Тогда
ПредставлениеТипа = Строка(КонкрентыйТип);
ИдентификаторТипа = "";
Если Найти(ПредставлениеТипа, "'") > 0 Тогда
// Антибаг платформы. При правке внешней обработки во время ее отладки ее тип может становиться "Тип не определен '794a4eb3-0aff-402c-b654-e1670e90df73'" https://www.hostedredmine.com/issues/992088
ПредставлениеТипа = "Внешняя обработка";
ИначеЕсли Найти(ПредставлениеТипа, ":") = 0 Тогда
ИдентификаторТипа = ирОбщий.ИдентификаторТипаЛкс(КонкрентыйТип);
Иначе
// Внешние метаданные
ПредставлениеТипа = ирОбщий.ПервыйФрагментЛкс(ПредставлениеТипа, ":");
Если НРег(ПредставлениеТипа) = Нрег("External data processor") Тогда
ПредставлениеТипа = "Внешняя обработка";
ИначеЕсли НРег(ПредставлениеТипа) = Нрег("External data processor tabular section") Тогда
ПредставлениеТипа = "Внешняя обработка табличная часть";
КонецЕсли;
КонецЕсли;
Если ИдентификаторТипа <> "" Тогда
КлючПоиска = Новый Структура("ИД", ИдентификаторТипа);
Иначе
//КлючПоиска = Новый Структура("Представление, ТипТипа", ирОбщий.ПервыйФрагментЛкс(ПредставлениеТипа, ":"), "Основной");
КлючПоиска = Новый Структура("Представление", ирОбщий.ПервыйФрагментЛкс(ПредставлениеТипа, ":"));
КонецЕсли;
Иначе
ЛиНеУчитыватьПодтип = (ЯзыкПрограммы <> 0) И СтруктураТипа.ТипЯзыка <> "ЗначениеВЗапросе";
ИмяОбщегоТипа = ИмяОбщегоТипаИзТипаЗначенияСМетаданными(КонкрентыйТип, МетаданныеТипа, ЛиНеУчитыватьПодтип);
СтруктураТипа.Метаданные = МетаданныеТипа;
КлючПоиска = Новый Структура("Слово, ТипТипа", ИмяОбщегоТипа, "Основной");
КонецЕсли;
НайденныеСтроки = ТаблицаОбщихТипов.НайтиСтроки(КлючПоиска);
Если НайденныеСтроки.Количество() > 0 Тогда
СтруктураТипа.ИмяОбщегоТипа = НайденныеСтроки[0].Слово;
//Если СтруктураТипа.СтрокаОписания = Неопределено Тогда
// СтруктураТипа.СтрокаОписания = НайденныеСтроки[0];
//КонецЕсли;
ИначеЕсли Найти(КонкрентыйТип, " ") = 0 Тогда
СтруктураТипа.ИмяОбщегоТипа = Строка(КонкрентыйТип);
Иначе
// Например тупиковый устаревший ПолеТабличногоДокументаФормы
//ирОбщий.СообщитьЛкс("Невозможно восстановить имя типа """ + КонкрентыйТип + """", СтатусСообщения.Важное);
КонецЕсли;
КонецЕсли;
Возврат СтруктураТипа;
КонецФункции
// Наиболее частый тип объекта метаданных. Это лучше чем абстрактный тип "ОбъектМетаданных" без членов.
Функция ИмяОбщегоТипаОбъектаМетаданных() Экспорт
//Возврат "ОбъектМетаданныхСправочник";
Возврат "ОбъектМетаданных";
КонецФункции
// Получает таблицу структур типов из описания типов.
//
// Параметры:
// ОписаниеТипов - ОписаниеТипов -
// *ТаблицаТипов - см. НоваяТаблицаТипов(), *Неопределено - существующая таблица.
//
// Возвращаемое значение:
// см. НоваяТаблицаТипов()
//
Функция ТаблицаТиповИзОписанияТипов(ОписаниеТипов, ТаблицаТипов = Неопределено) Экспорт
// TODO Заменить на прямой вызов ДобавитьВТаблицуТипов
Возврат ДобавитьВТаблицуТипов(ТаблицаТипов, ОписаниеТипов);
КонецФункции
Функция МаксЧислоТиповДляАнализа() Экспорт
Возврат 100;
КонецФункции
Функция ТаблицаТиповИзЗначения(Значение, ТаблицаТипов = Неопределено, ЯзыкПрограммы = 0) Экспорт
Если ТаблицаТипов = Неопределено Тогда
ТаблицаТипов = НоваяТаблицаТипов();
КонецЕсли;
СтруктураТипа = СтруктураТипаИзЗначения(Значение, ЯзыкПрограммы);
ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа);
Возврат ТаблицаТипов;
КонецФункции
// Получает объект по ссылке, кэшируя результат в соответствии.
//
// Параметры:
// Ссылка - Ссылка;
// ПринудительноОбновить - Булево, *Ложь.
//
// Возвращаемое значение:
// Объект.
//
Функция КэшОбъект(Ссылка, ПринудительноОбновить = Ложь) Экспорт
ТипСсылки = ТипЗнч(Ссылка);
Кэш = КэшОбъектов[ТипСсылки];
Если Кэш = Неопределено Тогда
Кэш = Новый Соответствие;
КэшОбъектов[ТипСсылки] = Кэш;
КонецЕсли;
Если Не ПринудительноОбновить Тогда
Результат = Кэш[Ссылка];
КонецЕсли;
Если Результат = Неопределено Тогда
Результат = Ссылка.ПолучитьОбъект();
Кэш[Ссылка] = Результат;
КонецЕсли;
Возврат Результат;
КонецФункции
// Получает строку конкретного типа.
//
// Параметры:
// СтруктураТипа - см. НоваяСтруктураТипа - описание типа.
//
// Возвращаемое значение:
// Строка - конкрентого типа.
//
Функция ИмяТипаИзСтруктурыТипа(Знач СтруктураТипа, Знач Подробное = Истина) Экспорт
КонкретныйТип = СтруктураТипа.ИмяОбщегоТипа;
МаркерРасширенияФормы = "РасширениеФормы";
Если ирОбщий.СтрНачинаетсяСЛкс(КонкретныйТип, МаркерРасширенияФормы, Истина) Тогда
КонкретныйТип = "Форма"; // TODO Сделать учет типа формы
КонецЕсли;
Если Подробное Тогда
Если Истина
И ирОбщий.ЛиИмяТипаФормыЛкс(КонкретныйТип, Истина, Истина)
И ирОбщий.ЛиФормаИлиИмитаторЛкс(СтруктураТипа.Метаданные)
Тогда
ИмяФормы = ирОбщий.ПолноеИмяФормыЛкс(СтруктураТипа.Метаданные);
Если ЗначениеЗаполнено(ИмяФормы) Тогда
КонкретныйТип = "Форма[" + ИмяФормы + "]";
Иначе
КонкретныйТип = СтруктураТипа.ИмяОбщегоТипа;
КонецЕсли;
ИначеЕсли КонкретныйТип = "ОбщийМодуль" И ТипЗнч(СтруктураТипа.Метаданные) = Тип("ОбъектМетаданных") Тогда
КонкретныйТип = КонкретныйТип + "[" + СтруктураТипа.Метаданные.Имя + "]";
Иначе
КонкретныйТип = СтруктураТипа.ИмяОбщегоТипа;
КонецЕсли;
КонецЕсли;
//Если Лев(КонкретныйТип, СтрДлина(МаркерКоллекцииМетаданных)) = МаркерКоллекцииМетаданных Тогда
// КонкретныйТип = МаркерКоллекцииМетаданных;
//КонецЕсли;
ОбъектМД = СтруктураТипа.Метаданные;
Если Истина
И ТипЗнч(ОбъектМД) = Тип("КоллекцияОбъектовМетаданных")
И ОбъектМД.Количество() > 0
Тогда
ОбъектМД = ОбъектМД[0].Родитель();
КонецЕсли;
ТипМетаданных = ТипЗнч(ОбъектМД);
Если Истина
И ТипМетаданных = Тип("ОбъектМетаданных")
И Найти(КонкретныйТип, "<") > 0
Тогда
ПолноеИмя = ОбъектМД.ПолноеИмя();
МассивФрагментов = ирОбщий.СтрРазделитьЛкс(ПолноеИмя);
Если МассивФрагментов[0] = "ТабличнаяЧасть" Тогда
// Баг платформы. У внешних метаданных полное имя не включает сам внешний метаобъект
МассивФрагментов.Вставить(0, "Имя");
МассивФрагментов.Вставить(0, "");
КонецЕсли;
Для Счетчик = 0 По МассивФрагментов.Количество() / 2 - 1 Цикл
ИмяЭлементаКоллекции = ирОбщий.ТекстМеждуМаркерамиЛкс(КонкретныйТип, "<", ">", Ложь, Истина);
КонкретныйТип = СтрЗаменить(КонкретныйТип, ИмяЭлементаКоллекции, МассивФрагментов[Счетчик * 2 + 1]);
КонецЦикла;
//ИначеЕсли ТипЗнч(СтруктураТипа.Метаданные) = Тип("Соответствие") Тогда
// Для Каждого ЭлементВида Из СтруктураТипа.Метаданные Цикл
// КонкретныйТип = СтрЗаменить(КонкретныйТип, ЭлементВида.Ключ, ЭлементВида.Значение);
// КонецЦикла;
ИначеЕсли Истина
И Подробное
И (Ложь
Или КонкретныйТип = "Массив"
Или КонкретныйТип = "ФиксированныйМассив")
И ТипЗнч(ОбъектМД) = Тип("ТаблицаЗначений")
И СтруктураТипа.Метаданные.Количество() > 0
И СтруктураТипа.Метаданные.Колонки.Найти(ИмяКолонкиФлагаТаблицыТипов()) <> Неопределено
Тогда
КонкретныйТип = КонкретныйТип + " Из " + ИмяТипаИзСтруктурыТипа(СтруктураТипа.Метаданные[0]); // Нужно для описания результата метода https://turboconf.ru/Tasks/9668
//ИначеЕсли Истина
// И (Ложь
// Или КонкретныйТип = "Структура"
// Или КонкретныйТип = "ФиксированнаяСтруктура")
// И ТипЗнч(ОбъектМД) = Тип("ТаблицаЗначений")
// И СтруктураТипа.Метаданные.Колонки.Найти(ИмяКолонкиФлагаТаблицыТипов()) <> Неопределено
//Тогда
// КонкретныйТип = КонкретныйТип + " Из КлючИЗначение"; // Нужно для описания результата метода https://turboconf.ru/Tasks/9668
ИначеЕсли Ложь
Или КонкретныйТип = "НеизвестныйКонтекст"
//Или КонкретныйТип = "Произвольный" // На него опирается подготовка ключевых параметров
Тогда
КонкретныйТип = "?";
КонецЕсли;
Попытка
Квалификаторы = СтруктураТипа.Квалификаторы;
Исключение
// Урезанная структура типа
Квалификаторы = Неопределено;
КонецПопытки;
Если Истина
И Подробное
И Квалификаторы <> Неопределено
И ирОбщий.ЛиИмяТипаСКвалификаторамиЛкс(КонкретныйТип)
Тогда
ирОбщий.ДобавитьКвалификаторыВПредставлениеТипаЛкс(КонкретныйТип, Тип(КонкретныйТип), Квалификаторы);
КонецЕсли;
Возврат КонкретныйТип;
КонецФункции
// Десериализатор структуры типа из неполной сериализации.
//
// Параметры:
// СтрокаСтруктурыТипа - Строка.
//
// Возвращаемое значение:
// СтруктураТипа - Структура.
//
Функция СтруктураТипаИзСтрокиВнутр(СтрокаСтруктурыТипа) Экспорт
СтруктураТипа = НоваяСтруктураТипа();
Если ПустаяСтрока(СтрокаСтруктурыТипа) Тогда
Возврат СтруктураТипа;
КонецЕсли;
Успех = Ложь;
Попытка
ОписательТипа = ЗначениеИзСтрокиВнутр(СтрокаСтруктурыТипа);
Успех = Истина;
Исключение
ОписательТипа = НоваяСтруктураТипа();
ОписательТипа.ИмяОбщегоТипа = "<Ошибка преобразования>";
КонецПопытки;
Если Успех Тогда
СтруктураТипа.ИмяОбщегоТипа = ОписательТипа.ИмяОбщегоТипа;
Если ТипЗнч(ОписательТипа.Метаданные) = Тип("Строка") Тогда
СтруктураТипа.Метаданные = ирКэш.ОбъектМДПоПолномуИмениЛкс(ОписательТипа.Метаданные);
ИначеЕсли ТипЗнч(ОписательТипа.Метаданные) = Тип("ХранилищеЗначения") Тогда
Поток = Новый ЧтениеXML;
Поток.УстановитьСтроку(ОписательТипа.Метаданные.Получить());
// Тут тормоз
СтруктураТипа.Метаданные = СериализаторXDTO.ПрочитатьXML(Поток);
Иначе
СтруктураТипа.Метаданные = ОписательТипа.Метаданные;
КонецЕсли;
КонецЕсли;
Возврат СтруктураТипа;
КонецФункции // СтруктураТипаВСтрокуВнутр()
// Получает новую структуру типа.
//
// Параметры:
// ИмяОбщегоТипа - Строка -
//
// Возвращаемое значение:
// Структура - :
// *ИмяОбщегоТипа - Строка
// *Метаданные
// *СтрокаОписания - СтрокаТаблицыЗначений, Структура
// *ТипЯзыка - Строка
// *Конструктор - Булево - каретка находится в имени конструктора (например "Новый К<>")
// *ДержательМетаданных - Произвольный - для объектов с модулем содержит имя расширения конфигурации, для элементов формы содержит форму
// *ВиртуальнаяТаблица - Структура -:
// **Выражение
// **НомерСтроки
//
Функция НоваяСтруктураТипа(ИмяОбщегоТипа = "НеизвестныйКонтекст") Экспорт
// Мультиметка73327878378078
Возврат Новый Структура("ИмяОбщегоТипа, Метаданные, СтрокаОписания, ТипЯзыка, Конструктор, ВиртуальнаяТаблица, ДержательМетаданных, Квалификаторы, МетаданныеСвойства",
ИмяОбщегоТипа, Неопределено, Неопределено, "", Ложь, Новый Структура("Выражение, НомерСтроки", "", 0));
КонецФункции
Функция НоваяТаблицаТипов() Экспорт
Если мТаблицаТипов = Неопределено Тогда
// Мультиметка73327878378078
мТаблицаТипов = Новый ТаблицаЗначений;
мТаблицаТипов.Колонки.Добавить("ИмяОбщегоТипа", Новый ОписаниеТипов("Строка"));
мТаблицаТипов.Колонки.Добавить("Метаданные");
мТаблицаТипов.Колонки.Добавить("СтрокаОписания"); // СтрокаТаблицыЗначений, Структура
мТаблицаТипов.Колонки.Добавить("ТипЯзыка", Новый ОписаниеТипов("Строка"));
мТаблицаТипов.Колонки.Добавить("ВиртуальнаяТаблица");
мТаблицаТипов.Колонки.Добавить("Конструктор", Новый ОписаниеТипов("Булево"));
мТаблицаТипов.Колонки.Добавить("ДержательМетаданных");
мТаблицаТипов.Колонки.Добавить("Квалификаторы");
мТаблицаТипов.Колонки.Добавить("МетаданныеСвойства");
мТаблицаТипов.Колонки.Добавить("Детальность");
КонецЕсли;
Возврат мТаблицаТипов.Скопировать();
КонецФункции
// Добавляет структуру типа в таблицу структур типов с поглощением.
//
// Параметры:
// ТаблицаПриемник - ТаблицаЗначений - ;
// ОписаниеТипов - Структура, ТаблицаЗначений, ОписаниеТипов, Массив из Структура - считаем что внутри этой коллекции типы не пересекаются.
//
Функция ДобавитьВТаблицуТипов(ТаблицаПриемник = Неопределено, Знач ОписаниеТипов, Знач _ПередаватьДополнительныеТипы = Ложь, Знач ВытеснятьБезУчетаОписания = Истина, Знач КопироватьСтруктуры = Ложь,
Знач ПереноситьОписание = Истина) Экспорт
Если ТаблицаПриемник = Неопределено Тогда
ТаблицаПриемник = НоваяТаблицаТипов();
КонецЕсли;
Если ОписаниеТипов = Неопределено Тогда
Возврат ТаблицаПриемник;
КонецЕсли;
ТипОписания = ТипЗнч(ОписаниеТипов);
Если ТипОписания = Тип("ОписаниеТипов") Тогда
//! ОписаниеТипов=0 // ОписаниеТипов
ТаблицаИсточник = Новый Массив;
Типы = ОписаниеТипов.Типы();
СлишкомМногоТипов = Типы.Количество() > МаксЧислоТиповДляАнализа();
Для Каждого Тип Из Типы Цикл
СтруктураТипа = СтруктураТипаИзКонкретногоТипа(Тип); // Циклическая ссылка СтрокаОписания
СтруктураТипа.Квалификаторы = ОписаниеТипов;
СтруктураТипа.Вставить("Детальность");
ТаблицаИсточник.Добавить(СтруктураТипа);
Если СлишкомМногоТипов И ТаблицаИсточник.Количество() = 10 Тогда
Прервать;
КонецЕсли;
КонецЦикла;
ИначеЕсли Истина
И ТипОписания <> Тип("ТаблицаЗначений")
И ТипОписания <> Тип("Массив")
Тогда
ТаблицаИсточник = Новый Массив;
ТаблицаИсточник.Добавить(ОписаниеТипов);
Иначе
ТаблицаИсточник = ОписаниеТипов; // см. НоваяТаблицаТипов()
Если Истина
И ТипОписания = Тип("ТаблицаЗначений")
И ТаблицаИсточник.Колонки.Метаданные.Заголовок <> ""
Тогда
ТаблицаПриемник.Колонки.Метаданные.Заголовок = ТаблицаИсточник.Колонки.Метаданные.Заголовок; // Флаги
КонецЕсли;
КонецЕсли;
КоличествоТипов = ТаблицаИсточник.Количество();
Если КоличествоТипов > МаксЧислоТиповДляАнализа() Тогда
// Для подстраховки. Нужно в вызывающем контексте это контролировать
Возврат ТаблицаПриемник;
КонецЕсли;
НужноВытеснять = КоличествоТипов > 0 И ТаблицаПриемник.Количество() > 0;
Детальность = Неопределено;
ИсключаемыеСвойства = "";
//Если НеередаватьДополнительныеТипы Тогда
// ИсключаемыеСвойства = ИсключаемыеСвойства + ",ДополнительныеТипы";
//КонецЕсли;
Если Не ПереноситьОписание Тогда
ИсключаемыеСвойства = ИсключаемыеСвойства + ",СтрокаОписания";
СтрокаОписания = Неопределено;
Если НужноВытеснять Тогда
СтрокаОписания = ТаблицаПриемник[0].СтрокаОписания;
КонецЕсли;
КонецЕсли;
ИсключаемыеСвойства = Сред(ИсключаемыеСвойства, 2);
Если ВытеснятьБезУчетаОписания Тогда
ИменаПоиска = "ИмяОбщегоТипа";
Иначе
ИменаПоиска = "ИмяОбщегоТипа,СтрокаОписания";
КонецЕсли;
Для Каждого СтрокаИсточника Из ТаблицаИсточник Цикл
Если Истина
//И НужноВытеснять
И СтрокаИсточника.ИмяОбщегоТипа = "НеизвестныйКонтекст"
И СтрокаИсточника.СтрокаОписания = Неопределено
Тогда
Продолжить;
КонецЕсли;
Если Истина
И ТипЗнч(СтрокаИсточника) = Тип("Структура")
И Не СтрокаИсточника.Свойство("Детальность", Детальность)
Тогда
СтрокаИсточника.Вставить("Детальность", Неопределено);
Иначе
Детальность = СтрокаИсточника.Детальность;
КонецЕсли;
Если Детальность = Неопределено Тогда
ОбновитьДетальностьСтруктурыТипа(СтрокаИсточника);
КонецЕсли;
Если НужноВытеснять Тогда
Если Найти(СтрокаИсточника.ИмяОбщегоТипа, "Массив") = 1 Тогда
ДобавлятьТип = Истина;
Для Каждого СтрокаПриемника Из ТаблицаПриемник Цикл
Если Найти(СтрокаПриемника.ИмяОбщегоТипа, "Массив") = 1 Тогда
Если Истина
И СтрокаИсточника.Метаданные = Неопределено
И СтрокаПриемника.Метаданные = Неопределено
Тогда
//
Иначе
ТипыЭлементовИсточника = ТаблицаТиповЭлементовКоллекции(СтрокаИсточника);
ТипыЭлементовПриемника = ТаблицаТиповЭлементовКоллекции(СтрокаПриемника);
СтрокаПриемника.Метаданные = ДобавитьВТаблицуТипов(ТипыЭлементовПриемника, ТипыЭлементовИсточника);
Если СтрокаПриемника.Метаданные.Количество() = 0 Тогда
СтрокаПриемника.Метаданные = Неопределено;
КонецЕсли;
КонецЕсли;
ДобавлятьТип = Ложь;
СтрокаПриемника.Детальность = Макс(СтрокаИсточника.Детальность, СтрокаПриемника.Детальность);
Прервать;
КонецЕсли;
КонецЦикла;
Если Не ДобавлятьТип Тогда
Прервать;
КонецЕсли;
Иначе
КлючПоиска = Новый Структура(ИменаПоиска);
ЗаполнитьЗначенияСвойств(КлючПоиска, СтрокаИсточника);
Найденные = ТаблицаПриемник.НайтиСтроки(КлючПоиска);
Если СтрокаИсточника.Детальность > 0 Тогда
Для Каждого СтрокаПриемника Из ТаблицаПриемник.НайтиСтроки(Новый Структура("Детальность", 0)) Цикл
ТаблицаПриемник.Удалить(СтрокаПриемника);
КонецЦикла;
Если ирОбщий.СтрНачинаетсяСЛкс(СтрокаИсточника.ИмяОбщегоТипа, "РасширениеФормы", Истина) Тогда // Учитывам регистр для ускорения
НайденныеФормы = ТаблицаПриемник.НайтиСтроки(Новый Структура("ИмяОбщегоТипа", "Форма"));
ирОбщий.ДополнитьМассивЛкс(Найденные, НайденныеФормы);
КонецЕсли;
КонецЕсли;
Для Каждого НайденнаяСтрока Из Найденные Цикл
Если СлитьМетаданныеСтруктурТипов(ТаблицаПриемник, СтрокаИсточника, НайденнаяСтрока) Тогда
Перейти ~КонецВерхний;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЕсли;
ТипМетаданных = ТипЗнч(СтрокаИсточника.Метаданные);
Если ТипМетаданных = Тип("COMОбъект") Тогда
// Мультметка8530527831 Их таблицы слов кэшируются https://www.hostedredmine.com/issues/986088
СтрокаПриемника = ТаблицаПриемник.Вставить(0);
Иначе
СтрокаПриемника = ТаблицаПриемник.Добавить();
КонецЕсли;
ЗаполнитьЗначенияСвойств(СтрокаПриемника, СтрокаИсточника, , ИсключаемыеСвойства);
Если Истина
И КопироватьСтруктуры
И ТипЗнч(СтрокаИсточника.Метаданные) = Тип("Структура")
Тогда
СтрокаПриемника.Метаданные = ирОбщий.СкопироватьКоллекциюЛкс(СтрокаПриемника.Метаданные);
КонецЕсли;
Если Не ПереноситьОписание Тогда
СтрокаПриемника.СтрокаОписания = СтрокаОписания;
КонецЕсли;
~КонецВерхний:
КонецЦикла;
Возврат ТаблицаПриемник;
КонецФункции
// .
//
// Параметры:
// ТаблицаТиповПриемник - ТаблицаЗначений - ;
// СтрокаИсточника - СтрокаТаблицыЗначений -
// СтрокаПриемника - СтрокаТаблицыЗначений -
//
// Возвращаемое значение:
// Булеов - Истина, если слияние выполнено в строку приемника и добавлять строку в таблицу приемника не нужно
//
Функция СлитьМетаданныеСтруктурТипов(Знач ТаблицаТиповПриемник, Знач СтрокаИсточника, Знач СтрокаПриемника) Экспорт
ТипМетаданныхИсточника = ТипЗнч(СтрокаИсточника.Метаданные);
ТипМетаданныхПриемника = ТипЗнч(СтрокаПриемника.Метаданные);
Если Истина
И СтрокаИсточника.СтрокаОписания <> Неопределено
И СтрокаПриемника.СтрокаОписания = Неопределено
Тогда
СтрокаПриемника.СтрокаОписания = СтрокаИсточника.СтрокаОписания;
КонецЕсли;
Если Ложь
Или СтрокаПриемника.Метаданные = СтрокаИсточника.Метаданные
Или СтрокаПриемника.Детальность > СтрокаИсточника.Детальность
Тогда
Возврат Истина;
КонецЕсли;
Если СтрокаПриемника.Детальность < СтрокаИсточника.Детальность Тогда
ТаблицаТиповПриемник.Удалить(СтрокаПриемника);
Иначе
// Далее детальности равны
Если Ложь
Или ТаблицаТиповПриемник.Количество() > 10
Или СтрокаПриемника.ИмяОбщегоТипа = "Строка" // Для ускорения вычисления типа результата ИмяМодуляИзСтруктурыТипа()
Или СтрокаПриемника.ИмяОбщегоТипа = "Число"
Или СтрокаПриемника.ИмяОбщегоТипа = "Булево"
Или СтрокаПриемника.ИмяОбщегоТипа = "Тип"
Тогда
Возврат Истина;
КонецЕсли;
ИмяКолонкиФлагаТаблицыТипов = ИмяКолонкиФлагаТаблицыТипов();
Если Ложь
Или (Истина
И ТипМетаданныхИсточника = Тип("ТаблицаЗначений")
И ТипМетаданныхПриемника = Тип("ТаблицаЗначений"))
Или (Истина
И ТипМетаданныхИсточника = Тип("ДеревоЗначений")
И ТипМетаданныхПриемника = Тип("ДеревоЗначений"))
Тогда
ирОбщий.СкопироватьКолонкиКоллекцииЛкс(СтрокаИсточника.Метаданные, СтрокаПриемника.Метаданные);
Возврат Истина;
ИначеЕсли Истина
И ТипМетаданныхПриемника = Тип("Неопределено")
И ТипМетаданныхИсточника = Тип("Структура")
Тогда
СтрокаПриемника.Метаданные = ирОбщий.СкопироватьКоллекциюЛкс(СтрокаИсточника.Метаданные);
Возврат Истина;
ИначеЕсли Истина
И ТипМетаданныхИсточника = Тип("Неопределено")
//И ТипМетаданныхПриемника = Тип("Структура")
Тогда
Возврат Истина;
ИначеЕсли Истина
И ТипМетаданныхИсточника = Тип("Структура")
И ТипМетаданныхПриемника = Тип("Структура")
Тогда
Для Каждого КлючИЗначение Из СтрокаИсточника.Метаданные Цикл
ЗначениеИзПриемника = ирОбщий.СвойствоСтруктурыЛкс(СтрокаПриемника.Метаданные, КлючИЗначение.Ключ);
Если Истина
И ТипЗнч(ЗначениеИзПриемника) = Тип("ТаблицаЗначений")
И ЗначениеИзПриемника.Колонки.Найти(ИмяКолонкиФлагаТаблицыТипов) <> Неопределено
И ТипЗнч(КлючИЗначение.Значение) = Тип("ТаблицаЗначений")
И КлючИЗначение.Значение.Колонки.Найти(ИмяКолонкиФлагаТаблицыТипов) <> Неопределено
Тогда
ДобавитьВТаблицуТипов(ЗначениеИзПриемника, КлючИЗначение.Значение);
Продолжить;
КонецЕсли;
//Если ЗначениеИзПриемника = Неопределено Тогда
Если Не ЗначениеЗаполнено(ЗначениеИзПриемника) Тогда // Чтобы пустая структура заменялась на полную для результата НоваяСтруктураТипа
СтрокаПриемника.Метаданные.Вставить(КлючИЗначение.Ключ, КлючИЗначение.Значение);
КонецЕсли;
КонецЦикла;
Возврат Истина;
ИначеЕсли Истина
И ТипМетаданныхИсточника = Тип("Массив")
И ТипМетаданныхПриемника = Тип("Массив")
Тогда
ирОбщий.СкопироватьКоллекциюЛкс(СтрокаИсточника.Метаданные, СтрокаПриемника.Метаданные);
Возврат Истина;
Иначе
СтруктураПриемник = Неопределено;
Если Истина
И ТипМетаданныхИсточника = Тип("ТаблицаЗначений")
И ТипМетаданныхПриемника = Тип("Структура")
Тогда
ТаблицаИсточник = СтрокаИсточника.Метаданные;
СтруктураПриемник = СтрокаПриемника.Метаданные;
ИначеЕсли Истина
И ТипМетаданныхИсточника = Тип("Структура")
И ТипМетаданныхПриемника = Тип("ТаблицаЗначений")
Тогда
ТаблицаИсточник = СтрокаПриемника.Метаданные;
СтруктураПриемник = СтрокаИсточника.Метаданные;
КонецЕсли;
Если Истина
И СтруктураПриемник <> Неопределено
И ТаблицаИсточник.Колонки.Найти(ИмяКолонкиФлагаТаблицыТипов) = Неопределено
Тогда
Для Каждого Колонка Из ТаблицаИсточник.Колонки Цикл
Если Истина
И ЗначениеЗаполнено(Колонка.Имя)
И ирОбщий.СвойствоСтруктурыЛкс(СтруктураПриемник, Колонка.Имя) = Неопределено
Тогда
ТаблицаТиповКолонки = ТаблицаТиповИзОписанияТипов(Колонка.ТипЗначения);
Если ТаблицаТиповКолонки.Количество() = 0 Тогда
ТаблицаТиповКолонки = Неопределено;
КонецЕсли;
СтруктураПриемник.Вставить(Колонка.Имя, ТаблицаТиповКолонки);
КонецЕсли;
КонецЦикла;
СтрокаПриемника.Метаданные = СтруктураПриемник;
Возврат Истина;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ОбновитьДетальностьСтруктурыТипа(СтруктураТипа) Экспорт
ТипМетаданных = ТипЗнч(СтруктураТипа.Метаданные);
ИмяОбщегоТипа = СтруктураТипа.ИмяОбщегоТипа;
Если Ложь
Или ИмяОбщегоТипа = "??"
Или ИмяОбщегоТипа = "НеизвестныйКонтекст"
Тогда
Результат = 0;
ИначеЕсли Ложь
Или ИмяОбщегоТипа = "" // Процедура
Или ИмяОбщегоТипа = "Произвольный"
Или ИмяОбщегоТипа = "Неопределено"
Тогда
Результат = 1;
// Отключил из-за Мультиметка29332671
//Если ИмяОбщегоТипа = "Неопределено" Тогда
// СтруктураТипа.Метаданные = Неопределено; // Чтобы раньше склеивались типы в ДобавитьВТаблицуТипов
//КонецЕсли;
ИначеЕсли Ложь
Или ИмяОбщегоТипа = "Строка"
Или ИмяОбщегоТипа = "Число"
Или ИмяОбщегоТипа = "Булево"
Или ИмяОбщегоТипа = "Дата"
Или ИмяОбщегоТипа = "Null"
Или ИмяОбщегоТипа = "Тип"
//Или ИмяОбщегоТипа = "Примитивный"
Тогда
Если ТипМетаданных = Тип(ИмяОбщегоТипа) Тогда
Результат = 3;
Иначе
Результат = 2;
Если Истина
И ИмяОбщегоТипа = "Строка"
И ТипМетаданных = Тип("ТаблицаЗначений")
Тогда
Результат = 5;
КонецЕсли;
КонецЕсли;
ИначеЕсли Ложь
Или ТипМетаданных = Тип("Неопределено")
Или ТипМетаданных = Тип("КоллекцияОбъектовМетаданных")
Или ТипМетаданных = Тип("ОбщийМодуль") // Пока платформа не позволяет узнать его имя
Тогда
Результат = 3;
ИначеЕсли ТипМетаданных = Тип("ОбъектМетаданных") Тогда
Результат = 4;
ИначеЕсли Истина
И ТипМетаданных = Тип("ТаблицаЗначений")
И СтруктураТипа.Метаданные.Количество() > 0
И СтруктураТипа.Метаданные.Колонки.Найти(ИмяКолонкиФлагаТаблицыТипов()) <> Неопределено
Тогда
//! СтруктураТипа.Метаданные = 0 // ТаблицаЗначений
Результат = Макс(3, СтруктураТипа.Метаданные[0].Детальность);
ИначеЕсли Ложь
#Если Клиент Тогда
Или ТипМетаданных = Тип("Форма")
Или ТипМетаданных = Тип("УправляемаяФорма")
#КонецЕсли
Тогда
Результат = 6;
ИначеЕсли ТипМетаданных = Тип("ПостроительЗапроса") Тогда
Результат = 7;
Иначе
Результат = 5;
КонецЕсли;
СтруктураТипа.Детальность = Результат;
Возврат Результат;
КонецФункции
//.
// Параметры:
// ТаблицаТипов - ТаблицаЗначений -
// МинДетальность - Число - минимальное достаточное значение детальности
// Возвращаемое значение:
// Булево -
Функция ЛиДетальностьТиповДостаточна(ТаблицаТипов, Знач МинДетальность = 3, Знач ВыбратьЛучшийТип = Ложь, выхЛучшийТип = Неопределено, Знач УчитыватьПримитивные = Истина) Экспорт
Если Ложь
Или ТаблицаТипов = Неопределено
Или ТаблицаТипов.Количество() = 0
Тогда
Возврат Ложь;
КонецЕсли;
Счетчик = 1;
МинДетальность = МинДетальность - 1;
Для Индекс = 1 - ТаблицаТипов.Количество() По 0 Цикл // Обратный обход
СтрокаТипа = ТаблицаТипов[-Индекс];
Успех = Ложь;
СтрокаВложенногоТипа = СтрокаТипа;
Если СтрокаТипа.Детальность > МинДетальность Тогда
Успех = Истина;
ИначеЕсли Истина
И СтрокаТипа.ИмяОбщегоТипа = "Массив"
И ТипЗнч(СтрокаТипа.Метаданные) = Тип("ТаблицаЗначений")
И СтрокаТипа.Метаданные.Количество()
Тогда
СтрокаВложенногоТипа = СтрокаТипа.Метаданные[0];
Если СтрокаВложенногоТипа.Детальность > МинДетальность Тогда
Успех = Истина;
КонецЕсли;
КонецЕсли;
Если Ложь
Или Успех
Или (Истина
И УчитыватьПримитивные
И (Ложь
Или СтрокаВложенногоТипа.ИмяОбщегоТипа = "Строка"
Или СтрокаВложенногоТипа.ИмяОбщегоТипа = "Число"
Или СтрокаВложенногоТипа.ИмяОбщегоТипа = "Булево" // почему закомментировал?
))
Тогда
выхЛучшийТип = СтрокаТипа;
МинДетальность = СтрокаТипа.Детальность;
Если Не ВыбратьЛучшийТип Тогда
Прервать;
КонецЕсли;
КонецЕсли;
Если Счетчик = 3 Тогда
// Проверяем не больше 3-х, т.к. бесполезных типов обычно очень мало указывают в описании, например Неопределено, Null
Прервать;
КонецЕсли;
Счетчик = Счетчик + 1;
КонецЦикла;
Возврат выхЛучшийТип <> Неопределено;
КонецФункции
// Получает массив структур типов из строки допустимых типов.
//
// Параметры:
// ДопустимыеТипы - Строка;
// *ШаблонСтруктурыТипа - Структура, *Неопределено - содержит значения по умолчанию для новой структуры типа.
//
Функция ТаблицаТиповИзДопустимыхТипов(ДопустимыеТипы, ШаблонСтруктурыТипа = Неопределено) Экспорт
ТаблицаТипов = НоваяТаблицаТипов();
Если ПустаяСтрока(ДопустимыеТипы) Тогда
Возврат ТаблицаТипов;
КонецЕсли;
МассивСериализованныхТипов = ирОбщий.СтрРазделитьЛкс(ДопустимыеТипы, ";");
Для Каждого СериализованныйТип Из МассивСериализованныхТипов Цикл
СтруктураТипа = СтруктураТипаИзСтрокиВнутр(СериализованныйТип);
Если ШаблонСтруктурыТипа <> Неопределено Тогда
ЗаполнитьЗначенияСвойств(СтруктураТипа, ШаблонСтруктурыТипа);
КонецЕсли;
ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа);
КонецЦикла;
Возврат ТаблицаТипов;
КонецФункции
// Получает описание типов из допустимых типов.
//
// Параметры:
// ДопустимыеТипы - Строка;
// ТипЗначенияЭУ - ОписаниеТипов - все возможные типы из элемента управления.
//
// Возвращаемое значение:
// ОписаниеТипов.
//
Функция ОписаниеТиповИзДопустимыхТипов(ДопустимыеТипы, ТипЗначенияЭУ = Неопределено) Экспорт
ТаблицаТипов = ТаблицаТиповИзДопустимыхТипов(ДопустимыеТипы);
ОписаниеТипов = ОписаниеТиповИзТаблицыТипов(ТаблицаТипов, ТипЗначенияЭУ);
Возврат ОписаниеТипов;
КонецФункции
// Получает описание типов из таблицы структур типов.
//
// Параметры:
// ДопустимыеТипы - Строка;
// ТипЗначенияЭУ - ОписаниеТипов - все возможные типы из элемента управления.
//
// Возвращаемое значение:
// ОписаниеТипов.
//
Функция ОписаниеТиповИзТаблицыТипов(ТаблицаТипов, ТипЗначенияЭУ = Неопределено) Экспорт
Если ТаблицаТипов = Неопределено Тогда
Возврат Новый ОписаниеТипов;
КонецЕсли;
МассивТипов = Новый Массив;
Для Каждого СтруктураТипа Из ТаблицаТипов Цикл
СтрокаКонкретногоТипа = ИмяТипаИзСтруктурыТипа(СтруктураТипа, Ложь);
Попытка
ТекущийТип = Тип(СтрокаКонкретногоТипа);
Исключение
Продолжить;
КонецПопытки;
ТипМетаданных = ТипЗнч(СтруктураТипа.Метаданные);
Если ТипМетаданных = Тип("КвалификаторыСтроки") Тогда
КвалификаторыСтроки = СтруктураТипа.Метаданные;
ИначеЕсли ТипМетаданных = Тип("КвалификаторыЧисла") Тогда
КвалификаторыЧисла = СтруктураТипа.Метаданные;
ИначеЕсли ТипМетаданных = Тип("КвалификаторыДаты") Тогда
КвалификаторыДаты = СтруктураТипа.Метаданные;
КонецЕсли;
Если ТипЗначенияЭУ <> Неопределено Тогда
Если Не ТипЗначенияЭУ.СодержитТип(ТекущийТип) Тогда
Продолжить;
КонецЕсли;
КонецЕсли;
МассивТипов.Добавить(ТекущийТип);
КонецЦикла;
ОписаниеТипов = Новый ОписаниеТипов(МассивТипов, КвалификаторыЧисла, КвалификаторыСтроки, КвалификаторыСтроки);
Возврат ОписаниеТипов;
КонецФункции
// Получает строку типа метаобъектов по единственному или множественному числу.
//
// Параметры:
// *Единственное - Строка, *Неопределено - единственное число типа;
// *Множественное - Строка, *Неопределено - множественное число типа.
// *Категория - Число, *Неопределено.
//
// Возвращаемое значение:
// СтрокаТаблицыЗначений - найденная строка типа;
// Неопределено - корневой тип не найден.
//
Функция ОписаниеТипаМетаОбъектов(Знач Единственное = Неопределено, Знач Множественное = Неопределено, Категория = Неопределено) Экспорт
СтруктураПоиска = Новый Структура;
Если Категория <> Неопределено Тогда
СтруктураПоиска.Вставить("Категория", Категория);
КонецЕсли;
Если Единственное <> Неопределено Тогда
СтруктураПоиска.Вставить("НЕдинственное", НРег(Единственное));
КонецЕсли;
Если Множественное <> Неопределено Тогда
СтруктураПоиска.Вставить("НМножественное", НРег(Множественное));
КонецЕсли;
НайденныеСтроки = ТаблицаТиповМетаОбъектов.НайтиСтроки(СтруктураПоиска);
Если НайденныеСтроки.Количество() = 0 Тогда
Результат = Неопределено;
Иначе
Результат = НайденныеСтроки[0];
КонецЕсли;
Возврат Результат;
КонецФункции
Процедура ПроверитьЗагрузитьКэшМДСеанса()
ПереданныйКэш = ирКэш.ПараметрыСеансаЛкс().ПереданныйКэш;
КэшМДСеанса = Неопределено;
Если ЗначениеЗаполнено(ПереданныйКэш) Тогда
КэшМДСеанса = ПолучитьИзВременногоХранилища(ПереданныйКэш);
КонецЕсли;
Если КэшМДСеанса = Неопределено Тогда
СостояниеРасчета = ирКэш.СостояниеПодготовкиКэшМДСеансаЛкс();
Если СостояниеРасчета <> Неопределено Тогда
ФоновоеЗадание = ФоновыеЗадания.НайтиПоУникальномуИдентификатору(СостояниеРасчета.ИдентификаторЗадания);
КонецЕсли;
Если ФоновоеЗадание <> Неопределено Тогда
Если ФоновоеЗадание.Состояние = СостояниеФоновогоЗадания.Активно Тогда
ирОбщий.ОжидатьЗавершенияФоновойОперацииЛкс(ФоновоеЗадание);
КонецЕсли;
Если ФоновоеЗадание.Состояние = СостояниеФоновогоЗадания.Завершено Тогда
КэшМДСеанса = ирОбщий.ПрочитатьРезультатФоновогоЗаданияЛкс(СостояниеРасчета.АдресРезультата, СостояниеРасчета.ФормаРезультата);
Если КэшМДСеанса = Null Тогда
КэшМДСеанса = Неопределено;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если КэшМДСеанса <> Неопределено Тогда
#Если Сервер И Не Сервер Тогда
КэшМДСеанса = Новый Структура;
#КонецЕсли
мТаблицаВсехТаблицБД = КэшМДСеанса.ТаблицаВсехТаблицБД;
Если КэшМДСеанса.Свойство("ДеревоОбъектовМД") Тогда
мДеревоОбъектовМД = КэшМДСеанса.ДеревоОбъектовМД;
КонецЕсли;
Возврат;
КонецЕсли;
КонецПроцедуры
Функция ДеревоОбъектовМД() Экспорт
ПроверитьЗагрузитьКэшМДСеанса();
Если мДеревоОбъектовМД <> Неопределено Тогда
#Если Сервер И Не Сервер Тогда
мДеревоОбъектовМД = Новый ДеревоЗначений;
#КонецЕсли
#Если Клиент Тогда
Если мДеревоОбъектовМД.Колонки.Найти("КоличествоСтрок") = Неопределено Тогда
мДеревоОбъектовМД.Колонки.Добавить("КоличествоСтрок", Новый ОписаниеТипов("Строка, Число"));
КонецЕсли;
#КонецЕсли
Возврат мДеревоОбъектовМД;
КонецЕсли;
ДеревоОбъектовМД = Новый ДеревоЗначений;
ДеревоОбъектовМД.Колонки.Добавить("Имя", Новый ОписаниеТипов("Строка"));
ДеревоОбъектовМД.Колонки.Добавить("Представление", Новый ОписаниеТипов("Строка"));
ДеревоОбъектовМД.Колонки.Добавить("ПолноеИмяОбъекта", Новый ОписаниеТипов("Строка"));
ДеревоОбъектовМД.Колонки.Добавить("ИндексКартинки", Новый ОписаниеТипов("Число"));
ДеревоОбъектовМД.Колонки.Добавить("ЕстьДоступ", Новый ОписаниеТипов("Булево"));
ДеревоОбъектовМД.Колонки.Добавить("ПравоПросмотр", Новый ОписаниеТипов("Булево"));
ДеревоОбъектовМД.Колонки.Добавить("ТипТаблицы", Новый ОписаниеТипов("Строка"));
АнализаторКода = ирОбщий.НовыйАнализаторКодаЛкс();
#Если Сервер И Не Сервер Тогда
АнализаторКода = Обработки.ирКлсПолеТекстаПрограммы.Создать();
#КонецЕсли
мТаблицаВсехТаблицБД = АнализаторКода.ДоступныеТаблицы.ВыгрузитьКолонки();
мТаблицаВсехТаблицБД.Колонки.Удалить("ПородившийЗапрос"); // Для экономии памяти
мТаблицаВсехТаблицБД.Колонки.Добавить("ТипСсылки");
//ТаблицаВсехТаблицБД.Колонки.Добавить("СтруктураКлюча");
Если Метаданные.Константы.Количество() > 0 Тогда
ирОбщий.ДобавитьДоступнуюТаблицуБДЛкс(мТаблицаВсехТаблицБД, ирОбщий.ПеревестиСтроку("Константы"),, "Константы"); // Мультиметка0012741388 опираемся на то, что эта таблица БД идет первой в списке
КонецЕсли;
КоллекцияКорневыхТипов = Новый Массив;
СтрокиМетаОбъектов = ТаблицаТиповМетаОбъектов.НайтиСтроки(Новый Структура("Категория", 0));
Для Каждого СтрокаТаблицыМетаОбъектов Из СтрокиМетаОбъектов Цикл
КоллекцияКорневыхТипов.Добавить(СтрокаТаблицыМетаОбъектов.Единственное);
КонецЦикла;
Если ирКэш.ДоступноВнешниеИсточникДанныхЛкс() Тогда
Для Каждого МетаВнешнийИсточникДанных Из Метаданные.ВнешниеИсточникиДанных Цикл
КоллекцияКорневыхТипов.Добавить(МетаВнешнийИсточникДанных.ПолноеИмя());
КонецЦикла;
КонецЕсли;
КоллекцияКорневыхТипов.Добавить("Отчет");
КоллекцияКорневыхТипов.Добавить("Обработка");
КоллекцияКорневыхТипов.Добавить("Роль");
КоллекцияКорневыхТипов.Добавить("Подсистема");
КоллекцияКорневыхТипов.Добавить("РегламентноеЗадание");
КоллекцияКорневыхТипов.Добавить("HTTPСервис");
КоллекцияКорневыхТипов.Добавить("WebСервис");
КоллекцияКорневыхТипов.Добавить("ОбщаяКоманда");
ИмяДвиженияССубконто = ирОбщий.ПеревестиСтроку("ДвиженияССубконто");
ИмяГраницы = ирОбщий.ПеревестиСтроку("Границы");
ИмяБаза = ирОбщий.ПеревестиСтроку("База");
ИмяДанныеГрафика = ирОбщий.ПеревестиСтроку("ДанныеГрафика");
ИмяФактическийПериодДействия = ирОбщий.ПеревестиСтроку("ФактическийПериодДействия");
ИмяЗадачиПоИсполнителю = ирОбщий.ПеревестиСтроку("ЗадачиПоИсполнителю");
ИмяКонстанта = ирОбщий.ПеревестиСтроку("Константа");
ИмяОбороты = ирОбщий.ПеревестиСтроку("Обороты");
ИмяОборотыДтКт = ирОбщий.ПеревестиСтроку("ОборотыДтКт");
ИмяОстатки = ирОбщий.ПеревестиСтроку("Остатки");
ИмяОстаткиИОбороты = ирОбщий.ПеревестиСтроку("ОстаткиИОбороты");
ИмяСрезПервых = ирОбщий.ПеревестиСтроку("СрезПервых");
ИмяСрезПоследних = ирОбщий.ПеревестиСтроку("СрезПоследних");
ИмяСубконто = ирОбщий.ПеревестиСтроку("Субконто");
ИмяТабличнаяЧасть = ирОбщий.ПеревестиСтроку("ТабличнаяЧасть");
ИмяТочки = ирОбщий.ПеревестиСтроку("Точки");
ИндексКартинкиТЧ = мОписаниеТипаМДТабличнаяЧасть.ИндексКартинкиЕдинственное;
ИндикаторТиповМД = ирОбщий.ПолучитьИндикаторПроцессаЛкс(КоллекцияКорневыхТипов.Количество(), "Анализ конфигурации");
Для Каждого КорневойТип Из КоллекцияКорневыхТипов Цикл
ирОбщий.ОбработатьИндикаторЛкс(ИндикаторТиповМД);
ОписаниеКорневогоТипа = ОписаниеТипаМетаОбъектов(КорневойТип);
Если ОписаниеКорневогоТипа = Неопределено Тогда
Если Найти(КорневойТип, ".") = 0 Тогда
// В текущей версии платформы нет поддержки такого типа метаданных
Продолжить;
КонецЕсли;
// Внешний источник данных
ОписаниеКорневогоТипа = мОписаниеТипаМДВнешнийИсточникДанных;
ОбъектМДКорневогоТипа = ирКэш.ОбъектМДПоПолномуИмениЛкс(КорневойТип);
МножественноеКорневогоТипа = КорневойТип;
ЕдинственноеКорневогоТипа = ОбъектМДКорневогоТипа.Имя;
ПредставлениеКатегории = ОбъектМДКорневогоТипа.Представление();
ЕстьДоступ = ПравоДоступа("Использование", ОбъектМДКорневогоТипа);
СхемаТаблиц = ОбъектМДКорневогоТипа.Имя;
ТипТаблицы = "Внешняя";
КоллекцияМетаОбъектов = ОбъектМДКорневогоТипа.Таблицы;
ЕстьТаблицаБД = Истина;
Иначе
МножественноеКорневогоТипа = ОписаниеКорневогоТипа.Множественное;
ЕдинственноеКорневогоТипа = ОписаниеКорневогоТипа.Единственное;
ПредставлениеКатегории = ирОбщий.ПредставлениеИзИдентификатораЛкс(МножественноеКорневогоТипа);
ЕстьДоступ = Истина;
СхемаТаблиц = "";
//Если КорневойТип = "КритерийОтбора" Тогда
// ТипТаблицы = "ВиртуальнаяТаблица";
//Иначе
ТипТаблицы = КорневойТип;
//КонецЕсли;
Если КорневойТип = "Перерасчет" Тогда
КоллекцияМетаОбъектов = Новый Массив;
Для Каждого МетаРегистрРасчета Из Метаданные.РегистрыРасчета Цикл
Для Каждого Перерасчет Из МетаРегистрРасчета.Перерасчеты Цикл
КоллекцияМетаОбъектов.Добавить(Перерасчет);
КонецЦикла;
КонецЦикла;
Иначе
КоллекцияМетаОбъектов = Метаданные[МножественноеКорневогоТипа]; // КоллекцияОбъектовМетаданных
КонецЕсли;
ЕстьТаблицаБД = Истина
И (Ложь
Или КорневойТип <> "Константа"
Или ирКэш.ДоступноТаблицыКонстантЛкс())
И (Ложь
Или КорневойТип = "Константа"
Или КорневойТип = "КритерийОтбора"
Или КорневойТип = "ЖурналДокументов"
Или ирОбщий.ЛиКорневойТипПеречисленияЛкс(КорневойТип)
Или ирОбщий.ЛиКорневойТипСсылочногоОбъектаБДЛкс(КорневойТип)
Или ирОбщий.ЛиКорневойТипРегистраБДЛкс(КорневойТип)
Или ирОбщий.ЛиКорневойТипПоследовательностиЛкс(КорневойТип));
КонецЕсли;
Если КоллекцияМетаОбъектов.Количество() = 0 Тогда
Продолжить;
КонецЕсли;
СтрокаТипаМетаданных = ДеревоОбъектовМД.Строки.Добавить();
СтрокаТипаМетаданных.Представление = ПредставлениеКатегории;
СтрокаТипаМетаданных.Имя = ЕдинственноеКорневогоТипа;
СтрокаТипаМетаданных.ПолноеИмяОбъекта = МножественноеКорневогоТипа;
СтрокаТипаМетаданных.ИндексКартинки = ОписаниеКорневогоТипа.ИндексКартинкиМножественное;
СтрокаТипаМетаданных.ЕстьДоступ = ЕстьДоступ;
ЛиКорневойТипОбъектаСТабличнымиЧастями = ирОбщий.ЛиКорневойТипСсылочногоОбъектаБДЛкс(КорневойТип);
ИндикаторОбъектовМД = ирОбщий.ПолучитьИндикаторПроцессаЛкс(КоллекцияМетаОбъектов.Количество(), "Анализ " + КорневойТип);
Для Каждого ОбъектМД Из КоллекцияМетаОбъектов Цикл
ирОбщий.ОбработатьИндикаторЛкс(ИндикаторОбъектовМД);
ПолноеИмяМД = ОбъектМД.ПолноеИмя();
ПредставлениеМД = ОбъектМД.Представление();
ПолноеИмяТаблицыБД = ирКэш.ИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД,, Ложь);
ФрагментыИмениТаблицы = ирОбщий.СтрРазделитьЛкс(ПолноеИмяТаблицыБД);
ИмяОбъектаМД = ОбъектМД.Имя;
Если КорневойТип = "Перерасчет" Тогда
//! ОбъектМД = 0 // ОбъектМетаданныхПерерасчет
МетаРегистрРасчета = ОбъектМД.Родитель(); // ОбъектМетаданныхРегистрРасчета
ИмяОбъектаМД = МетаРегистрРасчета.Имя + "." + ИмяОбъектаМД;
ПредставлениеМД = МетаРегистрРасчета.Представление() + "." + ПредставлениеМД;
КонецЕсли;
СтрокаОбъектаМД = ДобавитьСтрокуДереваМД(СтрокаТипаМетаданных, ПолноеИмяТаблицыБД, ИмяОбъектаМД, ПредставлениеМД, ТипТаблицы, ОписаниеКорневогоТипа.ИндексКартинкиЕдинственное,
ЕстьТаблицаБД, мТаблицаВсехТаблицБД, ПолноеИмяМД, ОбъектМД.Имя, ПредставлениеМД, СхемаТаблиц, ОбъектМД,, ФрагментыИмениТаблицы);
Попытка
СтрокаОбъектаМД.ПравоПросмотр = ПравоДоступа("Просмотр", ОбъектМД);
Исключение
СтрокаОбъектаМД.ПравоПросмотр = Истина;
КонецПопытки;
Если ЛиКорневойТипОбъектаСТабличнымиЧастями Тогда
СтруктураТЧ = ирОбщий.ТабличныеЧастиОбъектаЛкс(ОбъектМД, ФрагментыИмениТаблицы);
Для Каждого КлючИЗначение Из СтруктураТЧ Цикл
СтрокаТЧВДереве = ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + КлючИЗначение.Ключ, КлючИЗначение.Ключ, КлючИЗначение.Значение, "ТабличнаяЧасть", ИндексКартинкиТЧ,
ЕстьТаблицаБД, мТаблицаВсехТаблицБД, ПолноеИмяМД + "." + ИмяТабличнаяЧасть + "." + КлючИЗначение.Ключ,, ПредставлениеМД + "." + КлючИЗначение.Значение,, ОбъектМД);
МетаТЧ = ОбъектМД.ТабличныеЧасти.Найти(КлючИЗначение.Ключ);
Если МетаТЧ <> Неопределено Тогда
СтрокаТЧВДереве.ПравоПросмотр = ПравоДоступа("Просмотр", МетаТЧ);
КонецЕсли;
КонецЦикла;
Если КорневойТип = "БизнесПроцесс" Тогда
//! ОбъектМД = 0 // ОбъектМетаданныхБизнесПроцесс
ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяТочки, "Точки", "Точки", "Точки", ИндексКартинкиТЧ,
ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Точки",, ОбъектМД);
КонецЕсли;
Если КорневойТип = "Задача" Тогда
//! ОбъектМД = 0 // ОбъектМетаданныхЗадача
Если ОбъектМД.Адресация <> Неопределено Тогда
ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяЗадачиПоИсполнителю, "ЗадачиПоИсполнителю", "Задачи по исполнителю", "ВиртуальнаяТаблица", ИндексКартинкиТЧ,
ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Задачи по исполнителю",, ОбъектМД, 1);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если КорневойТип = "РегистрСведений" Тогда
//! ОбъектМД = 0 // ОбъектМетаданныхРегистрСведений
Если ОбъектМД.ПериодичностьРегистраСведений <> Метаданные.СвойстваОбъектов.ПериодичностьРегистраСведений.Непериодический Тогда
ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяСрезПоследних, "СрезПоследних", "срез последних", "ВиртуальнаяТаблица", ИндексКартинкиТЧ,
ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Срез последних",, ОбъектМД, 1);
ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяСрезПервых, "СрезПервых", "срез первых", "ВиртуальнаяТаблица", ИндексКартинкиТЧ,
ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Срез первых",, ОбъектМД, 1);
КонецЕсли;
ИначеЕсли КорневойТип = "РегистрНакопления" Тогда
//! ОбъектМД = 0 // ОбъектМетаданныхРегистрНакопления
ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяОбороты, "Обороты", "Обороты", "ВиртуальнаяТаблица", ИндексКартинкиТЧ,
ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Обороты",, ОбъектМД, 3);
Если ОбъектМД.ВидРегистра = Метаданные.СвойстваОбъектов.ВидРегистраНакопления.Остатки Тогда
ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяОстатки, "Остатки", "Остатки", "ВиртуальнаяТаблица", ИндексКартинкиТЧ,
ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Остатки",, ОбъектМД, 1);
ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяОстаткиИОбороты, "ОстаткиИОбороты", "Остатки и обороты", "ВиртуальнаяТаблица", ИндексКартинкиТЧ,
ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Остатки и обороты",, ОбъектМД, 4);
КонецЕсли;
ИначеЕсли КорневойТип = "РегистрБухгалтерии" Тогда
//! ОбъектМД = 0 // ОбъектМетаданныхРегистрБухгалтерии
ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяОбороты, "Обороты", "Обороты", "ВиртуальнаяТаблица", ИндексКартинкиТЧ,
ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Обороты",, ОбъектМД, 5);
ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяОстатки, "Остатки", "Остатки", "ВиртуальнаяТаблица", ИндексКартинкиТЧ,
ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Остатки",, ОбъектМД, 3);
ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяОстаткиИОбороты, "ОстаткиИОбороты", "Остатки и обороты", "ВиртуальнаяТаблица", ИндексКартинкиТЧ,
ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Остатки и обороты",, ОбъектМД, 6);
ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяДвиженияССубконто, "ДвиженияССубконто", "Движения с субконто", "ДвиженияССубконто", ИндексКартинкиТЧ,
ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Движения с субконто",, ОбъектМД, 2);
Если ОбъектМД.ПланСчетов.МаксКоличествоСубконто > 0 Тогда
ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяСубконто, "Субконто", "Субконто", "Субконто", ИндексКартинкиТЧ,
ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Субконто",, ОбъектМД);
КонецЕсли;
Если ОбъектМД.Корреспонденция Тогда
ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяОборотыДтКт, "ОборотыДтКт", "Обороты Дт Кт", "ВиртуальнаяТаблица", ИндексКартинкиТЧ,
ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Обороты Дт Кт",, ОбъектМД, 7);
КонецЕсли;
ИначеЕсли КорневойТип = "Последовательность" Тогда
//! ОбъектМД = 0 // ОбъектМетаданныхПоследовательность
ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяГраницы, "Границы", "Границы", "ВиртуальнаяТаблица", ИндексКартинкиТЧ,
ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Границы",, ОбъектМД);
ИначеЕсли КорневойТип = "РегистрРасчета" Тогда
//! ОбъектМД = 0 // ОбъектМетаданныхРегистрРасчета
Для Каждого БазовыйПлан Из ОбъектМД.ПланВидовРасчета.БазовыеВидыРасчета Цикл
Для Каждого БазовыйРегистрРасчета Из Метаданные.РегистрыРасчета Цикл
Если БазовыйРегистрРасчета.ПланВидовРасчета = БазовыйПлан Тогда
ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяБаза + БазовыйРегистрРасчета.Имя, "База", "База", "ВиртуальнаяТаблица", ИндексКартинкиТЧ,
ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "База " + БазовыйРегистрРасчета.Представление(),, ОбъектМД, 3);
КонецЕсли;
КонецЦикла;
КонецЦикла;
Если ОбъектМД.График <> Неопределено Тогда
ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяДанныеГрафика, "ДанныеГрафика", "Данные графика", "ВиртуальнаяТаблица", ИндексКартинкиТЧ,
ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Данные графика",, ОбъектМД, 0);
КонецЕсли;
Если ОбъектМД.ПериодДействия Тогда
ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяФактическийПериодДействия, "ФактическийПериодДействия", "Фактический период действия", "ВиртуальнаяТаблица", ИндексКартинкиТЧ,
ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Фактический период действия",, ОбъектМД, 0);
КонецЕсли;
КонецЕсли;
Если ирОбщий.ЕстьТаблицаИзмененийОбъектаМетаданных(ОбъектМД) Тогда
ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ирКэш.ИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД, Истина, Ложь), "Изменения", "Изменения", "Изменения", ИндексКартинкиТЧ,
ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Изменения",, ОбъектМД);
КонецЕсли;
КонецЦикла;
ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
Если СтрокаТипаМетаданных.Строки.Количество() = 0 Тогда
ДеревоОбъектовМД.Строки.Удалить(СтрокаТипаМетаданных);
КонецЕсли;
КонецЦикла;
ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
мТаблицаВсехТаблицБД.Индексы.Добавить("НПолноеИмя");
//мТаблицаВсехТаблицБД.Сортировать("НПолноеИмя"); // Вроде бы сортировка хранения уже не используется
мДеревоОбъектовМД = ДеревоОбъектовМД;
Возврат мДеревоОбъектовМД;
КонецФункции
Функция ДобавитьСтрокуДереваМД(СтрокаРодителяМД, ПолноеИмяТаблицы, Имя, Представление, ТипТаблицы = "", ИндексКартинки = 0, ЕстьТаблицаБД = Ложь, мТаблицаВсехТаблицБД = Неопределено,
ПолноеИмяМД ="", ИмяТаблицы = "", ПредставлениеТаблицы = "", СхемаТаблицы = "", ОбъектМД = Неопределено, ИндексПараметраОтбора = Неопределено, ФрагментыИмениТаблицы = Неопределено)
ДочерняяТаблица = СтрокаРодителяМД.Строки.Добавить();
ДочерняяТаблица.Имя = Имя;
ДочерняяТаблица.Представление = Представление;
ДочерняяТаблица.ПолноеИмяОбъекта = ПолноеИмяТаблицы;
ДочерняяТаблица.ИндексКартинки = ИндексКартинки;
ДочерняяТаблица.ПравоПросмотр = СтрокаРодителяМД.ПравоПросмотр;
ДочерняяТаблица.ТипТаблицы = ТипТаблицы;
Если ЕстьТаблицаБД Тогда
ОписаниеТаблицы = ирОбщий.ДобавитьДоступнуюТаблицуБДЛкс(мТаблицаВсехТаблицБД, ПолноеИмяТаблицы, ПолноеИмяМД, ТипТаблицы, ИмяТаблицы, ПредставлениеТаблицы, СхемаТаблицы,, ОбъектМД,
ИндексПараметраОтбора, ФрагментыИмениТаблицы);
ДочерняяТаблица.ЕстьДоступ = ОписаниеТаблицы.ЕстьДоступ;
Иначе
ДочерняяТаблица.ЕстьДоступ = СтрокаРодителяМД.ЕстьДоступ;
КонецЕсли;
Возврат ДочерняяТаблица;
КонецФункции
Функция ТаблицаВсехТаблицБД() Экспорт
ПроверитьЗагрузитьКэшМДСеанса();
Если мТаблицаВсехТаблицБД <> Неопределено Тогда
Возврат мТаблицаВсехТаблицБД;
КонецЕсли;
ДеревоОбъектовМД();
Возврат мТаблицаВсехТаблицБД;
КонецФункции
// Проверяет общий тип на агрегатность.
//
// Параметры:
// ИмяОбщегоТипа - Строка;
// *ЯзыкПрограммы - *Число, 0.
//
// Возвращаемое значение:
// Булево.
//
Функция ЭтоАгрегатныйОбщийТип(Знач ИмяОбщегоТипа, Знач ЯзыкПрограммы = 0) Экспорт
Если ИмяОбщегоТипа = "" Тогда
Возврат Ложь;
КонецЕсли;
ИмяОбщегоТипа = ирОбщий.ПервыйФрагментЛкс(ИмяОбщегоТипа, "[");
СтруктураКлюча = Новый Структура("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка", ИмяОбщегоТипа, ЯзыкПрограммы, ""); // 2021 добавил ТипЯзыка для попадания в индекс
Если Ложь
Или ирОбщий.СтрокиРавныЛкс(ИмяОбщегоТипа, "COMОбъект")
Или (Истина
И Найти(ИмяОбщегоТипа, " {") = 0 // подробный COM
И ТаблицаКонтекстов.НайтиСтроки(СтруктураКлюча).Количество() = 0
И ТаблицаШаблоновКонтекстов.НайтиСтроки(СтруктураКлюча).Количество() = 0
)
Тогда
Результат = Ложь;
Иначе
Результат = Истина;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция БазовыйФайлРедактораJSON() Экспорт
Если БазовыйФайлРедактораJSON = Неопределено Тогда
БазовыйКаталог = КаталогВременныхФайлов();
КаталогКомпоненты = "JSONEditor";
ДвоичныеДанные = ПолучитьМакет("JSONEditor");
Чтение = Вычислить("Новый ЧтениеДанных(ДвоичныеДанные)"); // 8.3.9+
Файл = Новый ЧтениеZipФайла(Чтение.ИсходныйПоток());
Файл.ИзвлечьВсе(БазовыйКаталог + КаталогКомпоненты);
БазовыйФайлРедактораJSON = БазовыйКаталог + КаталогКомпоненты + ирОбщий.РазделительПутиКФайлуЛкс() + "index.html";
КонецЕсли;
Возврат БазовыйФайлРедактораJSON;
КонецФункции
Функция БазовыйФайлРедактораКода() Экспорт
Если БазовыйФайлРедактораКода = Неопределено Тогда
БазовыйКаталог = КаталогВременныхФайлов();
КаталогКомпоненты = "MonacoEditor";
ДвоичныеДанные = ПолучитьМакет("MonacoEditor");
Чтение = Вычислить("Новый ЧтениеДанных(ДвоичныеДанные)"); // 8.3.9+
Файл = Новый ЧтениеZipФайла(Чтение.ИсходныйПоток());
Файл.ИзвлечьВсе(БазовыйКаталог + КаталогКомпоненты);
ИмяФайла = БазовыйКаталог + КаталогКомпоненты + ирОбщий.РазделительПутиКФайлуЛкс() + "editor.js";
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.Прочитать(ИмяФайла, КодировкаТекста.UTF8);
ТекстФайла = ТекстовыйДокумент.ПолучитьТекст();
ТекстФайла = ирОбщий.СтрЗаменитьЛкс(ТекстФайла, "customOptions: true",
", lineHeight: 15"
", suggestFontSize: 13, suggestLineHeight: 15"
, Истина);
ТекстовыйДокумент.УстановитьТекст(ТекстФайла);
ТекстовыйДокумент.Записать(ИмяФайла);
//ИмяФайла = БазовыйКаталог + КаталогКомпоненты + ирОбщий.РазделительПутиКФайлуЛкс() + "decorations.css";
//ТекстовыйДокумент = Новый ТекстовыйДокумент;
//ТекстовыйДокумент.Прочитать(ИмяФайла);
//ТекстовыйДокумент.ДобавитьСтроку("body {overflow: hidden;}");
//// Цвета статусной строки
//ТекстовыйДокумент.ДобавитьСтроку("
//|.statusbar-widget {
//| background: #c2dfef;
//| color: #000;
//|}");
//// Ширина списка автодополнения
//ТекстовыйДокумент.ДобавитьСтроку("
//|.monaco-editor .suggest-widget {
//| width: 500px;
//|}");
//// Ширина списка автодополнения вместе с окном детальной инфы
//ТекстовыйДокумент.ДобавитьСтроку("
//|.monaco-editor .suggest-widget.docs-side {
//| width: 1000px;
//|}");
//ТекстовыйДокумент.Записать(ИмяФайла);
БазовыйФайлРедактораКода = БазовыйКаталог + КаталогКомпоненты + ирОбщий.РазделительПутиКФайлуЛкс() + "index.html";
КонецЕсли;
Возврат БазовыйФайлРедактораКода;
КонецФункции
//.
// Параметры:
// МодульМетаданных - см. МодульМетаданных -
// ИмяМетода - ? -
// Возвращаемое значение:
// СтрокаТаблицыЗначений, Неопределено -
Функция СтрокаМетодаМодуляПоИмени(Знач МодульМетаданных, Знач ИмяМетода) Экспорт
Если Ложь
Или Не ЗначениеЗаполнено(ИмяМетода)
Или ИмяМетода = ИмяМетодаИнициация()
Тогда
Возврат Неопределено;
КонецЕсли;
СтрокаМетода = МодульМетаданных.Методы.Найти(НРег(ИмяМетода), "НИмя");
Если Истина
И СтрокаМетода <> Неопределено
И Не ЗначениеЗаполнено(СтрокаМетода.ИмяМодуля)
Тогда
СтрокаМетода.ИмяМодуля = МодульМетаданных.Имя;
КонецЕсли;
Возврат СтрокаМетода;
КонецФункции
#Если Клиент Тогда
// Не применяется для имитаторов.
// Параметры:
// ДанныеФормы - ДанныеФормы -
// ЛиКоллекция - Булево, Неопределено -
// Форма - УправляемаяФорма -
// Возвращаемое значение:
// Структура - "Ключ" содержит имя реквизита, а "Значение" содержит описание типов реквизита
Функция ДочерниеСвойстваДанныхФормы(ДанныеФормы, Знач ЛиДляКоллекции = Неопределено, Знач Форма, Знач ИмяСвойства = "") Экспорт
ДокументДОМ = Неопределено; // ДокументDOM
ПутьКРодителю = ПутьКРеквизитуУправляемойФормы(ДанныеФормы, ЛиДляКоллекции, ДокументДОМ);
СтруктураИмен = Новый Структура;
Если ЗначениеЗаполнено(ПутьКРодителю) Тогда
СтруктураИмен = ИменаРеквизитовФормы(Форма, ПутьКРодителю, ЛиДляКоллекции,, ДокументДОМ).Все;
Если ЗначениеЗаполнено(ИмяСвойства) И Не СтруктураИмен.Свойство(ИмяСвойства) Тогда
ДобавитьОтсутствиеЭлементаФормы(Форма, "Реквизит:" + ПутьКРодителю + "." + ИмяСвойства);
КонецЕсли;
Иначе
// parameters - там почему то всегда пусто
КонецЕсли;
Возврат СтруктураИмен;
КонецФункции
//.
// Параметры:
// ДанныеФормы - ДанныеФормы -
// выхЛиДляКоллекции - Булево, Неопределено - на выходе Булево
// выхДокументДОМ - ДокументDOM -
// Возвращаемое значение:
// Строка -
Функция ПутьКРеквизитуУправляемойФормы(Знач ДанныеФормы, выхЛиДляКоллекции = Неопределено, выхДокументДОМ = Неопределено) Экспорт
Если выхЛиДляКоллекции = Неопределено Тогда
выхЛиДляКоллекции = ирОбщий.ЛиКоллекцияЛкс(ДанныеФормы);
КонецЕсли;
выхДокументДОМ = ирОбщий.ТекстВДокументDOMЛкс(ирОбщий.ОбъектВСтрокуXMLЛкс(ДанныеФормы)); // 1.2 мс на малой форме
Разыменователь = РазыменовательПространствИменDOM();
Выражение = "/*[last()]/t:type[1]/text()";
ПутьКРодителю = выхДокументДОМ.ВычислитьВыражениеXPath(Выражение, выхДокументДОМ, Разыменователь, ТипРезультатаDOMXPath.Строка).СтроковоеЗначение;
Если Найти(ПутьКРодителю, "root.") = 1 Тогда
ПутьКРодителю = Сред(ПутьКРодителю, СтрДлина("root.") + 1);
Иначе
ПутьКРодителю = "";
КонецЕсли;
Возврат ПутьКРодителю;
КонецФункции
// Позволяет пользователю выбрать один из возможных вариантов описания слова.
//
// Параметры:
// СтруктураЦикла - Соответствие - где ключи - имена ветвей дерева, а значения - таблицы структур типов;
// *ВключатьПутьКОписаниюТипаЗначения - Булево, *Неопределено - признак добавления в список выбора тип значения слова.
//
// Возвращаемое значение:
// СтрокаТаблицыЗначений, Структура - описание слова.
//
Функция ВыбратьСтрокуОписанияИзМассиваСтруктурТипов(СтруктураЦикла, ВключатьПутьКОписаниюТипаЗначения = Ложь, ВладелецФормы = Неопределено, Слово = "",
НомерПараметраМетода = 0, БезусловнаяАктивизацияРезультатов = Истина, выхФормаВыбора = Неопределено, КоличествоФактПараметровМетода = 0) Экспорт
ДеревоВыбора = Новый ДеревоЗначений;
ДеревоВыбора.Колонки.Добавить("Ключ");
ДеревоВыбора.Колонки.Добавить("Представление");
ДеревоВыбора.Колонки.Добавить("ТипСлова");
СчетчикСтрокВторогоУровня = 0;
НачальнаяСтрокаВыбора = Неопределено;
Для Каждого ЭлементЦикла Из СтруктураЦикла Цикл
СтрокаЭлементаЦикла = ДеревоВыбора.Строки.Добавить();
СтрокаЭлементаЦикла.Представление = ЭлементЦикла.Ключ;
КонецЦикла;
ДеревоВыбора.Строки.Сортировать("Представление");
Для Каждого СтрокаЭлементаЦикла Из ДеревоВыбора.Строки Цикл
Для Каждого СтруктураТипаКонтекста Из СтруктураЦикла[СтрокаЭлементаЦикла.Представление] Цикл
//Если СтруктураТипаКонтекста.СтрокаОписания = Неопределено Тогда
// Продолжить;
//КонецЕсли;
Если СтруктураТипаКонтекста.ИмяОбщегоТипа = "НеизвестныйКонтекст" Тогда
Продолжить;
КонецЕсли;
СтрокаОписания = СтруктураТипаКонтекста.СтрокаОписания;
Если ТипЗнч(СтрокаОписания) = Тип("Структура") Тогда
СтрокаОписания = СтрокаОписания.СтрокаОписания;
КонецЕсли;
// Ранее среди параметров были: ПутьКСлову = "", ТекущееСлово = "",
//// Добавим строку описания слова
//ЭтоИмяТипа = Ложь;
//Попытка
// Если СтрокаОписания.ТипЯзыка = "ИмяТипа" Тогда
// ЭтоИмяТипа = Истина;
// КонецЕсли;
//Исключение
//КонецПопытки;
//
//Если ЭтоИмяТипа Тогда
//
// Если Прав(ПутьКСлову, 1) = "(" Тогда
// ЧистыйПутьКСлову = Лев(ПутьКСлову, СтрДлина(ПутьКСлову) - 1);
// Иначе
// ЧистыйПутьКСлову = ТекущееСлово;
// КонецЕсли;
//
// БазовыйТип = ирОбщий.ПервыйФрагментЛкс(ЧистыйПутьКСлову);
// Если БазовыйТип = "" Тогда
// // НеизвестныйКонтекст
// СтрокаОписания = Неопределено;
// Иначе
// СтрокаОписания = ТаблицаОбщихТипов.Найти(БазовыйТип, "БазовыйТип");
// КонецЕсли;
//КонецЕсли;
Если Истина
И ТипЗнч(СтрокаОписания) = Тип("СтрокаТаблицыЗначений")
И СтрокаЭлементаЦикла.Строки.Найти(СтрокаОписания, "Ключ") = Неопределено
И СтрокаОписания.Владелец().Колонки.Найти("ЛиЭкспорт") = Неопределено
И (Ложь
Или СтрокаОписания.Владелец().Колонки.Найти("ТипЯзыка") = Неопределено
Или СтрокаОписания.ТипЯзыка <> "ИмяТипа")
Тогда
ПредставлениеТипа = СтрокаОписания.Слово;
Если Истина
И СтрокаОписания.Владелец().Колонки.Найти("ТипКонтекста") <> Неопределено
И ЗначениеЗаполнено(СтрокаОписания.ТипКонтекста)
Тогда
ПредставлениеТипа = СтрокаОписания.ТипКонтекста + "." + ПредставлениеТипа;
КонецЕсли;
СтрокаДереваВыбора = СтрокаЭлементаЦикла.Строки.Добавить();
СтрокаДереваВыбора.Ключ = СтрокаОписания;
Попытка
СтрокаДереваВыбора.ТипСлова = СтрокаОписания.ТипСлова;
Исключение
СтрокаДереваВыбора.ТипСлова = "Тип";
КонецПопытки;
СтрокаДереваВыбора.Представление = ПредставлениеТипа;
КонецЕсли;
Если ВключатьПутьКОписаниюТипаЗначения Тогда
// Добавим строку описания типа значения
СтрокаОписанияТипаЗначения = ТаблицаОбщихТипов.Найти(НРег(СтруктураТипаКонтекста.ИмяОбщегоТипа), "НСлово");
Если СтрокаОписанияТипаЗначения <> Неопределено Тогда
Если СтрокаЭлементаЦикла.Строки.Найти(СтрокаОписанияТипаЗначения, "Ключ") = Неопределено Тогда
ПредставлениеТипа = СтрокаОписанияТипаЗначения.Слово;
СтрокаДереваВыбора = СтрокаЭлементаЦикла.Строки.Добавить();
СтрокаДереваВыбора.Ключ = СтрокаОписанияТипаЗначения;
СтрокаДереваВыбора.ТипСлова = "Тип";
СтрокаДереваВыбора.Представление = ПредставлениеТипа;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЦикла;
СчетчикСтрокВторогоУровня = СчетчикСтрокВторогоУровня + СтрокаЭлементаЦикла.Строки.Количество();
Если Истина
И НачальнаяСтрокаВыбора = Неопределено
И СтрокаЭлементаЦикла.Строки.Количество() > 0
Тогда
Если СтрокаДереваВыбора.ТипСлова = "Конструктор" Тогда
Отбор = Новый Структура;
Отбор.Вставить("ТипКонтекста", СтрокаОписания.ТипКонтекста);
Отбор.Вставить("Слово", "<Новый>");
Отбор.Вставить("ЯзыкПрограммы", 0);
ТаблицаВариантов = ТаблицаПараметров.Скопировать(Отбор);
НовыйТекущийВариант = ПодобратьВариантСинтаксисаМетода(ТаблицаВариантов, КоличествоФактПараметровМетода);
Для Каждого СтрокаВарианта Из СтрокаЭлементаЦикла.Строки Цикл
Если НовыйТекущийВариант = СтрокаВарианта.Ключ.Слово Тогда
НачальнаяСтрокаВыбора = СтрокаВарианта;
Прервать;
КонецЕсли;
КонецЦикла;
Иначе
НачальнаяСтрокаВыбора = СтрокаЭлементаЦикла.Строки[0];
КонецЕсли;
КонецЕсли;
СтрокаЭлементаЦикла.Строки.Сортировать("Представление");
КонецЦикла;
Если выхФормаВыбора = Неопределено Тогда
выхФормаВыбора = ирКлиент.ПолучитьФормуЛкс("Обработка.ирСинтаксПомощник.Форма");
КонецЕсли;
Если Ложь
Или Истина
//Или СчетчикСтрокВторогоУровня > 0
//Или выхФормаВыбора.Открыта()
Тогда
выхФормаВыбора.ДеревоТиповСлова = ДеревоВыбора;
выхФормаВыбора.ИскомоеСлово = Слово;
выхФормаВыбора.ПоискСУчетомТипаСлова = Истина;
выхФормаВыбора.НомерИскомогоПараметра = НомерПараметраМетода;
выхФормаВыбора.ВладелецФормы = ВладелецФормы;
выхФормаВыбора.ЗакрыватьПриЗакрытииВладельца = Ложь;
Если НачальнаяСтрокаВыбора <> Неопределено Тогда
выхФормаВыбора.ВыбратьИскомуюСтроку(НачальнаяСтрокаВыбора, БезусловнаяАктивизацияРезультатов);
Иначе
Если выхФормаВыбора.Открыта() Тогда
//выхФормаВыбора.ОбновитьРезультатыПоиска(); // - бесконечная рекурсия при открытии из поля текста по слову
Иначе
выхФормаВыбора.Открыть(); // - нужно для вызова из адаптера
КонецЕсли;
КонецЕсли;
выхФормаВыбора.ВладелецФормы = Неопределено; // Перенес в саму форму
КонецЕсли;
Если Ложь
Или СчетчикСтрокВторогоУровня = 1
Или (Истина
И СчетчикСтрокВторогоУровня = 2
И ДеревоВыбора.Строки[0].Строки.Количество() = 1
И НачальнаяСтрокаВыбора.Ключ = ДеревоВыбора.Строки[1].Строки[0].Ключ)
Тогда
ВыбранныйЭлементТипа = НачальнаяСтрокаВыбора;
ИначеЕсли СчетчикСтрокВторогоУровня > 1 Тогда
//ФормаВыбора = ПолучитьФорму("ФормаВыбораСправкиПоСлову");
//ФормаВыбора.ДеревоТиповСлова = ДеревоВыбора;
//ФормаВыбора.НачальноеЗначениеВыбора = НачальнаяСтрокаВыбора;
//ВыбранныйЭлементТипа = ФормаВыбора.ОткрытьМодально();
ВыбранныйЭлементТипа = НачальнаяСтрокаВыбора;
Иначе
ВыбранныйЭлементТипа = Неопределено;
КонецЕсли;
Если ВыбранныйЭлементТипа = Неопределено Тогда
СтрокаОписания = Неопределено;
Иначе
СтрокаОписания = ВыбранныйЭлементТипа.Ключ;
КонецЕсли;
Возврат СтрокаОписания;
КонецФункции
Функция НайтиИмяМетодаСтрокиМодуля(Знач ИмяМодуля, Знач НомерСтроки, Знач СодержаниеСтроки = Неопределено, ТекстыМодулей = Неопределено, СтароеИмяФайлаМодуляБезРасширения = "",
Знач ЧислоСтрокДляПоискаИмениМетода = 1000, выхСодержаниеСтроки = "") Экспорт
Если Не ЗначениеЗаполнено(ИмяМодуля) Тогда
// Динамический код
Возврат "";
КонецЕсли;
ОписаниеМодуля = ирКлиент.ОписаниеМодуляПоСжатомуИмениЛкс(ИмяМодуля);
ИмяМетода = НайтиИмяМетодаСтрокиФайлаМодуля(ОписаниеМодуля.ИмяМодуля, НомерСтроки, СодержаниеСтроки, ТекстыМодулей, СтароеИмяФайлаМодуляБезРасширения, ЧислоСтрокДляПоискаИмениМетода,,, выхСодержаниеСтроки);
Возврат ИмяМетода;
КонецФункции
Функция НайтиИмяМетодаСтрокиФайлаМодуля(Знач ИмяМодуля, Знач НомерСтроки, Знач СодержаниеСтроки = Неопределено, ТекстыМодулей = Неопределено, СтароеИмяФайлаМодуляБезРасширения = "",
Знач ЧислоСтрокДляПоискаИмениМетода = 2000, выхСмещениеСтрокиМетода = 0, Знач ПолеТекстаМодуля = Неопределено, выхСодержаниеСтроки = "") Экспорт
Если ПолеТекстаМодуля = Неопределено Тогда
ПолеТекстаМодуля = ирКлиент.ПолеТекстаМодуляБезСтруктурыТипаЛкс(ИмяМодуля);
КонецЕсли;
Если ПолеТекстаМодуля = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
выхСодержаниеСтроки = СокрЛП(ПолеТекстаМодуля.ПолеТекста.ПолучитьСтроку(НомерСтроки));
Если Ложь
Или СодержаниеСтроки = Неопределено
Или выхСодержаниеСтроки = СокрЛП(СодержаниеСтроки)
Тогда
НужноеОписаниеМетода = Неопределено; // СтрокаТаблицыЗначений, Неопределено
ИмяМетода = НайтиМетодПоНомеруСтроки(ПолеТекстаМодуля, НомерСтроки, ИмяМодуля, ТекстыМодулей, ЧислоСтрокДляПоискаИмениМетода, НужноеОписаниеМетода);
Если НужноеОписаниеМетода <> Неопределено Тогда
выхСмещениеСтрокиМетода = НомерСтроки - НужноеОписаниеМетода.НачальнаяСтрока;
Если НомерСтроки > НужноеОписаниеМетода.КонечнаяСтрока Тогда
НужноеОписаниеМетода.КонечнаяСтрока = НомерСтроки;
КонецЕсли;
КонецЕсли;
Иначе
Пустышка = 0; // Для отладки
КонецЕсли;
Возврат ИмяМетода;
КонецФункции
//.
// Параметры:
// ПолеТекстаМодуля - ОбработкаОбъект.ирКлсПолеТекстаПрограммы, Неопределено -
// НомерСтроки - -
// ИмяМодуля - Произвольный, Строка -
// ТекстыМодулейКэш - Соответствие, Неопределено -
// ЧислоСтрокДляПоискаИмениМетода - Число -
// КэшРазметкиМодуля - Структура, Неопределено -
// НужноеОписаниеМетода - СтрокаТаблицыЗначений, Неопределено -
// Возвращаемое значение:
// Произвольный, Строка, Неопределено -
Функция НайтиМетодПоНомеруСтроки(Знач ПолеТекстаМодуля, Знач НомерСтроки, Знач ИмяМодуля = "", Знач ТекстыМодулейКэш = Неопределено, Знач ЧислоСтрокДляПоискаИмениМетода = 2000, НужноеОписаниеМетода = Неопределено) Экспорт
Если ТекстыМодулейКэш = Неопределено Тогда
ТекстыМодулейКэш = Новый Соответствие;
КонецЕсли;
КэшРазметкиМодуля = ТекстыМодулейКэш[ИмяМодуля];
Если КэшРазметкиМодуля = Неопределено Тогда
Методы = Новый ТаблицаЗначений;
Методы.Колонки.Добавить("Метод");
Методы.Индексы.Добавить("Метод");
Методы.Колонки.Добавить("НачальнаяСтрока");
Методы.Колонки.Добавить("КонечнаяСтрока", Новый ОписаниеТипов("Число"));
КэшРазметкиМодуля = Новый Структура("Методы", Методы);
Если ТекстыМодулейКэш <> Неопределено Тогда
ТекстыМодулейКэш[ИмяМодуля] = КэшРазметкиМодуля;
КонецЕсли;
Методы = Неопределено;
КонецЕсли;
НужноеОписаниеМетода = Неопределено;
Если ирКэш.РежимОтладкиЛкс() Тогда
// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
Для Каждого ОписаниеМетода Из КэшРазметкиМодуля.Методы Цикл
Если Истина
И ОписаниеМетода.НачальнаяСтрока <= НомерСтроки
И ОписаниеМетода.КонечнаяСтрока >= НомерСтроки
Тогда
НужноеОписаниеМетода = ОписаниеМетода;
Прервать;
КонецЕсли;
КонецЦикла;
Иначе
// Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru)
Для Каждого ОписаниеМетода Из КэшРазметкиМодуля.Методы Цикл   Если Истина   И ОписаниеМетода.НачальнаяСтрока <= НомерСтроки   И ОписаниеМетода.КонечнаяСтрока >= НомерСтроки   Тогда   НужноеОписаниеМетода = ОписаниеМетода;   Прервать;   КонецЕсли;   КонецЦикла;
КонецЕсли;
Если НужноеОписаниеМетода = Неопределено Тогда
НачальнаяСтрокаДиапазона = Макс(1, НомерСтроки - ЧислоСтрокДляПоискаИмениМетода);
ПолеТекстаМодуля.ПолеТекста.УстановитьГраницыВыделения(НачальнаяСтрокаДиапазона, 1, НомерСтроки, 1);
ТекстГдеИскать = ПолеТекстаМодуля.ВыделенныйТекст();
Вхождения = НайтиЗаголовкиИКонцыМетодов(ТекстГдеИскать,, Истина);
Если Вхождения.Количество() > 0 Тогда
Вхождение = Вхождения[Вхождения.Количество() - 1];
ИмяМетода = Вхождение.SubMatches(0);
НужноеОписаниеМетода = КэшРазметкиМодуля.Методы.Найти(ИмяМетода, "Метод");
Если НужноеОписаниеМетода = Неопределено Тогда
НужноеОписаниеМетода = КэшРазметкиМодуля.Методы.Вставить(0);
НужноеОписаниеМетода.Метод = ИмяМетода;
НужноеОписаниеМетода.НачальнаяСтрока = НачальнаяСтрокаДиапазона + СтрЧислоСтрок(Лев(ПолеТекстаМодуля.ВыделенныйТекст(), Вхождение.FirstIndex + Вхождение.Length)) - 1;
Если ИмяМетода = ИмяМетодаИнициация() Тогда
НужноеОписаниеМетода.КонечнаяСтрока = 100000000;
КонецЕсли;
КонецЕсли;
Иначе
Пустышка = 0; // Для отладки
КонецЕсли;
Если ИмяМетода = Неопределено Тогда
ИмяМетода = ИмяМетодаИнициация();
КонецЕсли;
Иначе
ИмяМетода = НужноеОписаниеМетода.Метод;
КонецЕсли;
Возврат ИмяМетода;
КонецФункции
Функция НайтиЗаголовкиИКонцыМетодов(Знач ТекстГдеИскать, Знач ИскатьКонцы = Истина, Знач ТолькоПоследнее = Ложь) Экспорт
РегВыражение = ирКэш.ВычислительРегВыраженийЛкс();
#Если Сервер И Не Сервер Тогда
РегВыражение = Обработки.ирОболочкаРегВыражение.Создать();
#КонецЕсли
РегВыражение.Global = Истина;
РегВыражение.Pattern = "(?:" + шПустоеНачалоСтроки + "[\-\+]?(?:(?:Асинх|Async)\s+)?" + шМетодНачало + шРазделитель + "+(" + шИмя + ")" + шРазделитель + "*\()";
Если ИскатьКонцы Тогда
РегВыражение.Pattern = РегВыражение.Pattern + "|(?:" + шПустоеНачалоСтроки + шМетодКонец + шРазделитель + "+?(?=\n))";
КонецЕсли;
Вхождения = РегВыражение.НайтиВхождения(ТекстГдеИскать, ТолькоПоследнее);
Возврат Вхождения;
КонецФункции
Функция ИмяМодуляИзИмениФайла(Знач ПолноеИмя) Экспорт
//ИмяМодуля = ирОбщий.СтрокаБезПоследнегоФрагментаЛкс(СтрЗаменить(ПолноеИмя, ПапкаКэшаМодулей.ПолноеИмя + "\", ""));
ИмяМодуля = СтрЗаменить(ирОбщий.ПоследнийФрагментЛкс(ПолноеИмя, ПапкаКэшаМодулей.ПолноеИмя + "\"), "\", " ");
ИмяМодуля = ирОбщий.СтрокаБезПоследнегоФрагментаЛкс(ИмяМодуля);
Возврат ИмяМодуля;
КонецФункции
Функция ЗаполнитьСписокИнструментов() Экспорт
Если СписокИнструментов.Количество() = 0 Тогда
ТабличныйДокумент = ПолучитьМакет("СписокИнструментов");
СписокИнструментов.Загрузить(ирОбщий.ТаблицаЗначенийИзТабличногоДокументаЛкс(ТабличныйДокумент,,,, Истина));
КонецЕсли;
Возврат СписокИнструментов;
КонецФункции
// Инициализирует полное дерево типов платформы.
//
// Параметры:
// Нет.
//
Процедура ИнициироватьДеревоТипов() Экспорт
ИнициацияОписанияМетодовИСвойств();
Состояние("Инициализация дерева типов...");
Если ДеревоТипов <> Неопределено Тогда
Возврат;
КонецЕсли;
ДеревоТипов = Новый ДеревоЗначений;
ДеревоТипов.Колонки.Добавить("Пометка", Новый ОписаниеТипов("Булево"));
ДеревоТипов.Колонки.Добавить("Имя");
ДеревоТипов.Колонки.Добавить("ИндексКартинки", Новый ОписаниеТипов("Число"));
ДеревоТипов.Колонки.Добавить("СтруктураТипа");
лТаблицаТипов = ТаблицаОбщихТипов.Скопировать(Новый Структура("ЯзыкПрограммы", 0), "Слово");
лТаблицаТипов.Колонки.Слово.Имя = "Имя";
Для Каждого СтрокаТипа Из лТаблицаТипов Цикл
ЗаполнитьЗначенияСвойств(ДеревоТипов.Строки.Добавить(), СтрокаТипа);
КонецЦикла;
СтруктураТипа = НоваяСтруктураТипа();
СтруктураТипа.ТипЯзыка = "ИмяТипа";
СтруктураТипа.ИмяОбщегоТипа = "";
ОбработатьСтрокиДереваТипов(ДеревоТипов.Строки, СтруктураТипа);
ДеревоТипов.Строки.Сортировать("Имя", Истина);
ВсеТипы.Сортировать("Имя");
МассивВажныхТипов = Новый Массив;
// Порядок обратный
МассивВажныхТипов.Добавить("Массив");
МассивВажныхТипов.Добавить("Булево");
МассивВажныхТипов.Добавить("Дата");
МассивВажныхТипов.Добавить("Строка");
МассивВажныхТипов.Добавить("Число");
Для Каждого ВажныйТип Из МассивВажныхТипов Цикл
СтрокаТипа = ВсеТипы.Найти(ВажныйТип, "Имя");
ВсеТипы.Сдвинуть(СтрокаТипа, -ВсеТипы.Индекс(СтрокаТипа));
СтрокаТипа = ДеревоТипов.Строки.Найти(ВажныйТип, "Имя");
ДеревоТипов.Строки.Сдвинуть(СтрокаТипа, -ДеревоТипов.Строки.Индекс(СтрокаТипа));
КонецЦикла;
Состояние("");
КонецПроцедуры
Процедура ОбработатьСтрокиДереваТипов(Строки, КорневаяСтруктураТипа = Неопределено, ОкончаниеСтрокиТипа = "", _МетаданныеТипа = Неопределено) Экспорт
МассивСтрокКУдалению = Новый Массив;
Для Каждого СтрокаТипа Из Строки Цикл
ТекущееИмяТипа = СтрокаТипа.Имя;
СтрокаТипа.Имя = СтрокаТипа.Имя + ОкончаниеСтрокиТипа;
Уровень = СтрокаТипа.Уровень();
ФрагментыОбщегоТипа = Неопределено;
Если Уровень = 0 Тогда
Если Найти(ТекущееИмяТипа, ".") > 0 Тогда
КорневойТипМетаданных = ТекущееИмяТипа;
ФрагментыОбщегоТипа = ирОбщий.СтрРазделитьЛкс(ТекущееИмяТипа);
ТекущееИмяТипа = ФрагментыОбщегоТипа[0];
Если Ложь
Или ирОбщий.СтрКончаетсяНаЛкс(ТекущееИмяТипа, "ТабличнаяЧасть")
Или ирОбщий.СтрКончаетсяНаЛкс(ТекущееИмяТипа, "ТабличнаяЧастьСтрока")
Тогда
КорневойТипМетаданных = "ТабличнаяЧасть";
Иначе
КорневойТипМетаданных = СтрЗаменить(КорневойТипМетаданных, "Выборка.", ".");
КорневойТипМетаданных = СтрЗаменить(КорневойТипМетаданных, "Ссылка.", ".");
КорневойТипМетаданных = СтрЗаменить(КорневойТипМетаданных, "Объект.", ".");
КорневойТипМетаданных = СтрЗаменить(КорневойТипМетаданных, "Список.", ".");
КорневойТипМетаданных = СтрЗаменить(КорневойТипМетаданных, "Запись.", ".");
КорневойТипМетаданных = СтрЗаменить(КорневойТипМетаданных, "НаборЗаписей.", ".");
КорневойТипМетаданных = СтрЗаменить(КорневойТипМетаданных, "МенеджерЗначения.", ".");
КорневойТипМетаданных = СтрЗаменить(КорневойТипМетаданных, "Менеджер.", "."); // Должно быть последним, т.к. есть WSСсылкаМенеджер
КорневойТипМетаданных = ирОбщий.ПервыйФрагментЛкс(КорневойТипМетаданных);
КонецЕсли;
Иначе
КорневойТипМетаданных = ТекущееИмяТипа;
КонецЕсли;
СтрокаТипаМетаОбъектов = ОписаниеТипаМетаОбъектов(КорневойТипМетаданных);
Если СтрокаТипаМетаОбъектов <> Неопределено Тогда
СтрокаТипа.ИндексКартинки = СтрокаТипаМетаОбъектов.ИндексКартинкиЕдинственное;
КонецЕсли;
Уровень = 0;
//СтрокаТипа.ИмяОбщегоТипа = ТекущееИмяТипа;
Иначе
Если КорневаяСтруктураТипа <> Неопределено Тогда
КорневаяСтруктураТипа.Свойство("ФрагментыОбщегоТипа", ФрагментыОбщегоТипа);
КонецЕсли;
СтрокаТипа.ИндексКартинки = Строки.Родитель.ИндексКартинки;
КонецЕсли;
Если ФрагментыОбщегоТипа <> Неопределено Тогда
Если ФрагментыОбщегоТипа.ВГраница() > Уровень Тогда
ТекущийФрагмент = ФрагментыОбщегоТипа[Уровень + 1];
КонецЕсли;
Если Найти(ТекущийФрагмент, "<") > 0 Тогда
Если Истина
И КорневаяСтруктураТипа = Неопределено
Тогда
КорневаяСтруктураТипа = НоваяСтруктураТипа();
КорневаяСтруктураТипа.ТипЯзыка = "ИмяТипа";
КорневаяСтруктураТипа.ИмяОбщегоТипа = СтрокаТипа.Имя;
КонецЕсли;
Если Уровень = 0 Тогда
КорневаяСтруктураТипа.Вставить("ФрагментыОбщегоТипа", ФрагментыОбщегоТипа);
СтруктураТипа = НоваяСтруктураТипа();
ЗаполнитьЗначенияСвойств(СтруктураТипа, КорневаяСтруктураТипа);
СтруктураТипа.ИмяОбщегоТипа = ТекущееИмяТипа;
Иначе
СтруктураТипа = СтрокаТипа.СтруктураТипа;
КонецЕсли;
Попытка
ТаблицаСлов = СловаКонтекстаМетаданные(СтруктураТипа, НовыеПараметрыЗаполненияСлов("Свойство"));
Исключение
ТаблицаСлов = Новый ТаблицаЗначений;
КонецПопытки;
Если Истина
И Уровень > 0
И ТаблицаСлов.Количество() = 0
Тогда
МассивСтрокКУдалению.Добавить(СтрокаТипа);
Продолжить;
Иначе
ОкончаниеСтрокиТипаВниз = "";
Для Счетчик = Уровень + 2 По ФрагментыОбщегоТипа.ВГраница() Цикл
Фрагмент = ФрагментыОбщегоТипа[Счетчик];
ОкончаниеСтрокиТипаВниз = ОкончаниеСтрокиТипаВниз + "." + Фрагмент;
КонецЦикла;
Для Каждого СтрокаСлова Из ТаблицаСлов Цикл
НоваяСтрока = СтрокаТипа.Строки.Добавить();
СтруктураТипаВниз = СтрокаСлова.ТаблицаТипов[0];
НоваяСтрока.СтруктураТипа = СтруктураТипаВниз;
//НоваяСтрока.Имя = ИмяТипаИзСтруктурыТипа(СтруктураТипаВниз);
НоваяСтрока.Имя = ТекущееИмяТипа + "." + СтруктураТипаВниз.Метаданные.Имя;
КонецЦикла;
ОбработатьСтрокиДереваТипов(СтрокаТипа.Строки, КорневаяСтруктураТипа, ОкончаниеСтрокиТипаВниз);
КонецЕсли;
КонецЕсли;
КонецЕсли;
//ЗаполнитьЗначенияСвойств(СтруктураТипа, КорневаяСтруктураТипа, "ИмяОбщегоТипа");
ЗаполнитьЗначенияСвойств(ВсеТипы.Добавить(), СтрокаТипа);
КонецЦикла;
РодительСтрок = Строки.Родитель;
Для Каждого СтрокаКУдалению Из МассивСтрокКУдалению Цикл
РодительСтрок.Строки.Удалить(СтрокаКУдалению);
КонецЦикла;
КонецПроцедуры
// Открыть диалог для редактирования допустимых типов.
//
// Параметры:
// ДопустимыеТипы - Строка - сериализованные допустимые типы;
// *ТолькоПросмотр - Булево, *Истина - открыть только для просмотра.
//
// Возвращаемое значение:
// Строка - сериализованных допустимых типов;
// Неопределено - отмена.
//
Функция РедактироватьДопустимыеТипы(ДопустимыеТипы, ТолькоПросмотр = Ложь) Экспорт
ФормаВыбора = ПолучитьФорму("ВыборДопустимыхТипов");
ФормаВыбора.ДопустимыеТипы = ДопустимыеТипы;
ФормаВыбора.ТолькоПросмотр = ТолькоПросмотр;
Если ФормаВыбора.ОткрытьМодально() = Истина Тогда
Возврат ФормаВыбора.ДопустимыеТипы;
Иначе
Возврат Неопределено;
КонецЕсли;
КонецФункции
// Убирает из строки лишние кавычки.
//
// Параметры:
// ПервичнаяСтрока - Строка.
//
// Возвращаемое значение:
// Строка.
//
Функция ИзвлечьСтрокуШаблонаТекста(ПервичнаяСтрока)
мРегВыражение.Global = Истина;
СтрокаБезГраниц = Сред(ПервичнаяСтрока, 2, СтрДлина(ПервичнаяСтрока) - 2);
мРегВыражение.Pattern = "([^""]*"")""";
Результат = мРегВыражение.Заменить(СтрокаБезГраниц, "$1");
Возврат Результат;
КонецФункции // ИзвлечьСтрокуШаблонаТекста ()
// Загружает шаблоны текста из файла.
//
// Параметры:
// Нет.
//
// Возвращаемое значение:
// Булево - успешность операции.
//
Функция ПолучитьТаблицуШаблоновТекста(ИмяКласса, _мСообщенияЧерезПредупреждения = Ложь, ПринудительноОбновить = Ложь) Экспорт
Если Истина
И Не ПринудительноОбновить
И ТаблицаШаблоновТекста <> Неопределено
Тогда
Возврат ТаблицаШаблоновТекста;
КонецЕсли;
ТаблицаШаблоновТекста = Новый ТаблицаЗначений;
ТаблицаШаблоновТекста.Колонки.Добавить("Шаблон");
ТаблицаШаблоновТекста.Колонки.Добавить("Замена");
ТаблицаШаблоновТекста.Индексы.Добавить("Шаблон");
ФайлШаблонов = ирОбщий.ВосстановитьЗначениеЛкс(ИмяКласса + ".ФайлШаблоновТекста");
Файл = Новый Файл(ФайлШаблонов);
Если Не Файл.Существует() Тогда
Если ЗначениеЗаполнено(ФайлШаблонов) Тогда
ирОбщий.СообщитьСУчетомМодальностиЛкс("Не обнаружен файл шаблонов текста """ + ФайлШаблонов + """, указанный в настройках компоненты ""Контекстная подсказка""");
КонецЕсли;
Возврат Неопределено;
КонецЕсли;
Парсер = мПолучитьПарсер("ГрамматикаФайлаШаблоновТекста");
Если Парсер = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
ТекстовыйДокументФайла = Новый ТекстовыйДокумент;
ТекстовыйДокументФайла.Прочитать(ФайлШаблонов);
//Состояние("Идет загрузка файла шаблонов текста...");
gpMsgReduction = 2;
gpMsgAccept = 3;
gpMsgNotLoadedError = 4;
gpMsgLexicalError = 5;
gpMsgSyntaxError = 6;
gpMsgInternalError = 8;
Парсер.OpenTextString(ТекстовыйДокументФайла.ПолучитьТекст());
Закончили = Ложь;
ТекущаяСтрокаТаблицыШаблоновТекста = Неопределено;
Пока Не Закончили Цикл
Ответ = Парсер.Parse();
Если Ложь
Или Ответ = gpMsgLexicalError
Или Ответ = gpMsgSyntaxError
Или Ответ = gpMsgInternalError
Или Ответ = gpMsgNotLoadedError
Или Ответ = gpMsgAccept
Тогда
Закончили = Истина;
ИначеЕсли Ответ = gpMsgReduction Тогда
ТекущееСокращение = Парсер.CurrentReduction; // Reduction {GoldParserForNet.Parser} - Почему то TypeLib не сам видит этот тип
ИмяПравила = ТекущееСокращение.ParentRule.RuleNonterminal.Text;
Если ИмяПравила = "<Match>" Тогда
СтартовыйТокен = ТекущееСокращение.Tokens(0);
ТекущаяСтрокаТаблицыШаблоновТекста = ТаблицаШаблоновТекста.Добавить();
ТекущаяСтрокаТаблицыШаблоновТекста.Шаблон = Нрег(ИзвлечьСтрокуШаблонаТекста(СтартовыйТокен.Data));
ИначеЕсли ИмяПравила = "<Replacement>" Тогда
СтартовыйТокен = ТекущееСокращение.Tokens(0);
ТекущаяСтрокаТаблицыШаблоновТекста.Замена = ИзвлечьСтрокуШаблонаТекста(СтартовыйТокен.Data);
КонецЕсли;
КонецЕсли;
КонецЦикла;
//Состояние();
Если Ответ <> gpMsgAccept Тогда
ирОбщий.СообщитьСУчетомМодальностиЛкс("Указан неправильный файл шаблонов """ + ФайлШаблонов + """");
ТаблицаШаблоновТекста = Неопределено;
КонецЕсли;
Возврат ТаблицаШаблоновТекста;
КонецФункции
// .
// Параметры:
// Параметры - ТаблицаЗначений - :
// *ИмяПараметра
// *Значение
// *ТипЗначения
// ТипЗапроса - Строка, *"Построитель" - "Обычный", "Компоновка", "Построитель"
Функция РедактироватьЗапрос(Текст, Параметры = Неопределено, Знач ТипЗапроса = "Построитель", ПараметрыADO = Неопределено, ПараметрыWMI = Неопределено,
ВыделениеДвумерное = Неопределено, Знач Запрос = Неопределено) Экспорт
СтруктураЗапроса = Новый Структура;
СтруктураЗапроса.Вставить("ТекстЗапроса", Текст);
Если ПараметрыADO <> Неопределено Тогда
СтруктураЗапроса.Вставить("ПараметрыADO", ПараметрыADO);
КонецЕсли;
Если ПараметрыWMI <> Неопределено Тогда
СтруктураЗапроса.Вставить("ПараметрыWMI", ПараметрыWMI);
КонецЕсли;
СтруктураЗапроса.Вставить("ТипЗапроса", ТипЗапроса);
СтруктураЗапроса.Вставить("Имя", "Запрос");
СтруктураЗапроса.Вставить("ВыделениеДвумерное", ВыделениеДвумерное);
КонсольЗапросов = ирОбщий.СоздатьОбъектПоИмениМетаданныхЛкс("Обработка.ирКонсольЗапросов");
#Если Сервер И Не Сервер Тогда
КонсольЗапросов = Обработки.ирКонсольЗапросов.Создать();
#КонецЕсли
Если Параметры <> Неопределено Тогда
ПолныеПараметры = КонсольЗапросов.НоваяТаблицаПараметров();
ирОбщий.ЗагрузитьВТаблицуЗначенийЛкс(Параметры, ПолныеПараметры);
СтруктураЗапроса.Вставить("Параметры", ПолныеПараметры);
КонецЕсли;
Если Запрос <> Неопределено Тогда
КонсольЗапросов.мОбъектЗапроса = Запрос;
КонецЕсли;
РезультатФормы = КонсольЗапросов.РедактироватьСтруктуруЗапроса(, СтруктураЗапроса);
Результат = РезультатФормы <> Неопределено;
Если Результат Тогда
Текст = РезультатФормы.ТекстЗапроса;
Параметры = РезультатФормы.Параметры;
ПараметрыADO = РезультатФормы.ПараметрыADO;
ПараметрыWMI = РезультатФормы.ПараметрыWMI;
ВыделениеДвумерное = РезультатФормы.ВыделениеДвумерное;
КонецЕсли;
Возврат Результат;
КонецФункции
#КонецЕсли
////////////////////////////////////////////////////////////////////////////////
// РАБОТА С АЛГОРИТМАМИ
// Выполняет текст программы.
//
// Параметры:
// ТекстДляВыполнения - Строка;
// *ЛиСинтаксическийКонтроль - Булево, *Ложь - признак вызова только для синтаксического контроля.
//
Функция ВыполнитьЛокально(ТекстДляВыполнения, ЛиСинтаксическийКонтроль = Ложь) Экспорт
Если ЛиСинтаксическийКонтроль Тогда
ирОбщий.ВыполнитьАлгоритмБезРезультата(ТекстДляВыполнения);
Иначе
Результат = ирОбщий.ВыполнитьАлгоритм(ТекстДляВыполнения);
КонецЕсли;
Возврат Результат;
КонецФункции
// Выполняет программный код в контексте.
//
// Параметры:
// ТекстДляВыполнения - Строка;
// *ЛиСинтаксическийКонтроль - Булево, *Ложь - признак вызова только для синтаксического контроля.
//
Функция ВыполнитьПрограммныйКодВКонтексте(КонтекстВыполнения, МетодВыполнения = "ВыполнитьЛокально", ТекстДляВыполнения, ЛиСинтаксическийКонтроль = Ложь) Экспорт
Если ПустаяСтрока(МетодВыполнения) Тогда
ВызватьИсключение "Не указан метод выполнения";
КонецЕсли;
Если КонтекстВыполнения = Неопределено Тогда
ИнформацияОбОшибке = Вычислить(МетодВыполнения + "(ТекстДляВыполнения, ЛиСинтаксическийКонтроль)");
Иначе
ИнформацияОбОшибке = Вычислить("КонтекстВыполнения." + МетодВыполнения + "(ТекстДляВыполнения, ЛиСинтаксическийКонтроль)");
КонецЕсли;
Возврат ИнформацияОбОшибке;
КонецФункции
// Получает новый экземпляр ком-объекта парсера.
//
// Параметры:
// Нет.
//
// Возвращаемое значение:
// ОбработкаОбъект.ирТипКомпонентаADOUtils
//
Функция ПолучитьADOUtils(_ПытатьсяУстанавливать = Ложь, Знач СмещениеГодаADO = Неопределено, Знач Типизировать1С = Ложь, Знач БинарныеВСтроку = Ложь) Экспорт
Если мADOUtils = Неопределено Тогда
ИдентификаторКласса = "GameWithFire.ADOUtils";
ИмяОбъекта = "ADOUtils";
ПодключитьВнешнююКомпоненту(ИдентификаторКласса);
Попытка
мADOUtils = Новый ("AddIn." + ИмяОбъекта);
мADOUtils.BinaryDataAs1C = Истина; // Для проверки актуальности версии библиотеки
Исключение
мADOUtils = Неопределено;
КонецПопытки;
Если Истина
И мADOUtils = Неопределено
//И ПытатьсяУстанавливать
И Ложь
Тогда
ИмяМакетаДополнительнойБиблиотеки = "Zlib1";
ИмяМакетаКомпоненты = "GameWithFire";
ПолучитьCOMОбъектИзМакета(ИмяМакетаКомпоненты, ИдентификаторКласса,, ИмяМакетаДополнительнойБиблиотеки, ИмяОбъекта);
ПодключитьВнешнююКомпоненту(ИдентификаторКласса);
Попытка
мADOUtils = Новый ("AddIn." + ИмяОбъекта);
мADOUtils.BinaryDataAs1C = Истина; // Для проверки актуальности версии библиотеки
Исключение
КонецПопытки;
КонецЕсли;
// такой способ почему то не работает
//мADOUtils = ПолучитьОбъектВнешнейКомпонентыИзМакета(ИмяМакетаКомпоненты, , ИдентификаторКласса, ТипВнешнейКомпоненты.COM, ИмяМакетаДополнительнойБиблиотеки);
КонецЕсли;
Если мADOUtils <> Неопределено Тогда
мADOUtils.ДвоичныеДанныеВВидеСтрок = БинарныеВСтроку;
мADOUtils.BinaryDataAs1C = Типизировать1С;
мADOUtils.YearOffset = СмещениеГодаADO;
КонецЕсли;
Возврат мADOUtils;
КонецФункции
//#КонецЕсли
Функция ИдентификаторыПроцессовОтладчиков() Экспорт
Перем Результат;
ПортДляПодключенияОтладчика(Результат);
Возврат Результат;
КонецФункции
Функция ПортДляПодключенияОтладчика(выхИдентификаторыОтладчиков = Неопределено, выхПротокол = "") Экспорт
Результат = "";
ирОбщий.ПараметрыЗапускаСеансаТекущиеЛкс(Результат);
ИдентификаторЭтогоПроцесса = ирКэш.ИдентификаторПроцессаОСЛкс();
ТекстРезультата = ТекстРезультатаКомандыСистемы("netstat -n -a -o");
выхИдентификаторыОтладчиков = Новый Массив;
шАдресIP4 = "(?:[0-9]{1,3}\.){3}[0-9]{1,3}";
Результат = ирОбщий.ТекстМеждуМаркерамиЛкс(Результат, "/DEBUGGERURL""", """");
Если Истина
И ЗначениеЗаполнено(Результат)
И ирОбщий.СтрокиРавныЛкс(ирОбщий.ПервыйФрагментЛкс(Результат, ":"), "http")
Тогда
// http://CORTEX:1550
выхПротокол = "http";
ПортСервераОтладки = ирОбщий.ПоследнийФрагментЛкс(Результат, ":", Ложь);
Если ПортСервераОтладки = "" Тогда
ПортСервераОтладки = Неопределено;
КонецЕсли;
мРегВыражение.Global = Истина;
шСоединениеССерверомОтладки = "TCP(?:\s+)(" + шАдресIP4 +"):(?:\d+)(?:\s+)" + шАдресIP4 + ":" + ПортСервераОтладки +"(?:\s+)ESTABLISHED(?:\s+)";
мРегВыражение.Pattern = шСоединениеССерверомОтладки + Формат(ИдентификаторЭтогоПроцесса, "ЧГ=");
Вхождения = мРегВыражение.НайтиВхождения(ТекстРезультата);
Для Каждого Вхождение Из Вхождения Цикл
ЛокальныйАдрес4 = Вхождение.SubMatches(0);
Прервать;
КонецЦикла;
мРегВыражение.Pattern = шСоединениеССерверомОтладки + "(\d+)";
Вхождения = мРегВыражение.НайтиВхождения(ТекстРезультата);
Для Каждого Вхождение Из Вхождения Цикл
ИдентификаторОтладчика = Вхождение.SubMatches(1);
Если Истина
И ИдентификаторОтладчика <> Формат(ИдентификаторЭтогоПроцесса, "ЧГ=")
И выхИдентификаторыОтладчиков.Найти(ИдентификаторОтладчика) = Неопределено
Тогда
ПроцессОС = ирОбщий.ПолучитьПроцессОСЛкс(ИдентификаторОтладчика);
Если Истина
И ТипЗнч(ПроцессОС) = Тип("COMОбъект")
И ирОбщий.СтрокиРавныЛкс(ПроцессОС.Name, ирОбщий.ИмяИсполняемогоФайлаКлиентаПлатформыЛкс(Ложь))
И ирОбщий.ЛиПроцессОСКонфигуратораЛкс(ПроцессОС)
Тогда
выхИдентификаторыОтладчиков.Добавить(ИдентификаторОтладчика);
КонецЕсли;
КонецЕсли;
КонецЦикла;
выхИдентификаторыОтладчиков.Добавить("0"); // Чтобы неоднозначность сохранялась и с одним найденным отладчиком
Иначе
выхПротокол = "tcp";
мРегВыражение.Global = Истина;
мРегВыражение.Pattern = "TCP(?:\s+)0\.0\.0\.0:(\d+)(?:\s+)" + шАдресIP4 + ":(\d+)(?:\s+)LISTENING(?:\s+)" + Формат(ИдентификаторЭтогоПроцесса, "ЧГ=");
Вхождения = мРегВыражение.НайтиВхождения(ТекстРезультата);
МассивСлушающихПортов = Новый Массив;
СтрокаПоиска = "";
// Т.к. неясно какой из портов для отладки, используем все
Для Каждого Вхождение Из Вхождения Цикл
МассивСлушающихПортов.Добавить(Вхождение.SubMatches(0));
СтрокаПоиска = СтрокаПоиска + "|" + Вхождение.SubMatches(0);
КонецЦикла;
Если МассивСлушающихПортов.Количество() = 0 Тогда
Результат = Неопределено;
Возврат Результат;
КонецЕсли;
СтрокаПоиска = Сред(СтрокаПоиска, 2);
ЛокальныйАдрес = ирОбщий.ТекстДляРегВыраженияЛкс("127.0.0.1");
мРегВыражение.Pattern = "TCP(?:\s+)" + ЛокальныйАдрес + ":(?:\d+)(?:\s+)" + ЛокальныйАдрес + ":(" + СтрокаПоиска + ")(?:\s+)ESTABLISHED(?:\s+)(\d+)";
Вхождения = мРегВыражение.НайтиВхождения(ТекстРезультата);
Для Каждого Вхождение Из Вхождения Цикл
ИдентификаторКорреспондента = Вхождение.SubMatches(1);
Если ИдентификаторКорреспондента <> Формат(ИдентификаторЭтогоПроцесса, "ЧГ=") Тогда
выхИдентификаторыОтладчиков.Добавить(ИдентификаторКорреспондента);
Иначе
МассивСлушающихПортов.Удалить(МассивСлушающихПортов.Найти(Вхождение.SubMatches(0)));
КонецЕсли;
КонецЦикла;
Если МассивСлушающихПортов.Количество() > 0 Тогда
Результат = "tcp://127.0.0.1:" + МассивСлушающихПортов[0];
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
#Если Клиент Тогда
Функция ТаблицаТиповСтрокиТабличногоПоля(Знач РодительскаяСтруктураТипа, Знач МетаданныеРодителя = Неопределено, Знач СловоЦикл = "", Знач ТипЗначенияСлова = "", Знач выхМетаданныеСлова = Неопределено,
Знач ТаблицаТипов = Неопределено) Экспорт
Если МетаданныеРодителя = Неопределено Тогда
МетаданныеРодителя = РодительскаяСтруктураТипа.Метаданные
КонецЕсли;
Форма = РодительскаяСтруктураТипа.ДержательМетаданных;
ИмяРеквизитаФормы = "";
ДанныеЭлементаФормы = ирОбщий.ДанныеЭлементаФормыЛкс(МетаданныеРодителя, ИмяРеквизитаФормы, Форма);
Если ДанныеЭлементаФормы <> Неопределено Тогда
Если Форма = Неопределено И ТипЗнч(МетаданныеРодителя) <> Тип("ТабличноеПоле") Тогда
Форма = ирОбщий.РодительЭлементаУправляемойФормыЛкс(МетаданныеРодителя);
КонецЕсли;
Если ТипЗнч(ДанныеЭлементаФормы) = Тип("НастройкиКомпоновкиДанных") Тогда
Если СловоЦикл = "ТекущиеДанные" Тогда
НоваяТаблицаТипов = ДобавитьВТаблицуТипов(, НоваяСтруктураТипа("ТекущиеДанныеСтруктурыНастроекКомпоновкиДанных"));
Иначе
НоваяТаблицаТипов = ТаблицаТиповЭлементовКоллекции(СтруктураТипаИзЗначения(ДанныеЭлементаФормы.Структура));
КонецЕсли;
ИначеЕсли ирОбщий.ЛиКоллекцияКомпоновкиЛкс(ДанныеЭлементаФормы) Тогда
НоваяТаблицаТипов = ТаблицаТиповЭлементовКоллекции(СтруктураТипаИзЗначения(ДанныеЭлементаФормы.Элементы));
ИначеЕсли ТипЗнч(ДанныеЭлементаФормы) = Тип("ДинамическийСписок") Тогда
Если ТипЗначенияСлова <> "Произвольный" Тогда
выхМетаданныеСлова = ИменаРеквизитовФормы(Форма, ИмяРеквизитаФормы, Истина).Все;
КонецЕсли;
Иначе
НоваяСтруктураТипа = СтруктураТипаИзЗначения(ДанныеЭлементаФормы);
Если Истина
И ТипЗнч(МетаданныеРодителя) = Тип("ТабличноеПоле")
И ТипЗнч(Форма) = Тип("Форма")
Тогда
МодульФормы = ПодготовитьМодульМетаданных(СтруктураТипаИзЗначения(Форма));
Если МодульФормы.Переменные.Найти(НРег(МетаданныеРодителя.Данные), "НИмя") <> Неопределено Тогда
АнализаторКода = ПолеТекстаМодуля(МодульФормы);
ТаблицаТиповТаблицыФормы = АнализаторКода.ВычислитьТипЗначенияВыражения(МетаданныеРодителя.Данные,,,,,,, Истина);
ЗаполнитьЗначенияСвойств(НоваяСтруктураТипа, ТаблицаТиповТаблицыФормы[0]);
КонецЕсли;
КонецЕсли;
Если ТипЗнч(ДанныеЭлементаФормы) = Тип("ДеревоЗначений") Тогда
НоваяСтруктураТипа.ИмяОбщегоТипа = "КоллекцияСтрокДереваЗначений";
КонецЕсли;
НоваяТаблицаТипов = ТаблицаТиповЭлементовКоллекции(НоваяСтруктураТипа);
Если НоваяТаблицаТипов.Количество() = 0 Тогда
//Если ТипЗнч(ДанныеЭлементаФормы) = Тип("ДеревоЗначений") Тогда
// ТаблицаЗначений = ирОбщий.ДеревоЗначенийВТаблицуЛкс(ДанныеЭлементаФормы, Новый Массив);
//Иначе
Если ТипЗнч(МетаданныеРодителя) <> Тип("ТабличноеПоле") Тогда
ТаблицаЗначений = Новый ТаблицаЗначений;
Для Каждого КлючИЗначение Из ДочерниеСвойстваДанныхФормы(ДанныеЭлементаФормы, Истина, Форма) Цикл
ТаблицаЗначений.Колонки.Добавить(КлючИЗначение.Ключ, КлючИЗначение.Значение);
КонецЦикла;
НоваяТаблицаТипов = ТаблицаТиповЭлементовКоллекции(СтруктураТипаИзЗначения(ТаблицаЗначений));
Если ТипЗнч(ДанныеЭлементаФормы) = Тип("ДеревоЗначений") Тогда
НоваяТаблицаТипов[0].ИмяОбщегоТипа = "СтрокаДереваЗначений";
Иначе // Если ТипЗнч(ДанныеЭлементаФормы) = Тип("ДанныеФормыДерево") Тогда
НоваяТаблицаТипов[0].ИмяОбщегоТипа = "ДанныеФормыЭлементДерева";
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
ИначеЕсли ТипЗнч(МетаданныеРодителя) = Тип("Структура") Тогда
//: МетаданныеРодителя = 0 // см. ИмитаторЭлементаФормы()
выхМетаданныеСлова = Неопределено;
РеквизитФормы = ирОбщий.СлужебныеДанныеФормыЛкс(Форма).Реквизиты.Найти(НРег(МетаданныеРодителя.ПутьКДанным), "НИмя");
Если РеквизитФормы <> Неопределено Тогда
ОписаниеТипов = РеквизитФормы.ОписаниеТипов; //ОписаниеТипов
Если ОписаниеТипов <> Неопределено Тогда
Если ОписаниеТипов.СодержитТип(Тип("ДинамическийСписок")) Тогда
Если ТипЗначенияСлова <> "Произвольный" Тогда
выхМетаданныеСлова = ИменаРеквизитовФормы(Форма, ИмяРеквизитаФормы, Истина).Все;
КонецЕсли;
Иначе
ТаблицаТиповКоллекции = ТаблицаТиповИзОписанияТипов(ОписаниеТипов);
НоваяТаблицаТипов = ТаблицаТиповЭлементовКоллекции(ТаблицаТиповКоллекции[0]);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Истина
И НоваяТаблицаТипов <> Неопределено
И Форма <> Неопределено
Тогда
НоваяТаблицаТипов.ЗаполнитьЗначения(Форма, "ДержательМетаданных");
КонецЕсли;
Возврат НоваяТаблицаТипов;
КонецФункции
//.
// Параметры:
// ИмяФормы - Строка -
// Возвращаемое значение:
// Форма -
Функция ПассивнаяФормаПоИмениКэш(Знач ИмяФормы) Экспорт
Результат = мПассивныеФормы[НРег(ИмяФормы)];
Если Результат = Неопределено Тогда
Попытка
ОбъектМД = ирОбщий.ОбъектМДПоПолномуИмениЛкс(ИмяФормы);
Если ОбъектМД <> Неопределено Тогда
ИмяФормы = ОбъектМД.ПолноеИмя(); // Нормализуем имя, чтобы файл в кэше модулей имел оригинальные регистры букв
КонецЕсли;
ТекстРекомендации = ".
|Рекомендуется добавить в начало ПриСоздании: Если Параметры.Свойство(""АвтоТест"") Тогда Возврат КонецЕсли;";
Форма = ирКлиент.ПассивнаяФормаПоИмениЛкс(ИмяФормы);
ОписаниеОшибки = "Обработчик ПриСоздании формы вернул Отказ" + ТекстРекомендации;
Если Найти(ИмяФормы, "Ф::") > 0 И Не ирКэш.ЛиСеансТолстогоКлиентаУПЛкс() Тогда
ОписаниеОшибки = "Если форма управляемая, то ее невозможно создать из внешней обработки в обычном приложении.";
КонецЕсли;
Исключение
Форма = Неопределено;
ОписаниеОшибки = ОписаниеОшибки() + ТекстРекомендации;
Если Найти(ИмяФормы, "Ф::") > 0 И ирКэш.ЛиСеансТолстогоКлиентаУПЛкс() Тогда
ОписаниеОшибки = ОписаниеОшибки + Символы.ПС
+ "Если форма обычная, то ее невозможно создать из внешней обработки в управляемом приложении.";
КонецЕсли;
КонецПопытки;
Если Форма <> Неопределено Тогда
СлужебныеДанные = ирОбщий.СлужебныеДанныеФормыЛкс(Форма);
Результат = Форма;
Иначе
СлужебныеДанные = Новый Структура;
Результат = СлужебныеДанные;
КонецЕсли;
Если Не СлужебныеДанные.Свойство("ИмяФормы") Тогда
СлужебныеДанные.Вставить("ИмяФормы", ИмяФормы);
КонецЕсли;
ФайлФормы = ирКэш.Получить().ФайлМодуляИзИмениМодуля(СлужебныеДанные.ИмяФормы, "xml", Истина);
Если ФайлФормы.Существует() Тогда
ИмитаторФормы = ирОбщий.ЗагрузитьЗначениеИзФайлаЛкс(ФайлФормы.ПолноеИмя,,, Ложь); // см. ИмитаторУправляемойФормыИзДокументаДОМ()
Если Истина
И ИмитаторФормы <> Неопределено
И ИмитаторФормы.ВерсияФормата = ВерсияФорматаСтруктурыФормы()
Тогда
ДатаОбновления = ФайлФормы.ПолучитьВремяИзменения();
//ДатаОбновления = Дата(1,1,1); // При обновлении кэша адаптером позволяет перезапросить сразу форму
ирКэш.Получить().ДополнитьСлужебныеДанныеИзКэшаФормы(СлужебныеДанные, ИмитаторФормы, ДатаОбновления);
КонецЕсли;
КонецЕсли;
Если Результат = СлужебныеДанные И Не СлужебныеДанные.Свойство("Тип") Тогда
СлужебныеДанные.Вставить("Тип", ирОбщий.ТипУправляемаяФормаЛкс());
КонецЕсли;
Если Форма = Неопределено И ИмяФормы <> ИмяДинамическойФормы() Тогда
Сообщение = "Анализатор кода не видит полное содержимое формы (" + ИмяФормы + ") из-за недоступности ее создания: " + ОписаниеОшибки;
СтруктураТипа = СтруктураТипаИзКонкретногоТипа(СлужебныеДанные.Тип);
СтруктураТипа.Метаданные = СлужебныеДанные;
ИмяМодуляФормы = ИмяМодуляИзСтруктурыТипа(СтруктураТипа);
СсылкаМодуля = ирОбщий.СсылкаСтрокиМодуляЛкс(ИмяМодуляФормы,, "ПриСозданииНаСервере");
ДобавитьСообщениеВнешнемуКлиенту(Сообщение, СсылкаМодуля);
ирОбщий.СообщитьЛкс(Сообщение, СтатусСообщения.Информация);
КонецЕсли;
мПассивныеФормы[НРег(ИмяФормы)] = Результат;
КонецЕсли;
Возврат Результат;
КонецФункции
Процедура ДобавитьСообщениеВнешнемуКлиенту(Текст, Ссылка = "") Экспорт
Если мОчередьСообщенийВнешнемуКлиенту <> Неопределено Тогда
мОчередьСообщенийВнешнемуКлиенту.Сообщения.Добавить(Текст);
Если ЗначениеЗаполнено(Ссылка) Тогда
мОчередьСообщенийВнешнемуКлиенту.Ссылка = Ссылка;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Функция НоваяОчередьСообщенийВнешнемуКлиенту() Экспорт
Результат = Новый Структура;
Результат.Вставить("Сообщения", Новый Массив);
Результат.Вставить("Ссылка", );
Возврат Результат;
КонецФункции
Функция ПолучитьДокументDOMФормы(Форма) Экспорт
СтрокаФормы = ЗначениеВСтрокуВнутр(Форма);
XMLСтрокаФормы = ирОбщий.СтрокаВнутрВХМЛТелоЛкс(СтрокаФормы);
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.УстановитьСтроку(XMLСтрокаФормы);
ПостроительDOM = Новый ПостроительDOM;
ДокументDOM = ПостроительDOM.Прочитать(ЧтениеXML);
Возврат ДокументDOM;
КонецФункции
Функция ПолучитьXPathИмениРеквизитаВОписанииРеквизита()
ИДВерсииПлатформы = ирКэш.НомерИзданияПлатформыЛкс();
//Если ИДВерсииПлатформы = "81" Тогда
// Результат = "/d[3]";
//ИначеЕсли Ложь
// Или ИДВерсииПлатформы = "82"
// Или ИДВерсииПлатформы = "83"
//Тогда
Результат = "/d[4]";
//КонецЕсли;
Возврат Результат;
КонецФункции // ПолучитьXPathИмениРеквизитаВОписанииРеквизита()
Функция ИмяОсновногоРеквизитаФормы(Знач ФормаИлиДокументDOM, Знач РазрешитьАнализМодуля = Истина) Экспорт
Возврат ИменаРеквизитовФормы(ФормаИлиДокументDOM,,,,, РазрешитьАнализМодуля).Основной;
КонецФункции
// Функция - Имена реквизитов формы
// Параметры:
// ФормаИлиДокументDOM - Форма, ФормаКлиентскогоПриложения, ДокументДОМ -
// ПутьКРодителю - Строка, Неопределено - если тип "Строка", то подразумевается управляемая форма, иначе - обычная форма
// ЛиДляКоллекции - -
// выхИдентификаторыРеквизитов - -
// ДокументДОМ - ДокументДОМ - рекомендуется передавать для открытой управляемой формы, т.к. в ней нельзя хранить кэш
// РазрешитьАнализМодуля - -
// ЛиДляЭлементаКоллекции - Булево - пока не используем это разделение в имитаторе
// Возвращаемое значение:
// -
Функция ИменаРеквизитовФормы(Знач ФормаИлиДокументDOM, Знач ПутьКРодителю = Неопределено, Знач ЛиДляКоллекции = Ложь, выхИдентификаторыРеквизитов = Неопределено, ДокументДОМ = Неопределено,
Знач РазрешитьАнализМодуля = Истина) Экспорт
ИнициацияОписанияМетодовИСвойств();
ТипУправляемаяФорма = ирОбщий.ТипУправляемаяФормаЛкс();
Если Ложь
Или ТипЗнч(ФормаИлиДокументDOM) = ТипУправляемаяФорма
Или ПутьКРодителю <> Неопределено
Тогда
// Управляемая форма
ИменаРеквизитов = Неопределено;
КорневыеИменаРеквизитов = Неопределено;
выхИдентификаторыРеквизитов = Новый Соответствие;
ИмяОсновногоРеквизита = "";
Форма = ФормаИлиДокументDOM;
Если Форма <> Неопределено Тогда
СлужебныеДанные = ирОбщий.СлужебныеДанныеФормыЛкс(Форма);
Иначе
Пустышка = 0; // Для отладки. Желательно чтобы сюда не было приходов
КонецЕсли;
Если СлужебныеДанные = Неопределено Тогда
// Редко. Открытая форма. Фактически не используем кэш
СлужебныеДанные = Новый Структура;
КонецЕсли;
Если СлужебныеДанные.Свойство("КорневыеИменаРеквизитов") Тогда
КорневыеИменаРеквизитов = СлужебныеДанные.КорневыеИменаРеквизитов.Все;
КонецЕсли;
Если ДокументДОМ = Неопределено И СлужебныеДанные.Свойство("ДокументДОМ") Тогда
ДокументДОМ = СлужебныеДанные.ДокументДОМ;
КонецЕсли;
Если ТипЗнч(Форма) = ТипУправляемаяФорма И ДокументДОМ = Неопределено Тогда
СтруктураТипа = НоваяСтруктураТипа("ФормаКлиентскогоПриложения");
СтруктураТипа.Метаданные = Форма;
//МодульФормы = ПодготовитьМодульМетаданных(СтруктураТипа); // Раньше кэш ДокументДОМ хранился тут
ЛюбыеДанныеФормы = Неопределено;
КорневыеИменаРеквизитов = Новый Структура;
ИмяМодуля = ИмяМодуляИзСтруктурыТипа(СтруктураТипа);
КандидатыИменРеквизитов = ирОбщий.КандидатыИменОбъектныхРеквизитовФормыЛкс(Форма);
ПолеТекстаПрограммы = Неопределено;
МодульПроанализирован = Ложь;
Пока Истина Цикл
Для Каждого ИмяРеквизита Из КандидатыИменРеквизитов Цикл
Попытка
ЗначениеРеквизита = Форма[ИмяРеквизита];
Исключение
Продолжить;
КонецПопытки;
КорневыеИменаРеквизитов.Вставить(ИмяРеквизита);
Если Истина
И ИмяРеквизита = "Список"
И (Ложь
Или Найти(Форма.ИмяФормы, "ФормаВыбора")
Или Найти(Форма.ИмяФормы, "ФормаСписка"))
Тогда
ИмяОсновногоРеквизита = ИмяРеквизита; // Предварительно
КонецЕсли;
Если Истина
И ТипЗнч(ЗначениеРеквизита) <> Тип("СписокЗначений")
И мМассивТиповСМетаданными.Найти(ТипЗнч(ЗначениеРеквизита)) <> Неопределено
Тогда
ЛюбыеДанныеФормы = ЗначениеРеквизита;
Перейти ~Конец;
КонецЕсли;
КонецЦикла;
Если МодульПроанализирован Тогда
Прервать;
КонецЕсли;
Для Каждого ЭлементФормы Из Форма.Элементы Цикл
ИмяРеквизита = ирОбщий.ПервыйФрагментЛкс(ирОбщий.ПутьКДаннымЭлементаУправляемойФормыЛкс(ЭлементФормы,, Форма));
Если Истина
И ЗначениеЗаполнено(ИмяРеквизита)
И Не КорневыеИменаРеквизитов.Свойство(ИмяРеквизита)
Тогда
КорневыеИменаРеквизитов.Вставить(ИмяРеквизита);
Попытка
ЗначениеРеквизита = Форма[ИмяРеквизита];
Исключение
Продолжить;
КонецПопытки;
ТипЗначения = ТипЗнч(ЗначениеРеквизита);
Если мМассивТиповСМетаданными.Найти(ТипЗначения) <> Неопределено Тогда
ИмяТипа = ирОбщий.ИмяТипаЛкс(ТипЗначения);
Если МассивУправляемыхЭлементовУправления.Найти(ИмяТипа) = Неопределено Тогда
ЛюбыеДанныеФормы = ЗначениеРеквизита;
Перейти ~Конец;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если ЛюбыеДанныеФормы = Неопределено И РазрешитьАнализМодуля Тогда
// Самый долгий способ
ПолеТекстаМодуля = ПолеТекстаМодуля(ИмяМодуля);
#Если Сервер И Не Сервер Тогда
ПолеТекстаМодуля = Обработки.ирКлсПолеТекстаПрограммы.Создать();
#КонецЕсли
ТаблицаТипов = ДобавитьВТаблицуТипов(, СтруктураТипаИзКонкретногоТипа(ирОбщий.ТипУправляемаяФормаЛкс()));
ПолеТекстаМодуля.ЗаполнитьТаблицуСлов(ТаблицаТипов, Ложь,, Ложь, Ложь);
ПолеТекстаМодуля.ЗаполнитьЛокальныеСвойстваИМетодыПоТексту(Ложь, Ложь,,,,,, Истина);
ПолеТекстаМодуля.мРодительскийКонтекст = "ЭтаФорма"; // TODO добавить слова от ЭтотОбъект
ПолеТекстаМодуля.ЗаполнитьЛокальныеСвойстваИМетодыПоТексту(Ложь, Ложь, Истина, Ложь,,,, Истина);
КандидатыИменРеквизитов = ПолеТекстаМодуля.ТаблицаСлов.Выгрузить(Новый Структура("Определение", "Статистический")).ВыгрузитьКолонку("НСлово");
ВредныйКандидат = КандидатыИменРеквизитов.Найти(НРег("ЭтаФорма"));
Если ВредныйКандидат <> Неопределено Тогда
КандидатыИменРеквизитов.Удалить(ВредныйКандидат);
КонецЕсли;
ВредныйКандидат = КандидатыИменРеквизитов.Найти(НРег("ЭтотОбъект"));
Если ВредныйКандидат <> Неопределено Тогда
КандидатыИменРеквизитов.Удалить(ВредныйКандидат);
КонецЕсли;
КонецЕсли;
МодульПроанализирован = Истина;
КонецЦикла;
~Конец:
Если ЛюбыеДанныеФормы <> Неопределено Тогда
ДокументДОМ = ирОбщий.ТекстВДокументDOMЛкс(ирОбщий.ОбъектВСтрокуXMLЛкс(ЛюбыеДанныеФормы)); // Обычно выполняется достаточно быстро
КонецЕсли;
КонецЕсли;
Если ПутьКРодителю = "" И Не ЛиДляКоллекции Тогда
ИменаРеквизитов = КорневыеИменаРеквизитов;
КонецЕсли;
Если ИменаРеквизитов = Неопределено Тогда
ИменаРеквизитов = Новый Структура;
КонецЕсли;
Если СлужебныеДанные.Свойство("Реквизиты") Тогда
ИмяОсновногоРеквизита = СлужебныеДанные.ИмяОсновногоРеквизита;
//Если Истина
// И ЗначениеЗаполнено(ИмяОсновногоРеквизита)
// И ТипЗнч(Форма) = ТипУправляемаяФорма
//Тогда
// Попытка
// ЗначениеРеквизита = Форма[ИмяОсновногоРеквизита]; // может быть затратно часто обращаться к данным формы
// Исключение
// // Мультиметка250321_182536 Снимок формы устарел
// ДобавитьОтсутствиеЭлементаФормы(Форма, ИмяОсновногоРеквизита);
// ИмяОсновногоРеквизита = "";
// СлужебныеДанные.ИмяОсновногоРеквизита = "";
// КонецПопытки;
//КонецЕсли;
ТаблицаРеквизитов = СлужебныеДанные.Реквизиты;
Если ТаблицаРеквизитов <> Неопределено Тогда
УспехРеквизита = Истина;
Для Каждого ИмяРодителя Из ирОбщий.СтрРазделитьЛкс(НРег(ПутьКРодителю),,, Ложь) Цикл
СтрокаРодителя = ТаблицаРеквизитов.Найти(ИмяРодителя, "НИмя");
Если СтрокаРодителя = Неопределено Тогда
УспехРеквизита = Ложь;
Прервать;
КонецЕсли;
ТаблицаРеквизитов = СтрокаРодителя.Реквизиты;
КонецЦикла;
ЭтоКоллекция = Истина
И СтрокаРодителя <> Неопределено
И ТипЗнч(СтрокаРодителя.Значение) <> Тип("Структура"); // Мультиметка7726614
Если Истина
И УспехРеквизита
И (Ложь
Или ЛиДляКоллекции И ЭтоКоллекция
Или Не ЛиДляКоллекции)
Тогда
Для Каждого СтрокаРеквизита Из ТаблицаРеквизитов Цикл
ОписаниеТипов = СтрокаРеквизита.ОписаниеТипов; // ОписаниеТипов
Если СтрокаРеквизита.Значение = Неопределено Тогда
Если ОписаниеТипов = Неопределено Тогда
//ОписаниеТипов = Новый ОписаниеТипов;
ИначеЕсли ТипЗнч(ОписаниеТипов) = Тип("ТаблицаЗначений") Тогда
// см. ТаблицаТиповИзТекста
Иначе
Типы = ОписаниеТипов.Типы();
Если Типы.Количество() > 0 Тогда
ТипЗначения = Типы[0];
Если Ложь
Или ирОбщий.ЛиНаборЗаписейРегистраЛкс(ТипЗначения)
//Или ирОбщий.ЛиТипОбъектаБДЛкс(ТипЗначения) // TODO сделать для объектов генерацию структуры их свойств
Тогда
ОписаниеТипов = ТаблицаТиповИзОписанияТипов(ОписаниеТипов);
ОписаниеТипов[0].ИмяОбщегоТипа = "ДанныеФормыСтруктураСКоллекцией";
КонецЕсли;
КонецЕсли;
КонецЕсли;
Иначе
Если ТипЗнч(СтрокаРеквизита.Значение) = Тип("ТаблицаЗначений") Тогда
СтруктураТипа = НоваяСтруктураТипа("ДанныеФормыКоллекция");
ИначеЕсли ТипЗнч(СтрокаРеквизита.Значение) = Тип("ДеревоЗначений") Тогда
СтруктураТипа = НоваяСтруктураТипа("ДанныеФормыДерево");
// TODO Пока табличные части не сделаны и надо делать и для остальных типов объектов аналогично Мультиметка240813_080918
//ИначеЕсли ирОбщий.ЛиВнешняяОбработкаЛкс(СтрокаРеквизита.Значение) Тогда
// СтруктураТипа = НоваяСтруктураТипа("ДанныеФормыСтруктура");
// СтруктураТипа.Метаданные = СтрокаРеквизита.Значение.Метаданные();
Иначе
СтруктураТипа = СтруктураТипаИзЗначения(СтрокаРеквизита.Значение);
КонецЕсли;
Если СтруктураТипа.Метаданные = Неопределено Тогда
СтруктураТипа.Метаданные = СтрокаРеквизита.Значение;
КонецЕсли;
ОписаниеТипов = ДобавитьВТаблицуТипов(, СтруктураТипа);
КонецЕсли;
ИменаРеквизитов.Вставить(СтрокаРеквизита.Имя, ОписаниеТипов);
КонецЦикла;
Если Истина
И ТаблицаРеквизитов.Количество() = 0
И СтрокаРодителя <> Неопределено
Тогда
Типы = СтрокаРодителя.ОписаниеТипов.Типы();
Если Истина
И Типы.Количество() > 0
И Не ирОбщий.ЛиТипСсылкиБДЛкс(Типы[0], Ложь)
И Метаданные.НайтиПоТипу(Типы[0]) <> 0
Тогда
ТаблицаСлов = ТаблицаСловИзСтруктурыТипа(СтруктураТипаИзКонкретногоТипа(Типы[0]), НовыеПараметрыЗаполненияСлов("Свойство"));
Для Каждого СтрокаСлова Из ТаблицаСлов Цикл
ИменаРеквизитов.Вставить(СтрокаСлова.Слово, СтрокаСлова.ТаблицаТипов);
КонецЦикла;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ДокументДОМ <> Неопределено Тогда
ЗначениеРодитель = Неопределено;
Если ЗначениеЗаполнено(ПутьКРодителю) Тогда
Если Найти(ПутьКРодителю, ".") = 0 Тогда
Попытка
ЗначениеРодитель = Форма[СтрЗаменить(ПутьКРодителю, ".", "")];
Исключение
// Может быть ошибка "Поле объекта недоступно для чтения" https://www.hostedredmine.com/issues/98538
КонецПопытки;
КонецЕсли;
ПутьКРодителю = "." + ПутьКРодителю;
КонецЕсли;
Разыменователь = РазыменовательПространствИменDOM();
Если ЛиДляКоллекции Тогда
ПутьКРодителю = ПутьКРодителю + ".item";
КонецЕсли;
Выражение = "/*/*/*[@name=""root" + ПутьКРодителю + """]/*";
НаборУзлов = ДокументДОМ.ВычислитьВыражениеXPath(Выражение, ДокументДОМ, Разыменователь, ТипРезультатаDOMXPath.Любой);
УзелDOM = НаборУзлов.ПолучитьСледующий();
Пока УзелDOM <> Неопределено Цикл
ИмяРеквизита = УзелDOM.Атрибуты.ПолучитьИменованныйЭлемент("nameRu");
Если ИмяРеквизита = Неопределено Тогда
ИмяРеквизита = УзелDOM.Атрибуты.ПолучитьИменованныйЭлемент("name");
КонецЕсли;
Если ИмяРеквизита <> Неопределено Тогда
ИмяРеквизита = ИмяРеквизита.ТекстовоеСодержимое;
Если Истина
И Найти(ИмяРеквизита, ".") = 0 // Защита от нахождения "root" + ПутьКРодителю
И УзелDOM.ПервыйДочерний <> Неопределено
Тогда
КвалификаторыСтроки = Неопределено;
Типы = Новый Массив;
УзелТипаЗначения = УзелDOM.ПервыйДочерний.ПервыйДочерний;
Если УзелТипаЗначения <> Неопределено Тогда
ИменаТипов = ирОбщий.СтрРазделитьЛкс(УзелТипаЗначения.ТекстовоеСодержимое, " ");
Если ИменаТипов.Количество() < 11 Тогда
Для Каждого ИДТипа Из ИменаТипов Цикл
Попытка
Тип = ЗначениеИзСтрокиВнутр("{""T""," + ИДТипа + "}");
Исключение
Тип = Неопределено;
КонецПопытки;
Если Тип <> Неопределено Тогда
Типы.Добавить(Тип);
Если Тип = Тип("Строка") Тогда
Атрибут = УзелТипаЗначения.РодительскийУзел.Атрибуты.ПолучитьИменованныйЭлемент("length");
Если Атрибут <> Неопределено Тогда
ДлинаСтрока = Атрибут.ТекстовоеСодержимое;
КвалификаторыСтроки = Новый КвалификаторыСтроки(Число(ДлинаСтрока));
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЕсли;
Если Истина
И Типы.Количество() = 0
И ТипЗнч(Форма) = ТипУправляемаяФорма
Тогда
ЗначениеРеквизита = Null;
Если ПутьКРодителю = "" Тогда
Попытка
ЗначениеРеквизита = Форма[ИмяРеквизита];
Исключение
// Может быть ошибка "Поле объекта недоступно для чтения" https://www.hostedredmine.com/issues/985380
КонецПопытки;
Если ЗначениеРеквизита <> Null Тогда
Типы.Добавить(ТипЗнч(ЗначениеРеквизита));
КонецЕсли;
ИначеЕсли ЗначениеРодитель <> Неопределено Тогда
Попытка
ЗначениеРеквизита = ЗначениеРодитель[ИмяРеквизита];
Исключение
// Может быть ошибка "Поле объекта недоступно для чтения" https://www.hostedredmine.com/issues/98538
КонецПопытки;
Если ЗначениеРеквизита <> Null Тогда
ТаблицаТипов = ТаблицаТиповИзЗначения(ЗначениеРеквизита);
Если ИменаРеквизитов.Свойство(ИмяРеквизита) Тогда
ТаблицаТипов[0].МетаданныеСвойства = ИменаРеквизитов[ИмяРеквизита][0].Метаданные; /// Например объект МД табличной части
КонецЕсли;
ИменаРеквизитов.Вставить(ИмяРеквизита, ТаблицаТипов); // Мультиметка250303_191432
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Ложь
Или Не ИменаРеквизитов.Свойство(ИмяРеквизита)
Или (Истина
И Типы.Количество()
И ИменаРеквизитов[ИмяРеквизита] = Неопределено)
Тогда
ИменаРеквизитов.Вставить(ИмяРеквизита, Новый ОписаниеТипов(Типы,,,, КвалификаторыСтроки));
КонецЕсли;
выхИдентификаторыРеквизитов.Вставить(УзелDOM.Атрибуты[0].ТекстовоеСодержимое, ИмяРеквизита);
КонецЕсли;
КонецЕсли;
УзелDOM = НаборУзлов.ПолучитьСледующий();
КонецЦикла;
КонецЕсли;
Если ТипЗнч(Форма) = ТипУправляемаяФорма И Форма.Открыта() Тогда
// Нельзя размещать ДокументДОМ, т.к. он не сериализуется
Иначе
СлужебныеДанные.Вставить("ДокументДОМ", ДокументДОМ);
КонецЕсли;
Иначе // Обычная форма
ИменаРеквизитов = Новый Структура;
ДокументДОМ = ФормаИлиДокументDOM;
Если ТипЗнч(ФормаИлиДокументDOM) <> Тип("ДокументDOM") Тогда
СлужебныеДанные = ирОбщий.СлужебныеДанныеФормыЛкс(ФормаИлиДокументDOM);
Если СлужебныеДанные <> Неопределено Тогда
Результат = Неопределено;
Если СлужебныеДанные.Свойство("КорневыеИменаРеквизитов", Результат) Тогда
Возврат Результат;
КонецЕсли;
КонецЕсли;
ДокументДОМ = ПолучитьДокументDOMФормы(ФормаИлиДокументDOM);
КонецЕсли;
РазыменовательПИ = Новый РазыменовательПространствИменDOM(ДокументДОМ);
СтрокаXPath = "/e[1]/e[1]/e[2]/e[2]/e" + ПолучитьXPathИмениРеквизитаВОписанииРеквизита() + "/text()";
РезультатXPath = ДокументДОМ.ВычислитьВыражениеXPath(СтрокаXPath, ДокументДОМ, РазыменовательПИ, ТипРезультатаDOMXPath.НеупорядоченныйИтераторУзлов);
Пока Истина Цикл
Узел = РезультатXPath.ПолучитьСледующий();
Если Узел = Неопределено Тогда
Прервать;
КонецЕсли;
ИмяРеквизита = Узел.ТекстовоеСодержимое;
Длина = СтрДлина(ИмяРеквизита);
ИмяРеквизита = Сред(ИмяРеквизита, 2, Длина - 2);
ИменаРеквизитов.Вставить(ИмяРеквизита);
КонецЦикла;
ИмяЭлемента = "/e[1]/e[1]/e[2]/e[1]/d[1]/text()";
РезультатXPath = ДокументДОМ.ВычислитьВыражениеXPath(ИмяЭлемента, ДокументДОМ, РазыменовательПИ, ТипРезультатаDOMXPath.Строка);
КлючОсновногоРеквизита = РезультатXPath.СтроковоеЗначение;
ИмяЭлемента = "/e[1]/e[1]/e[2]/e[2]/e/e[1]/d[1]/text()";
РезультатXPath = ДокументДОМ.ВычислитьВыражениеXPath(ИмяЭлемента, ДокументДОМ, РазыменовательПИ,
ТипРезультатаDOMXPath.УпорядоченныйИтераторУзлов);
Счетчик = 1;
Пока 1 = 1 Цикл
Узел = РезультатXPath.ПолучитьСледующий();
Если Узел = Неопределено Тогда
Прервать;
КонецЕсли;
Если Узел.ТекстовоеСодержимое = КлючОсновногоРеквизита Тогда
Прервать;
КонецЕсли;
Счетчик = Счетчик + 1;
КонецЦикла;
Если Узел <> Неопределено Тогда
СтрокаXPath = "/e[1]/e[1]/e[2]/e[2]/e[" + Счетчик + "]" + ПолучитьXPathИмениРеквизитаВОписанииРеквизита() + "/text()";
РезультатXPath = ДокументДОМ.ВычислитьВыражениеXPath(СтрокаXPath, ДокументДОМ, РазыменовательПИ, ТипРезультатаDOMXPath.Строка);
Длина = СтрДлина(РезультатXPath.СтроковоеЗначение);
ИмяОсновногоРеквизита = Сред(РезультатXPath.СтроковоеЗначение, 2, Длина - 2);
КонецЕсли;
КонецЕсли;
Результат = Новый Структура;
Результат.Вставить("Основной", ИмяОсновногоРеквизита);
Результат.Вставить("Все", ИменаРеквизитов);
Если СлужебныеДанные <> Неопределено И Не ЗначениеЗаполнено(ПутьКРодителю) Тогда
СлужебныеДанные.Вставить("КорневыеИменаРеквизитов", Результат);
КонецЕсли;
Возврат Результат;
КонецФункции
//.
// Возвращаемое значение:
// РазыменовательПространствИменDOM -
Функция РазыменовательПространствИменDOM() Экспорт
СоответствиеПИ = Новый Соответствие;
СоответствиеПИ.Вставить("t", "http://v8.1c.ru/8.2/uobjects");
СоответствиеПИ.Вставить("xs", "http://www.w3.org/2001/XMLSchema");
СоответствиеПИ.Вставить("xsi", "http://www.w3.org/2001/XMLSchema-instance");
Разыменователь = Новый РазыменовательПространствИменDOM(СоответствиеПИ);
Возврат Разыменователь;
КонецФункции
//.
// Параметры:
// Форма - Форма -
// Возвращаемое значение:
// Структура, Неопределено -
Функция СтруктураТипаОбъектаОбычнойФормы(Знач Форма) Экспорт
СлужебныеДанные = ирОбщий.СлужебныеДанныеФормыЛкс(Форма);
СтруктураТипаОбъекта = Неопределено;
Если Истина
И СлужебныеДанные <> Неопределено
И Не СлужебныеДанные.Свойство("СтруктураТипаОбъекта", СтруктураТипаОбъекта)
Тогда
ОсновнойРеквизитФормы = ИмяОсновногоРеквизитаФормы(Форма, Ложь); // Иначе будет циклическая рекурсия при инициации модуля упр. формы
Если Истина
И ЗначениеЗаполнено(ОсновнойРеквизитФормы)
И ТипЗнч(Форма) <> Тип("Структура")
Тогда
Попытка
ОбъектОсновнойРеквизит = Форма[ОсновнойРеквизитФормы];
Исключение
// Мультиметка250321_182536 Снимок формы устарел
ОбъектОсновнойРеквизит = Неопределено;
КонецПопытки;
Если ОбъектОсновнойРеквизит <> Неопределено Тогда
Если ТипЗнч(ОбъектОсновнойРеквизит) = Тип("ДанныеФормыСтруктура") Тогда
ТаблицаТипов = ТаблицаТиповИзОписанияТипов(ИменаРеквизитовФормы(Форма).Все[ОсновнойРеквизитФормы]);
Если ТаблицаТипов.Количество() > 0 Тогда
СтруктураТипаОбъекта = ТаблицаТипов[0];
Иначе
Попытка
Ключ = Форма.Параметры.Ключ;
Исключение
Ключ = Неопределено;
КонецПопытки;
Если Ключ <> Неопределено Тогда
ИмяМД = Метаданные.НайтиПоТипу(ТипЗнч(Ключ)).ПолноеИмя();
Если ирОбщий.ЛиКлючЗаписиРегистраЛкс(Ключ) Тогда
Подтип = "МенеджерЗаписи";
Иначе
Подтип = "Объект";
КонецЕсли;
СтруктураТипаОбъекта = СтруктураТипаИзКонкретногоТипа(Тип(ирОбщий.ИмяТипаИзПолногоИмениМДЛкс(ИмяМД, Подтип)));
КонецЕсли;
КонецЕсли;
Иначе
СтруктураТипаОбъекта = СтруктураТипаИзЗначения(ОбъектОсновнойРеквизит);
КонецЕсли;
СлужебныеДанные.Вставить("СтруктураТипаОбъекта", СтруктураТипаОбъекта);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат СтруктураТипаОбъекта;
КонецФункции
//.
// Возвращаемое значение:
// Структура -
Функция ВсеИменаСтандартныхФорм() Экспорт
ВсеИменаСтандартныхФорм = Новый Структура;
ИменаСтандартныхФорм = Новый СписокЗначений;
ИменаСтандартныхФорм.Добавить("ФормаОбъекта", "Форма объекта");
ИменаСтандартныхФорм.Добавить("ФормаГруппы", "Форма группы");
ИменаСтандартныхФорм.Добавить("ФормаСписка", "Форма списка");
ИменаСтандартныхФорм.Добавить("ФормаВыбора", "Форма выбора");
ИменаСтандартныхФорм.Добавить("ФормаВыбораГруппы", "Форма выбора группы");
ВсеИменаСтандартныхФорм.Вставить("Справочник", ИменаСтандартныхФорм);
ИменаСтандартныхФорм = Новый СписокЗначений;
ИменаСтандартныхФорм.Добавить("ФормаСохранения", "Форма сохранения");
ИменаСтандартныхФорм.Добавить("ФормаЗагрузки", "Форма выбора");
ВсеИменаСтандартныхФорм.Вставить("ХранилищеНастроек", ИменаСтандартныхФорм);
ИменаСтандартныхФорм = Новый СписокЗначений;
ИменаСтандартныхФорм.Добавить("ФормаОбъекта", "Форма объекта");
ИменаСтандартныхФорм.Добавить("ФормаСписка", "Форма списка");
ИменаСтандартныхФорм.Добавить("ФормаВыбора", "Форма выбора");
ВсеИменаСтандартныхФорм.Вставить("Документ", ИменаСтандартныхФорм);
ИменаСтандартныхФорм = Новый СписокЗначений;
ИменаСтандартныхФорм.Добавить("ФормаСписка", "Форма списка");
ИменаСтандартныхФорм.Добавить("ФормаВыбора", "Форма выбора");
ВсеИменаСтандартныхФорм.Вставить("Перечисление", ИменаСтандартныхФорм);
ИменаСтандартныхФорм = Новый СписокЗначений;
ИменаСтандартныхФорм.Добавить("Форма", "Форма");
ИменаСтандартныхФорм.Добавить("ФормаНастроек", "Форма настроек");
ИменаСтандартныхФорм.Добавить("ФормаВарианта", "Форма варианта");
ВсеИменаСтандартныхФорм.Вставить("Отчет", ИменаСтандартныхФорм);
ИменаСтандартныхФорм = Новый СписокЗначений;
ИменаСтандартныхФорм.Добавить("ФормаЗаписи", "Форма записи");
ИменаСтандартныхФорм.Добавить("ФормаСписка", "Форма списка");
ВсеИменаСтандартныхФорм.Вставить("РегистрСведений", ИменаСтандартныхФорм);
ИменаСтандартныхФорм = Новый СписокЗначений;
ИменаСтандартныхФорм.Добавить("ФормаОбъекта", "Форма объекта");
ИменаСтандартныхФорм.Добавить("ФормаГруппы", "Форма группы");
ИменаСтандартныхФорм.Добавить("ФормаСписка", "Форма списка");
ИменаСтандартныхФорм.Добавить("ФормаВыбора", "Форма выбора");
ИменаСтандартныхФорм.Добавить("ФормаВыбораГруппы", "Форма выбора группы");
ВсеИменаСтандартныхФорм.Вставить("ПланВидовХарактеристик", ИменаСтандартныхФорм);
ИменаСтандартныхФорм = Новый СписокЗначений;
ИменаСтандартныхФорм.Добавить("ФормаОбъекта", "Форма объекта");
ИменаСтандартныхФорм.Добавить("ФормаСписка", "Форма списка");
ИменаСтандартныхФорм.Добавить("ФормаВыбора", "Форма выбора");
ВсеИменаСтандартныхФорм.Вставить("ПланСчетов", ИменаСтандартныхФорм);
ИменаСтандартныхФорм = Новый СписокЗначений;
ИменаСтандартныхФорм.Добавить("ФормаОбъекта", "Форма объекта");
ИменаСтандартныхФорм.Добавить("ФормаСписка", "Форма списка");
ИменаСтандартныхФорм.Добавить("ФормаВыбора", "Форма выбора");
ВсеИменаСтандартныхФорм.Вставить("ПланВидовРасчета", ИменаСтандартныхФорм);
ИменаСтандартныхФорм = Новый СписокЗначений;
ИменаСтандартныхФорм.Добавить("ФормаОбъекта", "Форма объекта");
ИменаСтандартныхФорм.Добавить("ФормаСписка", "Форма списка");
ИменаСтандартныхФорм.Добавить("ФормаВыбора", "Форма выбора");
ВсеИменаСтандартныхФорм.Вставить("БизнесПроцесс", ИменаСтандартныхФорм);
ИменаСтандартныхФорм = Новый СписокЗначений;
ИменаСтандартныхФорм.Добавить("ФормаОбъекта", "Форма объекта");
ИменаСтандартныхФорм.Добавить("ФормаСписка", "Форма списка");
ИменаСтандартныхФорм.Добавить("ФормаВыбора", "Форма выбора");
ВсеИменаСтандартныхФорм.Вставить("Задача", ИменаСтандартныхФорм);
ИменаСтандартныхФорм = Новый СписокЗначений;
ИменаСтандартныхФорм.Добавить("ФормаСписка", "Форма списка");
ВсеИменаСтандартныхФорм.Вставить("РегистрБухгалтерии", ИменаСтандартныхФорм);
ВсеИменаСтандартныхФорм.Вставить("РегистрРасчета", ИменаСтандартныхФорм);
ВсеИменаСтандартныхФорм.Вставить("РегистрНакопления", ИменаСтандартныхФорм);
ИменаСтандартныхФорм = Новый СписокЗначений;
ИменаСтандартныхФорм.Добавить("Форма", "Форма");
ВсеИменаСтандартныхФорм.Вставить("КритерийОтбора", ИменаСтандартныхФорм);
ВсеИменаСтандартныхФорм.Вставить("ЖурналДокументов", ИменаСтандартныхФорм);
ВсеИменаСтандартныхФорм.Вставить("Обработка", ИменаСтандартныхФорм);
Возврат ВсеИменаСтандартныхФорм;
КонецФункции
// Функция - Получить макет компоненты
//
// Параметры:
// Компонента - ОбработкаОбъект, ОбработкаОбъект.ирКлсПолеТекстаПрограммы -
//
// Возвращаемое значение:
// Форма -
//
Функция ПолучитьМакетКомпоненты(Компонента) Экспорт
Макет = 0;
Если Не МакетыКомпонент.Свойство(Компонента.ИмяКласса, Макет) Тогда
Макет = Компонента.ПолучитьФорму("ФормаМакет");
Попытка
Пустышка = Макет.мПлатформа;
Успех = Истина;
Исключение
Успех = Ложь;
КонецПопытки;
Если Успех Тогда
ирОбщий.СообщитьЛкс("Образована циклическая ссылка на ирПлатформа", СтатусСообщения.Внимание);
КонецЕсли;
МакетыКомпонент.Вставить(Компонента.ИмяКласса, Макет);
КонецЕсли;
Возврат Макет;
КонецФункции
//.
// Параметры:
// ФайлВнешнейОбработки - Файл -
// ОтФормы - -
// Возвращаемое значение:
// -
Функция ТекстМодуляВнешнейОбработкиАлгоритма(ФайлВнешнейОбработки, Знач ОтФормы = Ложь) Экспорт
Если Не ФайлВнешнейОбработки.Существует() Тогда
Возврат Неопределено;
КонецЕсли;
ТекстМодуля = ТекстМодуляСгенерированнойВнешнейОбработки(ФайлВнешнейОбработки, ОтФормы);
Если ТекстМодуля = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
ТекстАлгоритма = ирОбщий.ТекстМеждуМаркерамиЛкс(ТекстМодуля, МаркерНачалаАлгоритма, МаркерКонцаАлгоритма);
Результат = "";
ТекстАлгоритмаТД = Новый ТекстовыйДокумент;
ТекстАлгоритмаТД.УстановитьТекст(ТекстАлгоритма);
Для Счетчик = 1 По ТекстАлгоритмаТД.КоличествоСтрок() Цикл
СтрокаАлгоритма = ТекстАлгоритмаТД.ПолучитьСтроку(Счетчик);
Если Лев(СтрокаАлгоритма, 1) = Символы.Таб Тогда
СтрокаАлгоритма = Сред(СтрокаАлгоритма, 2);
КонецЕсли;
Результат = Результат + СтрокаАлгоритма + Символы.ПС;
КонецЦикла;
Возврат Результат;
КонецФункции
Функция ТекстМодуляСгенерированнойВнешнейОбработки(ФайлВнешнейОбработки, Знач ЛиМодульОтФормы = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
ФайлВнешнейОбработки = Новый Файл;
#КонецЕсли
ИспользоватьБыструюРаспаковку = ЛиИспользоватьБыструюРаспаковкуВнешнейОбработки();
Если Не ИспользоватьБыструюРаспаковку Тогда
// Штатный способ платформы, но работает только на 8.3.8+
ТекстЛога = Неопределено;
ИмяВременногоФайла = ПолучитьИмяВременногоФайла();
Если Не ирОбщий.ВыполнитьКомандуКонфигуратораЛкс("/DumpExternalDataProcessorOrReportToFiles """ + ИмяВременногоФайла + """ """ + ФайлВнешнейОбработки.ПолноеИмя + """",, ТекстЛога, Истина) Тогда
УдалитьФайлы(ИмяВременногоФайла);
ирОбщий.СообщитьЛкс(ТекстЛога);
Возврат Ложь;
КонецЕсли;
Если ЛиМодульОтФормы Тогда
ИмяФайлаМодуля = "Module.bsl"
Иначе
ИмяФайлаМодуля = "ObjectModule.bsl";
КонецЕсли;
Файлы = НайтиФайлы(ИмяВременногоФайла, ИмяФайлаМодуля, Истина);
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.Прочитать(Файлы[0].ПолноеИмя);
ТекстМодуля = ТекстовыйДокумент.ПолучитьТекст();
Иначе
КаталогРаспаковки = ПолучитьИмяВременногоФайла();
СоздатьКаталог(КаталогРаспаковки);
РаспаковатьФайлВнешнейОбработки(ФайлВнешнейОбработки.ПолноеИмя, КаталогРаспаковки);
Если ЛиМодульОтФормы Тогда
СубПутьКФайлуМодуля = СубПутьКФайлуМодуляФормыВнешнейОбработки;
Иначе
СубПутьКФайлуМодуля = СубПутьКФайлуМодуляВнешнейОбработки;
КонецЕсли;
ФайлТекстаМодуляОбработки = Новый Файл(КаталогРаспаковки + ирОбщий.РазделительПутиКФайлуЛкс() + СубПутьКФайлуМодуля);
ТекстовыйДокументМодуля = Новый ТекстовыйДокумент();
ТекстовыйДокументМодуля.Прочитать(ФайлТекстаМодуляОбработки.ПолноеИмя);
ТекстМодуля = ТекстовыйДокументМодуля.ПолучитьТекст();
УдалитьФайлы(КаталогРаспаковки);
КонецЕсли;
Возврат ТекстМодуля;
КонецФункции
// Открывает модуль внешней обработки алгоритма в конфигураторе.
//
// Параметры:
// АлгоритмОбъект - СправочникОбъект.Сервисы2iS;
// *НомерСтрокиВМодуле - Число, *0 - если указана, устанавливает текущую строку в модуле;
// *ИдентификаторПроцесса - Число, *0 - если указан, будет открываться только в заданном процессе;
// *Переоткрыть - Булево, *Истина - переоткрыть, если уже открыт
//
Процедура ОткрытьАлгоритмВОтладчике(АлгоритмОбъект, НомерСтрокиВМодуле = 0, ИдентификаторПроцесса = 0, Переоткрыть = Истина) Экспорт
Если Не ВыполнятьАлгоритмыЧерезВнешниеОбработки Тогда
ирОбщий.СообщитьЛкс("Данная функция доступна только в режиме выполнения сервисов через внешние обработки", СтатусСообщения.Информация);
Возврат;
КонецЕсли;
Если Не ФайловыйКэшАлгоритмовДопускаетРедактирование Тогда
ирОбщий.СообщитьЛкс("Изменения файла будут игнорироваться, т.к. в настройках алгоритмов не включено разрешение редактирования файлового кэша",
СтатусСообщения.Информация);
КонецЕсли;
ПолучитьФайлОткрывателя1С();
ФайлВнешнейОбработки = ПолучитьОбновитьФайлВнешнейОбработкиАлгоритма(АлгоритмОбъект);
Если ФайлВнешнейОбработки <> Неопределено Тогда
СтрокаЗапуска = """" + ФайлОткрывателя1С.ПолноеИмя + """ -com -ob1""" + ФайлВнешнейОбработки.ПолноеИмя + """";
Если ЗначениеЗаполнено(НомерСтрокиВМодуле) Тогда
СтрокаЗапуска = СтрокаЗапуска + " -num" + Формат(НомерСтрокиВМодуле, "ЧГ=");
КонецЕсли;
Если ЗначениеЗаполнено(ИдентификаторПроцесса) Тогда
СтрокаЗапуска = СтрокаЗапуска + " -pid" + Формат(ИдентификаторПроцесса, "ЧГ=");
КонецЕсли;
Если Переоткрыть Тогда
СтрокаЗапуска = СтрокаЗапуска + " -reopen";
КонецЕсли;
WshShell().Run(СтрокаЗапуска, 0, Ложь);
КонецЕсли;
КонецПроцедуры
Функция ПодключитьПерехватКлавиатуры(Знач Пересоздать = Ложь) Экспорт
Если мПерехватКлавиатуры = Неопределено Тогда
Попытка
мПерехватКлавиатуры = Вычислить("ирПерехватКлавиатуры");
Исключение
КонецПопытки;
КонецЕсли;
Если мПерехватКлавиатуры <> Неопределено Тогда
Попытка
Пустышка = мПерехватКлавиатуры.ЗахватРазрешен;
Исключение
// Антибаг платформы 8.3.21 https://www.hostedredmine.com/issues/956250
мПерехватКлавиатуры = Неопределено;
КонецПопытки;
КонецЕсли;
Если мПерехватКлавиатуры = Неопределено Или Пересоздать Тогда
Если Не ирКлиент.ЛиПерехватКлавиатурногоВводаЛкс() Тогда
мПерехватКлавиатуры = Новый Структура("ЗахватПервым,СобытиеПриНажатии,ЗахватРазрешен");
ПерехватКлавиатурногоВводаВОбычномПриложении = Ложь;
Иначе
мПерехватКлавиатуры = ПолучитьОбъектВнешнейКомпонентыИзМакета("KeyboardHook", "AddIn.ПерехватКлавиатуры.KeyboardHook", "ПерехватКлавиатуры", ТипВнешнейКомпоненты.Native);
КонецЕсли;
Если мПерехватКлавиатуры = Неопределено Тогда
ирОбщий.СообщитьЛкс("Не удалось подключить внешнюю компоненту ПерехватКлавиатуры. Поэтому некоторые функции инструментов отключены.", СтатусСообщения.Внимание);
Возврат Неопределено;
КонецЕсли;
Попытка
Выполнить("ирПерехватКлавиатуры = мПерехватКлавиатуры");
Исключение
КонецПопытки;
КонецЕсли;
мПерехватКлавиатуры.ЗахватРазрешен = ирКлиент.ЛиПерехватКлавиатурногоВводаЛкс();
мПерехватКлавиатуры.СобытиеПриНажатии = ирКлиент.ЛиПерехватКлавиатурногоВводаЛкс();
Возврат мПерехватКлавиатуры;
КонецФункции
// Открывает модуль внешней обработки в конфигураторе.
//
// Параметры:
// ПолноеИмяФайла - Строка;
// *НомерСтрокиВМодуле - Число - если указана, устанавливает текущую строку в модуле;
// *ИдентификаторПроцесса - Число - если указан, будет открываться только в заданном процессе;
// *ЖдатьКонца - Булево -
//
Процедура ОткрытьМодульВнешнейОбработкиВКонфигураторе(Знач ПолноеИмяФайла, Знач НомерСтрокиВМодуле = 0, Знач ИдентификаторПроцесса = 0, Знач ПерейтиКОпределению = Ложь, Знач ВнутреннееИмя = "",
Знач ЛиМодульОтФормы = Ложь) Экспорт
ФайлВнешнейОбработки = Новый Файл(ПолноеИмяФайла);
Если Ложь
Или мНомерВерсииПлатформы >= 803008 И ирКэш.НомерВерсииPowerShellЛкс() >= 3
Тогда
Если Не ЗначениеЗаполнено(ИдентификаторПроцесса) Тогда
ИдентификаторПроцесса = ВыбратьПроцессКонфигуратора();
Если ИдентификаторПроцесса = Неопределено Тогда
Возврат;
КонецЕсли;
КонецЕсли;
ТекстСкрипта = ПолучитьМакет("СкриптОткрытьМодульВнешнейОбработки");
ФайлСкрипта = Новый Файл(ПолучитьИмяВременногоФайла("ps1"));
ТекстСкрипта.Записать(ФайлСкрипта.ПолноеИмя);
СтрокаЗапуска = ирОбщий.КомандаСистемыЗапускаСкриптаPowerShellЛкс(ФайлСкрипта.Имя + " -processID " + ИдентификаторПроцесса + " -file """ + ПолноеИмяФайла + """");
Если НомерСтрокиВМодуле > 0 Тогда
СтрокаЗапуска = СтрокаЗапуска + " -line " + Формат(НомерСтрокиВМодуле, "ЧГ=");
КонецЕсли;
Если ЗначениеЗаполнено(ВнутреннееИмя) Тогда
СтрокаЗапуска = СтрокаЗапуска + " -internalName """ + ВнутреннееИмя + """";
КонецЕсли;
Если ЛиМодульОтФормы Тогда
СтрокаЗапуска = СтрокаЗапуска + " -form 1";
КонецЕсли;
Если ПерейтиКОпределению Тогда
СтрокаЗапуска = СтрокаЗапуска + " -jump 1";
КонецЕсли;
ЖдатьКонца = Ложь; // - иначе возникает 20с ожидание на инструкции $mainWindow = $rootElement.FindFirst(...)
РезультатКоманды = ирОбщий.ВыполнитьКомандуОСЛкс(СтрокаЗапуска, ЖдатьКонца);
//ЗапуститьПриложение(СтрокаЗапуска, КаталогВременныхФайлов(), ЖдатьКонца);
Иначе
ПолучитьФайлОткрывателя1С();
СтрокаЗапуска = """" + ФайлОткрывателя1С.ПолноеИмя + """ -com -ob1""" + ФайлВнешнейОбработки.ПолноеИмя + """";
Если НомерСтрокиВМодуле > 0 Тогда
СтрокаЗапуска = СтрокаЗапуска + " -num" + Формат(НомерСтрокиВМодуле, "ЧГ=");
КонецЕсли;
Если ЗначениеЗаполнено(ИдентификаторПроцесса) Тогда
СтрокаЗапуска = СтрокаЗапуска + " -pid" + Формат(ИдентификаторПроцесса, "ЧГ=");
КонецЕсли;
СтрокаЗапуска = СтрокаЗапуска + " -reopen";
WshShell().Run(СтрокаЗапуска, 0, ЖдатьКонца);
КонецЕсли;
КонецПроцедуры
Функция ВыбратьПроцессКонфигуратора(Знач ИдентификаторыОтладчиков = Неопределено) Экспорт
Если ИдентификаторыОтладчиков = Неопределено Тогда
ИдентификаторыОтладчиков = ИдентификаторыПроцессовОтладчиков();
#Если Сервер И Не Сервер Тогда
ИдентификаторыОтладчиков = Новый Массив;
#КонецЕсли
КонецЕсли;
ТекстСкрипта = ПолучитьМакет("СкриптОткрытыеПриложения1С");
ФайлСкрипта = Новый Файл(ПолучитьИмяВременногоФайла("ps1"));
ТекстСкрипта.Записать(ФайлСкрипта.ПолноеИмя);
КомандаСистемыЗапускаСкрипта = ирОбщий.КомандаСистемыЗапускаСкриптаPowerShellЛкс(ФайлСкрипта.Имя);
РезультатСкрипта = ирОбщий.ВыполнитьКомандуОСЛкс(КомандаСистемыЗапускаСкрипта); // - 1000мс
ТаблицаКонфигураторов = ирОбщий.ТаблицаИзСтрокиСРазделителемЛкс(РезультатСкрипта,,, Истина);
НачальноеЗначениеВыбора = Неопределено;
ПодходящиеПоПредставлению = Новый Массив;
СписокКонфигураторов = Новый СписокЗначений;
Для Каждого СтрокаКонфигуратора Из ТаблицаКонфигураторов Цикл
ПроцессОС = ирОбщий.ПолучитьПроцессОСЛкс(СтрокаКонфигуратора.Id); // - 50мс
Если Не ирОбщий.ЛиПроцессОСКонфигуратораЛкс(ПроцессОС) Тогда
Продолжить;
КонецЕсли;
ПредставлениеПроцесса = СтрокаКонфигуратора.MainWindowTitle;
ЛиОтладчик = ИдентификаторыОтладчиков.Найти(СтрокаКонфигуратора.Id) <> Неопределено;
Если ЛиОтладчик Тогда
ПредставлениеПроцесса = "<Отладчик>" + ПредставлениеПроцесса;
КонецЕсли;
НовыйЭлемент = СписокКонфигураторов.Добавить(СтрокаКонфигуратора.Id, ПредставлениеПроцесса);
Если ЛиОтладчик Тогда
НачальноеЗначениеВыбора = НовыйЭлемент;
КонецЕсли;
Если Найти(ПредставлениеПроцесса, Метаданные.Представление()) Тогда
НачальноеЗначениеВыбора = НовыйЭлемент;
ПодходящиеПоПредставлению.Добавить(НовыйЭлемент);
КонецЕсли;
КонецЦикла;
Если ПодходящиеПоПредставлению.Количество() = 1 Тогда
РезультатВыбора = ПодходящиеПоПредставлению[0];
ИначеЕсли СписокКонфигураторов.Количество() = 1 Тогда
РезультатВыбора = СписокКонфигураторов[0];
ИначеЕсли СписокКонфигураторов.Количество() > 1 Тогда
РезультатВыбора = СписокКонфигураторов.ВыбратьЭлемент("Выберите окно конфигуратора", НачальноеЗначениеВыбора);
Иначе
РезультатВыбора = Неопределено;
КонецЕсли;
Если РезультатВыбора <> Неопределено Тогда
РезультатВыбора = РезультатВыбора.Значение;
КонецЕсли;
Возврат РезультатВыбора;
КонецФункции
// Открывает файл в конфигураторе.
//
// Параметры:
// ПолноеИмя - Строка;
// *ЭлементОбработки - "Форма", "Модуль", *Неопределено$
// *ИдентификаторПроцесса - Число, *0 - если указан, будет открываться только в заданном процессе.
//
Процедура ОткрытьФайлВКонфигураторе(ПолноеИмя, ЭлементОбработки = "", ИдентификаторПроцесса = 0) Экспорт
ПолучитьФайлОткрывателя1С();
ФайлВнешнейОбработки = Новый Файл(ПолноеИмя);
Если ФайлВнешнейОбработки.Существует() Тогда
СтрокаЗапуска = """" + ФайлОткрывателя1С.ПолноеИмя + """";
Если ЭлементОбработки = "Форма" Тогда
СтрокаЗапуска = СтрокаЗапуска + " -cof";
ИначеЕсли ЭлементОбработки = "Модуль" Тогда
СтрокаЗапуска = СтрокаЗапуска + " -com";
Иначе
СтрокаЗапуска = СтрокаЗапуска + " -coa";
КонецЕсли;
СтрокаЗапуска = СтрокаЗапуска + " -ob1""" + ПолноеИмя + """";
Если ИдентификаторПроцесса > 0 Тогда
СтрокаЗапуска = СтрокаЗапуска + " -pid" + Формат(ИдентификаторПроцесса, "ЧГ=");
КонецЕсли;
WshShell().Run(СтрокаЗапуска, 0, Ложь);
КонецЕсли;
КонецПроцедуры
// Открывает диалог глобального поиска в конфигураторе и устанавливает каталог файлов.
//
// Параметры:
// КаталогРасположения - Строка;
// *ИдентификаторПроцесса - Число, *0 - если указан, будет открываться только в заданном процессе.
//
Процедура ОткрытьДиалогГлобальногоПоискаВКонфигураторе(КаталогРасположения, ИдентификаторПроцесса = 0) Экспорт
ПолучитьФайлОткрывателя1С();
СтрокаЗапуска = """" + ФайлОткрывателя1С.ПолноеИмя + """";
СтрокаЗапуска = СтрокаЗапуска + " -cgf";
СтрокаЗапуска = СтрокаЗапуска + " -ob1""" + КаталогРасположения + """";
Если ИдентификаторПроцесса > 0 Тогда
СтрокаЗапуска = СтрокаЗапуска + " -pid" + Формат(ИдентификаторПроцесса, "ЧГ=");
КонецЕсли;
WshShell().Run(СтрокаЗапуска, 0, Ложь);
КонецПроцедуры // ОткрытьДиалогГлобальногоПоискаВКонфигураторе()
// Активизирует главное окно процесса по PID.
//
// Параметры:
// *ИдентификаторПроцесса - Число.
//
Процедура АктивизироватьОкноПроцесса1С8(ИдентификаторПроцесса = 0) Экспорт
ПолучитьФайлОткрывателя1С();
СтрокаЗапуска = """" + ФайлОткрывателя1С.ПолноеИмя + """";
СтрокаЗапуска = СтрокаЗапуска + " -aaa -pid" + Формат(ИдентификаторПроцесса, "ЧГ=");
WshShell().Run(СтрокаЗапуска, 0, Ложь);
КонецПроцедуры
Процедура ПодключитьСвязанныйКонфигуратор(Знач ИД, Знач ИмяФайлаБуфера) Экспорт
мСвязанныйКонфигуратор = Новый Структура("ИД, ИмяФайлаБуфера", ИД, ИмяФайлаБуфера);
КонецПроцедуры
Процедура АктивизироватьОкноКонфигуратора(Знач ПередаваемыйТекст = "") Экспорт
АктивизироватьОкноПроцесса1С8(мСвязанныйКонфигуратор.ИД);
ТекстДок = Новый ТекстовыйДокумент;
ТекстДок.УстановитьТекст(ПередаваемыйТекст);
ТекстДок.Записать(мСвязанныйКонфигуратор.ИмяФайлаБуфера);
КонецПроцедуры
Процедура СохранитьНастройкиАлгоритмов() Экспорт
ирОбщий.СохранитьЗначениеЛкс("СинтаксическийКонтрольПередЗаписью", СинтаксическийКонтрольПередЗаписью);
ирОбщий.СохранитьЗначениеЛкс("ВыполнятьАлгоритмыЧерезВнешниеОбработки", ВыполнятьАлгоритмыЧерезВнешниеОбработки);
ирОбщий.СохранитьЗначениеЛкс("ФайловыйКэшАлгоритмовДопускаетРедактирование", ФайловыйКэшАлгоритмовДопускаетРедактирование);
КонецПроцедуры // СохранитьНастройкиАлгоритмов()
Функция ТаблицаРедактируемыхТиповИзОписанияТипов(ОписаниеТипов = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
ОписаниеТипов = Новый ОписаниеТипов;
#КонецЕсли
ПоляКлюча = "Имя, URIПространстваИмен";
Если мТаблицаРедактируемыхТипов = Неопределено Тогда
мТаблицаРедактируемыхТипов = РедактируемыеТипы.ВыгрузитьКолонки();
мТаблицаРедактируемыхТипов.Индексы.Добавить(ПоляКлюча);
Для Каждого Тип Из ирОбщий.ОписаниеТиповВсеРедактируемыеТипыЛкс().Типы() Цикл
СтрокаТипа = мТаблицаРедактируемыхТипов.Добавить();
//СтрокаТипа.Представление = "" + Тип;
ТипXML = СериализаторXDTO.XMLТип(Тип);
Если Тип = Тип("Число") Тогда
СтрокаТипа.Порядок = -4;
ИначеЕсли Тип = Тип("Строка") Тогда
СтрокаТипа.Порядок = -3;
ИначеЕсли Тип = Тип("Дата") Тогда
СтрокаТипа.Порядок = -2;
ИначеЕсли Тип = Тип("Булево") Тогда
СтрокаТипа.Порядок = -1;
ИначеЕсли Найти(ТипXML.ИмяТипа, ".") > 0 Тогда
СтрокаТипа.Порядок = 100;
ОбъектМД = Метаданные.НайтиПоТипу(Тип);
ТекущееИмяТипа = ОбъектМД.ПолноеИмя();
ИмяТипаМетаданных = ирОбщий.ПервыйФрагментЛкс(ТекущееИмяТипа);
СтрокаТипаМетаОбъектов = ОписаниеТипаМетаОбъектов(ИмяТипаМетаданных);
Если СтрокаТипаМетаОбъектов <> Неопределено Тогда
СтрокаТипа.ИндексКартинки = СтрокаТипаМетаОбъектов.ИндексКартинкиЕдинственное;
СтрокаТипа.Порядок = СтрокаТипаМетаОбъектов.Владелец().Индекс(СтрокаТипаМетаОбъектов);
КонецЕсли;
КонецЕсли;
СтрокаТипа.Имя = ТипXML.ИмяТипа;
СтрокаТипа.URIПространстваИмен = ТипXML.URIПространстваИмен;
СтрокаТипа.Представление = "" + Тип;
КонецЦикла;
КонецЕсли;
Если Ложь
Или ОписаниеТипов = Неопределено
Или ОписаниеТипов.Типы().Количество() = 0
Тогда
НоваяТаблица = мТаблицаРедактируемыхТипов;
Иначе
СтрокиДляКопирования = Новый Массив;
КлючПоиска = Новый Структура(ПоляКлюча);
Для Каждого Тип Из ОписаниеТипов.Типы() Цикл
ТипXML = СериализаторXDTO.XMLТип(Тип);
Если ТипXML = Неопределено Тогда
// Экзотические типы - Например НаправлениеСортировки
Продолжить;
КонецЕсли;
КлючПоиска.Имя = ТипXML.ИмяТипа;
КлючПоиска.URIПространстваИмен = ТипXML.URIПространстваИмен;
Найденные = мТаблицаРедактируемыхТипов.НайтиСтроки(КлючПоиска);
Если Найденные.Количество() = 0 Тогда
// Экзотические типы - например ТипИзмеренияПостроителяОтчета
Продолжить;
КонецЕсли;
СтрокиДляКопирования.Добавить(Найденные[0]);
КонецЦикла;
НоваяТаблица = мТаблицаРедактируемыхТипов.Скопировать(СтрокиДляКопирования);
КонецЕсли;
НоваяТаблица.Сортировать("Порядок, Представление");
Возврат НоваяТаблица;
КонецФункции
Функция ЛиКомпонентаFormsTextBoxДоступна() Экспорт
Если ЛиКомпонентаFormsTextBoxДоступна = Неопределено Тогда
ЛиКомпонентаFormsTextBoxДоступна = Истина;
ИдентификаторКласса = "Forms.TextBox.1";
Попытка
Пустышка = Новый COMОбъект(ИдентификаторКласса);
Исключение
ИмяМакетаДополнительнойБиблиотеки = "FM20ENU";
ИмяМакетаКомпоненты = "FM20";
Пустышка = ПолучитьCOMОбъектИзМакета(ИмяМакетаКомпоненты, ИдентификаторКласса,, ИмяМакетаДополнительнойБиблиотеки);
Если Пустышка = Неопределено Тогда
ТекстСообщения = "Для полной функциональности контекстной подсказки нужно выполнить одно из условий:";
#Если ТолстыйКлиентОбычноеПриложение Тогда
Если Не ирКлиент.ЛиПерехватКлавиатурногоВводаВОбычномПриложенииЛкс() Тогда
ТекстСообщения = ТекстСообщения + "
|- Включить флажок ""Перехват клавиатурного ввода в обычном приложении"" в окне ""Список инструментов и общие настройки""";
КонецЕсли;
#КонецЕсли
ТекстСообщения = ТекстСообщения + "
|- Использовать 32б приложение и зарегистрировать библиотеки FM20.dll и FM20ENU.dll из состава MS Office 97-2007. Это можно сделать с помощью формы ""Регистрация COM-компонент"" из состава подсистемы";
ирОбщий.СообщитьЛкс(ТекстСообщения);
ЛиКомпонентаFormsTextBoxДоступна = Ложь;
КонецЕсли;
КонецПопытки;
КонецЕсли;
Возврат ЛиКомпонентаFormsTextBoxДоступна;
КонецФункции
#КонецЕсли
////////////////////////////////////////////////////////////////////////////////////////////////////
Процедура Уничтожить() Экспорт
мПерехватКлавиатуры = Неопределено;
МакетыКомпонент = Неопределено;
ОткрытыеФормыПодсистемы = Неопределено;
ОчиститьКэшАнализатораЯзыка();
КонецПроцедуры
// Получает новый экземпляр ком-объекта парсера.
//
// Параметры:
// Нет.
//
// Возвращаемое значение:
// ComОбъект, Неопределено.
//
Функция мПолучитьПарсер(ИмяГрамматики, Кэшировать = Истина, СообщениеПользователюПриНеудаче = "") Экспорт
Если Кэшировать Тогда
Если Парсеры.Свойство(ИмяГрамматики) Тогда
Парсер = Парсеры[ИмяГрамматики];
Если Парсер <> Неопределено Тогда
Парсер.Restart(); // Без этого что то не очищается и приводит к зависанию парсинга.
КонецЕсли;
Возврат Парсер;
КонецЕсли;
КонецЕсли;
Парсер = ПолучитьCOMОбъектИзМакета("GoldParser", "GoldParserForNet.Parser"); // Новый Parser
//! Парсер = Новый COMОбъект("GoldParserForNet.Parser");
Если Парсер <> Неопределено Тогда
Парсер.TrimReductions = Истина;
МакетГрамматики = ПолучитьМакет(ИмяГрамматики);
ФайлСкомпилированнойГрамматики = ПолучитьИмяВременногоФайла("cgt");
МакетГрамматики.Записать(ФайлСкомпилированнойГрамматики);
Если Не Парсер.LoadCompiledGrammar(ФайлСкомпилированнойГрамматики) Тогда
ирОбщий.СообщитьСУчетомМодальностиЛкс("Не удалось загрузить файл грамматики """ + ФайлСкомпилированнойГрамматики + """",
Истина, СтатусСообщения.Важное);
Парсер = Неопределено;
КонецЕсли;
УдалитьФайлы(ФайлСкомпилированнойГрамматики);
Иначе
ирОбщий.СообщитьЛкс(СообщениеПользователюПриНеудаче, СтатусСообщения.Внимание);
КонецЕсли;
Если Кэшировать Тогда
Парсеры.Вставить(ИмяГрамматики, Парсер);
КонецЕсли;
Возврат Парсер;
КонецФункции
Процедура ПроверитьСтруктуруФайловогоКэша() Экспорт
ПроверитьКаталогФайловогоКэша();
СтруктураПодкаталоговФайловогоКэша = Новый Структура;
СтруктураПодкаталоговФайловогоКэша.Вставить("a"); // Внешние обработки алгоритмов
//СтруктураПодкаталоговФайловогоКэша.Вставить("b"); // Внешние обработки архива 2iS
СтруктураПодкаталоговФайловогоКэша.Вставить("c"); // Внешние компоненты
СтруктураПодкаталоговФайловогоКэша.Вставить("КэшМодулей");
СтруктураПодкаталоговФайловогоКэша.Вставить("КэшРолей");
Разделитель = ирОбщий.РазделительПутиКФайлуЛкс();
Для Каждого ЭлементПодкаталога Из СтруктураПодкаталоговФайловогоКэша Цикл
ПолныйПутьКаталога = КаталогФайловогоКэша + Разделитель + ЭлементПодкаталога.Ключ;
ФайлКаталога = Новый Файл(ПолныйПутьКаталога);
Если Не ФайлКаталога.Существует() Тогда
Попытка
СоздатьКаталог(ФайлКаталога.ПолноеИмя);
ПробныйФайл = Новый ТекстовыйДокумент;
ПробныйФайл.Записать(ФайлКаталога.ПолноеИмя + Разделитель + "1.txt");
Исключение
ОписаниеОшибки = ОписаниеОшибки();
Сообщить("Файловый кэш """ + ЭлементПодкаталога.Ключ + """ отключен из-за ошибки: " + ОписаниеОшибки, СтатусСообщения.Важное); // При использовании ирОбщий.СообщитьЛкс() может происходить переполнение стека
Продолжить;
КонецПопытки;
КонецЕсли;
СтруктураПодкаталоговФайловогоКэша[ЭлементПодкаталога.Ключ] = ФайлКаталога;
Если ЭлементПодкаталога.Ключ = "a" Тогда
//КаталогДинамическихВнешнихОбработок = ПолныйПутьКаталога;
ПапкаКешаВнешнихОбработокАлгоритмов = ФайлКаталога;
ТекущаяДатаДвижка = Дата("20100927"); // Здесь меняем редко. Будет приводить к разовой очистке кэша перед началом его использования
ФайлКэшаДвижка = Новый Файл(ПолныйПутьКаталога + Разделитель + "_EngineTimeStamp.mll");
ДатаКэшаДвижка = Неопределено;
Если ФайлКэшаДвижка.Существует() Тогда
Попытка
ДатаКэшаДвижка = ЗначениеИзФайла(ФайлКэшаДвижка.ПолноеИмя);
Исключение КонецПопытки;
КонецЕсли;
Если ДатаКэшаДвижка <> ТекущаяДатаДвижка Тогда
Попытка
УдалитьФайлы(ПолныйПутьКаталога + Разделитель, "*.*");
Исключение
Неудача = Истина;
КонецПопытки;
Если Неудача <> Истина Тогда
ЗначениеВФайл(ФайлКэшаДвижка.ПолноеИмя, ТекущаяДатаДвижка);
КонецЕсли;
КонецЕсли;
//ИначеЕсли ЭлементПодкаталога.Ключ = "b" Тогда
// ПапкаКешаВнешнихОбработокАрхива = ФайлКаталога;
ИначеЕсли ЭлементПодкаталога.Ключ = "c" Тогда
ПапкаВнешнихКомпонент = ФайлКаталога;
ИначеЕсли ЭлементПодкаталога.Ключ = "КэшМодулей" Тогда
ПапкаКэшаМодулей = ФайлКаталога;
ИначеЕсли ЭлементПодкаталога.Ключ = "КэшРолей" Тогда
ПапкаКэшаРолей = ФайлКаталога;
КонецЕсли;
КонецЦикла;
ПутьККаталогуСлужебныхВременныхФайлов = КаталогВременныхФайлов() + "temp1template\";
СоздатьКаталог(ПутьККаталогуСлужебныхВременныхФайлов);
МассивЗамков = НайтиФайлы(ПутьККаталогуСлужебныхВременныхФайлов, "*.lck");
Для Каждого Замок Из МассивЗамков Цикл
Попытка
УдалитьФайлы(Замок.ПолноеИмя);
УдалитьФайлы(Замок.Путь + Замок.ИмяБезРасширения);
Исключение
КонецПопытки;
КонецЦикла;
КонецПроцедуры
Функция ФайлРоли(Знач ИмяРоли) Экспорт
ФайлРоли = Новый Файл("" + ПапкаКэшаРолей.ПолноеИмя + "\Role." + ИмяРоли + ".Rights.xml");
Возврат ФайлРоли;
КонецФункции
Функция СловарьПеревода() Экспорт
Если мСловарьПеревода = Неопределено Тогда
Результат = ПолучитьМакет("РусскийАнглийский");
СловарьПеревода = ирОбщий.ТаблицаЗначенийИзТабличногоДокументаЛкс(Результат,,,,,,,,,,, Истина);
ирОбщий.ОбновитьКопиюКолонкиВНижнемРегистреЛкс(СловарьПеревода, "Русский");
ирОбщий.ОбновитьКопиюКолонкиВНижнемРегистреЛкс(СловарьПеревода, "Английский");
//! СловарьПеревода.Колонки.Добавить("НРусский")
//! СловарьПеревода.Колонки.Добавить("НАнглийский")
мСловарьПеревода = СловарьПеревода;
КонецЕсли;
Возврат мСловарьПеревода;
КонецФункции
Функция ПеревестиСтроку(РусскаяСтрока, Принудительно = Ложь) Экспорт
Если Не Принудительно И Метаданные.ВариантВстроенногоЯзыка = Метаданные.СвойстваОбъектов.ВариантВстроенногоЯзыка.Русский Тогда
Возврат РусскаяСтрока;
Иначе
Словарь = СловарьПеревода();
СтрокаПеревода = Словарь.Найти(НРег(РусскаяСтрока), "НРусский");
Если СтрокаПеревода = Неопределено Тогда
Английский = РусскаяСтрока;
Иначе
Английский = СтрокаПеревода.Английский;
КонецЕсли;
Возврат Английский;
КонецЕсли;
КонецФункции
Функция ПеревестиВРусский(ЛокальнаяСтрока, Принудительно = Ложь) Экспорт
Если Не Принудительно И Метаданные.ВариантВстроенногоЯзыка = Метаданные.СвойстваОбъектов.ВариантВстроенногоЯзыка.Русский Тогда
Возврат ЛокальнаяСтрока;
Иначе
Словарь = СловарьПеревода();
СтрокаПеревода = Словарь.НайтиСтроки(Новый Структура("НАнглийский", НРег(ЛокальнаяСтрока)));
КоличествоПереводов = СтрокаПеревода.Количество();
Если КоличествоПереводов = 0 Тогда
Русский = ЛокальнаяСтрока;
Иначе
Русский = СтрокаПеревода[0].Русский;
Если КоличествоПереводов > 1 Тогда
ирОбщий.СообщитьЛкс("Неоднозначный перевод на русский идентификатора """ + ЛокальнаяСтрока + """", СтатусСообщения.Внимание);
КонецЕсли;
КонецЕсли;
Возврат Русский;
КонецЕсли;
КонецФункции
Функция ТекстРезультатаКомандыСистемы(Знач Команда = "", Знач ИмяСервера = "", Элевация = Ложь) Экспорт
Если Не ЗначениеЗаполнено(ИмяСервера) Тогда
ФайлРезультата = Новый Файл(ПолучитьИмяВременногоФайла());
СтрокаЗапуска = Команда;
ирОбщий.ЗапуститьСкрытоеПриложениеИДождатьсяЗавершенияЛкс(СтрокаЗапуска, ФайлРезультата.Путь, ФайлРезультата.Имя, , Элевация);
Если ФайлРезультата.Существует() Тогда
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.Прочитать(ФайлРезультата.ПолноеИмя, КодировкаТекста.OEM);
УдалитьФайлы(ФайлРезультата.ПолноеИмя);
Результат = ТекстовыйДокумент.ПолучитьТекст();
Иначе
Результат = "Файл результата команды системы не найден! Попробуйте отключить антивирусное ПО.";
КонецЕсли;
Иначе
ВызватьИсключение "Получение результата команды системы на удаленном сервере не реализовано";
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ЗарегистрироватьПолучитьCOMОбъект(КлассКомпоненты, ПолноеИмяDll, Административная = Ложь, ИмяТипаВК = Ложь, ИмяМакетаКомпоненты = "", Знач Зарегистрировать = Истина) Экспорт
Если ирКэш.Это64битныйПроцессЛкс() Тогда
ТипПроцесса = "64";
Иначе
ТипПроцесса = "32";
КонецЕсли;
Если Найти(КлассКомпоненты, "ForNet") > 0 Тогда
ТипCOMКомпоненты = "-Net";
Иначе
ТипCOMКомпоненты = "";
КонецЕсли;
Если Зарегистрировать Тогда
ПрефикДействия = "За";
Иначе
ПрефикДействия = "Раз";
КонецЕсли;
Если Истина
И Не Административная
И Зарегистрировать
И ЗначениеЗаполнено(ИмяМакетаКомпоненты)
Тогда
Если Метаданные().Макеты.Найти(ИмяМакетаКомпоненты + "Reg") <> Неопределено Тогда
// http://stackoverflow.com/questions/37193356/registering-net-com-dlls-without-admin-rights-regasm
// http://stackoverflow.com/questions/35782404/registering-a-com-without-admin-rights
СкриптРегистрации = ПолучитьМакет(ИмяМакетаКомпоненты + "Reg").ПолучитьТекст();
СкриптРегистрации = ирОбщий.СтрЗаменитьЛкс(СкриптРегистрации, "HKEY_CLASSES_ROOT", "HKEY_CURRENT_USER\Software\Classes");
РезультатКоманды = ВнестиФайлCOMКомпонентыВРеестр(СкриптРегистрации, СтрЗаменить(ПолноеИмяDll, "\", "/"));
Компонента = ПолучитьПроверитьCOMОбъект(КлассКомпоненты, ИмяТипаВК);
Если Компонента <> Неопределено Тогда
ирОбщий.СообщитьЛкс(ПрефикДействия + "регистрирована COM" + ТипCOMКомпоненты + "-компонента " + КлассКомпоненты, СтатусСообщения.Информация);
Возврат Компонента;
Иначе
ирОбщий.СообщитьЛкс(РезультатКоманды);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ТипCOMКомпоненты = "-Net" Тогда
Если Административная Тогда
Если ФайлРегистратораNetКомпонент = Неопределено Тогда
ФайлРегистратораNetКомпонент = ПроверитьЗаписатьКомпонентуИзМакетаВФайл("RegasmExeWin" + ТипПроцесса, , "exe");
КонецЕсли;
КоманднаяСтрока = """" + ФайлРегистратораNetКомпонент.ПолноеИмя + """ """ + ПолноеИмяDll + """ /unregister"; // сначала надо отменить регистрацию, иначе новая может не выполниться
ИмяФайлаРезультата = "";
РезультатКоманды = ТекстРезультатаКомандыСистемы(КоманднаяСтрока,, Административная);
Если Зарегистрировать Тогда
КоманднаяСтрока = """" + ФайлРегистратораNetКомпонент.ПолноеИмя + """ """ + ПолноеИмяDll + """ /codebase";
ИмяФайлаРезультата = "";
РезультатКоманды = ТекстРезультатаКомандыСистемы(КоманднаяСтрока,, Административная);
Компонента = ПолучитьПроверитьCOMОбъект(КлассКомпоненты, ИмяТипаВК);
КонецЕсли;
Если Компонента <> Неопределено Тогда
ирОбщий.СообщитьЛкс(ПрефикДействия + "регистрирована COM" + ТипCOMКомпоненты + "-компонента " + КлассКомпоненты, СтатусСообщения.Информация);
Возврат Компонента;
Иначе
ирОбщий.СообщитьЛкс(РезультатКоманды);
КонецЕсли;
КонецЕсли;
Иначе
Если Административная Тогда
// HKLM
КоманднаяСтрока = "regsvr32 /s """ + ПолноеИмяDll + """";
Если Не Зарегистрировать Тогда
КоманднаяСтрока = КоманднаяСтрока + " /u";
КонецЕсли;
//ТекстРезультата = ТекстРезультатаКомандыСистемы(КоманднаяСтрока);
ирОбщий.ЗапуститьСкрытоеПриложениеИДождатьсяЗавершенияЛкс(КоманднаяСтрока,,,, Административная);
Компонента = ПолучитьПроверитьCOMОбъект(КлассКомпоненты, ИмяТипаВК);
Если Компонента <> Неопределено Тогда
ирОбщий.СообщитьЛкс(ПрефикДействия + "регистрирована COM" + ТипCOMКомпоненты + "-компонента " + КлассКомпоненты, СтатусСообщения.Информация);
Возврат Компонента;
КонецЕсли;
КонецЕсли;
КонецЕсли;
//Если ирКэш.Это64битныйПроцессЛкс() Тогда
// ирОбщий.СообщитьЛкс("Невозможно загрузить 32-битную COM" + ТипCOMКомпоненты + "-компоненту " + КлассКомпоненты + " в 64-битном приложении. Запустите 32-битное приложение.", СтатусСообщения.Внимание);
//Иначе
ТекстСообщения = "Не удалось " + ПрефикДействия + "регистрировать COM" + ТипCOMКомпоненты + "-компоненту " + КлассКомпоненты;
Если Истина
И Административная
И (Ложь
Или ирОбщий.ВКОбщаяЛкс().IsAdmin()
//Или ЕстьАдминистративныеПраваУУчетнойЗаписиОС()
)
Тогда
ТекстСообщения = ТекстСообщения + " от имени администратора!"
Иначе
ТекстСообщения = ТекстСообщения + ". Запустите приложение от имени администратора или используйте инструмент ""Регистрация COM-компонент"", чтобы ее " + ПрефикДействия + "регистрировать"
КонецЕсли;
//КонецЕсли;
ирОбщий.СообщитьЛкс(ТекстСообщения, СтатусСообщения.Внимание);
Возврат Неопределено;
КонецФункции
Функция ВнестиФайлCOMКомпонентыВРеестр(Знач СкриптРегистрации, Знач ПолноеИмяDll, Знач ИдентификаторКласса = "", Знач x64 = Неопределено) Экспорт
Если x64 = Неопределено Тогда
x64 = ирКэш.Это64битныйПроцессЛкс();
КонецЕсли;
СкриптРегистрации = ирОбщий.СтрЗаменитьЛкс(СкриптРегистрации, "%ComDllFilename%", ПолноеИмяDll);
Если ЗначениеЗаполнено(ИдентификаторКласса) Тогда
СкриптРегистрации = ирОбщий.СтрЗаменитьЛкс(СкриптРегистрации, "%ComDllCLSID%", ИдентификаторКласса);
КонецЕсли;
ИмяФайлаСкрипта = ПолучитьИмяВременногоФайла("reg");
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.УстановитьТекст(СкриптРегистрации);
ТекстовыйДокумент.Записать(ИмяФайлаСкрипта, КодировкаТекста.ANSI);
//РезультатКоманды = ТекстРезультатаКомандыСистемы("regedit /s """ + ИмяФайлаСкрипта + """); // Поддержка Windows XP
РезультатКоманды = ТекстРезультатаКомандыСистемы("reg import """ + ИмяФайлаСкрипта + """ /reg:" + ?(x64, "64", "32")); // Windows Vista и выше
Возврат РезультатКоманды;
КонецФункции
Функция ПолучитьПроверитьCOMОбъект(Знач КлассКомпоненты, ИмяТипаВК = "") Экспорт
Если ЗначениеЗаполнено(ИмяТипаВК) Тогда
ПодключитьВнешнююКомпоненту(КлассКомпоненты);
Попытка
Компонента = Новый ("AddIn." + ИмяТипаВК);
Исключение
КонецПопытки;
Возврат Компонента;
Иначе
Попытка
Компонента = Новый COMОбъект(КлассКомпоненты);
Если КлассКомпоненты = "GoldParserForNet.Parser" Тогда
Попытка
Если Компонента.Version = "5.08" Тогда
Возврат Компонента;
КонецЕсли;
Исключение
Компонента = Неопределено;
КонецПопытки;
Иначе
Возврат Компонента;
КонецЕсли;
Исключение
ОписаниеОшибки = ОписаниеОшибки(); // Для отладки
КонецПопытки;
КонецЕсли;
Возврат Неопределено;
КонецФункции
// Возвращает нужный com-объект. Если компонента не зарегистрирована, то пытается ее сохранить из макета и зарегистрировать.
//
// Параметры:
// Нет.
//
// Возвращаемое значение:
// COMОбъект, Неопределено.
//
Функция ПолучитьCOMОбъектИзМакета(ИмяМакетаКомпоненты, КлассКомпоненты, КаталогУстановки = "авто", ИмяМакетаДополнительнойБиблиотеки = "",
ИмяТипаВК = "") Экспорт
Результат = ПолучитьПроверитьCOMОбъект(КлассКомпоненты, ИмяТипаВК);
Если Результат = Неопределено И АвторегистрацияComКомпонент Тогда
Если Нрег(КаталогУстановки) = Нрег("авто") Тогда
КаталогУстановки = ПапкаВнешнихКомпонент.ПолноеИмя;
КонецЕсли;
#Если Клиент Тогда
Если КаталогУстановки = "" Тогда
Ответ = Вопрос("Для работы данной функции необходимо зарегистрировать
//|(необходимы права локального администратора)
| COM-компоненту """ + ИмяМакетаКомпоненты + """. Выполнить регистрацию?",
РежимДиалогаВопрос.ОКОтмена, 30, КодВозвратаДиалога.Отмена);
Если Ответ = КодВозвратаДиалога.Отмена Тогда
Возврат Неопределено;
КонецЕсли;
ВыборФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.ВыборКаталога);
ВыборФайла.Заголовок = "Укажите папку, куда установить компоненту.";
Если Не ВыборФайла.Выбрать() Тогда
Возврат Неопределено;
КонецЕсли;
КаталогУстановки = ВыборФайла.Каталог;
КонецЕсли;
#КонецЕсли
ФайлКомпоненты = ПроверитьЗаписатьКомпонентуИзМакетаВФайл(ИмяМакетаКомпоненты, КаталогУстановки);
Если ЗначениеЗаполнено(ИмяМакетаДополнительнойБиблиотеки) Тогда
ПроверитьЗаписатьКомпонентуИзМакетаВФайл(ИмяМакетаДополнительнойБиблиотеки, КаталогУстановки);
КонецЕсли;
Результат = ЗарегистрироватьПолучитьCOMОбъект(КлассКомпоненты, ФайлКомпоненты.ПолноеИмя, , ИмяТипаВК, ИмяМакетаКомпоненты);
КонецЕсли;
Возврат Результат;
КонецФункции
// Параметры:
// ИмяКомпоненты - Строка - имя макета компоненты
// КлассКомпоненты - Строка - имя
// ТипВнешнейКомпоненты - ТипВнешнейКомпоненты, * - по умолчанию Native
Функция ПолучитьОбъектВнешнейКомпонентыИзМакета(ИмяМакетаКомпоненты, ИмяОбъекта, ИмяКомпоненты = Неопределено, Знач ТипКомпоненты = Неопределено,
ИмяМакетаДополнительнойБиблиотеки = "") Экспорт
Если ТипКомпоненты = Неопределено Тогда
ТипКомпоненты = ТипВнешнейКомпоненты.Native;
КонецЕсли;
Попытка
Результат = Новый (ИмяОбъекта);
Исключение
Если ИмяКомпоненты = Неопределено Тогда
ИмяКомпоненты = ИмяМакетаКомпоненты;
КонецЕсли;
Если КодСимвола(ИмяМакетаКомпоненты, 1) >= 128 Тогда
// https://www.hostedredmine.com/issues/890335
ВызватьИсключение "Нельзя использовать кириллические буквы в именах файлов внешних компонент";
КонецЕсли;
Если ЗначениеЗаполнено(ИмяМакетаДополнительнойБиблиотеки) Тогда
ФайлДополнительнойБиблиотеки = ПроверитьЗаписатьКомпонентуИзМакетаВФайл(ИмяМакетаДополнительнойБиблиотеки);
КонецЕсли;
// Таким способом в некоторых средах не создавались объекты, возможно из-за работы антивируса https://www.hostedredmine.com/issues/1005009
//ФайлКомпоненты = ПроверитьЗаписатьКомпонентуИзМакетаВФайл(ИмяМакетаКомпоненты);
//Местоположение = ФайлКомпоненты.ПолноеИмя;
//
ДвоичныеДанныеМакета = ПолучитьДвоичныеДанныеКомпоненты(ИмяМакетаКомпоненты);
Местоположение = ПоместитьВоВременноеХранилище(ДвоичныеДанныеМакета);
Успех = ПодключитьВнешнююКомпоненту(Местоположение, ИмяКомпоненты, ТипКомпоненты);
ПодключитьВнешнююКомпоненту(ИмяОбъекта);
Попытка
Результат = Новый (ИмяОбъекта);
Исключение
Описание = ОписаниеОшибки(); // Для отладки
КонецПопытки;
КонецПопытки;
Возврат Результат;
КонецФункции
Функция НечеткоеСравнениеСлов() Экспорт
Если мНечеткоеСравнениеСлов = Неопределено Тогда
мНечеткоеСравнениеСлов = ПолучитьОбъектВнешнейКомпонентыИзМакета("FuzzySearch", "AddIn.FuzzySearch.FuzzyStringMatchExtension", "FuzzySearch"); // ОбработкаОбъект.ирТипКомпонентаFuzzySearch
КонецЕсли;
Возврат мНечеткоеСравнениеСлов;
КонецФункции
Функция ПроверитьЗаписатьКомпонентуИзМакетаВФайл(Знач ИмяМакетаКомпоненты, КаталогУстановки = "", Расширение = "dll") Экспорт
Если Не ЗначениеЗаполнено(КаталогУстановки) Тогда
КаталогУстановки = ПапкаВнешнихКомпонент.ПолноеИмя;
КонецЕсли;
ДвоичныеДанныеМакета = ПолучитьДвоичныеДанныеКомпоненты(ИмяМакетаКомпоненты);
ФайлКомпоненты = Новый Файл(КаталогУстановки + ирОбщий.РазделительПутиКФайлуЛкс() + ИмяМакетаКомпоненты + "." + Расширение);
ВременныйФайл = Новый Файл(ПолучитьИмяВременногоФайла());
Попытка
ДвоичныеДанныеМакета.Записать(ВременныйФайл.ПолноеИмя);
Исключение
ирОбщий.СообщитьЛкс("Не удалось создать временный файл компоненты """ + ИмяМакетаКомпоненты + """: " + ОписаниеОшибки(), СтатусСообщения.Внимание);
Возврат Неопределено;
КонецПопытки;
Счетчик = 1;
ФайлПодходит = Ложь;
Пока ФайлКомпоненты.Существует() Цикл
#Если Клиент Тогда
СравнениеФайлов = Новый СравнениеФайлов;
СравнениеФайлов.СпособСравнения = СпособСравненияФайлов.Двоичное;
СравнениеФайлов.ПервыйФайл = ВременныйФайл.ПолноеИмя;
СравнениеФайлов.ВторойФайл = ФайлКомпоненты.ПолноеИмя;
Если СравнениеФайлов.Сравнить() Тогда
ФайлПодходит = Истина;
Прервать;
КонецЕсли;
#Иначе
// Внешняя компонента может собираться с одинаковым размером (сборщик ее дополняет пустотой до нужного размера)
//Если ВременныйФайл.Размер() = ФайлКомпоненты.Размер() Тогда // Опасно. Переделать на Хэш
// ФайлПодходит = Истина;
// Прервать;
//КонецЕсли;
#КонецЕсли
Попытка
УдалитьФайлы(ФайлКомпоненты.ПолноеИмя);
Исключение
ФайлКомпоненты = Новый Файл(КаталогУстановки + ирОбщий.РазделительПутиКФайлуЛкс() + ИмяМакетаКомпоненты + "_" + Формат(Счетчик, "ЧГ=") + "." + Расширение);
Счетчик = Счетчик + 1;
КонецПопытки;
КонецЦикла;
Если Не ФайлПодходит Тогда
Попытка
ПереместитьФайлКакАдминистратор(ВременныйФайл.ПолноеИмя, ФайлКомпоненты.ПолноеИмя);
Исключение
УдалитьФайлы(ВременныйФайл.ПолноеИмя);
ирОбщий.СообщитьЛкс("Файл """ + ФайлКомпоненты.ПолноеИмя + """ недоступен для изменения и не был перезаписан.", СтатусСообщения.Внимание);
Возврат Неопределено;
КонецПопытки;
КонецЕсли;
Возврат ФайлКомпоненты;
КонецФункции
// Способ через ZIP архив (32+64) появился только в 8.3
Функция ПолучитьДвоичныеДанныеКомпоненты(БазовоеИмяМакетаКомпоненты) Экспорт
Если Метаданные().Макеты.Найти(БазовоеИмяМакетаКомпоненты) = Неопределено Тогда
Если ирКэш.ЛиПлатформаWindowsЛкс() Тогда
БазовоеИмяМакетаКомпоненты = БазовоеИмяМакетаКомпоненты + "Win";
Иначе
БазовоеИмяМакетаКомпоненты = БазовоеИмяМакетаКомпоненты + "Lin";
КонецЕсли;
Если ирКэш.Это64битныйПроцессЛкс() Тогда
БазовоеИмяМакетаКомпоненты = БазовоеИмяМакетаКомпоненты + "64";
Иначе
БазовоеИмяМакетаКомпоненты = БазовоеИмяМакетаКомпоненты + "32";
КонецЕсли;
КонецЕсли;
ДвоичныеДанныеМакета = ПолучитьМакет(БазовоеИмяМакетаКомпоненты);
Возврат ДвоичныеДанныеМакета;
КонецФункции
Функция СоздатьОбъектВнешнихМетаданных(ПолноеИмяФайла, МенеджерВнешнихОбъектов = Неопределено, Конвертировать = Истина) Экспорт
Если МенеджерВнешнихОбъектов = Неопределено Тогда
МенеджерВнешнихОбъектов = ВнешниеОбработки;
КонецЕсли;
Попытка
ВнешнийОбъект = МенеджерВнешнихОбъектов.Создать(ПолноеИмяФайла, Ложь);
Исключение
#Если Клиент Тогда
ОписаниеОшибки = ОписаниеОшибки();
Если Истина
И Конвертировать
И Найти(НРег(ОписаниеОшибки), НРег("не может быть прочитан")) > 0
//И мНомерВерсииПлатформы <> 802015 // Антибаг 8.2.15 http://partners.v8.1c.ru/forum/thread.jsp?id=1003164#1003164
Тогда
СтрокаЗапуска = "DESIGNER /ConvertFiles""" + ПолноеИмяФайла + """";
ЗапуститьСистему(СтрокаЗапуска, Истина);
ВнешнийОбъект = МенеджерВнешнихОбъектов.Создать(ПолноеИмяФайла, Ложь);
Иначе
#КонецЕсли
ВызватьИсключение;
#Если Клиент Тогда
КонецЕсли;
#КонецЕсли
КонецПопытки;
Возврат ВнешнийОбъект;
КонецФункции
Функция СоздатьВнешнююОбработкуАлгоритма(АлгоритмОбъект, ПолноеИмя) Экспорт
Попытка
ВнешняяОбработка = СоздатьОбъектВнешнихМетаданных(ПолноеИмя);
Результат = ВнешняяОбработка;
Исключение
ИнформацияОбОшибке = ИнформацияОбОшибке();
ОписаниеОшибки = ирОбщий.ПодробноеПредставлениеОшибкиЛкс(ИнформацияОбОшибке);
Если Найти(НРег(ОписаниеОшибки), НРег("не может быть прочитана текущей версией")) > 0 Тогда
УдалитьФайлы(ПолноеИмя);
КонецЕсли;
СобытиеОшибки = "Ошибка создания внешнего объекта";
ОписаниеОшибки = "Загрузка сервиса """ + АлгоритмОбъект.Наименование + """";
Если ИнформацияОбОшибке.Причина <> Неопределено Тогда
ОписаниеОшибки = ОписаниеОшибки + "
|" + ПредставлениеИнформацииОбОшибке(ИнформацияОбОшибке.Причина);
КонецЕсли;
ОписаниеОшибки = СобытиеОшибки + ": " + ОписаниеОшибки;
ОписаниеОшибки = ОписаниеОшибки + ": " + ИнформацияОбОшибке.Описание
+ Символы.ПС + ИнформацияОбОшибке.ИсходнаяСтрока;
ирОбщий.СообщитьЛкс(ОписаниеОшибки, СтатусСообщения.Важное);
ЗаписьЖурналаРегистрации(СобытиеОшибки, УровеньЖурналаРегистрации.Ошибка, Метаданные.НайтиПоТипу(ТипЗнч(АлгоритмОбъект.Ссылка)),
АлгоритмОбъект.Ссылка, ОписаниеОшибки);
Результат = Неопределено;
КонецПопытки;
Возврат Результат;
КонецФункции // СоздатьВнешнююОбработкуАлгоритма()
// Проверяет актуальность кэша. Вызывается когда кэш в памяти уже точно не соотвествует объекту БД.
Функция ПроверитьАктуальностьКэшаВнешнейОбработки(ЭлементКэша, ДатаИзмененияКэша, ФайлВнешнейОбработки, ДатаИзмененияОбъекта,
КэшВнешнейОбработкиАктуален, ФайлВнешнейОбработкиАктуален, ФайловыйКэшДопускаетРедактирование) Экспорт
Попытка
ДатаИзмененияФайла = ФайлВнешнейОбработки.ПолучитьВремяИзменения() + ирКэш.ПолучитьСмещениеВремениЛкс();
ФайлВнешнейОбработкиСуществует = Истина;
Исключение
ФайлВнешнейОбработкиСуществует = Ложь;
КонецПопытки;
Если ФайлВнешнейОбработкиСуществует Тогда
Если Истина
И ЭлементКэша <> Неопределено
И ЭлементКэша.ДатаИзменения >= ДатаИзмененияФайла
И ЭлементКэша.ДатаИзменения >= ДатаИзмененияОбъекта
Тогда
КэшВнешнейОбработкиАктуален = Истина;
ИначеЕсли Ложь
Или (Истина
И ЭлементКэша = Неопределено
И ДатаИзмененияФайла = ДатаИзмененияОбъекта)
Или (Истина
И ЭлементКэша <> Неопределено
И ДатаИзмененияФайла = ЭлементКэша.ДатаИзменения
И ДатаИзмененияФайла = ДатаИзмененияОбъекта)
Или (Истина
И ФайловыйКэшДопускаетРедактирование
И (Ложь
Или (Истина
И ЭлементКэша = Неопределено
И ДатаИзмененияФайла >= ДатаИзмененияОбъекта)
Или (Истина
И ЭлементКэша <> Неопределено
И ДатаИзмененияФайла >= ЭлементКэша.ДатаИзменения
И ДатаИзмененияФайла >= ДатаИзмененияОбъекта)))
Тогда
ФайлВнешнейОбработкиАктуален = Истина;
ДатаИзмененияКэша = ДатаИзмененияФайла;
КонецЕсли;
КонецЕсли;
КонецФункции // ПроверитьАктуальностьКэшаВнешнейОбработки()
Функция РазвернутьНовыйШаблонВнешнейОбработки(СуффиксМакета = "СМодулем", ГлобальныйКлюч = Неопределено, ФайлСИменем, ТекстФайлаСИменем = "") Экспорт
Если ГлобальныйКлюч = Неопределено Тогда
ГлобальныйКлюч = "" + Новый УникальныйИдентификатор;
КонецЕсли;
лПутьКШаблонуВнешнейОбработки = ПутьККаталогуСлужебныхВременныхФайлов + ГлобальныйКлюч;
Файл = Новый Файл(ПолучитьИмяВременногоФайла());
//ПолучитьМакет("ВнешняяОбработка").Записать(Файл.ПолноеИмя);
ИмяМакета = "ШаблонВнешнейОбработки" + СуффиксМакета;
ПолучитьМакет(ИмяМакета).Записать(Файл.ПолноеИмя);
ЧтениеZip = Новый ЧтениеZipФайла(Файл.ПолноеИмя);
ЧтениеZip.ИзвлечьВсе(лПутьКШаблонуВнешнейОбработки);
ФайлСИменем = Новый Файл(лПутьКШаблонуВнешнейОбработки + ирОбщий.РазделительПутиКФайлуЛкс() + СубПутьКФайлуЗаголовкаВнешнейОбработки);
ФайлСИменемОбработки = Новый ТекстовыйДокумент;
ФайлСИменемОбработки.Прочитать(ФайлСИменем.ПолноеИмя);
ТекстФайлаСИменем = ФайлСИменемОбработки.ПолучитьТекст();
СоздатьКомандныйФайлДляУпаковкиФайлаВнешнейОбработки(лПутьКШаблонуВнешнейОбработки);
Возврат лПутьКШаблонуВнешнейОбработки;
КонецФункции
Процедура СоздатьКомандныйФайлДляУпаковкиФайлаВнешнейОбработки(Каталог, выхИмяКомандногоФайла = "") Экспорт
Если Не ЗначениеЗаполнено(выхИмяКомандногоФайла) Тогда
выхИмяКомандногоФайла = "pack.bat";
КонецЕсли;
Разделитель = ирОбщий.РазделительПутиКФайлуЛкс();
ПодготовитьПакер(Каталог);
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.УстановитьТекст("
|FOR /D %%I IN (*.unp) DO " + ИмяФайлаПакера + " -pack %%I %%~nI
|FOR %%I IN (*.und) DO " + ИмяФайлаПакера + " -deflate %%I %%~nI
|" + ИмяФайлаПакера + " -pack .\ %1");
ТекстовыйДокумент.Записать(Каталог + Разделитель + выхИмяКомандногоФайла, КодировкаТекста.ANSI);
КонецПроцедуры
Процедура ПодготовитьПакер(Знач Каталог)
Разделитель = ирОбщий.РазделительПутиКФайлуЛкс();
Если ирКэш.ЛиПлатформаWindowsЛкс() Тогда
ДвоичныеДанны = ПолучитьМакет("V8unpackExeWin");
ПолучитьМакет("Zlib1").Записать(Каталог + Разделитель + "Zlib1.dll");
Иначе
//Если ирКэш.Это64битнаяОСЛкс() Тогда // Зависит от COM
Если ирКэш.Это64битныйПроцессЛкс() Тогда // В Linux равнозначно ирКэш.Это64битнаяОСЛкс()
ДвоичныеДанны = ПолучитьМакет("V8unpackExeLinux64");
Иначе
ирОбщий.СообщитьЛкс("Механизм распаковки файлов платформы 1С для Linux не поддерживает 32-разрядные ОС");
Возврат;
КонецЕсли;
КонецЕсли;
ПолноеИмяФайла = Каталог + ?(Прав(Каталог, 1) = Разделитель, "", Разделитель) + ИмяФайлаПакера;
ДвоичныеДанны.Записать(ПолноеИмяФайла);
Если Не ирКэш.ЛиПлатформаWindowsЛкс() Тогда
ирОбщий.ВыполнитьКомандуОСЛкс("chmod +x " + ПолноеИмяФайла); // Установим признак "Исполняемый файл"
КонецЕсли;
КонецПроцедуры
Процедура УпаковатьФайлВнешнейОбработки(КаталогРаспаковки, ПолноеИмяФайлаВнешнейОбработки) Экспорт
Если ирОбщий.ПроверитьПлатформаНеWindowsЛкс() Тогда
Возврат;
КонецЕсли;
ИмяКомандногоФайла = "";
СоздатьКомандныйФайлДляУпаковкиФайлаВнешнейОбработки(КаталогРаспаковки, ИмяКомандногоФайла);
ирОбщий.ЗапуститьСкрытоеПриложениеИДождатьсяЗавершенияЛкс(ИмяКомандногоФайла + " """ + ПолноеИмяФайлаВнешнейОбработки + """", КаталогРаспаковки);
КонецПроцедуры
// ПолноеИмяФайла - не должно содержать не английских букв
Процедура РаспаковатьФайлВнешнейОбработки(ПолноеИмяФайла, ПутьРаспаковки) Экспорт
Разделитель = ирОбщий.РазделительПутиКФайлуЛкс();
ПодготовитьПакер(ПутьРаспаковки);
ИмяФайлаЛога = "unpack.log";
Если Истина
//И Ложь // Для отладки
И ирКэш.ЛиПлатформаWindowsЛкс()
И ирКэш.ЛиДоступноВыполнениеКомандныхФайловЛкс()
Тогда
ИмяКомандногоФайла = "unpack.bat";
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.УстановитьТекст("
|" + ИмяФайлаПакера + " -unpack %1 .\
|FOR %%I IN (*.data) DO " + ИмяФайлаПакера + " -undeflate %%I %%~nI.data.und
|FOR %%I IN (*.und) DO " + ИмяФайлаПакера + " -unpack %%I %%~nI.und.unp
|");
ПолноеИмяКомандногоФайла = ПутьРаспаковки + Разделитель + ИмяКомандногоФайла;
ТекстовыйДокумент.Записать(ПолноеИмяКомандногоФайла, КодировкаТекста.ANSI);
ирОбщий.ЗапуститьСкрытоеПриложениеИДождатьсяЗавершенияЛкс(ИмяКомандногоФайла + " """ + ПолноеИмяФайла + """", ПутьРаспаковки, ИмяФайлаЛога);
Иначе
// Под Windows этот способ медленнее в 5 раз
// У версии под Linux немного отличаются параметры запуска по сравнению с Windows https://github.com/e8tools/v8unpack
ирОбщий.ЗапуститьСкрытоеПриложениеИДождатьсяЗавершенияЛкс("./" + ИмяФайлаПакера + " -unpack """ + ПолноеИмяФайла + """ ./", ПутьРаспаковки, ИмяФайлаЛога,,, Истина);
Для Каждого Файл Из НайтиФайлы(ПутьРаспаковки, "*.data") Цикл
#Если Сервер И Не Сервер Тогда
Файл = Новый Файл;
#КонецЕсли
// Можно наверное ускорить созданием командного файла
ирОбщий.ЗапуститьСкрытоеПриложениеИДождатьсяЗавершенияЛкс("./" + ИмяФайлаПакера + " -undeflate " + Файл.Имя + " " + Файл.Имя + ".und", ПутьРаспаковки, ИмяФайлаЛога,,, Истина);
ирОбщий.ЗапуститьСкрытоеПриложениеИДождатьсяЗавершенияЛкс("./" + ИмяФайлаПакера + " -unpack " + Файл.Имя + ".und " + Файл.Имя + ".und.unp", ПутьРаспаковки, ИмяФайлаЛога,,, Истина);
КонецЦикла;
КонецЕсли;
ЧитатьЛог = Ложь; // Для отладки
Если ЧитатьЛог Тогда
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.Прочитать(ПутьРаспаковки + Разделитель + ИмяФайлаЛога, ирОбщий.СистемнаяКодировкаТекстаОСЛкс());
ТекстЛога = ТекстовыйДокумент.ПолучитьТекст();
КонецЕсли;
УдалитьФайлы(ИмяФайлаЛога);
КонецПроцедуры
Функция ЛиИспользоватьБыструюРаспаковкуВнешнейОбработки() Экспорт
ИспользоватьБыстрыйГенератор = Истина;
Если ирОбщий.СтрокиРавныЛкс(ирКэш.ТекущийСеансЛкс().ИмяПриложения, "1cv8") Тогда
// Антибаг 8.3.11-?. Testplatform@1c.ru - Support #17972. В обычном приложении на клиенте при повторном создании с одним именем файла и внутренней версией используются метаданные первой обработки в сеансе.
// Начиная с 8.3.11 кэширование внешних обработок проверяет только Ид версии, которые в старом способе не меняются, поэтому на 8.3.11+ используется штатный долгий метод генерации внешней обработки
ИспользоватьБыстрыйГенератор = мНомерВерсииПлатформы < 803011;
КонецЕсли;
Возврат ИспользоватьБыстрыйГенератор;
КонецФункции
Функция СформироватьВнешнююОбработку(Знач ФайлОбработки, Знач ИмяОбработки, Знач ТекстМодуля, Знач ТекстМакета = Неопределено, Знач _ДляИДВерсииПлатформы = "", Знач ИспользоватьБыструюРаспаковку = Неопределено,
ЛиМодульОтФормы = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
ФайлОбработки = Новый файл;
#КонецЕсли
ДляИДВерсииПлатформы = "83";
//Если ИспользоватьБыструюРаспаковку = Неопределено Тогда
// ИспользоватьБыструюРаспаковку = ЛиИспользоватьБыструюРаспаковкуВнешнейОбработки();
//КонецЕсли;
ИспользоватьБыструюРаспаковку = Истина; // используется шаблон с макетом, то там надо добавить файл versions.data.und - https://github.com/e8tools/v8unpack/issues/69
Если Не ИспользоватьБыструюРаспаковку Тогда
// Штатный способ платформы, но работает только на 8.3.8+
Если ТекстМакета <> Неопределено Тогда
ВызватьИсключение "Парамер ТекстМакета для 8.3.11+ не поддерживается";
КонецЕсли;
КлючШаблона = "8" + ЛиМодульОтФормы;
ШаблонВнешнейОбработки = ШаблоныВнешнейОбработки[КлючШаблона];
Если ШаблонВнешнейОбработки = Неопределено Тогда
ИмяВременногоФайла = ПолучитьИмяВременногоФайла("epf");
ПолучитьМакет("ВнешняяОбработка").Записать(ИмяВременногоФайла);
ШаблонВнешнейОбработки = ПолучитьИмяВременногоФайла();
СоздатьКаталог(ШаблонВнешнейОбработки);
ТекстЛога = Неопределено;
Если Не ирОбщий.ВыполнитьКомандуКонфигуратораЛкс("/DumpExternalDataProcessorOrReportToFiles """ + ШаблонВнешнейОбработки + """ """ + ИмяВременногоФайла + """",, ТекстЛога, Истина,,,,,,, Ложь) Тогда
УдалитьФайлы(ШаблонВнешнейОбработки);
УдалитьФайлы(ИмяВременногоФайла);
ирОбщий.СообщитьЛкс(ТекстЛога);
Возврат Ложь;
КонецЕсли;
ШаблоныВнешнейОбработки[КлючШаблона] = ШаблонВнешнейОбработки;
КонецЕсли;
Если ЛиМодульОтФормы Тогда
ИмяФайлаМодуля = "Module.bsl"
Иначе
ИмяФайлаМодуля = "ObjectModule.bsl";
КонецЕсли;
Файлы = НайтиФайлы(ШаблонВнешнейОбработки, ИмяФайлаМодуля, Истина);
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.УстановитьТекст(ТекстМодуля);
ТекстовыйДокумент.Записать(Файлы[0].ПолноеИмя);
ТекстЛога = Неопределено;
ИмяКорневогоФайла = ШаблонВнешнейОбработки + ирОбщий.РазделительПутиКФайлуЛкс() + "ИмяВнешнейОбработки.xml";
Если ЗначениеЗаполнено(ИмяОбработки) Тогда
ПотокСИменемОбработки = Новый ТекстовыйДокумент;
ПотокСИменемОбработки.Прочитать(ИмяКорневогоФайла);
ПотокСИменемОбработки.УстановитьТекст(СтрЗаменить(ПотокСИменемОбработки.ПолучитьТекст(), "ИмяВнешнейОбработки", ИмяОбработки));
ПотокСИменемОбработки.Записать(ИмяКорневогоФайла);
КонецЕсли;
Если Не ирОбщий.ВыполнитьКомандуКонфигуратораЛкс("/LoadExternalDataProcessorOrReportFromFiles """ + ИмяКорневогоФайла + """ """ + ФайлОбработки.ПолноеИмя + """", , ТекстЛога, Истина,,,,,,, Ложь) Тогда
УдалитьФайлы(ШаблонВнешнейОбработки);
УдалитьФайлы(ИмяВременногоФайла);
ирОбщий.СообщитьЛкс(ТекстЛога);
Возврат Ложь;
КонецЕсли;
Результат = Истина;
Иначе
КлючШаблона = ДляИДВерсииПлатформы + ЛиМодульОтФормы;
Если ТекстМакета <> Неопределено Тогда
ШаблонВнешнейОбработкиСМакетом = ШаблоныВнешнейОбработкиСМакетом[КлючШаблона];
Если ШаблонВнешнейОбработкиСМакетом = Неопределено Тогда
ШаблонВнешнейОбработкиСМакетом = Новый Структура("Путь, ФайлСИменем, ФайлЗамок, ТекстФайлаСИменем");
ШаблонВнешнейОбработкиСМакетом.Путь = РазвернутьНовыйШаблонВнешнейОбработки("СМакетом",, ШаблонВнешнейОбработкиСМакетом.ФайлСИменем, ШаблонВнешнейОбработкиСМакетом.ТекстФайлаСИменем);
ФайлЗамокШаблонаСМакетом = Новый ЗаписьТекста;
ФайлЗамокШаблонаСМакетом.Открыть(ШаблонВнешнейОбработкиСМакетом.Путь + ".lck");
ШаблонВнешнейОбработкиСМакетом.ФайлЗамок = ФайлЗамокШаблонаСМакетом;
ШаблоныВнешнейОбработкиСМакетом[КлючШаблона] = ШаблонВнешнейОбработкиСМакетом;
КонецЕсли;
ПутьКШаблону = ШаблонВнешнейОбработкиСМакетом.Путь;
ФайлСИменем = ШаблонВнешнейОбработкиСМакетом.ФайлСИменем;
ТекстФайлаСИменем = ШаблонВнешнейОбработкиСМакетом.ТекстФайлаСИменем;
Иначе
ШаблонВнешнейОбработки = ШаблоныВнешнейОбработки[КлючШаблона];
Если ШаблонВнешнейОбработки = Неопределено Тогда
ШаблонВнешнейОбработки = Новый Структура("Путь, ФайлСИменем, ФайлЗамок, ТекстФайлаСИменем, ТекстФайлаМодулем");
Если ЛиМодульОтФормы Тогда
СуффиксМакета = "СФормой";
Иначе
СуффиксМакета = "СМодулем";
КонецЕсли;
ШаблонВнешнейОбработки.Путь = РазвернутьНовыйШаблонВнешнейОбработки(СуффиксМакета,, ШаблонВнешнейОбработки.ФайлСИменем, ШаблонВнешнейОбработки.ТекстФайлаСИменем);
ФайлЗамокШаблона = Новый ЗаписьТекста;
ФайлЗамокШаблона.Открыть(ШаблонВнешнейОбработки.Путь + ".lck");
ШаблонВнешнейОбработки.ФайлЗамок = ФайлЗамокШаблона;
ШаблоныВнешнейОбработки[КлючШаблона] = ШаблонВнешнейОбработки;
КонецЕсли;
ПутьКШаблону = ШаблонВнешнейОбработки.Путь;
ФайлСИменем = ШаблонВнешнейОбработки.ФайлСИменем;
ТекстФайлаСИменем = ШаблонВнешнейОбработки.ТекстФайлаСИменем;
КонецЕсли;
ИмяФайлаВерсий = "versions.data.und";
ФайлЗаголовка = Новый Файл(ПутьКШаблону + ирОбщий.РазделительПутиКФайлуЛкс() + ИмяФайлаВерсий);
// ДвоичныеДанныеЗаголовка = Новый ДвоичныеДанные(ФайлЗаголовка.ПолноеИмя);
// ПотокЗаписи = ФайловыеПотоки.ОткрытьДляЗаписи(ФайлЗаголовка.ПолноеИмя);
// Читатель = Новый ЧтениеДанных(ДвоичныеДанныеЗаголовка);
// Писатель = Новый ЗаписьДанных(ПотокЗаписи);
// Счетчик = 1;
// Пока Истина Цикл
// Целое16 = Читатель.ПрочитатьЦелое16();
// Если Целое16 = Неопределено Тогда
// Прервать;
// КонецЕсли;
// Если Ложь
// Или Счетчик = 1
// Тогда
// Целое16 = Целое16 + 1; // Увеличиваем номер версии содержимого
// КонецЕсли;
// Писатель.ЗаписатьЦелое16(Целое16);
// Счетчик = Счетчик + 1;
// КонецЦикла;
// Писатель.Закрыть();
// ПотокЗаписи.Закрыть();
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.Прочитать(ФайлЗаголовка.ПолноеИмя);
ТекстФайла = ТекстовыйДокумент.ПолучитьТекст();
ФрагментТекста = ирОбщий.ТекстМеждуМаркерамиЛкс(ТекстФайла, """4eb1cc18-835d-4f8c-a120-3f9d886d75d4""", """902f74d3-f929-4b0f-8719-4cbb655891aa""", Ложь, Истина);
ТекстФайла = ирОбщий.СтрЗаменитьЛкс(ТекстФайла, ФрагментТекста, """4eb1cc18-835d-4f8c-a120-3f9d886d75d4""," + Новый УникальныйИдентификатор + ",""902f74d3-f929-4b0f-8719-4cbb655891aa""");
ТекстовыйДокумент.УстановитьТекст(ТекстФайла);
ТекстовыйДокумент.Записать(ФайлЗаголовка.ПолноеИмя);
ПутьКШаблону = ПутьКШаблону + ирОбщий.РазделительПутиКФайлуЛкс();
Если ЗначениеЗаполнено(ИмяОбработки) Тогда
ТекстФайлаСИменем = СтрЗаменить(ТекстФайлаСИменем, "ИмяВнешнейОбработки", ИмяОбработки);
КонецЕсли;
ПотокСИменемОбработки = Новый ТекстовыйДокумент;
ПотокСИменемОбработки.УстановитьТекст(ТекстФайлаСИменем);
ПотокСИменемОбработки.Записать(ФайлСИменем.ПолноеИмя);
Если ЛиМодульОтФормы Тогда
СубПутьКФайлуМодуля = СубПутьКФайлуМодуляФормыВнешнейОбработки;
Иначе
СубПутьКФайлуМодуля = СубПутьКФайлуМодуляВнешнейОбработки;
КонецЕсли;
ФайлТекстаМодуляОбработки = Новый Файл(ПутьКШаблону + СубПутьКФайлуМодуля);
ТекстовыйДокументМодуля = Новый ТекстовыйДокумент();
Если ЛиМодульОтФормы Тогда
Если ПустаяСтрока(ШаблонВнешнейОбработки.ТекстФайлаМодулем) Тогда
ТекстовыйДокументМодуля.Прочитать(ФайлТекстаМодуляОбработки.ПолноеИмя);
ШаблонВнешнейОбработки.ТекстФайлаМодулем = ТекстовыйДокументМодуля.ПолучитьТекст();
КонецЕсли;
ТекстМодуля = ирОбщий.СтрЗаменитьЛкс(ШаблонВнешнейОбработки.ТекстФайлаМодулем, """//МодульФормы""", ирОбщий.ТекстВВыражениеВстроенногоЯзыкаЛкс(ТекстМодуля, Ложь, Ложь));
КонецЕсли;
ТекстовыйДокументМодуля.УстановитьТекст(ТекстМодуля);
ТекстовыйДокументМодуля.Записать(ФайлТекстаМодуляОбработки.ПолноеИмя);
Если ТекстМакета <> Неопределено Тогда
ФайлТекстаМакетаПараметров = Новый Файл(ПутьКШаблону + СубПутьКФайлуМакетаВнешнейОбработки);
ТекстовыйДокументМакета = Новый ТекстовыйДокумент();
ТекстовыйДокументМакета.УстановитьТекст(ТекстМакета);
ТекстовыйДокументМакета.Записать(ФайлТекстаМакетаПараметров.ПолноеИмя);
КонецЕсли;
Результат = УпаковатьВнешнююОбработку(ПутьКШаблону, ФайлОбработки.ПолноеИмя);
КонецЕсли;
Возврат Результат;
КонецФункции
// Файлы "Zlib1.dll" и "v8unpack.exe" должны быть в этом каталоге.
Функция УпаковатьВнешнююОбработку(ПутьКШаблонуВнешнейОбработки, ИмяВыходногоФайла, СоздатьФайлыУпаковщика = Ложь) Экспорт
// Небольшой накладной расход, но надежность повышаем
УдалитьФайлы(ПутьКШаблонуВнешнейОбработки + СубПутьККонтрольномуФайлуВнешнейОбработки);
Попытка
УдалитьФайлы(ИмяВыходногоФайла);
Исключение
Событие = "Ошибка создания служебного объекта (1)";
//ирОбщий.СообщитьЛкс(Событие, СтатусСообщения.Важное);
//ЗаписьЖурналаРегистрации(Событие, УровеньЖурналаРегистрации.Ошибка);
//Возврат Неопределено;
ВызватьИсключение Событие;
КонецПопытки;
Если СоздатьФайлыУпаковщика Тогда
ПодготовитьПакер(ПутьКШаблонуВнешнейОбработки);
КонецЕсли;
ИмяКомандногоФайла = "pack.bat";
ирОбщий.ЗапуститьСкрытоеПриложениеИДождатьсяЗавершенияЛкс(ИмяКомандногоФайла + " """ + ИмяВыходногоФайла + """", ПутьКШаблонуВнешнейОбработки);
КонтрольныйФайл1 = Новый Файл(ПутьКШаблонуВнешнейОбработки + СубПутьККонтрольномуФайлуВнешнейОбработки);
КонтрольныйФайл2 = Новый Файл(ИмяВыходногоФайла);
Если Ложь
Или Не КонтрольныйФайл1.Существует()
//Или Не КонтрольныйФайл2.Существует() // Отключил для повышения скорости
Тогда
Если ирКэш.ЛиДоступноВыполнениеКомандныхФайловЛкс(Истина) Тогда
ВызватьИсключение "Ошибка выполнения приложения V8unpack";
КонецЕсли;
КонецЕсли;
Возврат Истина;
КонецФункции
Функция ПолучитьФайлВнешнейОбработкиАлгоритма(АлгоритмОбъект) Экспорт
Если Ложь
Или СтрДлина(ПапкаКешаВнешнихОбработокАлгоритмов.ПолноеИмя) + СтрДлина(АлгоритмОбъект.Наименование) > 250
Тогда
// Ограничение WinAPI на путь к файлу
КлючСервиса = "" + АлгоритмОбъект.Ссылка.УникальныйИдентификатор();
Иначе
КлючСервиса = АлгоритмОбъект.Наименование;
КонецЕсли;
ИмяФайла = КлючСервиса + ".epf";
ФайлВнешнейОбработки = Новый Файл(ПапкаКешаВнешнихОбработокАлгоритмов.ПолноеИмя + ирОбщий.РазделительПутиКФайлуЛкс() + ИмяФайла);
Возврат ФайлВнешнейОбработки;
КонецФункции
Функция ПолучитьОбновитьФайлВнешнейОбработкиАлгоритма(ДескрипторСервиса, ЭлементКэша = Неопределено, ДатаИзмененияКэша = Неопределено) Экспорт
ФайлВнешнейОбработкиАктуален = Ложь;
КэшВнешнейОбработкиАктуален = Ложь;
ФайлВнешнейОбработки = ПолучитьФайлВнешнейОбработкиАлгоритма(ДескрипторСервиса);
ДатаИзмененияОбъекта = ДескрипторСервиса.ДатаИзмененияКонтекста;
//// Условие добавлено для мягкого перехода на новый кэш параметров сервисов 21.10.2010. Потом нужно убрать
//Если ЗначениеЗаполнено(ДескрипторСервиса.ДатаИзмененияКэша) Тогда
ПроверитьАктуальностьКэшаВнешнейОбработки(ЭлементКэша, ДатаИзмененияКэша, ФайлВнешнейОбработки, ДатаИзмененияОбъекта,
КэшВнешнейОбработкиАктуален, ФайлВнешнейОбработкиАктуален, ФайловыйКэшАлгоритмовДопускаетРедактирование);
//КонецЕсли;
Если Истина
И Не КэшВнешнейОбработкиАктуален
И Не ФайлВнешнейОбработкиАктуален
Тогда
СервисОбъект = ПроверитьПолучитьОбъектСервиса(ДескрипторСервиса);
СервисОбъект.СобратьКонтекст();
СформироватьВнешнююОбработку(ФайлВнешнейОбработки, СервисОбъект.Наименование,
СервисОбъект.ПолучитьТекстМодуляОбработки()
//, СервисОбъект.ПолучитьТекстМакетаПараметров()
);
Попытка
ФайлВнешнейОбработки.УстановитьВремяИзменения(СервисОбъект.ДатаИзмененияКонтекста);
Исключение
Если Не ФайлВнешнейОбработки.Существует() Тогда
ирОбщий.ПроверитьКодЯзыкаОСЛкс();
ВызватьИсключение "Файл внешней обработки сервиса """ + СервисОбъект.Наименование + """ не сформирован";
Иначе
ВызватьИсключение;
КонецЕсли;
КонецПопытки;
КонецЕсли;
Если КэшВнешнейОбработкиАктуален Тогда
Возврат Неопределено;
Иначе
Возврат ФайлВнешнейОбработки;
КонецЕсли;
КонецФункции
Функция ПолучитьВнешнююОбработкуПоАлгоритму(ДескрипторСервиса) Экспорт
// %%%% Здесь можно было бы структуру попробовать вместо ТЗ
//ЭлементКэша = 0;
//КешВнешнихОбработокАлгоритмов.Свойство(ДескрипторСервиса.Наименование, ЭлементКэша);
ЭлементКэша = ДескрипторСервиса.мСтруктураВнешнейОбработки;
Если Ложь
Или ЭлементКэша = Неопределено
Или ЭлементКэша.ДатаИзменения < ДескрипторСервиса.ДатаИзмененияКонтекста
Или ФайловыйКэшАлгоритмовДопускаетРедактирование
Тогда
ДатаИзмененияКэша = ДескрипторСервиса.ДатаИзмененияКонтекста;
// Для обхода бага платформы WshShell().Run(,,True)
Для Счетчик = 1 По 3 Цикл
ФайлВнешнейОбработки = ПолучитьОбновитьФайлВнешнейОбработкиАлгоритма(ДескрипторСервиса, ЭлементКэша,
ДатаИзмененияКэша);
Если ФайлВнешнейОбработки <> Неопределено Тогда
ВнешняяОбработка = СоздатьВнешнююОбработкуАлгоритма(ДескрипторСервиса, ФайлВнешнейОбработки.ПолноеИмя);
// Для обхода бага платформы.
Если ВнешняяОбработка <> Неопределено Тогда
ИмяАлгоритмаВнешнейОбработки = ВнешняяОбработка.Метаданные().Имя;
Если ИмяАлгоритмаВнешнейОбработки <> ДескрипторСервиса.Наименование Тогда
ЗаписьЖурналаРегистрации("Несоответствие внешней обработки и сервиса", УровеньЖурналаРегистрации.Ошибка, ,
ДескрипторСервиса.Ссылка, "Попытка №" + Счетчик + ". Внешняя обработка """ + ИмяАлгоритмаВнешнейОбработки + """");
УдалитьФайлы(ФайлВнешнейОбработки.ПолноеИмя);
Продолжить;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Прервать;
КонецЦикла;
Если ФайлВнешнейОбработки <> Неопределено Тогда
Если ЭлементКэша = Неопределено Тогда
ЭлементКэша = Новый Структура("ДатаИзменения, ВнешняяОбработка");
//КешВнешнихОбработокАлгоритмов.Вставить(ДескрипторСервиса.Наименование, ЭлементКэша);
ДескрипторСервиса.мСтруктураВнешнейОбработки = ЭлементКэша;
КонецЕсли;
Если ВнешняяОбработка <> Неопределено Тогда
ЭлементКэша.ДатаИзменения = ДатаИзмененияКэша;
ЭлементКэша.ВнешняяОбработка = ВнешняяОбработка;
Иначе
ЭлементКэша.ДатаИзменения = Дата("00010101");
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ЭлементКэша <> Неопределено Тогда
Результат = ЭлементКэша.ВнешняяОбработка;
Иначе
Результат = Неопределено;
КонецЕсли;
Возврат Результат;
КонецФункции // ПолучитьВнешнююОбработкуПоАлгоритму()
// https://www.mista.ru/topic/779525
Функция ЕстьАдминистративныеПраваУУчетнойЗаписиОС() Экспорт
Если мЕстьАдминистративныеПраваУУчетнойЗаписиОС <> Неопределено Тогда
Возврат мЕстьАдминистративныеПраваУУчетнойЗаписиОС;
КонецЕсли;
Если Не ирКэш.ЛиПлатформаWindowsЛкс() Тогда
Возврат Ложь;
КонецЕсли;
//Попытка
// Network = Новый COMОбъект("WScript.Network");
//Исключение
// ОписаниеОшибки = ОписаниеОшибки();
// Возврат Ложь;
//КонецПопытки;
////ПользовательОС = Network.UserDomain + "\" + Network.UserName;
//ПользовательОС = Network.UserName;
//КомандаСистемы = "Net user " + ПользовательОС;
КомандаСистемы = "whoami /all"; // ОС Windows Vista+
РезультатКоманды = ТекстРезультатаКомандыСистемы(КомандаСистемы);
мЕстьАдминистративныеПраваУУчетнойЗаписиОС = Ложь
Или Найти(РезультатКоманды, "Администраторы") > 0
Или Найти(РезультатКоманды, "Administrators") > 0;
Возврат мЕстьАдминистративныеПраваУУчетнойЗаписиОС;
КонецФункции
Функция ПереместитьФайлКакАдминистратор(ИмяИсточника, ИмяПриемника) Экспорт
Успех = Истина;
Попытка
//ПереместитьФайл(ИмяИсточника, ИмяПриемника); // так не работает наследование прав от каталога-приемника!
КопироватьФайл(ИмяИсточника, ИмяПриемника);
Исключение
ОписаниеОшибки = ОписаниеОшибки();
КонецПопытки;
Если ОписаниеОшибки <> Неопределено Тогда
//КомандаСистемы = "cmd.exe /c move """ + ИмяИсточника + """ """ + ИмяПриемника + """"; // так не работает наследование прав от каталога-приемника!
КомандаСистемы = "cmd.exe /c copy """ + ИмяИсточника + """ """ + ИмяПриемника + """";
ОписаниеОшибки = ТекстРезультатаКомандыСистемы(КомандаСистемы,, Истина);
// При успехе возвращает:
// Скопировано файлов: 1.
Если Найти(ОписаниеОшибки, "1") = 0 Тогда
ВызватьИсключение "Ошибка доступа к файлу """ + ИмяПриемника + """: " + ОписаниеОшибки;
КонецЕсли;
КонецЕсли;
Если Успех Тогда
Попытка
УдалитьФайлы(ИмяИсточника);
Исключение
КомандаСистемы = "cmd.exe /c del """ + ИмяИсточника + """";
ОписаниеОшибки = ТекстРезультатаКомандыСистемы(КомандаСистемы,, Истина);
// При успехе возвращает пустую строку
Если Не ПустаяСтрока(ОписаниеОшибки) Тогда
ВызватьИсключение "Ошибка доступа к файлу """ + ИмяИсточника + """: " + ОписаниеОшибки;
КонецЕсли;
КонецПопытки;
КонецЕсли;
Возврат Успех;
КонецФункции
Функция ПолучитьПолноеИмяКомпьютераСетиПоЛюбомуИмени(ИмяКомпьютера) Экспорт
ФайлРезультата = Новый Файл(ПолучитьИмяВременногоФайла());
ирОбщий.ЗапуститьСкрытоеПриложениеИДождатьсяЗавершенияЛкс("nslookup " + ИмяКомпьютера, ФайлРезультата.Путь, ФайлРезультата.Имя);
Если Не ФайлРезультата.Существует() Тогда
ПолноеИмяКомпьютера = "";
Иначе
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.Прочитать(ФайлРезультата.ПолноеИмя);
УдалитьФайлы(ФайлРезультата.ПолноеИмя);
ТекстРезультата = ТекстовыйДокумент.ПолучитьТекст();
мРегВыражение.IgnoreCase = Истина;
мРегВыражение.Pattern = "(?:name|имя|╚ь ):\s*([-" + шБукваЦифра + "]+(\.([-" + шБукваЦифра + "]+))*)\s*";
Результат = мРегВыражение.НайтиВхождения(ТекстРезультата);
Если Результат.Количество() > 0 Тогда
ПолноеИмяКомпьютера = Результат[0].SubMatches(0);
Иначе
ПолноеИмяКомпьютера = "";
КонецЕсли;
КонецЕсли;
//ASPDNS = ПолучитьCOMОбъектИзМакета("ASPDNS", "ASPDNS.DNSLookup");
//IP = ASPDNS.GetIPFromName(ИмяКомпьютера);
//ПолноеИмяКомпьютера = ASPDNS.GetNameFromIP(IP);
Возврат ПолноеИмяКомпьютера;
КонецФункции
Функция ПроверитьКаталогФайловогоКэша() Экспорт
//http://www.hostedredmine.com/issues/851201
//СтрокаСоединения = ирКэш.СтрокаСоединенияСервераЛкс();
СтрокаСоединения = СтрокаСоединенияИнформационнойБазы();
КаталогВерсииПлатформыВПрофиле = ирКэш.КаталогИзданияПлатформыВПрофилеЛкс();
КаталогФайловогоКэша = КаталогВерсииПлатформыВПрофиле + ирОбщий.РазделительПутиКФайлуЛкс() + ирОбщий.ИдентификаторИзПредставленияЛкс(СтрокаСоединения);
ПапкаФайловогоКэша = Новый Файл(КаталогФайловогоКэша);
Если Не ПапкаФайловогоКэша.Существует() Тогда
Попытка
СоздатьКаталог(ПапкаФайловогоКэша.ПолноеИмя);
ПробныйФайл = Новый ТекстовыйДокумент;
ПробныйФайл.Записать(ПапкаФайловогоКэша.ПолноеИмя + ирОбщий.РазделительПутиКФайлуЛкс() + "1.txt");
Исключение
ОписаниеОшибки = ОписаниеОшибки();
Сообщить("Файловые кэши отключены из-за ошибки: " + ОписаниеОшибки, СтатусСообщения.Важное); // При использовании ирОбщий.СообщитьЛкс() может происходить переполнение стека
ВыполнятьАлгоритмыЧерезВнешниеОбработки = Ложь;
Возврат Ложь;
КонецПопытки;
КонецЕсли;
Возврат Истина;
КонецФункции
Функция ПрочитатьНастройкиКомпьютераПервыйРаз(Знач ЛиДляБазы = Истина) Экспорт
Если ЛиДляБазы Тогда
НастройкиКомпьютера = НастройкиКомпьютераБазы;
Иначе
НастройкиКомпьютера = НастройкиКомпьютераГлобальные;
КонецЕсли;
СохранитьНастройкиКомпьтера = Ложь;
Если НастройкиКомпьютера = Неопределено Тогда
ФайлаНастроекКомпьютера = Новый Файл(ИмяФайлаНастроекКомпьютера(ЛиДляБазы));
Если ФайлаНастроекКомпьютера.Существует() Тогда
НастройкиКомпьютера = ирОбщий.ЗагрузитьЗначениеИзФайлаЛкс(ФайлаНастроекКомпьютера.ПолноеИмя,, "Внутр", мЭтотОбъектГотов);
Если НастройкиКомпьютера <> Неопределено И ЛиДляБазы Тогда
ЗначениеНастройки = НастройкиКомпьютера["ПапкаКэшаМодулей"];
ЗначениеНастройки = Новый Файл(ЗначениеНастройки);
Если ЗначениеНастройки.Существует() Тогда
ПапкаКэшаМодулей = ЗначениеНастройки;
КонецЕсли;
ЗначениеНастройки = НастройкиКомпьютера["ПапкаКэшаРолей"];
ЗначениеНастройки = Новый Файл(ЗначениеНастройки);
Если ЗначениеНастройки.Существует() Тогда
ПапкаКэшаРолей = ЗначениеНастройки;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если НастройкиКомпьютера = Неопределено Тогда
НастройкиКомпьютера = Новый Соответствие;
СохранитьНастройкиКомпьтера = Истина;
КонецЕсли;
Если ЛиДляБазы Тогда
ЭтотОбъект.НастройкиКомпьютераБазы = НастройкиКомпьютера;
Иначе
ЭтотОбъект.НастройкиКомпьютераГлобальные = НастройкиКомпьютера;
КонецЕсли;
Если СохранитьНастройкиКомпьтера Тогда
СохранитьНастройкиКомпьтера(ЛиДляБазы);
КонецЕсли;
Возврат НастройкиКомпьютера;
КонецФункции
Процедура ПрочитатьНастройкиКомпьютераВсе(Знач Обновить = Ложь) Экспорт
Если Обновить Тогда
НастройкиКомпьютераГлобальные = Неопределено;
НастройкиКомпьютераБазы = Неопределено;
КонецЕсли;
Если ЛиГлобальныеНастройкиВсехБаз Тогда
ПрочитатьНастройкиКомпьютераПервыйРаз(Ложь);
КонецЕсли;
ПрочитатьНастройкиКомпьютераПервыйРаз(Истина);
КонецПроцедуры
Процедура СохранитьНастройкиКомпьтера(Знач ЛиДляБазы = Истина) Экспорт
ИмяФайлаНастроекКомпьютера = ИмяФайлаНастроекКомпьютера(ЛиДляБазы);
ирОбщий.СохранитьЗначениеВФайлЛкс(ПрочитатьНастройкиКомпьютераПервыйРаз(ЛиДляБазы), ИмяФайлаНастроекКомпьютера,,, "Внутр", мЭтотОбъектГотов);
КонецПроцедуры
Функция ИмяФайлаНастроекКомпьютера(Знач ДляБазы = Истина, Знач ИмяГруппы = "IRSettings.xml") Экспорт
Если ДляБазы Тогда
ПапкаФайловогоКэша = Новый Файл(КаталогФайловогоКэша);
Иначе
ПапкаФайловогоКэша = Новый Файл(ирКэш.КаталогПлатформыВПрофилеЛкс(Истина));
КонецЕсли;
ИмяФайлаНастроекКомпьютера = ПапкаФайловогоКэша.ПолноеИмя + ирОбщий.РазделительПутиКФайлуЛкс() + ИмяГруппы;
Возврат ИмяФайлаНастроекКомпьютера;
КонецФункции
Функция ИмяНеопределеннойПеременнойИзИнформацииОбОшибке(ИнформацияОбОшибке, СообщитьНеобрабатываемуюОшибку = Ложь) Экспорт
Если ИнформацияОбОшибке <> Неопределено Тогда
мРегВыражение.Global = Ложь;
//ОписаниеОшибки = ирОбщий.ПодробноеПредставлениеОшибкиЛкс(ИнформацияОбОшибке);
Пока ИнформацияОбОшибке.Причина <> Неопределено Цикл // Добавлено 26.07.2011 из-за доработки синтаксического контроля в COM сеансе
ИнформацияОбОшибке = ИнформацияОбОшибке.Причина;
КонецЦикла;
ОписаниеОшибки = ИнформацияОбОшибке.Описание;
мРегВыражение.Pattern = "(?:Переменная не определена |Variable is not defined )\(([_0-9" + шБуква + "]+)\)";
Результат = мРегВыражение.НайтиВхождения(ОписаниеОшибки);
Если Результат.Количество() > 0 Тогда
ИмяПеременнойРезультата = Результат[0].SubMatches(0);
Иначе
Если СообщитьНеобрабатываемуюОшибку Тогда
ирОбщий.СообщитьЛкс(ирОбщий.ПодробноеПредставлениеОшибкиЛкс(ИнформацияОбОшибке), СтатусСообщения.Важное);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат ИмяПеременнойРезультата;
КонецФункции
Функция ИмяНеопределенногоМетодаИзИнформацииОбОшибке(ИнформацияОбОшибке, СообщитьНеобрабатываемуюОшибку = Ложь) Экспорт
Если ИнформацияОбОшибке <> Неопределено Тогда
мРегВыражение.Global = Ложь;
//ОписаниеОшибки = ирОбщий.ПодробноеПредставлениеОшибкиЛкс(ИнформацияОбОшибке);
Пока ИнформацияОбОшибке.Причина <> Неопределено Цикл // Добавлено 26.07.2011 из-за доработки синтаксического контроля в COM сеансе
ИнформацияОбОшибке = ИнформацияОбОшибке.Причина;
КонецЦикла;
ОписаниеОшибки = ИнформацияОбОшибке.Описание;
мРегВыражение.Pattern = "(?:Процедура или функция с указанным именем не определена |TODO_xxxx9469326459823 )\(([_0-9" + шБуква + "]+)\)";
Результат = мРегВыражение.НайтиВхождения(ОписаниеОшибки);
Если Результат.Количество() > 0 Тогда
ИмяМетодаРезультата = Результат[0].SubMatches(0);
Иначе
Если СообщитьНеобрабатываемуюОшибку Тогда
ирОбщий.СообщитьЛкс(ирОбщий.ПодробноеПредставлениеОшибкиЛкс(ИнформацияОбОшибке), СтатусСообщения.Важное);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат ИмяМетодаРезультата;
КонецФункции
#Если Клиент Или ВнешнееСоединение Тогда
Функция ВыполнитьАлгоритм(СсылкаАлгоритма, СтруктураПараметров = Неопределено) Экспорт
Если СтруктураПараметров = Неопределено Тогда
СтруктураПараметров = Новый Структура;
КонецЕсли;
АлгоритмОбъект = Неопределено;
Если Не КешАлгоритмов.Свойство(СсылкаАлгоритма, АлгоритмОбъект) Тогда
АлгоритмОбъект = СсылкаАлгоритма.ПолучитьОбъект();
КешАлгоритмов.Вставить(СсылкаАлгоритма, АлгоритмОбъект);
КонецЕсли;
Результат = ВыполнитьМетодАлгоритма(АлгоритмОбъект, 1, СтруктураПараметров);
Возврат Результат;
КонецФункции
Процедура ОчиститьКешАлгоритмов(ОчиститьКэшНаДиске = Ложь) Экспорт
КешАлгоритмов.Очистить();
//КешВнешнихОбработокАлгоритмов.Очистить();
Если ОчиститьКэшНаДиске Тогда
//Для Каждого ЭлементПодкаталога Из СтруктураПодкаталоговФайловогоКэша Цикл
// УдалитьФайлы(ЭлементПодкаталога.Значение.ПолноеИмя, "*.dat");
// УдалитьФайлы(ЭлементПодкаталога.Значение.ПолноеИмя, "*.epf");
//КонецЦикла;
ФайлПодкаталога = СтруктураПодкаталоговФайловогоКэша["a"];
УдалитьФайлы(ФайлПодкаталога.ПолноеИмя + ирОбщий.РазделительПутиКФайлуЛкс(), "*.*");
ПроверитьСтруктуруФайловогоКэша();
КонецЕсли;
КонецПроцедуры
Процедура ОбновитьАлгоритмВКеше(АлгоритмОбъект) Экспорт
КешАлгоритмов.Вставить(АлгоритмОбъект.Ссылка, АлгоритмОбъект);
КонецПроцедуры // УдалитьАлгоритмИзКеша()
Функция ПолучитьФайлОткрывателя1С(БыстраяПроверка = Истина) Экспорт
Если Ложь
Или Не БыстраяПроверка
Или ФайлОткрывателя1С = Неопределено
Тогда
ФайлОткрывателя1С = Новый Файл(ПолучитьИмяВременногоФайла("exe"));
ПолучитьМакет("OpenIn1Cv8ExeWin").Записать(ФайлОткрывателя1С.ПолноеИмя);
КонецЕсли;
Возврат ФайлОткрывателя1С;
КонецФункции
Функция ФайлФорматераЗапросовБД(БыстраяПроверка = Истина) Экспорт
Если Ложь
Или Не БыстраяПроверка
Или ФайлФорматераЗапросовБД = Неопределено
Тогда
ФайлФорматераЗапросовБД = Новый Файл(ПолучитьИмяВременногоФайла("exe"));
ПолучитьМакет("SqlFormatter").Записать(ФайлФорматераЗапросовБД.ПолноеИмя);
КонецЕсли;
Возврат ФайлФорматераЗапросовБД;
КонецФункции
Функция ПолучитьФайлРаспаковщикаZIP(БыстраяПроверка = Ложь) Экспорт
Если ирКэш.ЛиПлатформаWindowsЛкс() Тогда
Если Ложь
Или Не БыстраяПроверка
Или ФайлРаспаковщикаZIP = Неопределено
Тогда
ФайлРаспаковщикаZIP = Новый Файл(ПолучитьИмяВременногоФайла("exe"));
ПолучитьМакет("unzip").Записать(ФайлРаспаковщикаZIP.ПолноеИмя);
КонецЕсли;
Иначе
// Может потребоваться установка - sudo apt install unzip
ФайлРаспаковщикаZIP = Новый Файл("unzip");
КонецЕсли;
Возврат ФайлРаспаковщикаZIP;
КонецФункции
// Получает из длинного пути к файлу короткий в формате DOS (8.3)
//
// Параметры:
// ПолноеИмяФайла - Строка;
//
// Возвращаемое значение:
// Строка;
//
Функция ПолучитьИмяФайлаВФорматеDOS(ПолноеИмяФайла) Экспорт
Если Не ирКэш.ЛиПлатформаWindowsЛкс() Тогда
Возврат ПолноеИмяФайла;
КонецЕсли;
Если ирКэш.Это64битныйПроцессЛкс() Тогда
ВызватьИсключение "Получение имени файла в формате ""8.3"" недоступно в 64б процессе";
КонецЕсли;
Если VBScript = Неопределено Тогда
VBScript = Новый COMОбъект("MSScriptControl.ScriptControl"); // Не работает в 64б процессе
VBScript.language = "vbscript";
КонецЕсли;
VBScript.addcode("
|Public Function GetShortPath()
|Set fso = CreateObject(""scripting.filesystemobject"")
|Set fsoFile = fso.GetFile(""" + ПолноеИмяФайла + """)
|GetShortPath = fsoFile.ShortPath
|End Function
|");
DOSИмя = VBScript.Run("GetShortPath");
Возврат DOSИмя;
КонецФункции
Процедура УдалитьСлужебныеФайлы() Экспорт
СтруктураЦикла = Новый Массив;
СтруктураЦикла.Добавить(ШаблоныВнешнейОбработки);
СтруктураЦикла.Добавить(ШаблоныВнешнейОбработкиСМакетом);
Для Каждого ЭлементЦикла Из СтруктураЦикла Цикл
Для Каждого КлючИЗначение Из ЭлементЦикла Цикл
ШаблонВнешнейОбработки = КлючИЗначение.Значение;
Если ШаблонВнешнейОбработки.ФайлЗамок <> Неопределено Тогда
ШаблонВнешнейОбработки.ФайлЗамок.Закрыть();
Попытка
УдалитьФайлы(ШаблонВнешнейОбработки.Путь + ".lck");
УдалитьФайлы(ШаблонВнешнейОбработки.Путь);
Исключение
КонецПопытки;
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецПроцедуры // УдалитьСлужебныеФайлы()
// Функция - Поле текста программы
//
// Параметры:
// ЯзыкПрограммы - Число -
// НачалоТекста - Строка - первые 1000 символов текста для определения его языка
//
// Возвращаемое значение:
// -
//
Функция ПолеТекстаПрограммы(Знач ЯзыкПрограммы = 0, Знач НачалоТекста = "") Экспорт
Если мПоляТекстаПрограммы = Неопределено Тогда
мПоляТекстаПрограммы = Новый Соответствие;
КонецЕсли;
Если ЯзыкПрограммы = 0 И ирОбщий.ЛиТекстЯзыкаЗапросовЛкс(НачалоТекста) Тогда
ЯзыкПрограммы = 1;
КонецЕсли;
ПолеТекстаПрограммы = мПоляТекстаПрограммы[ЯзыкПрограммы];
Если ПолеТекстаПрограммы = Неопределено Тогда
ПолеТекстаПрограммы = ирОбщий.НовыйАнализаторКодаЛкс();
#Если Сервер И Не Сервер Тогда
ПолеТекстаПрограммы = Обработки.ирКлсПолеТекстаПрограммы.Создать();
#КонецЕсли
ПолеТекстаПрограммы.ИнициироватьНеинтерактивно(ЯзыкПрограммы);
ПолеТекстаПрограммы.ЭтоМодуль = Истина;
мПоляТекстаПрограммы[ЯзыкПрограммы] = ПолеТекстаПрограммы;
КонецЕсли;
Возврат ПолеТекстаПрограммы;
КонецФункции
#КонецЕсли
Процедура ПроверитьФлагОтменыВычислений() Экспорт
Если Истина
И мФайлОтменыВычислений <> Неопределено
И Не мФайлОтменыВычислений.Существует() // 3мс на 100шт
Тогда
ВызватьИсключение "Установлен флаг отмены вычислений";
КонецЕсли;
КонецПроцедуры
Функция РеквизитыДляСервера(Параметры) Экспорт
//Результат = ирОбщий.РеквизитыОбработкиЛкс(ЭтотОбъект);
Возврат Новый Структура;
КонецФункции
Функция ЗаполнитьТипыДанныхМакетовКонфигурации(Знач Параметры) Экспорт
ТаблицаМакетов = Параметры.МакетыКонфигурации; // см. МакетыКонфигурации.Выгрузить()
ИндикаторМакетов = ирОбщий.ПолучитьИндикаторПроцессаЛкс(МакетыКонфигурации.Количество());
Для Каждого СтрокаМакета Из ТаблицаМакетов Цикл
ирОбщий.ОбработатьИндикаторЛкс(ИндикаторМакетов);
ИзвлечьСодержимоеМакета(СтрокаМакета);
КонецЦикла;
ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
Результат = Новый Структура;
Результат.Вставить("МакетыКонфигурации", ТаблицаМакетов);
Возврат Результат;
КонецФункции
//.
// Параметры:
// СтрокаМакета - ОбработкаТабличнаяЧастьСтрока.ирПлатформа.МакетыКонфигурации -
// МетаМакет - ОбъектМетаданныхМакет -
Процедура ИзвлечьСодержимоеМакета(Знач СтрокаМакета, Знач МетаМакет = Неопределено) Экспорт
Если МетаМакет = Неопределено Тогда
МетаМакет = Метаданные.НайтиПоПолномуИмени(СтрокаМакета.ПолноеИмя);
КонецЕсли;
РодительМД = МетаМакет.Родитель();
Если ТипЗнч(РодительМД) = Тип("ОбъектМетаданныхКонфигурация") Тогда
ДанныеМакета = ПолучитьОбщийМакет(МетаМакет.Имя);
Иначе
Менеджер = ирОбщий.ПолучитьМенеджерЛкс(РодительМД);
ДанныеМакета = Менеджер.ПолучитьМакет(МетаМакет.Имя);
КонецЕсли;
ТипМакета = ТипЗнч(ДанныеМакета);
СтрокаМакета.ТипДанных = ТипМакета;
СтрокаМакета.ИмяТипа = ирОбщий.ИмяТипаЛкс(ТипМакета);
КонецПроцедуры
Функция ПредставлениеПустогоЗначенияЛкс(ПустоеЗначение) Экспорт
Результат = мКэшПустыхЗначений[ПустоеЗначение];
Если Результат = Неопределено Тогда
Результат = ирОбщий.ПредставлениеПустогоЗначенияЛкс(ПустоеЗначение);
мКэшПустыхЗначений[ПустоеЗначение] = Результат;
КонецЕсли;
Возврат Результат;
КонецФункции
// Возвращает текущее время в миллисекундах.
//
// Параметры:
// Нет.
//
// Возвращаемое значение:
// Число.
//
Функция ПолучитьТекущееВремяВМиллисекундах() Экспорт
Если ирКэш.НомерИзданияПлатформыЛкс() > "82" Тогда
Результат = Вычислить("ТекущаяУниверсальнаяДатаВМиллисекундах()");
КонецЕсли;
Если Результат = Неопределено Тогда
Если JavaScript = Неопределено Тогда
Попытка
JavaScript = Новый COMОбъект("MSScriptControl.ScriptControl");
Исключение
ирОбщий.СообщитьЛкс("Ошибка создания MSScriptControl.ScriptControl: " + ОписаниеОшибки(), СтатусСообщения.Внимание);
Возврат 0;
КонецПопытки;
JavaScript.Language = "javascript";
КонецЕсли;
Результат = JavaScript.Eval("new Date().getTime()");
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПроверитьПолучитьОбъектСервиса(Знач АлгоритмОбъект) Экспорт
Если ТипЗнч(АлгоритмОбъект) = Тип("СтрокаТаблицыЗначений") Тогда
лОбъект = АлгоритмОбъект.ЭтотОбъект;
Если лОбъект = Неопределено Тогда
лОбъект = АлгоритмОбъект.Ссылка.ПолучитьОбъект();
ЗаполнитьЗначенияСвойств(лОбъект, АлгоритмОбъект, , "ЭтотОбъект, Ссылка, мПолнаяТаблицаПараметров"); ////%!%
АлгоритмОбъект.ЭтотОбъект = лОбъект;
КонецЕсли;
АлгоритмОбъект = лОбъект;
КонецЕсли;
Возврат АлгоритмОбъект;
КонецФункции
Функция ПредставлениеИнформацииОбОшибке(Знач ИнформацияОбОшибке) Экспорт
// Антибаг платформы. В описании повторяется причина и описание между уровнями. В общем бардак.
ОписаниеОшибки = ИнформацияОбОшибке.Описание;
Если ИнформацияОбОшибке.Причина <> Неопределено Тогда
Пока Истина
И ИнформацияОбОшибке.Причина <> Неопределено
И ИнформацияОбОшибке.Описание = ОписаниеОшибки
Цикл
ИнформацияОбОшибке = ИнформацияОбОшибке.Причина;
КонецЦикла;
Если ИнформацияОбОшибке.Описание <> ОписаниеОшибки Тогда
ОписаниеОшибки = ОписаниеОшибки + Символы.ПС + ПредставлениеИнформацииОбОшибке(ИнформацияОбОшибке);
КонецЕсли;
Иначе
Фрагмент = ирОбщий.ПоследнийФрагментЛкс(ОписаниеОшибки, "по причине:" + Символы.ПС);
Позиция = Найти(ОписаниеОшибки, Фрагмент + Символы.ПС + "по причине:" + Символы.ПС + Фрагмент);
Если Позиция > 0 Тогда
ОписаниеОшибки = Лев(ОписаниеОшибки, Позиция) + Фрагмент;
КонецЕсли;
КонецЕсли;
Возврат ОписаниеОшибки;
КонецФункции // ПредставлениеИнформацииОбОшибке()
Функция ОбработатьВнешнееИсключениеАлгоритма(ДескрипторСервиса, ИнформацияОбОшибке, РежимВыполненияАлгоритма, Интерактивно = Истина) Экспорт
//СервисОбъект = ПроверитьПолучитьОбъектСервиса(ДескрипторСервиса);
// Такой прием применен для избежания обращения к БД внутри сломанной транзакции
Если ТипЗнч(ДескрипторСервиса) = Тип("СтрокаТаблицыЗначений") Тогда
лОбъект = ДескрипторСервиса.ЭтотОбъект;
Если лОбъект = Неопределено Тогда
//лОбъект = Справочники.Сервисы2iS.СоздатьЭлемент();
//ЗаполнитьЗначенияСвойств(лОбъект, ДескрипторСервиса, , "ЭтотОбъект, Ссылка, КэшПараметров");
лОбъект = Новый ("СправочникОбъект.Сервисы2iS");
ЗаполнитьЗначенияСвойств(лОбъект, ДескрипторСервиса, "мЗначенияПоУмолчанию, мВнешниеПараметры, мВнутренниеПараметры");
КонецЕсли;
СервисОбъект = лОбъект;
Иначе
//! ДескрипторСервиса = Справочники.ирАлгоритмы.СоздатьЭлемент();
СервисОбъект = ДескрипторСервиса;
КонецЕсли;
Если РежимВыполненияАлгоритма = 2 Тогда
Смещение = СервисОбъект.ПолучитьСтартовуюСтрокуАлгоритмаВТексте();
ИмяМодуляСервиса = "";
ИначеЕсли Ложь
Или РежимВыполненияАлгоритма = 1
Или РежимВыполненияАлгоритма = 0
Тогда
Смещение = СервисОбъект.ПолучитьСтартовуюСтрокуМетодаВМодуле();
ИмяМодуляСервиса = "ВнешняяОбработка." + ДескрипторСервиса.Наименование;
ИмяМодуляСервиса = ИмяМодуляСервиса + ".МодульОбъекта";
КонецЕсли;
ПрефиксСервиса = "Сервис ";
Если ИмяМодуляСервиса = ИнформацияОбОшибке.ИмяМодуля Тогда
НомерСтрокиАлгоритма = ИнформацияОбОшибке.НомерСтроки;
НомерСтрокиАлгоритма = НомерСтрокиАлгоритма - Смещение;
ОписаниеОшибки = ПрефиксСервиса + """" + ДескрипторСервиса.Наименование + """[" + РежимВыполненияАлгоритма + "]{"
+ НомерСтрокиАлгоритма + "}:" + Символы.ПС + "==========================================================================" + Символы.ПС
+ ИнформацияОбОшибке.Описание + Символы.ПС + ИнформацияОбОшибке.ИсходнаяСтрока;
Иначе
ОписаниеОшибки = ПрефиксСервиса + """" + ДескрипторСервиса.Наименование + """[" + РежимВыполненияАлгоритма + "]";
МаркерСлужебногоИсключения = "ВызватьИсключение Ошибка;//#Служебное";
Если Найти(ИнформацияОбОшибке.ИсходнаяСтрока, МаркерСлужебногоИсключения) = 0 Тогда
ОписаниеОшибки = ОписаниеОшибки + "{" + ИнформацияОбОшибке.ИмяМодуля + "(" + ИнформацияОбОшибке.НомерСтроки + ")}: ";
КонецЕсли;
ОписаниеОшибки = ОписаниеОшибки + Символы.ПС + ИнформацияОбОшибке.Описание;
Если Найти(ИнформацияОбОшибке.ИсходнаяСтрока, МаркерСлужебногоИсключения) = 0 Тогда
ОписаниеОшибки = ОписаниеОшибки + Символы.ПС + ИнформацияОбОшибке.ИсходнаяСтрока;
КонецЕсли;
КонецЕсли;
Если ИнформацияОбОшибке.Причина <> Неопределено Тогда
ОписаниеОшибки = ОписаниеОшибки + "
|" + ПредставлениеИнформацииОбОшибке(ИнформацияОбОшибке.Причина);
КонецЕсли;
Возврат ОписаниеОшибки;
КонецФункции
Функция ВыполнитьМетодАлгоритма(ДескрипторСервиса, Режим, П0 = Null, П1 = Null, П2 = Null, П3 = Null, П4 = Null,
П5 = Null, П6 = Null, П7 = Null, П8 = Null, П9 = Null) Экспорт
//#Если Клиент Тогда
Если ВыполнятьАлгоритмыЧерезВнешниеОбработки Тогда
Если Ложь
Или ВнешняяОбработкаСервисы = Неопределено
Или ДескрипторСервиса.ИндивидуальнаяВнешняяОбработка
Тогда
ВнешняяОбработкаАлгоритма = ПолучитьВнешнююОбработкуПоАлгоритму(ДескрипторСервиса);
//Иначе
// ВнешняяОбработкаАлгоритма = ДескрипторСервиса.мСтруктураВнешнейОбработки;
// Если ВнешняяОбработкаАлгоритма = Неопределено Тогда
// ВнешняяОбработкаАлгоритма = ВнешняяОбработкаСервисы.ПолучитьФорму(ДескрипторСервиса.Наименование);
// ДескрипторСервиса.мСтруктураВнешнейОбработки = ВнешняяОбработкаАлгоритма;
// КонецЕсли;
//КонецЕсли;
Если ВнешняяОбработкаАлгоритма <> Неопределено Тогда
Результат = ВнешняяОбработкаАлгоритма.мМетод(ДескрипторСервиса, Режим, П0, П1, П2, П3, П4, П5, П6, П7, П8, П9);
Иначе
//ирОбщий.СообщитьЛкс("Ошибка компиляции сервиса """ + ДескрипторСервиса.Наименование + """. Сервис не выполнен.", СтатусСообщения.Внимание);
ВызватьИсключение "Ошибка компиляции сервиса """ + ДескрипторСервиса.Наименование + """";
КонецЕсли;
Иначе
Результат = Вычислить("ВнешняяОбработкаСервисы._" + ДескрипторСервиса.Наименование
+ "(ДескрипторСервиса, Режим, П0, П1, П2, П3, П4, П5, П6, П7, П8, П9)");
КонецЕсли;
Иначе
//#КонецЕсли
//#Если Не Клиент И Не ВнешнееСоединение Тогда
//ДескрипторСервиса.ирПлатформа = ЭтотОбъект;
//#КонецЕсли
СервисОбъект = ПроверитьПолучитьОбъектСервиса(ДескрипторСервиса);
#Если Сервер И Не Сервер Тогда
СервисОбъект = Обработки.ирИмитаторАлгоритмОбъект.Создать();
#КонецЕсли
ТекстАлгоритмаСПараметрами = СервисОбъект.ПолучитьТелоМетода();
Результат = ирОбщий.ВыполнитьАлгоритм(ТекстАлгоритмаСПараметрами, СервисОбъект, Режим, П0, П1, П2, П3, П4, П5, П6, П7, П8, П9);
//#Если Клиент Тогда
КонецЕсли;
//#КонецЕсли
Возврат Результат;
КонецФункции
Функция ПолучитьИмяТипаCOMVariant(ReturnType) Экспорт
Перем ScrptCtrl;
ТекстМодуля = "
|Function getMemberReturn( ReturnType )
| Dim ret
| On Error Resume Next
| If ReturnType Is Nothing Then
| ret = """"
| ElseIf Not IsEmpty(ReturnType.TypedVariant) Then
| ff = ReturnType.TypedVariant
| ff.VariantInit()
| ret = ff.Name
| ElseIf Not ReturnType.TypeInfo Is Nothing Then
| ret = ReturnType.TypeInfo.Name
| Else
| ret = """"
| End If
| getMemberReturn = ret
|End Function";
ScrptCtrl = Новый COMОбъект("MSScriptControl.ScriptControl");
ScrptCtrl.Language = "vbscript";
Попытка
ScrptCtrl.AddCode(ТекстМодуля);
Исключение
ирОбщий.СообщитьЛкс(ScrptCtrl.Error.Description);
ирОбщий.СообщитьЛкс(ScrptCtrl.Error.Source);
ирОбщий.СообщитьЛкс(ScrptCtrl.Error.Text);
ирОбщий.СообщитьЛкс(ScrptCtrl.Error.Line);
КонецПопытки;
Результат = ScrptCtrl.Run("getMemberReturn", ReturnType);
Возврат Результат;
КонецФункции
Функция WshShell() Экспорт
Если WScriptShell = Неопределено Тогда
WScriptShell = Новый COMОбъект("WScript.Shell");
КонецЕсли;
Возврат WScriptShell;
КонецФункции
Процедура ПрочитатьОбщиеНастройки() Экспорт
#Если Клиент Тогда
ЛиГлобальныеНастройкиВсехБаз = ирОбщий.ВосстановитьЗначениеЛкс("ЛиГлобальныеНастройкиВсехБаз",,, ЭтотОбъект);
Если ЛиГлобальныеНастройкиВсехБаз = Неопределено Тогда
ЛиГлобальныеНастройкиВсехБаз = Истина;
КонецЕсли;
ПерехватКлавиатурногоВводаВОбычномПриложении = ирОбщий.ВосстановитьЗначениеЛкс("ПерехватКлавиатурногоВводаВОбычномПриложении",,, ЭтотОбъект);
Если ПерехватКлавиатурногоВводаВОбычномПриложении = Неопределено Тогда
ПерехватКлавиатурногоВводаВОбычномПриложении = Истина;
КонецЕсли;
ФайловыйКэшАлгоритмовДопускаетРедактирование = ирОбщий.ВосстановитьЗначениеЛкс("ФайловыйКэшАлгоритмовДопускаетРедактирование",,, ЭтотОбъект);
Если ФайловыйКэшАлгоритмовДопускаетРедактирование = Неопределено Тогда
ФайловыйКэшАлгоритмовДопускаетРедактирование = Ложь;
КонецЕсли;
НеИспользоватьУправляемыеФормыИнструментов = ирОбщий.ВосстановитьЗначениеЛкс("НеИспользоватьУправляемыеФормыИнструментов",,, ЭтотОбъект);
Если НеИспользоватьУправляемыеФормыИнструментов = Неопределено Тогда
НеИспользоватьУправляемыеФормыИнструментов = Ложь;
КонецЕсли;
//СинтаксическийКонтрольПередЗаписью = ирОбщий.ВосстановитьЗначениеЛкс("СинтаксическийКонтрольПередЗаписью");
СинтаксическийКонтрольПередЗаписью = Истина;
#Иначе
ЛиГлобальныеНастройкиВсехБаз = Ложь;
#КонецЕсли
// Далее идут глобализуемые настройки
// Фиксированные. Больше не меняем.
ВыполнятьАлгоритмыЧерезВнешниеОбработки = Ложь;
// Антибаг http://partners.v8.1c.ru/forum/thread.jsp?id=861032#861032
АвторегистрацияComКомпонент = Истина;
ИспользоватьЭмуляциюНажатияКлавиш = Истина;
#Если Клиент Тогда
//ПерехватКлавиатурногоВводаВОбычномПриложении = Метаданные.ОсновнойРежимЗапуска = РежимЗапускаКлиентскогоПриложения.УправляемоеПриложение;
ВыделениеРезультатовПоиска = "⧼⧽";
#КонецЕсли
ПрочитатьНастройкиКомпьютераВсе(Истина);
ОбщиеНастройкиГлобализуемые = ирОбщий.ВосстановитьЗначениеЛкс(КлючХраненияОбщихНастроек(),,, ЭтотОбъект); // см. НовыйОбщиеНастройкиГлобализуемые
Если ОбщиеНастройкиГлобализуемые <> Неопределено Тогда
ирОбщий.СкопироватьКоллекциюЛкс(НовыйОбщиеНастройкиГлобализуемые(), ОбщиеНастройкиГлобализуемые,, Ложь);
Если Не мЭтотОбъектГотов Тогда
ВызватьИсключение "Внутренняя ошибка";
КонецЕсли;
ЗаполнитьЗначенияСвойств(ЭтотОбъект, ОбщиеНастройкиГлобализуемые, ИменаСохраняемыхСвойств());
Если Не ирКэш.ЛиФайловаяБазаЛкс() Тогда
ОбщиеНастройкиДляСервера = ирОбщий.ВосстановитьЗначениеЛкс("ОбщиеНастройкиБазы",,, ЭтотОбъект);
Если Ложь
Или ОбщиеНастройкиДляСервера = Неопределено
Или ОбщиеНастройкиДляСервера._ВерсияДанных < ОбщиеНастройкиГлобализуемые._ВерсияДанных
Тогда
СохранитьОбщиеНастройкиДляСервера(ОбщиеНастройкиГлобализуемые); // 10мс
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Функция КлючХраненияОбщихНастроек() Экспорт
Если ЛиГлобальныеНастройкиВсехБаз Тогда
КлючНастроек = "ОбщиеНастройкиГлобально";
Иначе
КлючНастроек = "ОбщиеНастройкиБазы";
КонецЕсли;
Возврат КлючНастроек;
КонецФункции
Процедура СохранитьОбщиеНастройкиДляСервера(Знач ОбщиеНастройки) Экспорт
Если Не ирКэш.ЛиФайловаяБазаЛкс() И ЛиГлобальныеНастройкиВсехБаз Тогда
// Дублируем глобальные настройки в базу для чтения на сервере
ирОбщий.СохранитьЗначениеЛкс("ОбщиеНастройкиБазы", ОбщиеНастройки,,,, ЭтотОбъект);
КонецЕсли;
КонецПроцедуры
Функция СохранитьОбщиеНастройки() Экспорт
ирОбщий.СохранитьЗначениеЛкс("ЛиГлобальныеНастройкиВсехБаз", ЛиГлобальныеНастройкиВсехБаз,,,, ЭтотОбъект);
ирОбщий.СохранитьЗначениеЛкс("ПерехватКлавиатурногоВводаВОбычномПриложении", ПерехватКлавиатурногоВводаВОбычномПриложении,,,, ЭтотОбъект);
ирОбщий.СохранитьЗначениеЛкс("ФайловыйКэшАлгоритмовДопускаетРедактирование", ФайловыйКэшАлгоритмовДопускаетРедактирование,,,, ЭтотОбъект);
ирОбщий.СохранитьЗначениеЛкс("НеИспользоватьУправляемыеФормыИнструментов", НеИспользоватьУправляемыеФормыИнструментов,,,, ЭтотОбъект);
ОбщиеНастройки = НовыйОбщиеНастройкиГлобализуемые();
КлючНастроек = КлючХраненияОбщихНастроек();
Попытка
ирОбщий.СохранитьЗначениеЛкс(КлючНастроек, ОбщиеНастройки,,,, ЭтотОбъект);
Исключение
ирОбщий.СообщитьЛкс("Ошибка сохранения глобальных настроек: " + ОписаниеОшибки());
КонецПопытки;
СохранитьОбщиеНастройкиДляСервера(ОбщиеНастройки);
Возврат ОбщиеНастройки;
КонецФункции
Функция НовыйОбщиеНастройкиГлобализуемые() Экспорт
ОбщиеНастройки = Новый Структура(ИменаСохраняемыхСвойств());
ОбщиеНастройки.Вставить("_ВерсияДанных", ТекущаяДата());
ЗаполнитьЗначенияСвойств(ОбщиеНастройки, ЭтотОбъект);
Возврат ОбщиеНастройки;
КонецФункции
Функция ИменаСохраняемыхСвойств() Экспорт
Возврат "АвторегистрацияComКомпонент, ВыделениеРезультатовПоиска, ИспользоватьЭмуляциюНажатияКлавиш, КлючСервисаИИ, КлючСервисаНапарник, СерверИИ, МодельИИ, МаксОжиданиеИИ, ЛиЗапросыИИНаСервере, ПредлагатьОчиститьМенеджерВременныхТаблицЧерезМинут";
КонецФункции
Функция НовоеСлужебноеПолеТекста(Знач СлужебнаяФорма = Неопределено, Знач Суффикс = "") Экспорт
Перем ПолеТекста;
Если СлужебнаяФорма = Неопределено Тогда
СлужебнаяФорма = мСлужебнаяФорма;
КонецЕсли;
ПолеТекста = СлужебнаяФорма.ЭлементыФормы.Добавить(Тип("ПолеТекстовогоДокумента"), "СлужебноеПолеТекста" + Суффикс, Ложь);
Возврат ПолеТекста;
КонецФункции
Функция ТерминалыЯзыкаЗапросов() Экспорт
Если мТерминалыЯзыкаЗапросов = Неопределено Тогда
мТерминалыЯзыкаЗапросов = ирОбщий.ТаблицаЗначенийИзТабличногоДокументаЛкс(ПолучитьМакет("ТерминалыЯзыкаЗапросов"));
мТерминалыЯзыкаЗапросов.Индексы.Добавить("Ключ");
мТерминалыЯзыкаЗапросов.Индексы.Добавить("МожетБытьПсевдонимом, Русский");
мТерминалыЯзыкаЗапросов.Индексы.Добавить("МожетБытьПсевдонимом, Английский");
КонецЕсли;
Возврат мТерминалыЯзыкаЗапросов;
КонецФункции
Функция КлючСервисаИИ() Экспорт
Если ТипЗнч(КлючСервисаИИ) = Тип("ХранилищеЗначения") Тогда
Возврат КлючСервисаИИ.Получить();
КонецЕсли;
КонецФункции
Функция КлючСервисаНапарник() Экспорт
Если ТипЗнч(КлючСервисаНапарник) = Тип("ХранилищеЗначения") Тогда
Возврат КлючСервисаНапарник.Получить();
КонецЕсли;
КонецФункции
Функция МодельИИ(Знач РазрешитьПоУмолчанию = Истина, Знач Модель = Неопределено, Знач Сервер = "") Экспорт
Если Модель = Неопределено Тогда
Модель = МодельИИ;
КонецЕсли;
Если ПустаяСтрока(Модель) И РазрешитьПоУмолчанию Тогда
Если Сервер = "https://api.smartbuddy.ru" Тогда
Модель = "deepseek/deepseek-chat";
ИначеЕсли Сервер = "https://api.vsegpt.ru" Тогда
Модель = "deepseek/deepseek-chat";
ИначеЕсли Сервер = "https://api.together.xyz" Тогда
Модель = "deepseek-ai/DeepSeek-V3";
Иначе
//Модель = "qwen/qwen-2.5-coder-32b-instruct:free"; // Слишком тупая
//Модель = "deepseek/deepseek-chat-v3-0324:free"; // Часто недоступна
Модель = "deepseek/deepseek-chat-v3.1:free";
КонецЕсли;
КонецЕсли;
Возврат Модель;
КонецФункции
Функция СерверИИ(Знач РазрешитьПоУмолчанию = Истина, Знач Сервер = Неопределено) Экспорт
Если Сервер = Неопределено Тогда
Сервер = СерверИИ;
КонецЕсли;
Если ПустаяСтрока(Сервер) И РазрешитьПоУмолчанию Тогда
Сервер = "https://openrouter.ai/api";
КонецЕсли;
Возврат Сервер;
КонецФункции
Функция МаксОжиданиеИИ() Экспорт
МаксОжидание = МаксОжиданиеИИ;
Если ПустаяСтрока(МаксОжидание) Тогда
МаксОжидание = 60;
КонецЕсли;
Возврат МаксОжидание;
КонецФункции
Функция ЛиЗапросыИИНаСервере() Экспорт
ЛиЗапросыИИНаСервере = ЛиЗапросыИИНаСервере;
Если ЛиЗапросыИИНаСервере = Неопределено Тогда
ЛиЗапросыИИНаСервере = ирОбщий.ЛиАсинхронностьДоступнаЛкс();
КонецЕсли;
Возврат ЛиЗапросыИИНаСервере;
КонецФункции
Функция ЗаголовокСтороныМодуляКонфигуратора() Экспорт
Возврат "Кэш (новый)";
КонецФункции
//ирПортативный Контейнер = Новый Структура();
//ирПортативный #Если Клиент Тогда
//ирПортативный Оповестить("ирПолучитьБазовуюФорму", Контейнер);
//ирПортативный #КонецЕсли
//ирПортативный Если Не Контейнер.Свойство("ирПортативный", ирПортативный) Тогда
//ирПортативный Файл = Новый Файл(ИспользуемоеИмяФайла);
//ирПортативный ПолноеИмяФайлаБазовогоМодуля = Лев(Файл.Путь, СтрДлина(Файл.Путь) - СтрДлина("Модули\")) + "ирПортативный.epf";
//ирПортативный ирПортативный = ВнешниеОбработки.Создать(ПолноеИмяФайлаБазовогоМодуля, Ложь); // Это будет второй экземпляр объекта
//ирПортативный КонецЕсли;
//ирПортативный ирОбщий = ирПортативный.ОбщийМодульЛкс("ирОбщий");
//ирПортативный ирКэш = ирПортативный.ОбщийМодульЛкс("ирКэш");
//ирПортативный ирСервер = ирПортативный.ОбщийМодульЛкс("ирСервер");
//ирПортативный ирКлиент = ирПортативный.ОбщийМодульЛкс("ирКлиент");
#Если Сервер И Не Сервер Тогда
мТаблицаВсехТаблицБД = Обработки.ирКлсПолеТекстаПрограммы.Создать().ДоступныеТаблицы.ВыгрузитьКолонки();
ИнициацияОписанияМетодовИСвойств();
НоваяТаблицаТипов();
ТерминалыЯзыкаЗапросов();
#КонецЕсли
мЭтотОбъектГотов = Ложь;
ЛиГлобальныеНастройкиВсехБаз = Ложь;
ИнициализацияОписанияОбщихТипов();
мНомерВерсииПлатформы = ирКэш.НомерВерсииПлатформыЛкс();
мМетаданные = Метаданные;
КэшОбъектов = Новый Соответствие;
мКэшПустыхЗначений = Новый Соответствие;
мПассивныеФормы = новый Соответствие;
СисИнфо = Новый СистемнаяИнформация;
Фрагменты = ирОбщий.СтрРазделитьЛкс(СисИнфо.ВерсияПриложения);
ВерсияПлатформы = Число(Фрагменты[0]) * 100 * 1000 + Число(Фрагменты[1]) * 1000 + Число(Фрагменты[2]);
ЭтоИнтеграция = Метаданные.Справочники.Найти("иисМетаданные") <> Неопределено;
МаркерНачалаАлгоритма = "//НАЧАЛО.СЕРВИС" + Символы.ПС;
МаркерКонцаАлгоритма = "//КОНЕЦ_.СЕРВИС" + Символы.ПС;
мМаркерИмениЗапросаПакета = "{Запрос: ";
мМаркерИмениЧастиОбъединения = "{Выборка: ";
шЛюбой = "(?:.|\n|\r)";
шБуква = "_ЁА-ЯA-Z";
шБукваЦифра = "_ЁА-ЯA-Z0-9";
шБукваСРешеткой = "_ЁА-ЯA-Z#";
шКомментарий = "//[^\n]*(?=(?:\n|$))";
шРазделитель = "(?:" + шКомментарий + "|\s|\xa0|$)"; // Возможно стоит добавить |\n|\r . Пришлось явно добавить неразрывный пробел (\xa0), т.к. VBScript не находит его через \s
шПустоеНачалоСтроки = "(?:\n|^)(?:\t| )*";
шИнструкцияПрепроцессора = "#[^\n\r]*(?=(?:\n|$))";
шМетодНачало = "(?:Функция|Процедура|Function|Procedure)";
шМетодКонец = "(?:Конец|End)(?:Процедуры|Функции|Procedure|Function)";
// Когда внутри шРазделитель был управляющий символ <начало строки>, то возникали зависания на больших литералах https://www.hostedredmine.com/issues/966307
//шЛитералПрограммы = """(?:""""|[^""\n])*(?:" + шРазделитель + "*\|(?:""""|[^""\n])*(?=(?:""|\n|$)))*(?:""|$)"; // Возможно, что с последними правками и этот вариант будет хорошо работать, но в нем не учтены инструкции препроцессора
шЛитералПрограммы = """(?:""""|[^""\n\r])*(?:(?:\n|\r|^)(?:\t| )*(?:" + шКомментарий + "|" + шИнструкцияПрепроцессора + "|\|(?:""""|[^""\n\r])*(?=(?:""|\n|$)))|[\s\xa0])*(?:""|(?=\n|\r|$))"; // Так быстрее (меньше откатов) 14.08.2023 . \r добавил для защиты от зависаний на экзотических файлах с OD-OD-OA
шЛитералВЗапросе = """(?:(?:"""")|[^""\n])*(?:""|\n|$)"; // Есть сильно связанный шаблон шНачалоЛитералаВЗапросе в ирКлсПолеТекстаПрограммы
шGUID = "[A-F0-9]{8}(?:-[A-F0-9]{4}){3}-[A-F0-9]{12}";
шЧисло = "\d+(\.\d+)?";
шИндекс = "(\[[^\n\r\]\[]+?(?:(?:\[[^\n\r\]]+?\][^\n\r\]\[]*?)*)*\])"; // Внутри квадратных скобок не допускаем переноса строки для избежания бесконечных откатов
//шЛитералПростой = шЛитералПрограммы; // Так будут зависания в тесте "завис"
шЛитералПростой = """(?:[^""\n\r]|[\s\xa0]*\|)*""";
шМеждуСкобок = "[^\(\);""]";
шСкобки = "(\(" + шМеждуСкобок + "*(?:(?:" + шЛитералПростой + "|\((?:" + "[^\);""]" + "|" + шЛитералПростой + ")*\))" + шМеждуСкобок + "*)*\))"; // МультиМетка82355611
шИмя = "[" + шБуква + "][" + шБуква + "\d]*";
шИмяСРешеткой = "[" + шБукваСРешеткой + "][" + шБукваСРешеткой + "\d]*";
шИмяВременнойТаблицы = шИмяСРешеткой + "(?:\." + шИмяСРешеткой + ")*";
шГиперСсылка = "(\b(?:[" + шБукваЦифра + "]+)://[" + шБукваЦифра + "\-+&@#\\/%?=~|!:,.;()]*[" + шБукваЦифра + "/])";
ВложенностьИндикации = 0;
ИмяКластераСерверов = НСтр(СтрокаСоединенияИнформационнойБазы(), "Srvr");
ЭтоФайловаяБаза = ПустаяСтрока(ИмяКластераСерверов);
ПроверитьСтруктуруФайловогоКэша();
//ПрочитатьОбщиеНастройки(); // Пришлось тут отключить, т.к. нужно обращение через ЭтотОбъект
Парсеры = Новый Структура;
ШаблоныВнешнейОбработки = Новый Соответствие;
ШаблоныВнешнейОбработкиСМакетом = Новый Соответствие;
ИмяФайлаПакера = "v8unpack.exe";
МассивОбычныхЭлементовУправления = Новый Массив;
мМассивТиповЭлементовОбычнойФормы = Новый Массив;
РежимОтладки = Ложь;
АсинхронностьЗапрещена = Ложь;
#Если Клиент Тогда
РежимОтладки = Найти(НРег(ПараметрЗапуска), НРег("РежимОтладкиИР")) > 0;
АсинхронностьЗапрещена = Найти(НРег(ПараметрЗапуска), НРег("ЗапретитьАсинхронностьИР")) > 0;
COMНавигатор = "НеИнициализирован";
ОтложенноеОткрытиеИсточникаОшибки = Новый ТаблицаЗначений;
ОтложенноеОткрытиеИсточникаОшибки.Колонки.Добавить("АлгоритмОбъект");
ОтложенноеОткрытиеИсточникаОшибки.Колонки.Добавить("ИнформацияОбОшибке");
ОтложенноеОткрытиеИсточникаОшибки.Колонки.Добавить("РежимВыполненияАлгоритма");
ОтложенноеОткрытиеИсточникаОшибки.Колонки.Добавить("Смещение", Новый ОписаниеТипов("Число"));
мСлужебнаяФорма = ПолучитьФорму("Служебная");
Если мСлужебнаяФорма <> Неопределено Тогда // Для портативного режима управляемого приложения
СлужебноеПолеТекста = НовоеСлужебноеПолеТекста();
СлужебноеПолеТекста2 = НовоеСлужебноеПолеТекста(, "2");
//СлужебноеПолеHtmlДокумента = СлужебнаяФорма.ЭлементыФормы.Добавить(Тип("ПолеHTMLДокумента"), "СлужебноеПолеHTMLДокумента", Ложь); // Тяжелая операция
КонецЕсли;
МассивОбычныхЭлементовУправления.Добавить("Диаграмма");
МассивОбычныхЭлементовУправления.Добавить("ДиаграммаГанта");
МассивОбычныхЭлементовУправления.Добавить("Дендрограмма");
МассивОбычныхЭлементовУправления.Добавить("Индикатор");
МассивОбычныхЭлементовУправления.Добавить("ПолеКалендаря");
МассивОбычныхЭлементовУправления.Добавить("Кнопка");
МассивОбычныхЭлементовУправления.Добавить("КолонкаТабличногоПоля");
МассивОбычныхЭлементовУправления.Добавить("КоманднаяПанель");
МассивОбычныхЭлементовУправления.Добавить("Надпись");
МассивОбычныхЭлементовУправления.Добавить("Панель");
МассивОбычныхЭлементовУправления.Добавить("Переключатель");
МассивОбычныхЭлементовУправления.Добавить("ПолеГрафическойСхемы");
МассивОбычныхЭлементовУправления.Добавить("ПолеГеографическойСхемы");
МассивОбычныхЭлементовУправления.Добавить("ПолеТабличногоДокумента");
МассивОбычныхЭлементовУправления.Добавить("ПолеHTMLДокумента");
МассивОбычныхЭлементовУправления.Добавить("ПолеТекстовогоДокумента");
МассивОбычныхЭлементовУправления.Добавить("ПолеВвода");
МассивОбычныхЭлементовУправления.Добавить("ПолеВыбора");
МассивОбычныхЭлементовУправления.Добавить("ПолеСписка");
МассивОбычныхЭлементовУправления.Добавить("ПолеКартинки");
МассивОбычныхЭлементовУправления.Добавить("ПолосаРегулирования");
МассивОбычныхЭлементовУправления.Добавить("Разделитель");
МассивОбычныхЭлементовУправления.Добавить("РамкаГруппы");
МассивОбычныхЭлементовУправления.Добавить("СводнаяДиаграмма");
МассивОбычныхЭлементовУправления.Добавить("СтраницаПанели");
МассивОбычныхЭлементовУправления.Добавить("ТабличноеПоле");
МассивОбычныхЭлементовУправления.Добавить("Флажок");
Для Каждого ИмяТипа Из МассивОбычныхЭлементовУправления Цикл
мМассивТиповЭлементовОбычнойФормы.Добавить(Тип(ИмяТипа));
КонецЦикла;
#КонецЕсли
МассивУправляемыхЭлементовУправления = Новый Массив;
мМассивТиповЭлементовУправляемойФормы = Новый Массив;
МассивУправляемыхЭлементовУправления.Добавить("ПолеФормы");
МассивУправляемыхЭлементовУправления.Добавить("КнопкаФормы");
МассивУправляемыхЭлементовУправления.Добавить("ТаблицаФормы");
МассивУправляемыхЭлементовУправления.Добавить("ГруппаФормы");
МассивУправляемыхЭлементовУправления.Добавить("ДекорацияФормы");
Для Каждого ИмяТипа Из МассивУправляемыхЭлементовУправления Цикл
мМассивТиповЭлементовУправляемойФормы.Добавить(Тип(ИмяТипа));
КонецЦикла;
// Мультиметка121095773
мМассивТиповСМетаданными = Новый Массив;
мМассивТиповСМетаданными.Добавить(Тип("ОбъектМетаданных"));
мМассивТиповСМетаданными.Добавить(Тип("КоллекцияОбъектовМетаданных"));
мМассивТиповСМетаданными.Добавить(Тип("КоллекцияДвижений"));
мМассивТиповСМетаданными.Добавить(Тип("ОписанияСтандартныхРеквизитов"));
мМассивТиповСМетаданными.Добавить(Тип("СписокПолей"));
мМассивТиповСМетаданными.Добавить(Тип("Структура"));
мМассивТиповСМетаданными.Добавить(Тип("СписокЗначений"));
мМассивТиповСМетаданными.Добавить(Тип("ФиксированнаяСтруктура"));
мМассивТиповСМетаданными.Добавить(Тип("Массив"));
мМассивТиповСМетаданными.Добавить(Тип("Соответствие"));
мМассивТиповСМетаданными.Добавить(Тип("ТаблицаЗначений"));
мМассивТиповСМетаданными.Добавить(Тип("ДеревоЗначений"));
мМассивТиповСМетаданными.Добавить(Тип("СтрокаТаблицыЗначений"));
мМассивТиповСМетаданными.Добавить(Тип("СтрокаДереваЗначений"));
//мМассивТиповСМетаданными.Добавить(Тип("КолонкаТаблицыЗначений"));
//мМассивТиповСМетаданными.Добавить(Тип("КолонкаДереваЗначений"));
мМассивТиповСМетаданными.Добавить(Тип("ВыборкаИзРезультатаЗапроса"));
мМассивТиповСМетаданными.Добавить(Тип("РезультатЗапроса"));
мМассивТиповСМетаданными.Добавить(Тип("Отбор"));
мМассивТиповСМетаданными.Добавить(Тип("НастройкаОформления"));
мМассивТиповСМетаданными.Добавить(Тип("COMОбъект"));
мМассивТиповСМетаданными.Добавить(Тип("ВнешнийОбъект"));
мМассивТиповСМетаданными.Добавить(Тип("ОбъектXDTO"));
мМассивТиповСМетаданными.Добавить(Тип("СвойствоXDTO"));
//мМассивТиповСМетаданными.Добавить(Тип("ОбщийМодуль"));
мМассивТиповСМетаданными.Добавить(Тип("ПостроительЗапроса"));
мМассивТиповСМетаданными.Добавить(Тип("ПостроительОтчета"));
мМассивТиповСМетаданными.Добавить(Тип("ПоляНастройки"));
мМассивТиповСМетаданными.Добавить(Тип("СхемаКомпоновкиДанных"));
мМассивТиповСМетаданными.Добавить(Тип("ТабличныйДокумент"));
мМассивТиповСМетаданными.Добавить(Тип("ОбластьЯчеекТабличногоДокумента"));
мМассивТиповСМетаданными.Добавить(Тип("ТекстовыйДокумент"));
мМассивТиповСМетаданными.Добавить(Тип("НаборыДанныхСхемыКомпоновкиДанных"));
мМассивТиповСМетаданными.Добавить(Тип("ПараметрыСхемыКомпоновкиДанных"));
//мМассивТиповСМетаданными.Добавить(Тип("ДинамическийСписок")); // Будет давать ошибку сериализации
мМассивТиповСМетаданными.Добавить(Тип("ДанныеФормыДерево"));
мМассивТиповСМетаданными.Добавить(Тип("ДанныеФормыКоллекция"));
мМассивТиповСМетаданными.Добавить(Тип("ДанныеФормыКоллекцияЭлементовДерева"));
мМассивТиповСМетаданными.Добавить(Тип("ДанныеФормыСтруктура"));
мМассивТиповСМетаданными.Добавить(Тип("ДанныеФормыСтруктураСКоллекцией"));
мМассивТиповСМетаданными.Добавить(Тип("ДанныеФормыЭлементДерева"));
мМассивТиповСМетаданными.Добавить(Тип("ДанныеФормыЭлементКоллекции"));
мМассивТиповСМетаданными.Добавить(ирОбщий.ТипУправляемаяФормаЛкс());
мМассивТиповСМетаданными.Добавить(Тип("ПолеФормы"));
мМассивТиповСМетаданными.Добавить(Тип("ГруппаФормы"));
мМассивТиповСМетаданными.Добавить(Тип("ТаблицаФормы"));
мМассивТиповСМетаданными.Добавить(Тип("КомандаФормы"));
//мМассивТиповСМетаданными.Добавить(Тип("СообщениеПользователю"));
#Если Клиент Тогда
мМассивТиповСМетаданными.Добавить(Тип("Форма"));
мМассивТиповСМетаданными.Добавить(Тип("ТабличноеПоле"));
мМассивТиповСМетаданными.Добавить(Тип("КолонкиТабличногоПоля"));
//мМассивТиповСМетаданными.Добавить(Тип("КолонкаТабличногоПоля")); // Пользы не увидел
мМассивТиповСМетаданными.Добавить(Тип("Панель"));
мМассивТиповСМетаданными.Добавить(Тип("КнопкаКоманднойПанели"));
мМассивТиповСМетаданными.Добавить(Тип("КнопкиКоманднойПанели"));
мМассивТиповСМетаданными.Добавить(Тип("КоманднаяПанель"));
мМассивТиповСМетаданными.Добавить(Тип("ПолеВвода"));
#КонецЕсли
Если ирКэш.НомерВерсииПлатформыЛкс() > 803007 Тогда
мМассивТиповСМетаданными.Добавить(Тип("ВременнаяТаблицаЗапроса"));
КонецЕсли;
//#Если Клиент Или ВнешнееСоединение Тогда
СубПутьКФайлуМодуляВнешнейОбработки = "1ad4dbd4-e136-4202-8121-02c33ad2af45.0.data.und.unp\text.data";
СубПутьКФайлуМодуляФормыВнешнейОбработки = "f362602c-e100-4638-b267-aa18ef493734.0.data.und";
СубПутьКФайлуМакетаВнешнейОбработки = "902f74d3-f929-4b0f-8719-4cbb655891aa.0.data.und";
СубПутьКФайлуЗаголовкаВнешнейОбработки = "4eb1cc18-835d-4f8c-a120-3f9d886d75d4.data.und";
СубПутьККонтрольномуФайлуВнешнейОбработки = "1ad4dbd4-e136-4202-8121-02c33ad2af45.0.data";
//КешВнешнихОбработокАлгоритмов = Новый Структура;
КешАлгоритмов = Новый Структура;
ТаблицаТиповМетаОбъектов = ирКэш.ТипыМетаОбъектов();
МакетыКомпонент = Новый Структура;
//МаркерКоллекцииМетаданных = "КоллекцияОбъектовМетаданных";
МаркерКоллекцииМетаданных = "КоллекцияМетаданных";
МаркерОбъектаМетаданных = "ОбъектМетаданных";
мМассивИсключенийИменКоллекций = Новый СписокЗначений;
мМассивИсключенийИменКоллекций.Добавить("Свойства");
мМассивИсключенийИменКоллекций.Добавить("Методы");
мМассивИсключенийИменКоллекций.Добавить("");
СоответствиеВидовСравнения = Новый ТаблицаЗначений;
СоответствиеВидовСравнения.Колонки.Добавить("Построитель");
СоответствиеВидовСравнения.Колонки.Добавить("Компоновка");
СоответствиеВидовСравнения.Колонки.Добавить("Имя");
СоответствиеВидовСравнения.Индексы.Добавить("Построитель");
СоответствиеВидовСравнения.Индексы.Добавить("Компоновка");
//Интервал
//ИнтервалВключаяГраницы
//ИнтервалВключаяНачало
//ИнтервалВключаяОкончание
СоответствиеВидовСравнения.Добавить().Имя = "Больше";
СоответствиеВидовСравнения.Добавить().Имя = "БольшеИлиРавно";
СоответствиеВидовСравнения.Добавить().Имя = "ВИерархии";
СоответствиеВидовСравнения.Добавить().Имя = "ВСписке";
СоответствиеВидовСравнения.Добавить().Имя = "ВСпискеПоИерархии";
СоответствиеВидовСравнения.Добавить().Имя = "Меньше";
СоответствиеВидовСравнения.Добавить().Имя = "МеньшеИлиРавно";
СоответствиеВидовСравнения.Добавить().Имя = "НеВИерархии";
СоответствиеВидовСравнения.Добавить().Имя = "НеВСписке";
СоответствиеВидовСравнения.Добавить().Имя = "НеВСпискеПоИерархии";
СоответствиеВидовСравнения.Добавить().Имя = "НеРавно";
СоответствиеВидовСравнения.Добавить().Имя = "НеСодержит";
СоответствиеВидовСравнения.Добавить().Имя = "Равно";
СоответствиеВидовСравнения.Добавить().Имя = "Содержит";
Для Каждого СтрокаСоответствия Из СоответствиеВидовСравнения Цикл
СтрокаСоответствия.Построитель = ПредопределенноеЗначение("ВидСравнения." + СтрокаСоответствия.Имя);
СтрокаСоответствия.Компоновка = ПредопределенноеЗначение("ВидСравненияКомпоновкиДанных." + СтрокаСоответствия.Имя);
КонецЦикла;
мТаблицаЗамеров = Новый ТаблицаЗначений;
мТаблицаЗамеров.Колонки.Добавить("_0");
мТаблицаЗамеров.Колонки.Добавить("Ключ");
мТаблицаЗамеров.Колонки.Добавить("ДатаНачала");
мТаблицаЗамеров.Колонки.Добавить("ОтладкаРазрешена", Новый ОписаниеТипов("Булево"));
мТаблицаЗамеров.Колонки.Добавить("КоличествоПроходов", Новый ОписаниеТипов("Число"));
мИндикаторы = Новый ТаблицаЗначений;
мИндикаторы.Колонки.Добавить("КоличествоПроходов", Новый ОписаниеТипов("Число"));
мИндикаторы.Колонки.Добавить("ПредставлениеПроцесса", Новый ОписаниеТипов("Строка"));
мИндикаторы.Колонки.Добавить("ЛиВыводитьВремя", Новый ОписаниеТипов("Булево"));
мИндикаторы.Колонки.Добавить("РазрешитьПрерывание", Новый ОписаниеТипов("Булево"));
мИндикаторы.Колонки.Добавить("Автозавершение", Новый ОписаниеТипов("Булево"));
мИндикаторы.Колонки.Добавить("ДатаНачалаПроцесса", Новый ОписаниеТипов("Дата"));
мИндикаторы.Колонки.Добавить("МинимальныйПериодОбновления", Новый ОписаниеТипов("Число"));
мИндикаторы.Колонки.Добавить("СледующееОбновление", Новый ОписаниеТипов("Дата"));
мИндикаторы.Колонки.Добавить("Шаг", Новый ОписаниеТипов("Число"));
мИндикаторы.Колонки.Добавить("ТекстСостояния", Новый ОписаниеТипов("Строка"));
мИндикаторы.Колонки.Добавить("СледующийСчетчик", Новый ОписаниеТипов("Число"));
мИндикаторы.Колонки.Добавить("Счетчик", Новый ОписаниеТипов("Число"));
мИндикаторы.Колонки.Добавить("СледующаяПроверкаПрерывания", Новый ОписаниеТипов("Дата"));
//#КонецЕсли
мРегВыражение = ирОбщий.НовоеРегВыражениеЛкс();
мРегВыражение.IgnoreCase = Истина;
мРегВыражение.MultiLine = Ложь;
мРегВыражение2 = ирОбщий.НовоеРегВыражениеЛкс();
мРегВыражение2.IgnoreCase = Истина;
мРегВыражение2.MultiLine = Ложь;
мИменаОсновныхКлассовБиблиотекCOM = Новый Соответствие;
мОбразцыCOMОбъектов = Новый Соответствие;
БуферыСравнения = Новый Соответствие;
МодальныеГруппы = Новый СписокЗначений;
ОтмененныеФоновыеЗадания = Новый Массив;
мДобавленныеОбщиеМодули = Новый Структура;
мОписаниеТипаМДТабличнаяЧасть = ОписаниеТипаМетаОбъектов("ТабличнаяЧасть");
мОписаниеТипаМДВнешнийИсточникДанных = ОписаниеТипаМетаОбъектов("ВнешнийИсточникДанных");
мРежимПроверкиМодуля = Ложь;
мРежимПереходаКОпределению = Ложь;
мКэшСловГлобальногоКонтекста = Новый Соответствие;
ЛиРежимСовместимости83 = ирКэш.НомерРежимаСовместимостиЛкс() >= 803006;
мМодулиМетаданных = Новый Соответствие;
мПрямыеВызовыМетодов = Новый Соответствие;
мТипыВыражений = Новый Соответствие;
мЭтотОбъектГотов = Истина;