RDT1C/src/DataProcessors/ирПлатформа/Ext/ObjectModule.bsl
Администратор a547e1b487 .
2024-01-16 00:22:41 +03:00

11526 lines
838 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

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

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

//ирПортативный Перем ирПортативный Экспорт;
//ирПортативный Перем ирОбщий Экспорт;
//ирПортативный Перем ирСервер Экспорт;
//ирПортативный Перем ирКэш Экспорт;
//ирПортативный Перем ирКлиент Экспорт;
Перем ЧистыйКонтекст;
Перем ФиксироватьВнешниеИсключенияАлгоритмов Экспорт;
Перем ВерсияПлатформы Экспорт;
Перем ЭтоФайловаяБаза Экспорт;
Перем мМетаданные Экспорт;
Перем мПустойМодуль;
Перем ЭтоИнтеграция Экспорт;
Перем СоответствиеВидовСравнения Экспорт;
Перем МаркерНачалаАлгоритма Экспорт;
Перем МаркерКонцаАлгоритма Экспорт;
Перем МакетыКомпонент Экспорт;
Перем мКэшПустыхЗначений Экспорт;
Перем ВложенностьИндикации Экспорт;
Перем КэшОбъектов Экспорт;
Перем ВремяОбъект Экспорт;
Перем СловарьПеревода Экспорт;
Перем АрхитектураПроцессора Экспорт;
Перем ВыполнятьАлгоритмыЧерезВнешниеОбработки Экспорт;
Перем ВнешняяОбработкаСервисы Экспорт;
Перем ФайловыйКэшАлгоритмовДопускаетРедактирование Экспорт;
Перем ФормаПустышка Экспорт;
Перем КешАлгоритмов;
Перем СубПутьКФайлуПотокаМодуляВнешнейОбработки;
Перем СубПутьКФайлуПотокаМакетаВнешнейОбработки;
Перем СубПутьКФайлуПотокаЗаголовкаВнешнейОбработки;
Перем СубПутьККонтрольномуФайлуВнешнейОбработки;
Перем ПутьККаталогуСлужебныхВременныхФайлов;
Перем мЕстьАдминистративныеПраваУУчетнойЗаписиОС;
Перем СообщениеОНеобходимостиОбновитьКэшМодулейВыводилось;
Перем ПапкаКешаВнешнихОбработокАлгоритмов Экспорт;
Перем ПапкаВнешнихКомпонент Экспорт;
Перем ПапкаКэшаМодулей Экспорт;
Перем ПапкаКэшаРолей Экспорт;
Перем КаталогФайловогоКэша Экспорт;
Перем СтруктураПодкаталоговФайловогоКэша Экспорт;
Перем ИмяФайлаПакера Экспорт;
Перем ШаблоныВнешнейОбработки;
Перем ШаблоныВнешнейОбработкиСМакетом;
Перем ФайлРегистратораКомпонентCU;
Перем ФайлРегистратораNetКомпонент;
Перем МассивСравненияТекстов Экспорт;
Перем мВопросОтключенияПроверкиМодальностиЗадавался Экспорт;
Перем мПроверкаСовместимостиКонфигурацииВыполнялась Экспорт;
Перем мПроверкаЗащитыОтОпасныхДействийВыполнялась Экспорт;
Перем мПроверкаСоединенияADOЭтойБДВыполнялась Экспорт;
Перем мПерехватКлавиатуры;
Перем АсинхронностьЗапрещена Экспорт;
Перем РежимОтладки Экспорт; // Отключает использование однострочных сверток кода. Снижает скорость, но облегчает отладку.
Перем НастройкиКомпьютера Экспорт;
Перем мДиалектыSQL Экспорт; // Используется в Обработка.ирКлсПолеТекстаПрограммы
Перем WScriptShell;
Перем RegExp Экспорт;
Перем RegExp2 Экспорт;
Перем шЛюбой Экспорт;
Перем шБуква Экспорт;
Перем шБукваЦифра Экспорт;
Перем шИмя Экспорт;
Перем шЧисло Экспорт;
Перем шИндекс Экспорт;
Перем шСкобки Экспорт;
Перем шGUID Экспорт;
Перем шКомментарий Экспорт;
Перем шРазделитель Экспорт;
Перем шПустоеНачалоСтроки Экспорт;
Перем шСтрокаПрограммы Экспорт;
Перем шСтрокаПростая Экспорт;
Перем шСтрокаЗапроса Экспорт;
Перем шИмяВременнойТаблицы Экспорт;
Перем шГиперСсылка Экспорт;
Перем МаркерОбъектаМетаданных;
Перем МаркерКоллекцииОбъектовМетаданных;
//#Если Клиент Или ВнешнееСоединение Тогда
Перем ИдентификаторПроцессаОС Экспорт;
Перем VBScript Экспорт;
Перем JavaScript Экспорт;
Перем ДеревоТипов Экспорт;
Перем ТаблицаОбщихТипов Экспорт;
Перем ТаблицаИменЭлементовКоллекций Экспорт;
Перем ТаблицаРасширенийТипов Экспорт;
Перем ТаблицаШаблоновКонтекстов Экспорт;
Перем ТаблицаТиповМетаОбъектов Экспорт;
Перем ТаблицаПараметров Экспорт;
Перем СлужебноеПолеТекста Экспорт;
Перем СлужебноеПолеТекста2 Экспорт;
//Перем СлужебноеПолеHtmlДокумента Экспорт;
Перем МассивОбычныхЭлементовУправления Экспорт;
Перем МассивУправляемыхЭлементовУправления Экспорт;
Перем мМассивТиповЭлементовУправления Экспорт;
Перем ТаблицаСтатистикиВыбора Экспорт;
Перем мМассивТиповСМетаданными Экспорт;
Перем мТаблицаТипов; // Образец таблицы структур типа
Перем мТаблицаСоответствияВидов;
Перем мТаблицаЗамеров Экспорт;
Перем мТаблицаИндикаторов Экспорт;
Перем мИменаОсновныхКлассовБиблиотекCOM; // Кэш имен классов, например Exel - Application
Перем мОбразцыCOMОбъектов; // Для вычисления свойств
Перем мADOUtils; // GameWithFire.ADOUtils
Перем мКэшСловГлобальногоКонтекста;
Перем мКолонкиБД Экспорт;
Перем мСтруктураХраненияБДСРазмерами Экспорт;
Перем мТаблицаРедактируемыхТипов;
Перем мОписаниеТипаМДТабличнаяЧасть;
Перем мОписаниеТипаМДВнешнийИсточникДанных;
Перем мДеревоОбъектовМД;
Перем мТаблицаВсехТаблицБД;
Перем мПоляТекстаПрограммы;
Перем мШаблоныДляАнализаВстроенногоЯзыка;
Перем мСлужебнаяФорма;
Перем COMНавигатор Экспорт;
Перем ТаблицаШаблоновТекста Экспорт;
Перем мКартинкиТипов;
Перем мМассивИсключенийИменКоллекций;
Перем мПассивныеФормы;
Перем мИменаТиповМетаданныхСМенеджерами;
Перем мКэшРазбораВыражений Экспорт;
Перем ФайлЗапаковщика1С Экспорт;
Перем ФайлБиблиотекиЗапаковщика;
Перем ФайлОткрывателя1С Экспорт;
Перем ФайлФорматераЗапросовБД Экспорт;
Перем ФайлРаспаковщикаZIP Экспорт;
Перем СинтаксПомощник;
Перем Парсеры Экспорт;
Перем БуферыСравнения Экспорт;
Перем ПараметрыОбработчикаОжидания Экспорт;
Перем БазовыйФайлРедактораJSON;
Перем БазовыйФайлРедактораКода;
Перем мМаркерИмениЗапросаПакета Экспорт;
Перем мМаркерИмениЧастиОбъединения Экспорт;
Перем ПоказыватьВнешниеИсключенияПриВыполненииАлгоритмов Экспорт;
Перем СинтаксическийКонтрольПередЗаписью Экспорт;
Перем ОтложенноеОткрытиеИсточникаОшибки Экспорт;
Перем АвторегистрацияComКомпонент Экспорт;
Перем ЛиКомпонентаFormsTextBoxДоступна;
Перем МодальныеГруппы Экспорт;
Перем мМодулиМетаданных;
Перем мВызовыВсехСловПоМодулям;
Перем ОткрытыеФормыПодсистемы Экспорт;
Перем ОтслеживаемыеФормы Экспорт;
Перем ПерехватКлавиатурногоВводаВОбычномПриложении Экспорт;
Перем ОтмененныеФоновыеЗадания Экспорт;
Перем ВнутреннийБуферОбмена Экспорт;
Перем ПроверочноеСоединениеЭтойСУБД Экспорт;
Перем ИспользоватьЭмуляциюНажатияКлавиш Экспорт;
Перем ВыделениеРезультатовПоиска Экспорт;
Перем НеИспользоватьУправляемыеФормыИнструментов Экспорт;
Перем мСвязанныйКонфигуратор Экспорт;
Перем мДатаОбновленияКэшаМодулей;
Перем мДобавленныеОбщиеМодули;
// Инициализирует, если необходимо, большие таблицы платформы.
// К ним относятся таблицы методов и свойств.
//
// Параметры:
// Нет.
//
Процедура ИнициацияОписанияМетодовИСвойств() Экспорт
Если ТаблицаКонтекстов.Количество() > 0 Тогда
Возврат;
КонецЕсли;
#Если Клиент Тогда
Состояние("Инициализация таблицы методов и свойств...");
#КонецЕсли
МассивТаблиц = ЗначениеИзСтрокиВнутр(ПолучитьМакет("ТаблицаМетодовИСвойств").ПолучитьТекст());
ТаблицаКонтекстов = МассивТаблиц.ТаблицаКонтекстов;
ТаблицаКонтекстов.Колонки.Добавить("Описание");
ТаблицаКонтекстов.Индексы.Добавить("ТипКонтекста");
ТаблицаКонтекстов.Индексы.Добавить("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка");
ТаблицаКонтекстов.Индексы.Добавить("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка, ТипСлова");
ТаблицаКонтекстов.Индексы.Добавить("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка, НСлово");
ТаблицаКонтекстов.Индексы.Добавить("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка, НСлово, ТипСлова");
ТаблицаШаблоновКонтекстов = МассивТаблиц.ТаблицаШаблоновКонтекстов;
ТаблицаШаблоновКонтекстов.Колонки.Добавить("Описание"); // Нужно для вирт. таблицы КритерийОтбора.<Имя критерия отбора>()
ТаблицаШаблоновКонтекстов.Индексы.Добавить("ТипКонтекста");
ТаблицаШаблоновКонтекстов.Индексы.Добавить("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка");
ТаблицаШаблоновКонтекстов.Индексы.Добавить("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка, ТипСлова");
ТаблицаПараметров = МассивТаблиц.ТаблицаПараметров; // Теперь на старте пустая
ТаблицаПараметров.Колонки.Добавить("Описание");
ТаблицаПараметров.Индексы.Добавить("ТипКонтекста, ЯзыкПрограммы, Слово");
//ТаблицаПараметров.Индексы.Добавить("ТипКонтекста, ЯзыкПрограммы, Слово, Номер");
#Если Клиент Тогда
Состояние("");
#КонецЕсли
КонецПроцедуры
// Инициализирует, если необходимо, малые таблицы платформы.
// К ним относятся таблицы типов и коллекций.
//
// Параметры:
// Нет.
//
Процедура ИнициализацияОписанияОбщихТипов() Экспорт
Если ТипЗнч(ТаблицаОбщихТипов) = Тип("ТаблицаЗначений") Тогда
Возврат;
КонецЕсли;
МассивТаблиц = ЗначениеИзСтрокиВнутр(ПолучитьМакет("ТаблицаИменЭлементовКоллекций").ПолучитьТекст());
ТаблицаИменЭлементовКоллекций = МассивТаблиц.ТаблицаИменЭлементовКоллекций;
#Если Сервер И Не Сервер Тогда
ТаблицаИменЭлементовКоллекций = НОвый ТаблицаЗначений;
#КонецЕсли
ТаблицаИменЭлементовКоллекций.Индексы.Добавить("ИмяКоллекции");
ТаблицаИменЭлементовКоллекций.Индексы.Добавить("ИмяЭлементаКоллекции");
ТаблицаИменЭлементовКоллекций.Индексы.Добавить("ИмяОбщегоТипа, ИмяЭлементаКоллекции");
ТаблицаРасширенийТипов = МассивТаблиц.ТаблицаРасширений;
#Если Сервер И Не Сервер Тогда
ТаблицаРасширенийТипов = НОвый ТаблицаЗначений;
#КонецЕсли
ТаблицаРасширенийТипов.Индексы.Добавить("Расширение");
МассивТаблиц = ЗначениеИзСтрокиВнутр(ПолучитьМакет("ТаблицаОбщихТипов").ПолучитьТекст());
ТаблицаОбщихТипов = МассивТаблиц.ТаблицаОбщихТипов;
#Если Сервер И Не Сервер Тогда
ТаблицаОбщихТипов = НОвый ТаблицаЗначений;
#КонецЕсли
ТаблицаОбщихТипов.Индексы.Добавить("Слово, ЯзыкПрограммы");
ТаблицаОбщихТипов.Индексы.Добавить("Слово, ТипТипа");
//ТаблицаОбщихТипов.Индексы.Добавить("Слово, ЯзыкПрограммы, ТипТипа");
ТаблицаОбщихТипов.Индексы.Добавить("НСлово, ЯзыкПрограммы, ЕстьКонструктор");
ТаблицаОбщихТипов.Индексы.Добавить("Представление, ТипТипа");
ТаблицаОбщихТипов.Индексы.Добавить("ИД");
КонецПроцедуры
// Добавляет дополнительные Свойства для типов контекстов платформы.
Процедура ДобавитьСловоВОписаниеТипаКонтекста(ТипКонтекста, Слово, ТипСлова, ТипЗначения) Экспорт
ИнициацияОписанияМетодовИСвойств();
НоваяСтрока = ТаблицаКонтекстов.Добавить();
НоваяСтрока.ТипКонтекста = ТипКонтекста;
НоваяСтрока.Слово = Слово;
НоваяСтрока.НСлово = НРег(Слово);
НоваяСтрока.ТипСлова = ТипСлова;
НоваяСтрока.ТипЗначения = ТипЗначения;
КонецПроцедуры
// Добавляет в список значений коллекцию объектов метаданных.
//
// Параметры:
// пСписокМетаданных - СписокЗначений - куда добавляем объекты;
// пИмяМетаданных - Строка - имя коллекции объектов метаданных или имя корневого типа;
// *ЛиПолноеИмя - Булево, *Истина - добавлять полные имена, иначе краткие;
// *ЛиДобавлятьКартинки - Булево, *Истина - добавлять картинки;
// *ОтборПоПраву - Строка, *Неопределено - проверять перед добавлением право текущего пользователя.
//
Процедура ДобавитьВСписокКоллекциюМетаданных(пСписокМетаданных, пИмяМетаданных, ЛиПолноеИмя = Истина, ЛиДобавлятьКартинки = Истина, ОтборПоПраву = Неопределено) Экспорт
Картинка = Неопределено;
СтрокаКорневогоТипа = ОписаниеТипаМетаОбъектов(пИмяМетаданных, , 0);
Если СтрокаКорневогоТипа <> Неопределено Тогда
ИмяКоллекцииМетаданных = СтрокаКорневогоТипа.Множественное;
#Если Клиент Тогда
Если ЛиДобавлятьКартинки Тогда
КорневойТип = пИмяМетаданных;
Картинка = ирКлиент.КартинкаКорневогоТипаМДЛкс(КорневойТип);
КонецЕсли;
#КонецЕсли
Иначе
ИмяКоллекцииМетаданных = пИмяМетаданных;
#Если Клиент Тогда
Если ЛиДобавлятьКартинки Тогда
КорневойТип = ОписаниеТипаМетаОбъектов(, пИмяМетаданных, 0).Единственное;
Картинка = ирКлиент.КартинкаКорневогоТипаМДЛкс(КорневойТип);
КонецЕсли;
#КонецЕсли
КонецЕсли;
Для Каждого Объект ИЗ мМетаданные[ИмяКоллекцииМетаданных] Цикл
Если Истина
И ОтборПоПраву <> Неопределено
И Не ПравоДоступа(ОтборПоПраву, Объект)
Тогда
Продолжить;
КонецЕсли;
Если ЛиПолноеИмя Тогда
ИмяМетаОбъекта = Объект.ПолноеИмя();
Иначе
ИмяМетаОбъекта = Объект.Имя;
КонецЕсли;
пСписокМетаданных.Добавить(ИмяМетаОбъекта, Объект.Представление(), , Картинка);
КонецЦикла;
КонецПроцедуры
// Получает список ключевых слов языка запросов.
//
// Параметры:
// *Расширение - Тип, *Неопределено - для определения расширения языка запросов.
//
// Возвращаемое значение:
// СписокЗначений - где значение содержит слово.
//
Функция КлючевыеСловаЯзыкаЗапросов(РежимКомпоновкиДанных = Ложь, Русские = Истина, Английские = Ложь) Экспорт
Список = Новый СписокЗначений;
Если Русские Тогда
Список.Добавить("АВТОУПОРЯДОЧИВАНИЕ");
Список.Добавить("ВНУТРЕННЕЕ");
Список.Добавить("ВОЗР");
Список.Добавить("ВСЕ");
Список.Добавить("ВЫБРАТЬ");
Список.Добавить("ГДЕ");
Список.Добавить("ДЛЯ");
Список.Добавить("ИЗ");
Список.Добавить("ИЗМЕНЕНИЯ");
Список.Добавить("ИМЕЮЩИЕ");
Список.Добавить("ИНДЕКСИРОВАТЬ");
Список.Добавить("ИТОГИ");
Список.Добавить("КАК");
Список.Добавить("ЛЕВОЕ");
Список.Добавить("ОБЩИЕ");
Список.Добавить("ОБЪЕДИНИТЬ");
Список.Добавить("ПЕРВЫЕ");
Список.Добавить("ПО");
Список.Добавить("ПОЛНОЕ");
Список.Добавить("ПОМЕСТИТЬ");
Список.Добавить("ПРАВОЕ");
Список.Добавить("РАЗЛИЧНЫЕ");
Список.Добавить("РАЗРЕШЕННЫЕ");
Список.Добавить("СГРУППИРОВАТЬ");
Список.Добавить("СОЕДИНЕНИЕ");
Список.Добавить("УБЫВ");
Список.Добавить("УНИЧТОЖИТЬ");
Список.Добавить("УПОРЯДОЧИТЬ");
Список.Добавить("НЕ");
Список.Добавить("И");
Список.Добавить("ИЛИ");
Список.Добавить("ВЫБОР");
Список.Добавить("КОГДА");
Список.Добавить("ТОГДА");
Список.Добавить("ИНАЧЕ");
Список.Добавить("КОНЕЦ");
Список.Добавить("ЕСТЬ");
Список.Добавить("NULL");
Список.Добавить("МЕЖДУ");
Список.Добавить("В");
Список.Добавить("ПОДОБНО");
Список.Добавить("СПЕЦСИМВОЛ");
Список.Добавить("ИЕРАРХИЯ");
Список.Добавить("ИЕРАРХИИ");
Список.Добавить("ССЫЛКА");
Если РежимКомпоновкиДанных Тогда
// Видимо это устаревшие слова
Список.Добавить("ЗНАЧЕНИЕ");
Список.Добавить("ЗНАЧЕНИЯ");
Список.Добавить("ИДЕНТИФИКАТОР");
Список.Добавить("ИМЯ");
Список.Добавить("ОБЪЕКТ");
Список.Добавить("СПИСОК");
Список.Добавить("ТИПЗНАЧЕНИЯ");
Список.Добавить("ХАРАКТЕРИСТИКА");
// Это новые слова
Список.Добавить("ЗНАЧЕНИЯХАРАКТЕРИСТИК");
Список.Добавить("ПОЛЕИМЕНИ");
Список.Добавить("ПОЛЕКЛЮЧА");
Список.Добавить("ПОЛЕЗНАЧЕНИЯ");
Список.Добавить("ПОЛЕВИДА");
Список.Добавить("ПОЛЕТИПАЗНАЧЕНИЯ");
Список.Добавить("ПОЛЕОБЪЕКТА");
Список.Добавить("ВИДЫХАРАКТЕРИСТИК");
КонецЕсли;
КонецЕсли;
Если Английские Тогда
Список.Добавить("AUTOORDER");
Список.Добавить("INNER");
Список.Добавить("ASC");
Список.Добавить("ALL");
Список.Добавить("SELECT");
Список.Добавить("WHERE");
Список.Добавить("FOR");
Список.Добавить("FROM");
Список.Добавить("UPDATE");
Список.Добавить("HAVING");
Список.Добавить("INDEX");
Список.Добавить("TOTALS");
Список.Добавить("AS");
Список.Добавить("LEFT");
//Список.Добавить("ОБЩИЕ"); // ЗАБЫЛ перевод
Список.Добавить("UNION");
Список.Добавить("FIRST");
Список.Добавить("BY");
Список.Добавить("ON");
Список.Добавить("FULL");
Список.Добавить("INTO");
Список.Добавить("RIGHT");
Список.Добавить("DISTINCT");
Список.Добавить("ALLOWED");
Список.Добавить("GROUP");
Список.Добавить("JOIN");
Список.Добавить("DESC");
Список.Добавить("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");
// // Это новые слова
// Список.Добавить("ЗНАЧЕНИЯХАРАКТЕРИСТИК");
// Список.Добавить("ПОЛЕИМЕНИ");
// Список.Добавить("ПОЛЕКЛЮЧА");
// Список.Добавить("ПОЛЕЗНАЧЕНИЯ");
// Список.Добавить("ПОЛЕВИДА");
// Список.Добавить("ПОЛЕТИПАЗНАЧЕНИЯ");
// Список.Добавить("ПОЛЕОБЪЕКТА");
// Список.Добавить("ВИДЫХАРАКТЕРИСТИК");
//КонецЕсли;
КонецЕсли;
Возврат Список;
КонецФункции // ПолучитьСписокСловЯзыкаЗапросов()
// Получает список ключевых встроенного языка.
//
// Параметры:
// Нет.
//
// Возвращаемое значение:
// СписокЗначений - где значение содержит слово.
//
Функция КлючевыеСловаВстроенногоЯзыка() Экспорт
Список = Новый СписокЗначений;
Список.Добавить("Знач");
Список.Добавить("Val");
Список.Добавить("Возврат");
Список.Добавить("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");
Список.Добавить("Процедура");
Список.Добавить("Procedure");
Список.Добавить("Тогда");
Список.Добавить("Then");
Список.Добавить("Функция");
Список.Добавить("Function");
Список.Добавить("Цикл");
Список.Добавить("Do");
Список.Добавить("Экспорт");
Список.Добавить("Export");
// 8.3
Список.Добавить("Ждать");
Список.Добавить("Await");
Список.Добавить("Асинх");
Список.Добавить("Async");
//// Инструкции препроцессора. Добавлено 28.01.2012
//// Здесь им не место, т.к. по этому списку проверяется валидность имен переменных
//Список.Добавить("Клиент");
//Список.Добавить("Сервер");
//Список.Добавить("ВнешнееСоединение");
//Список.Добавить("ТолстыйКлиентУправляемоеПриложение");
//Список.Добавить("ТолстыйКлиентОбычноеПриложение");
//Список.Добавить("ТонкийКлиент");
//Список.Добавить("ВебКлиент");
Возврат Список;
КонецФункции
Функция ЛитералыЗначенияВсехЯзыков1С() Экспорт
Список = Новый СписокЗначений;
Список.Добавить("Истина", "Истина");
Список.Добавить("True", "Истина");
Список.Добавить("Ложь", "Ложь");
Список.Добавить("False", "Ложь");
Список.Добавить("Неопределено", "Неопределено");
Список.Добавить("Undefined", "Неопределено");
Список.Добавить("Null", "Null");
Возврат Список;
КонецФункции
// Размаскирует обращения к временным таблицам в тексте запроса.
//
// Параметры:
// ТекстЗапроса - Строка;
// МассивВременныхТаблиц - Массив - элементами являются имена временных таблиц, замаскированных ранее.
//
// Возвращаемое значение:
// Строка - новые текст запроса.
//
Функция РазмаскироватьВременныеТаблицы(ТекстЗапроса, МассивВременныхТаблиц, выхВсеРазмаскировано = Ложь) Экспорт
Если МассивВременныхТаблиц.Количество() = 0 Тогда
Возврат ТекстЗапроса;
КонецЕсли;
// Допустимы 2 уровня скобок внутри имитатора временной таблицы.
RegExp.Global = Истина;
RegExp.MultiLine = Ложь;
RegExp.IgnoreCase = Истина;
ИмяВременнойТаблицы = "";
Для Каждого ПодмененнаяВременнаяТаблица Из МассивВременныхТаблиц Цикл
ИмяВременнойТаблицы = ИмяВременнойТаблицы + "|" + ПодмененнаяВременнаяТаблица;
КонецЦикла;
ИмяВременнойТаблицы = Сред(ИмяВременнойТаблицы, 2);
НовыйТекстЗапроса = ТекстЗапроса;
// Сначала делаем красивые замены - подзапрос на имя временной таблицы
//RegExp.Pattern = "\(ВЫБРАТЬ(?:" + шСкобки + "|[^$\(\)])*?""ВременнаяТаблица"" = ""(" + ИмяВременнойТаблицы + ")""\)";
RegExp.Pattern = "\(ВЫБРАТЬ(?:[^\(\)]*(?:" + шСкобки + "[^\(\)]*)*)""ВременнаяТаблица"" = ""("
+ ИмяВременнойТаблицы + ")""\s*\)";
НовыйТекстЗапроса = RegExp.Заменить(НовыйТекстЗапроса, "$2");
выхВсеРазмаскировано = Найти(НовыйТекстЗапроса, """ВременнаяТаблица"" = """) = 0;
Если Не выхВсеРазмаскировано Тогда
// А теперь делаем некрасивые замены - оставляем подзапросы но заменяем в них имена полей и временной таблицы
RegExp.Pattern = "\(ВЫБРАТЬ(?:[^\(\)]*(?:" + шСкобки + "[^\(\)]*)*)""ВременнаяТаблица"" = ""("
+ ИмяВременнойТаблицы + ")""";
НовыйТекстЗапроса = RegExp.Заменить(НовыйТекстЗапроса, "(ВЫБРАТЬ Т.* ИЗ $2 КАК Т ГДЕ ИСТИНА");
// и0ие90цаун787
RegExp.Pattern = "ВЫБОР\s+КОГДА\s+""!ИмяПоля!""\s+=\s+""(.+?)""\s+ТОГДА\s+.+?\n\s*(?:КОГДА\s+ЛОЖЬ\s+ТОГДА\s+.+?\n)*\s*КОНЕЦ";
НовыйТекстЗапроса = RegExp.Заменить(НовыйТекстЗапроса, "Т.$1");
выхВсеРазмаскировано = Найти(НовыйТекстЗапроса, """ВременнаяТаблица"" = """) = 0;
КонецЕсли;
Если Не выхВсеРазмаскировано Тогда
ВызватьИсключение "Не удалось размаскировать временные таблицы в тексте запроса. Возможно на них был наложен несовместимый с маскировкой отбор компоновки.";
КонецЕсли;
Возврат НовыйТекстЗапроса;
КонецФункции // РазмаскироватьВременныеТаблицы()
// Получает текст запроса, где каждая временная таблица заменена своим имитатором.
//
// Параметры:
// ОбъектЗапроса - Запрос -
// *ТекстЗапроса - Строка, *Неопределено -
// *МассивВременныхТаблиц - Массив, *Неопределено - все подменяемые таблицы заносятся сюда.
//
// Возвращаемое значение:
// Строка - новый текст запроса.
//
Функция ЗамаскироватьВременныеТаблицы(ОбъектЗапроса, Знач ТекстЗапроса = Неопределено, МассивВременныхТаблиц = Неопределено) Экспорт
Если ТекстЗапроса = Неопределено Тогда
ТекстЗапроса = ОбъектЗапроса.Текст;
КонецЕсли;
ВременныйЗапрос = Новый Запрос;
ВременныйЗапрос.МенеджерВременныхТаблиц = ОбъектЗапроса.МенеджерВременныхТаблиц;
ПроверочныйЗапрос = Новый ПостроительЗапроса;
//// Исключительная ситуация должна быть обработана сверху
//ПараметрыЗапроса = ВременныйЗапрос.НайтиПараметры();
Если ТипЗнч(МассивВременныхТаблиц) <> Тип("Массив") Тогда
МассивВременныхТаблиц = Новый Массив;
КонецЕсли;
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.УстановитьТекст(ТекстЗапроса);
Пока Истина Цикл
Попытка
ПроверочныйЗапрос.Текст = ТекстЗапроса;
//ПроверочныйЗапрос.НайтиПараметры();
Прервать;
Исключение
ИнформацияОбОшибке = ИнформацияОбОшибке();
//ИмяВременнойТаблицы = ирОбщий.ТекстМеждуМаркерамиЛкс(ИнформацияОбОшибке.Причина.Описание, """", """");
ИмяВременнойТаблицы = ирОбщий.ТекстМеждуМаркерамиЛкс(ИнформацияОбОшибке.Причина.Описание, "Таблица не найдена """, """", Ложь);
Если ЗначениеЗаполнено(ИмяВременнойТаблицы) Тогда
ВременныйЗапрос.Текст = "ВЫБРАТЬ * ИЗ " + ИмяВременнойТаблицы;
Попытка
КолонкиВременнойТаблицы = ВременныйЗапрос.Выполнить().Колонки;
Исключение
Прервать;
КонецПопытки;
КонецЕсли;
// В 8.2.15 такой прием лишен смысла, т.к. движок запросов потом не сможет обработать обращения к дочерним полям
//Если Не ЗначениеЗаполнено(ИмяВременнойТаблицы) Тогда
// ИмяВременнойТаблицы = ирОбщий.ТекстМеждуМаркерамиЛкс(ИнформацияОбОшибке.Причина.Описание, "Неверные параметры """, """", Ложь);
// Если ЗначениеЗаполнено(ИмяВременнойТаблицы) Тогда
// Попытка
// КолонкиВременнойТаблицы = ОбъектЗапроса.Параметры[ИмяВременнойТаблицы].Колонки;
// Исключение
// Попытка
// КолонкиВременнойТаблицы = ВременныйЗапрос.Выполнить().Колонки;
// Исключение
// Прервать;
// КонецПопытки;
// КонецПопытки;
// ИмяВременнойТаблицы = "&" + ИмяВременнойТаблицы;
// КонецЕсли;
//КонецЕсли;
Если Не ЗначениеЗаполнено(ИмяВременнойТаблицы) Тогда
Прервать;
КонецЕсли;
ИмитаторВременнойТаблицы = ирОбщий.ЗапросИмитаторКоллекцииПолейЛкс(КолонкиВременнойТаблицы)
+ " ГДЕ ""ВременнаяТаблица"" = """ + ИмяВременнойТаблицы + """";
КоординатыОбращения = ирОбщий.ТекстМеждуМаркерамиЛкс(ИнформацияОбОшибке.Причина.Описание, "{(", ")}");
НомерСтроки = Число(ирОбщий.ПервыйФрагментЛкс(КоординатыОбращения, ", "));
НомерКолонки = Число(ирОбщий.ПоследнийФрагментЛкс(КоординатыОбращения, ","));
СтрокаЗапроса = ТекстовыйДокумент.ПолучитьСтроку(НомерСтроки);
ТекстПосле = Сред(СтрокаЗапроса, НомерКолонки + СтрДлина(ИмяВременнойТаблицы));
СтрокаКАК = "КАК";
Если Не ирОбщий.СтрокиРавныЛкс(Лев(СокрЛ(ТекстПосле), СтрДлина(СтрокаКАК)), СтрокаКАК) Тогда
ТекстПосле = " КАК " + ИмяВременнойТаблицы + " " + ТекстПосле;
КонецЕсли;
НоваяСтрока = Лев(СтрокаЗапроса, НомерКолонки - 1) + "(" + ИмитаторВременнойТаблицы + ")" + ТекстПосле;
ТекстовыйДокумент.ЗаменитьСтроку(НомерСтроки, НоваяСтрока);
ТекстЗапроса = ТекстовыйДокумент.ПолучитьТекст();
МассивВременныхТаблиц.Добавить(ИмяВременнойТаблицы);
КонецПопытки;
КонецЦикла;
Возврат ТекстЗапроса;
КонецФункции
// Результат - Массив
Функция НайтиВозможныеИменаВременныхТаблиц(ТекстЗапроса, ЛиДиалект1С = Истина) Экспорт
Имена = Новый Соответствие;
RegExp.Global = Истина;
RegExp.pattern = "(?:ИЗ|FROM|СОЕДИНЕНИЕ|JOIN|УНИЧТОЖИТЬ|DROP|,)\s+(" + шИмяВременнойТаблицы + ")(?:\s|$|[^\(\._\d" + шБуква + "])";
РезультатПоиска = RegExp.НайтиВхождения(ТекстЗапроса);
Для Каждого Вхождение Из РезультатПоиска Цикл
Имена.Вставить(Нрег(Вхождение.SubMatches(0)), Вхождение.SubMatches(0));
КонецЦикла;
Результат = Новый Массив();
Для Каждого КлючИЗначение Из Имена Цикл
Если Истина
И ЛиДиалект1С
И (Ложь
Или ирОбщий.СтрокиРавныЛкс(КлючИЗначение.Значение, "Константы")
Или Найти(КлючИЗначение.Значение, ".") > 0)
Тогда
Продолжить;
КонецЕсли;
Результат.Добавить(КлючИЗначение.Значение);
КонецЦикла;
Возврат Результат;
КонецФункции
Функция РазбитьГрубоТекстПакетногоЗапросаНаЗапросы(Знач ТекстПакета, Знач ПозицияКурсора = Неопределено, выхПозиции0 = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
RegExp = Обработки.ирОболочкаРегВыражение.Создать();
#КонецЕсли
МассивТекстовЗапросов = Новый Массив;
Если Не ирКэш.ДоступныРегВыраженияЛкс() Тогда
Если ирКэш.ДоступноСхемаЗапросаЛкс() Тогда
Схема = Вычислить("Новый СхемаЗапроса");
#Если Сервер И Не Сервер Тогда
Схема = Новый СхемаЗапроса;
#КонецЕсли
Попытка
Схема.УстановитьТекстЗапроса(ТекстПакета);
Исключение
ОписаниеОшибки = ОписаниеОшибки(); // Для отладки
Возврат МассивТекстовЗапросов;
КонецПопытки;
Для Каждого ЗапросПакета Из Схема.ПакетЗапросов Цикл
МассивТекстовЗапросов.Добавить(ЗапросПакета.ПолучитьТекстЗапроса());
КонецЦикла;
КонецЕсли;
Возврат МассивТекстовЗапросов;
КонецЕсли;
RegExp.Global = Истина;
RegExp.Multiline = Ложь;
//RegExp.Pattern = "(?:" + шСтрокаЗапроса + ")|" + шКомментарий + "|;(?:\s*\n)*|$";
RegExp.Pattern = "(?:" + шСтрокаЗапроса + ")|" + шКомментарий + "|;|$";
Результат = RegExp.НайтиВхождения(ТекстПакета,, Истина);
НачалоЗапроса = 1;
ОстальнойТекст = ТекстПакета;
ДлинаТекстаПакета = СтрДлина(ТекстПакета);
выхПозиции0 = Новый Массив;
выхПозиции0.Добавить(0);
Для Каждого Match Из Результат Цикл
ПозицияВхождения = Match.FirstIndex;
Если Истина
И Не ирОбщий.СтрНачинаетсяСЛкс(Match.Value, ";")
И ПозицияВхождения <> ДлинаТекстаПакета
Тогда
Продолжить;
КонецЕсли;
ИмяВременнойТаблицы = "";
ДлинаТекстаЗапроса = ПозицияВхождения + Match.Length;
ТекстЗапроса = Сред(ТекстПакета, НачалоЗапроса, ДлинаТекстаЗапроса - НачалоЗапроса + 1);
Если ПустаяСтрока(ТекстЗапроса) Тогда
Продолжить;
КонецЕсли;
//Если ТекстЗапроса = ";" Тогда
// Продолжить;
//КонецЕсли;
ОстальнойТекст = Сред(ОстальнойТекст, ДлинаТекстаЗапроса + 1);
НачалоЗапроса = НачалоЗапроса + СтрДлина(ТекстЗапроса);
МассивТекстовЗапросов.Добавить(ТекстЗапроса);
выхПозиции0.Добавить(ПозицияВхождения + 1);
Если ПозицияКурсора <> Неопределено И ПозицияКурсора < ПозицияВхождения Тогда
Прервать;
КонецЕсли;
КонецЦикла;
Если МассивТекстовЗапросов.Количество() = 0 Тогда
МассивТекстовЗапросов.Добавить(ТекстПакета);
КонецЕсли;
Возврат МассивТекстовЗапросов;
КонецФункции
// Структура результата пакетного запроса на основе разметки в комментариях.
//
// Параметры:
// ТекстПакетаИлиМассивТекстовЗапросов - -
// ПрефиксКомментария - -
//
// Возвращаемое значение:
// -
//
Функция СтруктураРезультатаПакетногоЗапроса(Знач ТекстПакетаИлиМассивТекстовЗапросов, Знач ПрефиксКомментария = "//") Экспорт
Результат = Новый Структура;
Если Не ирКэш.ДоступныРегВыраженияЛкс() Тогда
Возврат Результат;
КонецЕсли;
Если ТипЗнч(ТекстПакетаИлиМассивТекстовЗапросов) = Тип("Строка") Тогда
МассивТекстовЗапросов = РазбитьГрубоТекстПакетногоЗапросаНаЗапросы(ТекстПакетаИлиМассивТекстовЗапросов);
Иначе
МассивТекстовЗапросов = ТекстПакетаИлиМассивТекстовЗапросов;
КонецЕсли;
RegExp.Global = Ложь;
RegExp.Multiline = Ложь;
RegExp.Pattern = ирОбщий.ПодготовитьТекстДляРегВыраженияЛкс(ПрефиксКомментария + мМаркерИмениЗапросаПакета) + "(" + шИмя + ")(?: |\n|\r)";
Индекс = -1;
Для Каждого ТекстЗапроса Из МассивТекстовЗапросов Цикл
Индекс = Индекс + 1;
Вхождения = RegExp.НайтиВхождения(ТекстЗапроса);
Если Вхождения.Количество() = 0 Тогда
Продолжить;
КонецЕсли;
ИмяЗапроса = Вхождения[0].SubMatches(0);
Если ирОбщий.ЛиИмяПеременнойЛкс(ИмяЗапроса) Тогда
Результат.Вставить(ИмяЗапроса, Индекс);
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
Функция ПреобразоватьЗапросВПодзапрос(Текст, ТекстВыбранныхПолей = "*", ПсевдонимВложенногоЗапроса = "ВложенныйЗапрос",
ОбрезатьНачинаяСУпорядочивания = Ложь, ЭтоРусскийЯзык = Истина, Знач Смещение = "") Экспорт
//ЭтоРусскийЯзык = ЭтоРусскийВариантТекстаЗапроса(ТекстЗапроса);
RegExp.Pattern = "^(?:\s|(" + шКомментарий + "))*((?:ВЫБРАТЬ|SELECT)\s+((?:РАЗРЕШЕННЫЕ|ALLOWED)\s+)?)((?:(?:.|\r|\n)*\s((?:УПОРЯДОЧИТЬ|ORDER)\s+(?:ПО|BY)\s+" + шИмя
+ "(?:\s*,\s*" + шИмя + ")*(?:\s+(?:АВТОУПОРЯДОЧИВАНИЕ|AUTOORDER))?|(?:АВТОУПОРЯДОЧИВАНИЕ|AUTOORDER)))*)((?:.|\r|\n)*)$";
РезультатПоиска = RegExp.НайтиВхождения(Текст)[0];
Если ЭтоРусскийЯзык Тогда
Результат = "ВЫБРАТЬ";
Иначе
Результат = "SELECT";
КонецЕсли;
Если Не ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(РезультатПоиска.SubMatches(2)) Тогда
Если ЭтоРусскийЯзык Тогда
Результат = Результат + " РАЗРЕШЕННЫЕ";
Иначе
Результат = Результат + " ALLOWED";
КонецЕсли;
КонецЕсли;
Смещение = Смещение + Символы.Таб;
Если ЭтоРусскийЯзык Тогда
Результат = Результат + " " + ТекстВыбранныхПолей + " ИЗ (";
Иначе
Результат = Результат + " " + ТекстВыбранныхПолей + " FROM (";
КонецЕсли;
НачальныйКомментарий = РезультатПоиска.SubMatches(0);
Если ЗначениеЗаполнено(НачальныйКомментарий) Тогда
Результат = Результат + Символы.ПС + Смещение + НачальныйКомментарий;
Иначе
Результат = Результат + Символы.ПС;
КонецЕсли;
Если ЭтоРусскийЯзык Тогда
Результат = Результат + Смещение + "ВЫБРАТЬ ";
Иначе
Результат = Результат + Смещение + "SELECT ";
КонецЕсли;
ТекстДоПоследнегоУПОРЯДОЧИТЬ = РезультатПоиска.SubMatches(3);
Если ЗначениеЗаполнено(ТекстДоПоследнегоУПОРЯДОЧИТЬ) Тогда
ТекстДоПоследнегоУПОРЯДОЧИТЬ = ирОбщий.СтрокаБезКонцаЛкс(ТекстДоПоследнегоУПОРЯДОЧИТЬ, СтрДлина(РезультатПоиска.SubMatches(4)));
ирОбщий.ДобавитьМногострочнуюСтрокуВТекстЛкс(Результат, ТекстДоПоследнегоУПОРЯДОЧИТЬ, Смещение);
Иначе
ирОбщий.ДобавитьМногострочнуюСтрокуВТекстЛкс(Результат, РезультатПоиска.SubMatches(5), Смещение);
КонецЕсли;
Если ЭтоРусскийЯзык Тогда
Результат = Результат + ") КАК ";
Иначе
Результат = Результат + ") AS ";
КонецЕсли;
Результат = Результат + ПсевдонимВложенногоЗапроса;
Если Истина
//И ТекстДоПоследнегоУПОРЯДОЧИТЬ <> Неопределено
И Не ПустаяСтрока(ТекстДоПоследнегоУПОРЯДОЧИТЬ)
И Не ОбрезатьНачинаяСУпорядочивания
Тогда
Результат = Результат + Символы.ПС + РезультатПоиска.SubMatches(4) + РезультатПоиска.SubMatches(5);
КонецЕсли;
Возврат Результат;
КонецФункции // ПолучитьТекстЗапросаДоУпорядочивания()
Функция СоздаваемыеВременныеТаблицыПакетаЗапросов(Знач ТекстПакетаИлиМассивТекстовЗапросов, Знач ТолькоТребующиеУничтоженияНаВходе = Ложь, Знач ВместеСУничтожениями = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
RegExp2 = Обработки.ирОболочкаРегВыражение.Создать();
#КонецЕсли
СозданныеТаблицы = Новый СписокЗначений;
Если ТипЗнч(ТекстПакетаИлиМассивТекстовЗапросов) = Тип("Массив") Тогда
ТекстыЗапросовПакета = ТекстПакетаИлиМассивТекстовЗапросов;
Иначе
Если Не ирКэш.ДоступныРегВыраженияЛкс() Тогда
Если ирКэш.ДоступноСхемаЗапросаЛкс() Тогда
Схема = Вычислить("Новый СхемаЗапроса");
#Если Сервер И Не Сервер Тогда
Схема = Новый СхемаЗапроса;
#КонецЕсли
Попытка
Схема.УстановитьТекстЗапроса(ТекстПакетаИлиМассивТекстовЗапросов);
Исключение
ОписаниеОшибки = ОписаниеОшибки(); // Для отладки
Возврат СозданныеТаблицы;
КонецПопытки;
Для Каждого ЗапросПакета Из Схема.ПакетЗапросов Цикл
ИмяСоздаваемойТаблицы = Неопределено;
Если Истина
И ТипЗнч(ЗапросПакета) = Тип("ЗапросВыбораСхемыЗапроса")
И ЗначениеЗаполнено(ЗапросПакета.ТаблицаДляПомещения)
Тогда
ИмяСоздаваемойТаблицы = ЗапросПакета.ТаблицаДляПомещения;
КонецЕсли;
СозданныеТаблицы.Добавить(НРег(ИмяСоздаваемойТаблицы), ИмяСоздаваемойТаблицы);
КонецЦикла;
КонецЕсли;
Возврат СозданныеТаблицы;
КонецЕсли;
ТекстыЗапросовПакета = РазбитьГрубоТекстПакетногоЗапросаНаЗапросы(ТекстПакетаИлиМассивТекстовЗапросов);
КонецЕсли;
RegExp2.Global = Истина;
// Ищем в каждом запросе пакета предложение ПОМЕСТИТЬ/УНИЧТОЖИТЬ
ШаблонПОМЕСТИТЬИЗ = "(?:" + шСтрокаЗапроса + ")|(?:(?:" + шРазделитель + "|\|)(?:(ПОМЕСТИТЬ|INTO\s+TABLE|INTO)|(УНИЧТОЖИТЬ|DROP|DROP\s+TABLE))" + шРазделитель
//+ "+(" + шИмяВременнойТаблицы + ")(" + шРазделитель + "|;|')|(?:" + шРазделитель + "))|.+?";
+ "+(" + шИмяВременнойТаблицы + ")(" + шРазделитель + "|;|')|\s)|" + шРазделитель + "|.+?";
RegExp2.Pattern = ШаблонПОМЕСТИТЬИЗ;
СозданныеТаблицыНрег = Новый Массив;
СначалаУничтоженныеТаблицы = Новый Массив;
Для Каждого ТекстЗапроса Из ТекстыЗапросовПакета Цикл
ИмяСозданнойВременнойТаблицы = Неопределено;
СозданиеВременнойТаблицы = RegExp2.Заменить(ТекстЗапроса, "$1");
ИмяВременнойТаблицы = RegExp2.Заменить(ТекстЗапроса, "$3");
Если ЗначениеЗаполнено(СозданиеВременнойТаблицы) Тогда
Если Ложь
Или Не ТолькоТребующиеУничтоженияНаВходе
Или СначалаУничтоженныеТаблицы.Найти(НРег(ИмяВременнойТаблицы)) = Неопределено
Тогда
ИмяСозданнойВременнойТаблицы = ИмяВременнойТаблицы;
Если ИмяСозданнойВременнойТаблицы <> Неопределено Тогда
СозданныеТаблицыНрег.Добавить(НРег(ИмяСозданнойВременнойТаблицы));
КонецЕсли;
КонецЕсли;
ИначеЕсли ЗначениеЗаполнено(ИмяВременнойТаблицы) Тогда
Если ВместеСУничтожениями Тогда
ИмяСозданнойВременнойТаблицы = "-" + ИмяВременнойТаблицы;
КонецЕсли;
ИмяВременнойТаблицы = НРег(ИмяВременнойТаблицы);
Если ТолькоТребующиеУничтоженияНаВходе Тогда
Если СозданныеТаблицыНрег.Найти(ИмяВременнойТаблицы) = Неопределено Тогда
СначалаУничтоженныеТаблицы.Добавить(ИмяВременнойТаблицы);
КонецЕсли;
КонецЕсли;
КонецЕсли;
СозданныеТаблицы.Добавить(НРег(ИмяСозданнойВременнойТаблицы), ИмяСозданнойВременнойТаблицы);
КонецЦикла;
Возврат СозданныеТаблицы;
КонецФункции
////////////////////////////////////////////////////////////////////////////////
// РАБОТА С ТИПАМИ
// Получает чистую внутреннюю таблицу предопределенных слов.
//
// Параметры:
// Нет.
//
// Возвращаемое значение:
// ТаблицаЗначений - с колонками "Слово", "ТипСлова", "ТаблицаТипов".
//
Функция НоваяТаблицаСвойствТипа() Экспорт
ВнутрТаблицаСлов = Новый ТаблицаЗначений;
ВнутрТаблицаСлов.Колонки.Добавить("Слово");
ВнутрТаблицаСлов.Колонки.Добавить("ТипСлова");
ВнутрТаблицаСлов.Колонки.Добавить("ТаблицаТипов");
ВнутрТаблицаСлов.Колонки.Добавить("ТипЗначения");
ВнутрТаблицаСлов.Колонки.Добавить("Определение");
ВнутрТаблицаСлов.Колонки.Добавить("МожноУточнитьТип");
ВнутрТаблицаСлов.Индексы.Добавить("Слово, ТипСлова");
Возврат ВнутрТаблицаСлов;
КонецФункции
// Функция - Подобрать вариант синтаксиса метода
//
// Параметры:
// ТаблицаВариантов - - содержимое будет утеряно!
//
// Возвращаемое значение:
// строка - название варианта синтаксиса
//
Функция ПодобратьВариантСинтаксисаМетода(Знач ТаблицаВариантов, Знач КоличествоФактПараметровМетода = 0, Знач ТекущийВариант = "", Знач ТекущийВариантУстановленВручную = Ложь, выхНомер = 0) Экспорт
#Если Сервер И Не Сервер Тогда
ТаблицаВариантов = Новый ТаблицаЗначений;
#КонецЕсли
ТаблицаВариантов.Колонки.Добавить("Количество", Новый ОписаниеТипов("Число"));
ТаблицаВариантов.ЗаполнитьЗначения(1, "Количество");
ТаблицаВариантов.Свернуть("ВариантСинтаксиса", "Количество");
//ТаблицаВариантов.Сортировать("Количество"); // Если закомментировано, то ОткрытьФорму("") правильно показывает и ближе к поведению конфигуратора
НовыйТекущийВариант = "";
Если ТаблицаВариантов.Количество() > 0 Тогда
Для Каждого СтрокаВарианта Из ТаблицаВариантов Цикл
Если ТекущийВариантУстановленВручную И СтрокаВарианта.ВариантСинтаксиса = ТекущийВариант Тогда
НовыйТекущийВариант = ТекущийВариант;
выхНомер = ТаблицаВариантов.Индекс(СтрокаВарианта);
Прервать;
КонецЕсли;
Если СтрокаВарианта.Количество >= КоличествоФактПараметровМетода Тогда
НовыйТекущийВариант = СтрокаВарианта.ВариантСинтаксиса;
выхНомер = ТаблицаВариантов.Индекс(СтрокаВарианта);
Если Не ТекущийВариантУстановленВручную Тогда
Прервать;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если СтрокаВарианта.Количество < КоличествоФактПараметровМетода Тогда
НовыйТекущийВариант = СтрокаВарианта.ВариантСинтаксиса;
выхНомер = ТаблицаВариантов.Индекс(СтрокаВарианта);
КонецЕсли;
КонецЕсли;
выхНомер = выхНомер + 1;
Возврат НовыйТекущийВариант;
КонецФункции
Функция СинтаксПомощник() Экспорт
Если СинтаксПомощник = Неопределено Тогда
СинтаксПомощник = ирОбщий.СоздатьОбъектПоИмениМетаданныхЛкс("Обработка.ирСинтаксПомощник");
КонецЕсли;
Возврат СинтаксПомощник;
КонецФункции
Функция ДоступныеЗначенияТипа(Знач ИмяТипаИлиТипЗначения) Экспорт
ИнициацияОписанияМетодовИСвойств();
Если ТипЗнч(ИмяТипаИлиТипЗначения) = Тип("Тип") Тогда
ИмяТипаИлиТипЗначения = СтруктураТипаИзКонкретногоТипа(ИмяТипаИлиТипЗначения).ИмяОбщегоТипа;
КонецЕсли;
//Пустышка = Вычислить("Метаданные.СвойстваОбъектов." + ИмяТипаЗначения);
СтрокиЗначений = ТаблицаКонтекстов.НайтиСтроки(Новый Структура("ТипКонтекста, ТипСлова", "ПеречислениеМетаданных: " + ИмяТипаИлиТипЗначения, "Свойство"));
Если СтрокиЗначений.Количество() = 0 Тогда
ИмяТипаПеречисления = ИмяТипаИлиТипЗначения;
Если Не ирОбщий.СтрНачинаетсяСЛкс(ИмяТипаИлиТипЗначения, "Перечисление") Тогда
ИмяТипаПеречисления = "Перечисление" + ИмяТипаПеречисления;
КонецЕсли;
СтрокиЗначений = ТаблицаКонтекстов.НайтиСтроки(Новый Структура("ТипКонтекста, ТипСлова", ИмяТипаПеречисления, "Свойство"));
КонецЕсли;
СтрокиЗначений = ТаблицаКонтекстов.Скопировать(СтрокиЗначений);
СписокЗначений = Новый СписокЗначений;
СписокЗначений.ЗагрузитьЗначения(СтрокиЗначений.ВыгрузитьКолонку("Слово"));
Возврат СписокЗначений;
КонецФункции
// Формирует построитель запроса по структуре типа.
//
// Параметры:
// СтруктураТипа - Структура - описатель типа.
//
// Возвращаемое значение:
// ПостроительЗапроса.
//
Функция ПостроительЗапросаПоСтруктуреТипа(СтрокаОбщегоТипа, ВиртуальнаяТаблица = Неопределено)
МетаданныеРодителя = СтрокаОбщегоТипа.Метаданные;
Если ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") Тогда
ПолноеИмя = МетаданныеРодителя.ПолноеИмя();
Иначе
ПолноеИмя = ирОбщий.КорневойТипКонфигурацииЛкс(КэшОбъект(МетаданныеРодителя).ПолноеИмя);
КонецЕсли;
МассивФрагментов = ирОбщий.СтрРазделитьЛкс(ПолноеИмя);
КорневойТипРодителя = МассивФрагментов[0];
Если ОписаниеТипаМетаОбъектов(КорневойТипРодителя, , 0) <> Неопределено Тогда
Если Ложь
Или (Истина
И МассивФрагментов.Количество() = 2
И МассивФрагментов[0] <> "ВнешнийИсточникДанных")
Или (Истина
И МассивФрагментов.Количество() = 4
И МассивФрагментов[2] = "ТабличнаяЧасть")
Тогда
ПостроительЗапроса = Новый Структура("ДоступныеПоля", Новый Массив);
Если СтрокаОбщегоТипа.ИмяОбщегоТипа = "Константы.<Имя константы>" Тогда
ИмяТаблицы = "Константы." + МассивФрагментов[1];
Иначе
ИмяТаблицы = ирКэш.ИмяТаблицыИзМетаданныхЛкс(ПолноеИмя, Ложь, ВиртуальнаяТаблица = Неопределено);
КонецЕсли;
Если ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") Тогда
Если Ложь
Или ВиртуальнаяТаблица = Неопределено
Или Найти(ВиртуальнаяТаблица.Выражение, "(") = 0
Тогда
ТаблицаРезультата = ирКэш.ПоляТаблицыБДЛкс(ИмяТаблицы + ВиртуальнаяТаблица.Выражение);
#Если Сервер И Не Сервер Тогда
ТаблицаРезультата = Новый ТаблицаЗначений;
#КонецЕсли
ТаблицаРезультата = ТаблицаРезультата.Скопировать(, "Имя, ТипЗначения"); // Делаем копию, т.к. будем ее модифицировать
ПостроительЗапроса = Новый Структура("ДоступныеПоля", ТаблицаРезультата);
Иначе
Если СтрокаОбщегоТипа.ИмяОбщегоТипа = "Константы.<Имя константы>" Тогда
ОпределениеТаблицы = "ВЫБРАТЬ " + ИмяТаблицы;
Иначе
УникальноеИмяТаблицы = "______________________";
ОпределениеТаблицы = "ВЫБРАТЬ * ИЗ " + ИмяТаблицы ;
Если ВиртуальнаяТаблица <> Неопределено Тогда
ОпределениеТаблицы = ОпределениеТаблицы + ВиртуальнаяТаблица.Выражение;
КонецЕсли;
ОпределениеТаблицы = ОпределениеТаблицы + " КАК " + УникальноеИмяТаблицы;
КонецЕсли;
Попытка
//ПостроительЗапроса.Текст = ОпределениеТаблицы;
ТаблицаРезультата = ирОбщий.ПустаяТаблицаЗначенийИзТекстаЗапросаЛкс(ОпределениеТаблицы,,, Ложь);
Исключение
Успех = Ложь;
Если ВиртуальнаяТаблица <> Неопределено Тогда
ПозицияСкобки = Найти(ВиртуальнаяТаблица.Выражение, "(");
Если ПозицияСкобки > 0 Тогда
ОпределениеТаблицы = "ВЫБРАТЬ * ИЗ " + ИмяТаблицы ;
ОпределениеТаблицы = ОпределениеТаблицы + Лев(ВиртуальнаяТаблица.Выражение, ПозицияСкобки - 1);
ОпределениеТаблицы = ОпределениеТаблицы + " КАК " + УникальноеИмяТаблицы;
Попытка
//ПостроительЗапроса.Текст = ОпределениеТаблицы;
ТаблицаРезультата = ирОбщий.ПустаяТаблицаЗначенийИзТекстаЗапросаЛкс(ОпределениеТаблицы);
Успех = Истина;
Исключение
КонецПопытки;
КонецЕсли;
КонецЕсли;
Если Не Успех Тогда
ВызватьИсключение "ОшибкаВычисленияВиртуальнойТаблицы";
КонецЕсли;
КонецПопытки;
ТаблицаРезультата = ирОбщий.ТаблицаЗначенийВТаблицуПолейБДЛкс(ТаблицаРезультата);
ПостроительЗапроса = Новый Структура("ДоступныеПоля", ТаблицаРезультата);
КонецЕсли;
ТаблицаРезультата.Колонки.Добавить("НИмя");
ирОбщий.ОбновитьКопиюКолонкиВНижнемРегистреЛкс(ТаблицаРезультата);
ирОбщий.ДополнитьТаблицуПолейТаблицыБДВиртуальнымиПолямиЛкс(ПостроительЗапроса.ДоступныеПоля, ирОбщий.ОписаниеТаблицыБДЛкс(ИмяТаблицы));
Иначе
// Внешние метаданные
ПостроительЗапроса = Новый ПостроительЗапроса;
ЗапросРеквизитов = Новый Запрос("ВЫБРАТЬ Имя, ТипыСтрокой ИЗ Справочник.СвойстваМетаданных ГДЕ Владелец = &СсылкаМД");
ЗапросРеквизитов.УстановитьПараметр("СсылкаМД", МетаданныеРодителя);
ТаблицаРеквизитов = ЗапросРеквизитов.Выполнить().Выгрузить();
Для Каждого СтрокаРеквизита Из ТаблицаРеквизитов Цикл
ДоступноеПоле = ПостроительЗапроса.ДоступныеПоля.Добавить(СтрокаРеквизита.Имя);
Для Каждого СтрокаТипа Из СтрокаРеквизита.Типы Цикл
МассивТипов = Новый Массив;
ОбъектМД = КэшОбъект(СтрокаТипа.Объект);
МассивТипов.Добавить(Тип(ОбъектМД.Наименование));
КонецЦикла;
ДоступноеПоле.ТипЗначения = Новый ОписаниеТипов(МассивТипов);
КонецЦикла;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат ПостроительЗапроса;
КонецФункции
// Получает массив общих типов, дополняя исходный тип расширениями.
//
// Параметры:
// СтруктураТипа - Структура.
//
// Возвращаемое значение:
// Массив - структур типа.
//
Функция ТаблицаОбщихТиповИзСтруктурыТипа(Знач СтруктураТипа, Знач ЭтоЛокальныйКонтекст) Экспорт
МассивОбщихТипов = НоваяТаблицаДополнительныхТипов();
Если СтруктураТипа.ТипЯзыка <> "" Тогда
ЗаполнитьЗначенияСвойств(МассивОбщихТипов.Добавить(), СтруктураТипа);
Возврат МассивОбщихТипов;
КонецЕсли;
Если Ложь
Или (Истина
И ТипЗнч(СтруктураТипа.Метаданные) <> Тип("COMОбъект")
И (Ложь
Или СтруктураТипа.ИмяОбщегоТипа = "Локальный" // Для подстраховки
Или ЭтоЛокальныйКонтекст И СтруктураТипа.ИмяОбщегоТипа <> "Глобальный"))
Или СтруктураТипа.ИмяОбщегоТипа = "Automation сервер"
Или СтруктураТипа.ИмяОбщегоТипа = "Внешнее соединение"
Тогда
// Должен идти первым в списке!
НоваяСтрока = МассивОбщихТипов.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа,, "ИмяОбщегоТипа, Метаданные");
НоваяСтрока.ИмяОбщегоТипа = "Глобальный";
НоваяСтрока.Метаданные = Метаданные;
КонецЕсли;
СтрокаТаблицы = МассивОбщихТипов.Добавить();
ЗаполнитьЗначенияСвойств(СтрокаТаблицы, СтруктураТипа);
Если СтрокаТаблицы.ИмяОбщегоТипа = "УправляемаяФорма" Тогда
СтрокаТаблицы.ИмяОбщегоТипа = "ФормаКлиентскогоПриложения";
КонецЕсли;
Если Найти(СтруктураТипа.ИмяОбщегоТипа, "ТабличнаяЧасть.") > 0 Тогда
НоваяСтрока = МассивОбщихТипов.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа);
НоваяСтрока.ИмяОбщегоТипа = "Табличная часть";
ИначеЕсли Найти(СтруктураТипа.ИмяОбщегоТипа, "ТабличнаяЧастьСтрока.") > 0 Тогда
НоваяСтрока = МассивОбщихТипов.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа);
НоваяСтрока.ИмяОбщегоТипа = "Строка табличной части";
ИначеЕсли СтруктураТипа.ИмяОбщегоТипа = "ПолеТекстовогоДокумента" Тогда
НоваяСтрока = МассивОбщихТипов.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа);
НоваяСтрока.ИмяОбщегоТипа = "ТекстовыйДокумент";
ИначеЕсли СтруктураТипа.ИмяОбщегоТипа = "ПолеГрафическойСхемы" Тогда
НоваяСтрока = МассивОбщихТипов.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа);
НоваяСтрока.ИмяОбщегоТипа = "ГрафическаяСхема";
ИначеЕсли СтруктураТипа.ИмяОбщегоТипа = "ПолеТабличногоДокумента" Тогда
НоваяСтрока = МассивОбщихТипов.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа);
НоваяСтрока.ИмяОбщегоТипа = "ТабличныйДокумент";
ИначеЕсли Найти(СтруктураТипа.ИмяОбщегоТипа, "КоллекцияМетаданных:") > 0 Тогда
НоваяСтрока = МассивОбщихТипов.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа);
НоваяСтрока.ИмяОбщегоТипа = "КоллекцияОбъектовМетаданных";
//ИначеЕсли Найти(СтруктураТипа.ИмяОбщегоТипа, "Расширение формы") > 0 Тогда
// НоваяСтрока = МассивОбщихТипов.Добавить();
// ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа);
// НоваяСтрока.ИмяОбщегоТипа = "Форма";
Иначе
ОбщийТипМетаданных = ирОбщий.ТекстМеждуМаркерамиЛкс(СтруктураТипа.ИмяОбщегоТипа, , ": ", Ложь);
//Если ОбщийТипМетаданных <> "" Тогда
Если ЗначениеЗаполнено(ОбщийТипМетаданных) Тогда
НоваяСтрока = МассивОбщихТипов.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа);
НоваяСтрока.ИмяОбщегоТипа = ОбщийТипМетаданных;
КонецЕсли;
КонецЕсли;
// TODO добавить расширения управляемой формы Мультиметка638663811
// Расширения, образованные элементом управления и типом связанных с ним данных
СтрокаРасширения = ТаблицаРасширенийТипов.Найти(СтруктураТипа.ИмяОбщегоТипа, "Расширение");
Если СтрокаРасширения <> Неопределено Тогда
Если Истина
И СтрокаРасширения.ОсновнойТип = "Форма"
И СтруктураТипа.ДополнительныеТипы = Неопределено
Тогда
НоваяСтрока = МассивОбщихТипов.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа);
НоваяСтрока.ИмяОбщегоТипа = СтрокаРасширения.РасширяющийТип;
#Если Клиент Тогда
Если ТипЗнч(СтруктураТипа.Метаданные) = Тип("Форма") Тогда
ОсновнойРеквизитФормы = ИмяОсновногоРеквизитаФормы(СтруктураТипа.Метаданные);
РасширяющийОбъект = СтруктураТипа.Метаданные[ОсновнойРеквизитФормы];
СтруктураТипаОбъекта = СтруктураТипаИзЗначения(РасширяющийОбъект);
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипаОбъекта);
//НоваяСтрока.Метаданные = ирОбщий.ПолучитьМетаданныеЛкс(РасширяющийОбъект);
КонецЕсли;
#КонецЕсли
КонецЕсли;
НоваяСтрока = МассивОбщихТипов.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа);
НоваяСтрока.ИмяОбщегоТипа = СтрокаРасширения.ОсновнойТип;
КонецЕсли;
// Общие расширения элементов управления
Для Счетчик = 1 По Мин(2, МассивОбщихТипов.Количество()) Цикл // Для поля табличного документа будет 2 типа https://www.hostedredmine.com/issues/956247
лИмяОбщегоТипа = МассивОбщихТипов[МассивОбщихТипов.Количество() - Счетчик].ИмяОбщегоТипа;
Если МассивОбычныхЭлементовУправления.Найти(лИмяОбщегоТипа) <> Неопределено Тогда
НоваяСтрока = МассивОбщихТипов.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа);
НоваяСтрока.ИмяОбщегоТипа = "Расширение элементов управления, расположенных в форме";
НоваяСтрока = МассивОбщихТипов.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа);
// Эту синтаксическую ошибку исправили только в 13-м релизе.
//НоваяСтрока.ИмяОбщегоТипа = "Расширение элементов управления расположенных на панели";
НоваяСтрока.ИмяОбщегоТипа = "Расширение элементов управления, расположенных на панели";
//ИначеЕсли МассивУправляемыхЭлементовУправления.Найти(лИмяОбщегоТипа) <> Неопределено Тогда
// // http://www.hostedredmine.com/issues/882998
// НоваяСтрока = МассивОбщихТипов.Добавить();
// ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа);
// НоваяСтрока.ИмяОбщегоТипа = "Расширение элементов управления, расположенных в форме";
КонецЕсли;
КонецЦикла;
Если СтруктураТипа.ДополнительныеТипы <> Неопределено Тогда
ирОбщий.ЗагрузитьВТаблицуЗначенийЛкс(СтруктураТипа.ДополнительныеТипы, МассивОбщихТипов);
КонецЕсли;
Возврат МассивОбщихТипов;
КонецФункции
Процедура ОчиститьКэшАнализатораЯзыка() Экспорт
мМодулиМетаданных = Неопределено;
мВызовыВсехМетодовПоМодулям = Неопределено;
мКэшСловГлобальногоКонтекста = Неопределено;
мПассивныеФормы.Очистить();
КонецПроцедуры
Процедура ПроверитьОбновитьКэш() Экспорт
НоваяДатаОбновленияКэшаМодулей = ирОбщий.ДатаОбновленияКэшаМодулейЛкс();
Если мДатаОбновленияКэшаМодулей <> НоваяДатаОбновленияКэшаМодулей Тогда
ОчиститьКэшАнализатораЯзыка();
мДатаОбновленияКэшаМодулей = НоваяДатаОбновленияКэшаМодулей;
КонецЕсли;
КонецПроцедуры
// Получает внутреннюю таблицу предопределенных слов заданного родительского типа.
//
// Параметры:
// РодительскаяСтруктураТипа - Структура;
// *Слово - Строка, *Неопределено - для отбора;
// *ТипСлова - Строка, *Неопределено - для отбора;
// *ВиртуальнаяТаблица - Структура, *Неопределено - описание виртуальной таблицы;
// *ЯзыкПрограммы - *Число, 0;
//
// Возвращаемое значение:
// ТаблицаЗначений - с колонками "Слово", "ТипСлова", "ТаблицаТипов".
//
Функция СловаКонтекстаПредопределенные(Знач РодительскаяСтруктураТипа, Знач Слово = Неопределено, Знач ТипСлова = Неопределено, Знач ВиртуальнаяТаблица = Неопределено, Знач ЯзыкПрограммы = 0,
Знач Конфигурация = Неопределено, Знач ВычислятьТипы = Истина, Знач ФлагиКомпиляции = Неопределено, Знач ТаблицаСлов = Неопределено, Знач ЭтоЛокальныйКонтекст = Ложь, Знач мНаборыСлов = Неопределено,
Знач БазовоеРасширениеКонфигурации = "") Экспорт
Если Истина
И Не РодительскаяСтруктураТипа.Конструктор
И Не ЗначениеЗаполнено(РодительскаяСтруктураТипа.ИмяОбщегоТипа)
И РодительскаяСтруктураТипа.ТипЯзыка = ""
Тогда
// родительский контекст является Процедурой
Если ТаблицаСлов = Неопределено Тогда
ТаблицаСлов = НоваяТаблицаСвойствТипа();
КонецЕсли;
Возврат ТаблицаСлов;
КонецЕсли;
КлючПоискаКонструктора = Новый Структура;
Если РодительскаяСтруктураТипа.Конструктор Тогда
КлючПоискаКонструктора = Новый Структура("ЕстьКонструктор, ЯзыкПрограммы, НСлово", Истина, ЯзыкПрограммы);
КонецЕсли;
ИмяОбщегоТипаРодителяБезДеталей = РодительскаяСтруктураТипа.ИмяОбщегоТипа;
Если Найти(ИмяОбщегоТипаРодителяБезДеталей, " {V") > 0 Тогда
ЧистоеИмяТипа = ирОбщий.ПервыйФрагментЛкс(ИмяОбщегоТипаРодителяБезДеталей, " ");
Если Найти(ЧистоеИмяТипа, "IV8COMConnector") = 1 Тогда
РодительскаяСтруктураТипа.ИмяОбщегоТипа = "Менеджер COM-соединений";
ИначеЕсли Найти(ЧистоеИмяТипа, "IServerAgentConnection") = 1 Тогда
РодительскаяСтруктураТипа.ИмяОбщегоТипа = "Соединение с агентом сервера";
ИначеЕсли Найти(ИмяОбщегоТипаРодителяБезДеталей, "IWorkingProcessConnection") Тогда
РодительскаяСтруктураТипа.ИмяОбщегоТипа = "Соединение с рабочим процессом";
ИначеЕсли Найти(ИмяОбщегоТипаРодителяБезДеталей, "Application") Тогда
РодительскаяСтруктураТипа.ИмяОбщегоТипа = "Automation сервер";
КонецЕсли;
КонецЕсли;
МассивОбщихТипов = ТаблицаОбщихТиповИзСтруктурыТипа(РодительскаяСтруктураТипа, ЭтоЛокальныйКонтекст);
#Если Сервер И Не Сервер Тогда
МассивОбщихТипов = Новый ТаблицаЗначений;
ТаблицаСлов = Новый ТаблицаЗначений;
#КонецЕсли
НомерВерсииПлатформы = ирКэш.НомерВерсииПлатформыЛкс();
Для Каждого СтрокаОбщегоТипа Из МассивОбщихТипов Цикл
ИмяОбщегоТипаРодителяБезДеталей = ирОбщий.ПервыйФрагментЛкс(СтрокаОбщегоТипа.ИмяОбщегоТипа, "[");
ИспользоватьКэширование = Истина
И Слово = Неопределено
И (Ложь
Или ИмяОбщегоТипаРодителяБезДеталей = "Глобальный"
Или ИмяОбщегоТипаРодителяБезДеталей = "" // ИмяТипа
);
Если ИспользоватьКэширование Тогда
// Мультиметка3398476724
ЛиСеансТолстогоКлиентаУП = ирКэш.ЛиСеансТолстогоКлиентаУПЛкс();
НаСервере = ирОбщий.СвойствоСтруктурыЛкс(ФлагиКомпиляции, "Сервер", Истина);
КлиентОбычноеПриложение = ирОбщий.СвойствоСтруктурыЛкс(ФлагиКомпиляции, "КлиентОбычноеПриложение", Не ЛиСеансТолстогоКлиентаУП);
КлиентУправляемоеПриложение = ирОбщий.СвойствоСтруктурыЛкс(ФлагиКомпиляции, "КлиентУправляемоеПриложение", ЛиСеансТолстогоКлиентаУП);
КлючКэширования = "" + ЯзыкПрограммы + ";" + Конфигурация + ";" + ВычислятьТипы + ";" + ТипСлова + ";" + НаСервере + ";" + КлиентОбычноеПриложение + ";" + КлиентУправляемоеПриложение
+ ";" + РодительскаяСтруктураТипа.ТипЯзыка + ";" + БазовоеРасширениеКонфигурации;
Если мКэшСловГлобальногоКонтекста = Неопределено Тогда
мКэшСловГлобальногоКонтекста = Новый Соответствие;
КонецЕсли;
ТаблицаСловИзКэша = мКэшСловГлобальногоКонтекста[КлючКэширования];
#Если Сервер И Не Сервер Тогда
ТаблицаСловИзКэша = Новый ТаблицаЗначений;
#КонецЕсли
Если ТаблицаСловИзКэша <> Неопределено Тогда
Если ТаблицаСлов <> Неопределено Тогда
ВызватьИсключение "Для глобального контекста нельзя передавать таблицу-приемник";
КонецЕсли;
Если мНаборыСлов <> Неопределено Тогда
мНаборыСлов.Вставить(КлючКэширования, ТаблицаСловИзКэша);
ТаблицаСлов = НоваяТаблицаСвойствТипа();
Иначе
ТаблицаСлов = ТаблицаСловИзКэша.Скопировать();
КонецЕсли;
Продолжить;
КонецЕсли;
КонецЕсли;
Если ТаблицаСлов = Неопределено Тогда
ТаблицаСлов = НоваяТаблицаСвойствТипа();
КонецЕсли;
Если Истина
И ИмяОбщегоТипаРодителяБезДеталей <> "Глобальный"
И ФлагиКомпиляции <> Неопределено
И ФлагиКомпиляции.БезКонтекста
И ЭтоЛокальныйКонтекст
Тогда
Продолжить;
КонецЕсли;
МетаданныеРодителя = СтрокаОбщегоТипа.Метаданные;
Если Истина
И ТипЗнч(МетаданныеРодителя) = Тип("Структура")
И ирОбщий.СвойствоСтруктурыЛкс(МетаданныеРодителя, "Форма") <> Неопределено
Тогда
МетаданныеРодителя = МетаданныеРодителя.Форма;
КонецЕсли;
КорневойТипРодителя = Неопределено;
ПостроительЗапросаРодителя = Неопределено;
ТипМетаданныхРодителя = ТипЗнч(МетаданныеРодителя);
Если Истина
И ТипМетаданныхРодителя = Тип("ОбъектМетаданных")
И РодительскаяСтруктураТипа.ТипЯзыка <> "ИмяТипа"
Тогда
Если ТипМетаданныхРодителя = Тип("ОбъектМетаданных") Тогда
КорневойТипРодителя = ирОбщий.КорневойТипКонфигурацииЛкс(МетаданныеРодителя);
Иначе
КорневойТипРодителя = ирОбщий.КорневойТипКонфигурацииЛкс(КэшОбъект(МетаданныеРодителя).ПолноеИмя);
КонецЕсли;
ПостроительЗапросаРодителя = ПостроительЗапросаПоСтруктуреТипа(СтрокаОбщегоТипа, РодительскаяСтруктураТипа.ВиртуальнаяТаблица);
КонецЕсли;
Если ИмяОбщегоТипаРодителяБезДеталей = "Локальный" Тогда
НайденныеСтроки = Новый Массив;
ИначеЕсли ТипСлова = "Конструктор" Тогда
НайденныеСтроки = Новый Массив;
Если ИмяОбщегоТипаРодителяБезДеталей = "Глобальный" Тогда
СтруктураКлюча = Новый Структура("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка, ТипСлова",
Слово, ЯзыкПрограммы, РодительскаяСтруктураТипа.ТипЯзыка, ТипСлова);
НайденныеСтроки = ТаблицаКонтекстов.НайтиСтроки(СтруктураКлюча);
КонецЕсли;
Иначе
// Состав полей совпадает с индексом
СтруктураКлюча = Новый Структура("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка",
ИмяОбщегоТипаРодителяБезДеталей, ЯзыкПрограммы, РодительскаяСтруктураТипа.ТипЯзыка);
Если Слово <> Неопределено Тогда
СтруктураКлюча.Вставить("НСлово", НРег(Слово));
Если Истина
И ЯзыкПрограммы = 0 // В языке запросов может быть неоднозначность между типами слов Таблица и Поле. Поэтому для них жертвуем попаданием в индекс
И ТипСлова = Неопределено
Тогда
//ирОбщий.СообщитьЛкс("Использован медленный поиск по таблице контекстов");
ТипСлова = "Свойство"; // Так будем всегда попадать в индекс
КонецЕсли;
КонецЕсли;
Если ТипСлова <> Неопределено Тогда
СтруктураКлюча.Вставить("ТипСлова", ТипСлова);
КонецЕсли;
Если ЯзыкПрограммы <> 0 Тогда
ирОбщий.ДобавитьИндексВТаблицуЛкс(ТаблицаКонтекстов, СтруктураКлюча); // спасает в случае языка запросов, где ТипСлова не используется
КонецЕсли;
НайденныеСтроки = ТаблицаКонтекстов.НайтиСтроки(СтруктураКлюча);
КонецЕсли;
ПредыдущаяСтрокаСлова = Неопределено; // Для регистра бухгалтерии
ВычислятьТипыЦикл = ВычислятьТипы Или НайденныеСтроки.Количество() < 100;
Для Каждого СтрокаСлова Из НайденныеСтроки Цикл
Если Истина
И ПредыдущаяСтрокаСлова <> Неопределено
И ПредыдущаяСтрокаСлова.НСлово = СтрокаСлова.НСлово
И ПредыдущаяСтрокаСлова.ТипСлова = СтрокаСлова.ТипСлова
Тогда
Продолжить;
КонецЕсли;
ПредыдущаяСтрокаСлова = СтрокаСлова;
Если СтрокаСлова.НомерВерсииПлатформы > НомерВерсииПлатформы Тогда
Продолжить;
КонецЕсли;
Если Истина
И СтрокаСлова.ТипСлова = "Метод"
И СтрокаОбщегоТипа.НеВключатьМетоды
Тогда
Продолжить;
КонецЕсли;
Если Истина
И ТипСлова = Неопределено
И (Ложь
Или СтрокаСлова.ТипСлова = "Событие"
Или СтрокаСлова.ТипСлова = "Параметр"
Или СтрокаСлова.ТипСлова = "Конструктор")
Тогда
Продолжить;
КонецЕсли;
Если РодительскаяСтруктураТипа.Конструктор Тогда
КлючПоискаКонструктора.НСлово = НРег(СтрокаСлова.Слово);
Если ТаблицаОбщихТипов.НайтиСтроки(КлючПоискаКонструктора).Количество() = 0 Тогда
Продолжить;
КонецЕсли;
КонецЕсли;
ЛиТипСКвалификаторами = Истина
И (Ложь
Или СтрокаСлова.ТипСлова = "Свойство"
Или СтрокаСлова.ТипСлова = "Поле")
И ирОбщий.ЛиИмяТипаСКвалификаторамиЛкс(СтрокаСлова.ТипЗначения)
И Не ирОбщий.СтрНачинаетсяСЛкс(РодительскаяСтруктураТипа.ИмяОбщегоТипа, "ОбъектМетаданных");
ТаблицаТипов = Неопределено;
Если ВычислятьТипыЦикл Тогда
ТаблицаТипов = НоваяТаблицаТипов();
ЛиДобавляемСлово = Истина;
Если Найти(СтрокаСлова.ТипЗначения, "[") > 0 Тогда
МассивТиповЗначения = ирОбщий.ЗначенияВМассивЛкс(СтрокаСлова.ТипЗначения);
Иначе
МассивТиповЗначения = ирОбщий.СтрРазделитьЛкс(СтрокаСлова.ТипЗначения, ", ");
КонецЕсли;
Для Каждого ИмяОбщегоТипаСлова Из МассивТиповЗначения Цикл
СтруктураТипа = НоваяСтруктураТипа();
СтруктураТипа.СтрокаОписания = СтрокаСлова;
ЗаполнитьЗначенияСвойств(СтруктураТипа, РодительскаяСтруктураТипа, , "ИмяОбщегоТипа, СтрокаОписания, Метаданные");
Если Истина
//И ТипЗнч(МетаданныеРодителя) <> Тип("COMОбъект")
//И ИмяОбщегоТипаСлова <>
//И СтрокаСлова.ТипСлова = "Свойство"
Тогда
ЗаполнитьЗначенияСвойств(СтруктураТипа, СтрокаОбщегоТипа, "Метаданные");
КонецЕсли;
Если ИмяОбщегоТипаСлова = "ОбъектМетаданныхКонфигурация" Тогда
//СтруктураТипа.Метаданные = Конфигурация;
Если Конфигурация <> Неопределено Тогда
СтруктураТипа.Метаданные = Конфигурация;
Иначе
СтруктураТипа.Метаданные = мМетаданные;
КонецЕсли;
ИначеЕсли ИмяОбщегоТипаСлова = "Отбор" Тогда
Если Истина
И ТипЗнч(СтрокаОбщегоТипа.Метаданные) = Тип("ОбъектМетаданных")
И (Ложь
//Или Найти(НРег(СтрокаОбщегоТипа.ИмяОбщегоТипа), "объект.") > 0
Или Найти(НРег(СтрокаОбщегоТипа.ИмяОбщегоТипа), "наборзаписей.") > 0)
Тогда
ИмяТаблицыБД = ирКэш.ИмяТаблицыИзМетаданныхЛкс(СтрокаОбщегоТипа.Метаданные.ПолноеИмя());
СтруктураОбъекта = ирОбщий.ОбъектБДПоКлючуЛкс(ИмяТаблицыБД);
СтруктураТипа.Метаданные = СтруктураОбъекта.Методы;
ИначеЕсли СтрокаОбщегоТипа.ИмяОбщегоТипа = "Расширение табличного поля табличной части" Тогда
Если ТипЗнч(СтрокаОбщегоТипа.Метаданные) = Тип("ТабличноеПоле") Тогда
СтруктураТипа.Метаданные = Метаданные.НайтиПоТипу(ТипЗнч(СтрокаОбщегоТипа.Метаданные.Значение));
КонецЕсли;
Иначе
КонкретныйТип = ИмяТипаИзСтруктурыТипа(СтрокаОбщегоТипа);
Если Истина
И Найти(КонкретныйТип, "<") = 0
И ТипЗнч(СтруктураТипа.Метаданные) <> Тип(КонкретныйТип)
Тогда
Попытка
Образователь = Новый (КонкретныйТип);
СтруктураТипа.Метаданные = Образователь;
Исключение
// Срабатывает для табличных полей
КонецПопытки;
КонецЕсли;
КонецЕсли;
КонецЕсли;
СтруктураТипа.ИмяОбщегоТипа = ИмяОбщегоТипаСлова;
Если ВиртуальнаяТаблица <> Неопределено Тогда
ЗаполнитьЗначенияСвойств(СтруктураТипа.ВиртуальнаяТаблица, ВиртуальнаяТаблица);
КонецЕсли;
Если РодительскаяСтруктураТипа.ТипЯзыка = "ИмяТипа" Тогда
СтруктураТипа.ИмяОбщегоТипа = СтрокаСлова.Слово;
Если СтрокаСлова.ТипКонтекста <> "" Тогда
СтруктураТипа.ИмяОбщегоТипа = СтрокаСлова.ТипКонтекста + "." + СтруктураТипа.ИмяОбщегоТипа;
КонецЕсли;
КонецЕсли;
Если Истина
И Найти(СтруктураТипа.ИмяОбщегоТипа, "Строка табличной части") > 0
И Найти(РодительскаяСтруктураТипа.ИмяОбщегоТипа, "ТабличнаяЧасть.") > 0
Тогда
ИмяТипаСтрокиТЧ = СтрЗаменить(РодительскаяСтруктураТипа.ИмяОбщегоТипа, "ТабличнаяЧасть.", "ТабличнаяЧастьСтрока.");
СтруктураТипа.ИмяОбщегоТипа = СтрЗаменить(СтруктураТипа.ИмяОбщегоТипа, "Строка табличной части", ИмяТипаСтрокиТЧ);
КонецЕсли;
Если Истина
И ТипЗнч(МетаданныеРодителя) = Тип("ТабличноеПоле")
И ИмяОбщегоТипаСлова = "КолонкаТабличногоПоля"
Тогда
ИмяОбщегоТипаРасширения = ИмяТипаРасширенияЭлементаФормы(ИмяОбщегоТипаСлова, МетаданныеРодителя);
Если ИмяОбщегоТипаРасширения <> Неопределено Тогда
СтруктураТипа.ИмяОбщегоТипа = ИмяОбщегоТипаРасширения;
КонецЕсли;
КонецЕсли;
МаркерРасширений = "Расширение ";
Если Истина
И Лев(РодительскаяСтруктураТипа.ИмяОбщегоТипа, СтрДлина(МаркерРасширений)) = МаркерРасширений
И СтрокаСлова.Слово = "Значение"
Тогда
Если РодительскаяСтруктураТипа.Метаданные <> Неопределено Тогда
СтруктураТипа = СтруктураТипаИзЗначения(РодительскаяСтруктураТипа.Метаданные.Значение);
Иначе
СтрокаРасширения = ТаблицаРасширенийТипов.Найти(РодительскаяСтруктураТипа.ИмяОбщегоТипа, "Расширение");
//Если СтрокаРасширения <> Неопределено Тогда
СтруктураТипа.ИмяОбщегоТипа = СтрокаРасширения.РасширяющийТип;
//КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Истина
И МетаданныеРодителя <> Неопределено
И СтрокаСлова.ТипСлова = "Свойство"
Тогда
Если Ложь
Или ТипЗнч(МетаданныеРодителя) = Тип("ПостроительЗапроса")
Или (Истина // Нельзя допускать неявного выполнения запроса при обращении к свойству "Результат" построителя
И СтруктураТипа.ИмяОбщегоТипа = "РезультатЗапроса"
И ТипЗнч(МетаданныеРодителя) = Тип("ПостроительЗапроса"))
Или (Истина // Здесь свойство есть у объекта метаданных, но имеет другой смысл
И СтрокаСлова.Слово = "ВидыСубконто"
И СтруктураТипа.ИмяОбщегоТипа = "ПланСчетовВидыСубконто.<Имя плана счетов>")
Тогда
ЗначениеСвойства = МетаданныеРодителя;
Иначе
Если Истина
#Если Клиент Тогда
И ТипЗнч(МетаданныеРодителя) = Тип("ТабличноеПоле")
#Иначе
И Ложь
#КонецЕсли
И СтрокаСлова.Слово = "ТекущийРодитель"
Тогда
// Антибаг платформы 8.2.16. Вывести в чистом виде не удалось. Падает при вычислении свойства ТекущийРодитель в форме списка РС.ООП_ВаучерыТез
ЗначениеСвойства = Неопределено;
Иначе
Попытка
ЗначениеСвойства = МетаданныеРодителя[СтрокаСлова.Слово];
Исключение
ЗначениеСвойства = Неопределено;
КонецПопытки;
КонецЕсли;
КонецЕсли;
Если ЗначениеСвойства <> Неопределено Тогда
Если мМассивТиповСМетаданными.Найти(ТипЗнч(ЗначениеСвойства)) <> Неопределено Тогда
Если СтрокаСлова.ТипЗначения = "ВсеЭлементыФормы" Тогда
// Для имитатора формы
Иначе
СтруктураТипа.Метаданные = ЗначениеСвойства;
КонецЕсли;
Если ирОбщий.ЛиФормаИлиИмитаторЛкс(МетаданныеРодителя, Ложь) Тогда
СтруктураТипа.ДержательМетаданных = МетаданныеРодителя;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
// Для методов метаданных нужна специфическая обработка для усечения типов
Если Истина
И СтрокаСлова.ТипСлова = "Метод"
И Лев(ИмяОбщегоТипаСлова, СтрДлина(МаркерОбъектаМетаданных)) = МаркерОбъектаМетаданных
И СтрокаСлова.Слово = "Родитель"
Тогда
Родитель = Неопределено;
Если ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") Тогда
Родитель = МетаданныеРодителя.Родитель();
КонецЕсли;
Если Родитель <> Неопределено Тогда
МассивФрагментов = ирОбщий.СтрРазделитьЛкс(Родитель.ПолноеИмя());
СтруктураТипа.ИмяОбщегоТипа = МаркерОбъектаМетаданных + ": " + МассивФрагментов[МассивФрагментов.ВГраница() - 1];
Иначе
СтруктураТипа.ИмяОбщегоТипа = "Неопределено";
КонецЕсли;
СтруктураТипа.Метаданные = Родитель;
ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа);
Прервать;
ИначеЕсли Истина
И СтрокаСлова.ТипСлова = "Метод"
И Лев(ИмяОбщегоТипаСлова, СтрДлина(МаркерКоллекцииОбъектовМетаданных)) = МаркерКоллекцииОбъектовМетаданных
И (Ложь
Или СтрокаСлова.Слово = "Найти"
Или СтрокаСлова.Слово = "Получить")
Тогда
СтруктураКлюча = Новый Структура("БазовыйТип, ЯзыкПрограммы", ИмяОбщегоТипаСлова, ЯзыкПрограммы);
НайденныеСтроки = ТаблицаОбщихТипов.НайтиСтроки(СтруктураКлюча);
СтруктураТипа.ИмяОбщегоТипа = НайденныеСтроки[0].ТипЭлементаКоллекции;
ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа);
Прервать;
ИначеЕсли Истина
И ТипЗнч(МетаданныеРодителя) = Тип("ОписаниеТипов")
И СтрокаСлова.ТипКонтекста = "ОписаниеТипов"
И СтрокаСлова.Слово = "ПривестиЗначение"
Тогда
Если МетаданныеРодителя.Типы().Количество() = 1 Тогда
ДобавитьВТаблицуТипов(ТаблицаТипов, МетаданныеРодителя);
КонецЕсли;
Прервать;
ИначеЕсли Истина
И ТипЗнч(МетаданныеРодителя) = Тип("ТекстовыйДокумент")
И ИмяОбщегоТипаРодителяБезДеталей = "ТекстовыйДокумент"
И СтрокаСлова.Слово = "ПолучитьТекст"
Тогда
СтруктураТипа = НоваяСтруктураТипа("Строка");
СтруктураТипа.Метаданные = МетаданныеРодителя.ПолучитьТекст();
ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа);
Прервать;
ИначеЕсли Истина
И (Ложь
Или ИмяОбщегоТипаРодителяБезДеталей = "КлючИЗначение"
Или ИмяОбщегоТипаРодителяБезДеталей = "ЭлементСпискаЗначений")
И ТипЗнч(МетаданныеРодителя) = Тип("Структура")
И МетаданныеРодителя.Свойство(СтрокаСлова.Слово)
Тогда
ТаблицаТипов = МетаданныеРодителя[СтрокаСлова.Слово];
Если ТаблицаТипов <> Неопределено Тогда
Прервать;
КонецЕсли;
ИначеЕсли Истина
И ИмяОбщегоТипаРодителяБезДеталей = "Соответствие"
И СтрокаСлова.Слово = "Получить"
И ТипЗнч(МетаданныеРодителя) = Тип("Структура")
Тогда
ТаблицаТипов = МетаданныеРодителя.Значение;
Если ТаблицаТипов <> Неопределено Тогда
Прервать;
КонецЕсли;
ИначеЕсли Истина
И ИмяОбщегоТипаРодителяБезДеталей = "Запрос"
И ИмяОбщегоТипаСлова = "МенеджерВременныхТаблиц"
Тогда
МенеджерВременныхТаблиц = РодительскаяСтруктураТипа.ДержательМетаданных;
Если Истина
И ТипЗнч(МенеджерВременныхТаблиц) = Тип("Структура")
//И МенеджерВременныхТаблиц.Тип = Тип("МенеджерВременныхТаблиц")
И МенеджерВременныхТаблиц.Активен
Тогда
СтруктураТипа = СтруктураТипаИзКонкретногоТипа(Тип("МенеджерВременныхТаблиц"));
СтруктураТипа.Метаданные = МенеджерВременныхТаблиц;
ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа);
Продолжить;
Иначе
СтруктураТипа.Метаданные = Неопределено;
КонецЕсли;
ИначеЕсли Истина
И РодительскаяСтруктураТипа.ИмяОбщегоТипа = "Массив[РезультатЗапроса]"
И СтрокаСлова.ТипСлова = "Метод"
И ТипЗнч(МетаданныеРодителя) = Тип("ПостроительЗапроса")
И (Ложь
Или СтрокаСлова.Слово = "Количество"
Или СтрокаСлова.Слово = "ВГраница")
Тогда
КоличествоЗапросов = РазбитьГрубоТекстПакетногоЗапросаНаЗапросы(МетаданныеРодителя.Текст).Количество();
Если СтрокаСлова.Слово = "Количество" Тогда
СтруктураТипа.Метаданные = КоличествоЗапросов;
Иначе
СтруктураТипа.Метаданные = КоличествоЗапросов - 1;
КонецЕсли;
ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа);
Прервать;
ИначеЕсли Истина
И СтрокаСлова.Слово = "ИсходныйКлючЗаписи"
И ТипЗнч(МетаданныеРодителя) = Тип("ДанныеФормыСтруктура")
Тогда
ЛиДобавляемСлово = ЗначениеСвойства <> Неопределено;
Если ЛиДобавляемСлово Тогда
СтруктураТипа = СтруктураТипаИзЗначения(ЗначениеСвойства, СтруктураТипа);
КонецЕсли;
Прервать;
#Если Клиент Тогда
ИначеЕсли Ложь
Или (Истина
И СтрокаСлова.ТипСлова = "Метод"
И СтрокаСлова.Слово = "ДанныеСтроки"
И (Ложь
Или ТипЗнч(МетаданныеРодителя) = Тип("ТаблицаФормы")
Или ТипЗнч(МетаданныеРодителя) = Тип("ТабличноеПоле")
Или ТипЗнч(МетаданныеРодителя) = Тип("Структура") И МетаданныеРодителя.Тип = Тип("ТаблицаФормы")))
Или (Истина
И СтрокаСлова.ТипСлова = "Свойство"
И (Ложь
Или (Истина
И (Ложь
Или СтрокаСлова.Слово = "ТекущиеДанные"
Или СтрокаСлова.Слово = "ОформленияЯчеекДинамическогоСписка")
И (Ложь
Или ТипЗнч(МетаданныеРодителя) = Тип("ТаблицаФормы")
Или ТипЗнч(МетаданныеРодителя) = Тип("Структура") И МетаданныеРодителя.Тип = Тип("ТаблицаФормы")))
Или (Истина
И ТипЗнч(МетаданныеРодителя) = Тип("ТабличноеПоле")
И (Ложь
Или СтрокаСлова.Слово = "ДанныеСтроки"
Или СтрокаСлова.Слово = "ТекущаяСтрока"
Или СтрокаСлова.Слово = "ТекущиеДанные"))))
Тогда
ИмяРеквизитаФормы = "";
Форма = РодительскаяСтруктураТипа.ДержательМетаданных;
ДанныеЭлементаФормы = ирОбщий.ДанныеЭлементаФормыЛкс(МетаданныеРодителя, ИмяРеквизитаФормы, Форма);
ТаблицаТипов = Неопределено;
Если ДанныеЭлементаФормы <> Неопределено Тогда
Если Форма = Неопределено Тогда
Форма = ирОбщий.РодительЭлементаУправляемойФормыЛкс(МетаданныеРодителя);
КонецЕсли;
Если ТипЗнч(ДанныеЭлементаФормы) = Тип("НастройкиКомпоновкиДанных") Тогда
ТаблицаТипов = ТаблицаТиповЭлементовКоллекции(СтруктураТипаИзЗначения(ДанныеЭлементаФормы.Структура));
ИначеЕсли ТипЗнч(ДанныеЭлементаФормы) = Тип("ДинамическийСписок") Тогда
СтруктураТипа = НоваяСтруктураТипа("ДанныеФормыСтруктура");
СтруктураТипа.Метаданные = ИменаРеквизитовФормы(Форма, ИмяРеквизитаФормы).Все;
Иначе
ТаблицаТипов = ТаблицаТиповЭлементовКоллекции(СтруктураТипаИзЗначения(ДанныеЭлементаФормы));
Если ТаблицаТипов.Количество() = 0 Тогда
// Деревья
#Если Клиент Тогда
ТаблицаЗначений = ирКлиент.ТаблицаИлиДеревоЗначенийИзТаблицыФормыСКоллекциейЛкс(МетаданныеРодителя, Новый Массив);
Если ТаблицаЗначений <> Неопределено Тогда
ТаблицаТипов = ТаблицаТиповЭлементовКоллекции(СтруктураТипаИзЗначения(ТаблицаЗначений));
ТаблицаТипов[0].ИмяОбщегоТипа = "СтрокаДереваЗначений";
КонецЕсли;
#КонецЕсли
КонецЕсли;
КонецЕсли;
ИначеЕсли ТипЗнч(МетаданныеРодителя) = Тип("Структура") Тогда
ОписаниеТипов = МетаданныеРодителя.ОписаниеТипов; //ОписаниеТипов
Если ОписаниеТипов <> Неопределено Тогда
Если ОписаниеТипов.СодержитТип(Тип("ДинамическийСписок")) Тогда
СтруктураТипа = НоваяСтруктураТипа("ДанныеФормыСтруктура");
СтруктураТипа.Метаданные = ИменаРеквизитовФормы(Форма, ИмяРеквизитаФормы).Все;
Иначе
ТаблицаТиповКоллекции = ТаблицаТиповИзОписанияТипов(ОписаниеТипов);
ТаблицаТипов = ТаблицаТиповЭлементовКоллекции(ТаблицаТиповКоллекции[0]);
КонецЕсли;
Иначе
СтруктураТипа.Метаданные = Неопределено;
КонецЕсли;
КонецЕсли;
Если ТаблицаТипов <> Неопределено Тогда
ТаблицаТипов.ЗаполнитьЗначения(СтрокаСлова, "СтрокаОписания");
Если Форма <> Неопределено Тогда
ТаблицаТипов.ЗаполнитьЗначения(Форма, "ДержательМетаданных");
КонецЕсли;
Прервать;
КонецЕсли;
#КонецЕсли
ИначеЕсли Истина
// Опасно широкое условие. Не подходит для Соответствие
И КорневойТипРодителя = Неопределено
И СтрокаСлова.ТипСлова = "Метод"
И СтрокаСлова.Слово = "Получить"
И СтрокаСлова.ТипЗначения = "Произвольный"
Тогда
ТаблицаТипов = ТаблицаТиповЭлементовКоллекции(РодительскаяСтруктураТипа,, ЯзыкПрограммы);
Прервать;
КонецЕсли;
Если КорневойТипРодителя <> Неопределено Тогда
ДоступноеПолеСлова = Неопределено;
Если ПостроительЗапросаРодителя <> Неопределено Тогда
ДоступноеПолеСлова = ПостроительЗапросаРодителя.ДоступныеПоля.Найти(НРег(СтрокаСлова.Слово));
КонецЕсли;
// Частные случаи
Если Истина
И ПостроительЗапросаРодителя <> Неопределено
И (Ложь
Или СтрокаСлова.ТипСлова = "Поле"
Или СтрокаСлова.Слово = "Активность"
Или СтрокаСлова.Слово = "Владелец"
Или СтрокаСлова.Слово = "ВидДвижения"
Или СтрокаСлова.Слово = "Код"
Или СтрокаСлова.Слово = "МоментВремени"
Или СтрокаСлова.Слово = "НомерСтроки"
Или СтрокаСлова.Слово = "Период"
Или СтрокаСлова.Слово = "Регистратор"
//Или СтрокаСлова.Слово = "СубконтоДт" // Закомментировано 14.04.2012
//Или СтрокаСлова.Слово = "СубконтоКт" // Закомментировано 14.04.2012
Или СтрокаСлова.Слово = "СчетДт"
Или СтрокаСлова.Слово = "СчетКт"
Или ЛиТипСКвалификаторами И ДоступноеПолеСлова <> Неопределено)
Тогда
Если ДоступноеПолеСлова = Неопределено Тогда
ЛиДобавляемСлово = Ложь;
Иначе
ОписаниеТиповСлова = ДоступноеПолеСлова.ТипЗначения;
// Мультиметка73777324
Для Каждого ТипЗначенияСлова Из ОписаниеТиповСлова.Типы() Цикл
ШаблонСтруктурыТипа = Новый Структура("СтрокаОписания, ТипЯзыка, Квалификаторы");
ШаблонСтруктурыТипа.СтрокаОписания = СтрокаСлова;
ШаблонСтруктурыТипа.Квалификаторы = ОписаниеТиповСлова;
ЗаполнитьЗначенияСвойств(ШаблонСтруктурыТипа, РодительскаяСтруктураТипа, "ТипЯзыка");
СтруктураТипа = СтруктураТипаИзКонкретногоТипа(ТипЗначенияСлова, ЯзыкПрограммы, ШаблонСтруктурыТипа);
ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа);
КонецЦикла;
КонецЕсли;
Прервать;
ИначеЕсли Ложь
Или (Истина
И ИмяОбщегоТипаРодителяБезДеталей = "КонстантаМенеджер.<Имя константы>"
И СтрокаСлова.Слово = "Получить")
Или (Истина
И ИмяОбщегоТипаРодителяБезДеталей = "КонстантаМенеджерЗначения.<Имя константы>"
И СтрокаСлова.Слово = "Значение")
Тогда
ОписаниеТиповСлова = МетаданныеРодителя.Тип;
// Мультиметка73777324
Для Каждого ТипЗначенияСлова Из ОписаниеТиповСлова.Типы() Цикл
ШаблонСтруктурыТипа = Новый Структура("СтрокаОписания, ТипЯзыка, Квалификаторы");
ШаблонСтруктурыТипа.СтрокаОписания = СтрокаСлова;
ШаблонСтруктурыТипа.Квалификаторы = ОписаниеТиповСлова;
ЗаполнитьЗначенияСвойств(ШаблонСтруктурыТипа, РодительскаяСтруктураТипа, "ТипЯзыка");
СтруктураТипа = СтруктураТипаИзКонкретногоТипа(ТипЗначенияСлова, ЯзыкПрограммы, ШаблонСтруктурыТипа);
ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа);
КонецЦикла;
ИначеЕсли Истина
И СтрокаСлова.ТипСлова = "Метод"
И (Ложь
Или СтрокаСлова.Слово = "Выгрузить"
Или СтрокаСлова.Слово = "ВыгрузитьКолонки")
И ТипЗнч(СтрокаОбщегоТипа.Метаданные) = Тип("ОбъектМетаданных")
Тогда
КонкретныйТип = ИмяТипаИзСтруктурыТипа(СтрокаОбщегоТипа);
Образователь = Неопределено;
Если НРег(КонкретныйТип) = Нрег("Табличная часть") Тогда
МассивФрагментов = ирОбщий.СтрРазделитьЛкс(СтрокаОбщегоТипа.Метаданные.ПолноеИмя());
Если Ложь
Или МассивФрагментов[0] = "Обработка"
Или МассивФрагментов[0] = "Отчет"
Тогда
Образователь = Новый (МассивФрагментов[0] + "Объект." + МассивФрагментов[1]);
Образователь = Образователь[МассивФрагментов[3]];
Иначе
СтруктураОбъекта = ирОбщий.ОбъектБДПоКлючуЛкс(МассивФрагментов[0] + "." + МассивФрагментов[1]);
Образователь = СтруктураОбъекта.Данные[МассивФрагментов[3]];
КонецЕсли;
ИначеЕсли НРег(СтрокаОбщегоТипа.ИмяОбщегоТипа) = Нрег("ПланСчетовВидыСубконто.<Имя плана счетов>") Тогда
МассивФрагментов = ирОбщий.СтрРазделитьЛкс(СтрокаОбщегоТипа.Метаданные.ПолноеИмя());
СтруктураОбъекта = ирОбщий.ОбъектБДПоКлючуЛкс(МассивФрагментов[0] + "." + МассивФрагментов[1]);
Образователь = СтруктураОбъекта.Данные.ВидыСубконто;
ИначеЕсли Ложь
Или НРег(СтрокаОбщегоТипа.ИмяОбщегоТипа) = Нрег("ВытесняющиеВидыРасчета.<Имя плана видов расчета>")
Или НРег(СтрокаОбщегоТипа.ИмяОбщегоТипа) = Нрег("БазовыеВидыРасчета.<Имя плана видов расчета>")
Или НРег(СтрокаОбщегоТипа.ИмяОбщегоТипа) = Нрег("ВедущиеВидыРасчета.<Имя плана видов расчета>")
Тогда
МассивФрагментов = ирОбщий.СтрРазделитьЛкс(СтрокаОбщегоТипа.Метаданные.ПолноеИмя());
СтруктураОбъекта = ирОбщий.ОбъектБДПоКлючуЛкс(МассивФрагментов[0] + "." + МассивФрагментов[1]);
ИмяТЧ = ирОбщий.ПервыйФрагментЛкс(СтрокаОбщегоТипа.ИмяОбщегоТипа);
Попытка
Образователь = СтруктураОбъекта.Данные[ИмяТЧ];
Исключение
КонецПопытки;
ИначеЕсли Найти(КонкретныйТип, "<") = 0 Тогда
СтруктураОбъекта = ирОбщий.ОбъектБДПоКлючуЛкс(ирКэш.ИмяТаблицыИзМетаданныхЛкс(СтрокаОбщегоТипа.Метаданные.ПолноеИмя()));
Образователь = СтруктураОбъекта.Данные;
КонецЕсли;
Если Образователь <> Неопределено Тогда
Если ТипЗнч(Образователь) = Тип("ТаблицаЗначений") Тогда
Образователь = Образователь;
Иначе
Образователь = Образователь.ВыгрузитьКолонки();
КонецЕсли;
СтруктураТипа.Метаданные = Образователь;
КонецЕсли;
ИначеЕсли Истина
И (Ложь
Или СтрокаСлова.Слово = "СрезПервых"
Или СтрокаСлова.Слово = "СрезПоследних")
И КорневойТипРодителя = "РегистрСведений"
И МетаданныеРодителя.ПериодичностьРегистраСведений = мМетаданные.СвойстваОбъектов.ПериодичностьРегистраСведений.Непериодический
Тогда
ЛиДобавляемСлово = Ложь;
Прервать;
ИначеЕсли Истина
И (Ложь
Или СтрокаСлова.Слово = "Остатки"
Или СтрокаСлова.Слово = "ОстаткиИОбороты")
И КорневойТипРодителя = "РегистрНакопления"
И МетаданныеРодителя.ВидРегистра = мМетаданные.СвойстваОбъектов.ВидРегистраНакопления.Обороты
Тогда
ЛиДобавляемСлово = Ложь;
Прервать;
ИначеЕсли Истина
И (Ложь
Или СтрокаСлова.Слово = "ОборотыДтКт")
И КорневойТипРодителя = "РегистрБухгалтерии"
И Не МетаданныеРодителя.Корреспонденция
Тогда
ЛиДобавляемСлово = Ложь;
Прервать;
Иначе
ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа);
КонецЕсли;
ИначеЕсли Истина
И СтрокаСлова.Слово = "Выполнить"
И СтрокаСлова.ТипСлова = "Метод"
И ТипЗнч(МетаданныеРодителя) = Тип("Запрос")
Тогда
ПостроительЗапроса = ПостроительЗапросаИзТекстаДляТипа(МетаданныеРодителя.Текст);
СтруктураТипа.Метаданные = ПостроительЗапроса;
ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа, Ложь);
ИначеЕсли Истина
И СтрокаСлова.Слово = "Выгрузить"
И СтрокаСлова.ТипСлова = "Метод"
И (Ложь
Или ТипЗнч(МетаданныеРодителя) = Тип("Запрос")
Или ТипЗнч(МетаданныеРодителя) = Тип("ПостроительЗапроса"))
Тогда
ПостроительЗапроса = МетаданныеРодителя;
Если ТипЗнч(ПостроительЗапроса) = Тип("Запрос") Тогда
ПостроительЗапроса = ПостроительЗапросаИзТекстаДляТипа(ПостроительЗапроса.Текст);
КонецЕсли;
ПодготовитьМетаданныеПостроителяЗапроса(ПостроительЗапроса, РодительскаяСтруктураТипа.ДержательМетаданных);
СтруктураТипа.Метаданные = ПустаяТаблицаЗначенийИзПостроителя(ПостроительЗапроса);
ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа, Ложь);
ИначеЕсли Истина
И СтрокаСлова.Слово = "Выгрузить"
И СтрокаСлова.ТипСлова = "Метод"
И (Ложь
Или ТипЗнч(СтрокаОбщегоТипа.Метаданные) = Тип("ДанныеФормыКоллекция")
Или ТипЗнч(СтрокаОбщегоТипа.Метаданные) = Тип("ДанныеФормыСтруктураСКоллекцией"))
Тогда
#Если Клиент Тогда
ТаблицаЗначений = Новый ТаблицаЗначений;
Для Каждого КлючИЗначение Из ДочерниеСвойстваДанныхФормы(МетаданныеРодителя,, РодительскаяСтруктураТипа.ДержательМетаданных, Слово) Цикл
ТаблицаЗначений.Колонки.Добавить(КлючИЗначение.Ключ, КлючИЗначение.Значение);
КонецЦикла;
СтруктураТипа.Метаданные = ТаблицаЗначений;
ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа, Ложь);
#КонецЕсли
ИначеЕсли Истина
И СтрокаСлова.Слово = "Значение"
И СтрокаСлова.ТипСлова = "Свойство"
И ТипЗнч(СтрокаОбщегоТипа.Метаданные) = Тип("СписокЗначений")
И СтрокаОбщегоТипа.Метаданные.ТипЗначения.Типы().Количество() = 1
Тогда
СтруктураТипа = СтруктураТипаИзКонкретногоТипа(СтрокаОбщегоТипа.Метаданные.ТипЗначения.Типы()[0]);
ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа, Ложь);
Иначе
Если Истина
И ИмяОбщегоТипаСлова = "Форма" // TODO возможно нужно заменить на ирОбщий.ЛиИмяТипаФормыЛкс()
И СтрокаСлова.Слово = "ЭтаФорма"
Тогда
ДобавитьВТаблицуТипов(ТаблицаТипов, РодительскаяСтруктураТипа, Истина);
Иначе
ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа, Ложь);
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если Не ЛиДобавляемСлово Тогда
Продолжить;
КонецЕсли;
Если ТаблицаТипов.Количество() = 0 Тогда
ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа);
КонецЕсли;
КонецЕсли;
ТипЗначения = СтрокаСлова.ТипЗначения;
Если ЛиТипСКвалификаторами Тогда
ТипЗначения = "??," + ТипЗначения;
КонецЕсли;
ДобавитьВТаблицуСлов(ТаблицаСлов, СтрокаСлова.Слово, СтрокаСлова.ТипСлова, ТаблицаТипов, ТипЗначения, "Предопределенный");
КонецЦикла;
Если ИспользоватьКэширование Тогда
СтруктураТипаГлобальный = НоваяСтруктураТипа("Глобальный");
СтруктураТипаГлобальный.Метаданные = Метаданные;
СтруктураТипаГлобальный.Конструктор = РодительскаяСтруктураТипа.Конструктор;
СтруктураТипаГлобальный.ТипЯзыка = РодительскаяСтруктураТипа.ТипЯзыка;
СловаКонтекстаМетаданные(СтруктураТипаГлобальный,, ТипСлова,, ЯзыкПрограммы,,, ВычислятьТипы, ФлагиКомпиляции,, ТаблицаСлов,,,, БазовоеРасширениеКонфигурации);
ТаблицаСловИзКэша = ТаблицаСлов.Скопировать();
мКэшСловГлобальногоКонтекста[КлючКэширования] = ТаблицаСловИзКэша;
Если мНаборыСлов <> Неопределено Тогда
мНаборыСлов.Вставить(КлючКэширования, ТаблицаСловИзКэша);
ТаблицаСлов.Очистить();
КонецЕсли;
КонецЕсли;
КонецЦикла;
Возврат ТаблицаСлов;
КонецФункции
//.
// Параметры:
// ПостроительЗапроса - ПостроительЗапроса -
// Возвращаемое значение:
// ТаблицаЗначений, Неопределено -
Функция ПустаяТаблицаЗначенийИзПостроителя(Знач ПостроительЗапроса) Экспорт
ТаблицаЗначений = Новый ТаблицаЗначений;
Для Каждого ВыбранноеПоле Из ПостроительЗапроса.ВыбранныеПоля Цикл
ТаблицаЗначений.Колонки.Добавить(ВыбранноеПоле.Имя, ПостроительЗапроса.ДоступныеПоля[ВыбранноеПоле.Имя].ТипЗначения);
КонецЦикла;
Возврат ТаблицаЗначений;
КонецФункции
// Получает внутреннюю таблицу метаданных слов заданного родительского типа.
//
// Параметры:
// РодительскаяСтруктураТипа - - Структура;
// Слово - - Строка, *Неопределено - для отбора;
// ТипСлова - - Строка, *Неопределено - для отбора;
// ВнутриГруппыОбщихМодулей - Булево - ;
// ЯзыкПрограммы - - *Число, 0;
// ТекущийИндекс - Строка - выражение в квадратных скобках.
// ВнешниеФункцииКомпоновкиДанных - -
// ВычислятьТипы - -
// ФлагиКомпиляции - см. НовыеФлагиКомпиляции() -
// МодульМетаданныхДинамический - -
// ТаблицаСлов - -
// ВычислятьТипыМетодовМодулей - Булево -
// ЭтоЛокальныйКонтекст - Булево -
// БазовоеРасширениеКонфигурации - Строка - "" - основная конфигурация, "*" - все расширения
//
// Возвращаемое значение:
// ТаблицаЗначений - с колонками "Слово", "ТипСлова", "ТаблицаТипов".
//
Функция СловаКонтекстаМетаданные(Знач РодительскаяСтруктураТипа, Знач Слово = Неопределено, Знач ТипСлова = Неопределено, Знач ВнутриГруппыОбщихМодулей = Ложь, Знач ЯзыкПрограммы = 0,
Знач ТекущийИндекс = Неопределено, Знач ВнешниеФункцииКомпоновкиДанных = Истина, Знач ВычислятьТипы = Истина, Знач ФлагиКомпиляции = Неопределено, Знач МодульМетаданныхДинамический = Неопределено,
Знач ТаблицаСлов = Неопределено, Знач ВычислятьТипыМетодовМодулей = Ложь, Знач ЭтоЛокальныйКонтекст = Ложь, Знач ЛиВместеСЛокальнымКонтекстом = Ложь, Знач БазовоеРасширениеКонфигурации = "") Экспорт
Если ТаблицаСлов = Неопределено Тогда
ТаблицаСлов = НоваяТаблицаСвойствТипа();
КонецЕсли;
Если Ложь
Или ТипСлова = "Конструктор"
Или РодительскаяСтруктураТипа.Конструктор
Или Не ЗначениеЗаполнено(РодительскаяСтруктураТипа.ИмяОбщегоТипа) // родительский контекст является процедурой
Или РодительскаяСтруктураТипа.ИмяОбщегоТипа = "Произвольный"
Или РодительскаяСтруктураТипа.ИмяОбщегоТипа = "Неопределено"
Тогда
Возврат ТаблицаСлов;
КонецЕсли;
// Мультиметка3398476724
ЛиСеансТолстогоКлиентаУП = ирКэш.ЛиСеансТолстогоКлиентаУПЛкс();
НаСервере = ирОбщий.СвойствоСтруктурыЛкс(ФлагиКомпиляции, "Сервер", Истина);
КлиентОбычноеПриложение = ирОбщий.СвойствоСтруктурыЛкс(ФлагиКомпиляции, "КлиентОбычноеПриложение", Не ЛиСеансТолстогоКлиентаУП);
КлиентУправляемоеПриложение = ирОбщий.СвойствоСтруктурыЛкс(ФлагиКомпиляции, "КлиентУправляемоеПриложение", ЛиСеансТолстогоКлиентаУП);
БезКонтекста = ирОбщий.СвойствоСтруктурыЛкс(ФлагиКомпиляции, "БезКонтекста", ЛиСеансТолстогоКлиентаУП);
ПредставлениеМетаданных = ирОбщий.ПредставлениеЗначенияЛкс(РодительскаяСтруктураТипа.Метаданные);
ЭтоМетаданныеТабличнойЧастиВнешнейОбработки = ирОбщий.ПервыйФрагментЛкс(ПредставлениеМетаданных) = "ВнешняяОбработкаТабличнаяЧасть";
Если Не ирОбщий.СтрНачинаетсяСЛкс(ПредставлениеМетаданных, "Внешн") Тогда
КонкретныйТип = ИмяТипаИзСтруктурыТипа(РодительскаяСтруктураТипа);
Если Найти(ирОбщий.ПервыйФрагментЛкс(КонкретныйТип, "["), "<") > 0 Тогда
// Такой конкретный тип не разрешен
Возврат ТаблицаСлов;
КонецЕсли;
КонецЕсли;
Если Слово <> Неопределено Тогда
ВычислятьТипыМетодовМодулей = Истина;
КонецЕсли;
Если Слово <> Неопределено И ТекущийИндекс <> Неопределено Тогда
Если Ложь
Или РодительскаяСтруктураТипа.ИмяОбщегоТипа = "Соответствие"
Или РодительскаяСтруктураТипа.ИмяОбщегоТипа = "ФиксированноеСоответствие"
Тогда
Если Истина
И ТипЗнч(РодительскаяСтруктураТипа.Метаданные) = Тип("Структура")
И РодительскаяСтруктураТипа.Метаданные.Значение <> Неопределено
Тогда
ТаблицаТипов = ДобавитьВТаблицуТипов(, РодительскаяСтруктураТипа.Метаданные.Значение);
ДобавитьВТаблицуСлов(ТаблицаСлов, "*", "Свойство", ТаблицаТипов,, "Метаданные1");
Возврат ТаблицаСлов;
КонецЕсли;
ИначеЕсли Ложь
Или РодительскаяСтруктураТипа.ИмяОбщегоТипа = "Структура"
Или РодительскаяСтруктураТипа.ИмяОбщегоТипа = "ФиксированнаяСтруктура"
Тогда
// у них значениями именованных свойств являются произвольные типы
Иначе
ЛиИндексИдентификатор = Ложь;
RegExp.Global = Ложь;
RegExp.Pattern = "^""(" + шИмя + ")""$";
РезультатСтроковойКонстанты = RegExp.НайтиВхождения(Слово);
Если РезультатСтроковойКонстанты.Количество() > 0 Тогда
Слово = РезультатСтроковойКонстанты[0].SubMatches(0);
RegExp.Pattern = "^(" + шИмя + ")$";
ЛиИндексИдентификатор = RegExp.Проверить(Слово);
КонецЕсли;
Если Не ЛиИндексИдентификатор Тогда
ТаблицаТипов = ТаблицаТиповЭлементовКоллекции(РодительскаяСтруктураТипа, Слово, ЯзыкПрограммы);
ДобавитьВТаблицуСлов(ТаблицаСлов, "*", "Свойство", ТаблицаТипов,, "Метаданные1");
Возврат ТаблицаСлов;
КонецЕсли;
КонецЕсли;
КонецЕсли;
ЭтоГруппаОбщихМодулей = Ложь;
ПолноеИмяПодсистемыИР = ирОбщий.ИмяПродуктаЛкс();
МаксЧислоТиповДляАнализа = МаксЧислоТиповДляАнализа();
ТаблицаОбщихТиповСтруктурыТипа = ТаблицаОбщихТиповИзСтруктурыТипа(РодительскаяСтруктураТипа, ЭтоЛокальныйКонтекст);
НомерВерсииПлатформы = ирКэш.НомерВерсииПлатформыЛкс();
Для Каждого СтрокаОбщегоТипа Из ТаблицаОбщихТиповСтруктурыТипа Цикл
ИмяОбщегоТипаРодителя = СтрокаОбщегоТипа.ИмяОбщегоТипа;
Если Истина
И ИмяОбщегоТипаРодителя = "Глобальный"
И РодительскаяСтруктураТипа.ИмяОбщегоТипа <> "Глобальный" // пропускаем вызов для заполнения кэша
И Слово = Неопределено
И ТекущийИндекс = Неопределено
Тогда
// Подразумеваем, что в ТаблицаСлов уже помещен кэш Предопределенные+Метаданные
Продолжить;
КонецЕсли;
Если ирОбщий.СтрокиРавныЛкс(ИмяОбщегоТипаРодителя, "ISWbemObject {WbemScripting.SwbemLocator}") Тогда
Если ТипЗнч(СтрокаОбщегоТипа.Метаданные) = Тип("COMОбъект") Тогда
СтруктураЦикла = Новый Структура();
Попытка
СтруктураЦикла.Вставить("Свойство", СтрокаОбщегоТипа.Метаданные.Properties_);
СтруктураЦикла.Вставить("Метод", СтрокаОбщегоТипа.Метаданные.Methods_);
Исключение
КонецПопытки;
Для Каждого КлючИЗначение Из СтруктураЦикла Цикл
КоллекцияСвойств = КлючИЗначение.Значение;
лТипСлова = КлючИЗначение.Ключ;
Если Истина
И ТипСлова <> Неопределено
И Не ирОбщий.СтрокиРавныЛкс(лТипСлова, ТипСлова)
Тогда
Продолжить;
КонецЕсли;
Для Каждого Свойство Из КоллекцияСвойств Цикл
ИмяСвойства = Свойство.Name;
Если Истина
И Слово <> Неопределено
И Не ирОбщий.СтрокиРавныЛкс(ИмяСвойства, Слово)
Тогда
Продолжить;
КонецЕсли;
ТаблицаТипов = НоваяТаблицаТипов();
СтруктураТипа = ТаблицаТипов.Добавить();
СтруктураТипа.СтрокаОписания = Свойство;
СтруктураТипа.ИмяОбщегоТипа = ирОбщий.ИмяТипаИзКвалификаторовWMIЛкс(Свойство);
СтруктураТипа.Метаданные = РодительскаяСтруктураТипа.Метаданные;
ДобавитьВТаблицуСлов(ТаблицаСлов, ИмяСвойства, лТипСлова, ТаблицаТипов,, "Метаданные");
КонецЦикла;
КонецЦикла;
КонецЕсли;
КонецЕсли;
МетаданныеРодителя = СтрокаОбщегоТипа.Метаданные;
Если Ложь
Или ИмяОбщегоТипаРодителя = "Локальный"
Или (Истина
И ИмяОбщегоТипаРодителя <> "Глобальный"
И ФлагиКомпиляции <> Неопределено
И ФлагиКомпиляции.БезКонтекста
И ЭтоЛокальныйКонтекст)
Тогда
НайденныеСтроки = Новый Массив;
Иначе
КорневойТипРодителя = Неопределено;
ПостроительЗапросаРодителя = Неопределено;
Если РодительскаяСтруктураТипа.ТипЯзыка <> "ИмяТипа" Тогда
ТипМетаданныхРодителя = ТипЗнч(МетаданныеРодителя);
Если Ложь
Или ТипМетаданныхРодителя = Тип("ОбъектМетаданных")
Или (Истина
И ЭтоИнтеграция
И (Ложь
Или ТипМетаданныхРодителя = Тип("СправочникСсылка.МетаданныеИис")
Или ТипМетаданныхРодителя = Тип("СправочникСсылка.СвойстваМетаданныхИис")))
Тогда
Если ТипМетаданныхРодителя = Тип("ОбъектМетаданных") Тогда
КорневойТипРодителя = ирОбщий.КорневойТипКонфигурацииЛкс(МетаданныеРодителя);
Иначе
КорневойТипРодителя = ирОбщий.КорневойТипКонфигурацииЛкс(КэшОбъект(МетаданныеРодителя).ПолноеИмя);
КонецЕсли;
ПостроительЗапросаРодителя = ПостроительЗапросаПоСтруктуреТипа(СтрокаОбщегоТипа, РодительскаяСтруктураТипа.ВиртуальнаяТаблица);
КонецЕсли;
КонецЕсли;
Если Истина
И ЯзыкПрограммы = 2
И ИмяОбщегоТипаРодителя = "Глобальный"
И ВнешниеФункцииКомпоновкиДанных
Тогда
СтруктураКлюча = Новый Структура("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка, НСлово", ИмяОбщегоТипаРодителя, 0, РодительскаяСтруктураТипа.ТипЯзыка, НРег("<Имя общего модуля>"));
Иначе
СтруктураКлюча = Новый Структура("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка", ИмяОбщегоТипаРодителя, ЯзыкПрограммы, РодительскаяСтруктураТипа.ТипЯзыка);
КонецЕсли;
Если ТипСлова <> Неопределено Тогда
СтруктураКлюча.Вставить("ТипСлова", ТипСлова);
КонецЕсли;
НайденныеСтроки = ТаблицаШаблоновКонтекстов.НайтиСтроки(СтруктураКлюча);
КонецЕсли;
ПредыдущаяСтрокаВида = Неопределено; // Для регистра бухгалтерии
Для Каждого СтрокаВида Из НайденныеСтроки Цикл
Если Ложь
Или (Истина
И ПредыдущаяСтрокаВида <> Неопределено
И ПредыдущаяСтрокаВида.НСлово = СтрокаВида.НСлово
И ПредыдущаяСтрокаВида.ТипСлова = СтрокаВида.ТипСлова)
Или СтрокаВида.НомерВерсииПлатформы > НомерВерсииПлатформы
Или СтрокаВида.ТипСлова = "Событие"
Тогда
Продолжить;
КонецЕсли;
ПредыдущаяСтрокаВида = СтрокаВида;
ЛиТипСКвалификаторами = ирОбщий.ЛиИмяТипаСКвалификаторамиЛкс(СтрокаВида.ТипЗначения);
СхемаКоллекции = Новый Соответствие;
МетаданныеЭлементов = Новый Соответствие;
КоллекцияЗначений = Неопределено;
ИмяЭлементаКоллекции = ирОбщий.ТекстМеждуМаркерамиЛкс(СтрокаВида.Слово, "<", ">", Ложь, Истина);
КлючПоиска = Новый Структура("ИмяОбщегоТипа, ИмяЭлементаКоллекции", ИмяОбщегоТипаРодителя, ИмяЭлементаКоллекции);
СтрокаОписанияВида = Неопределено;
НайденныеСтрокиКоллекций = ТаблицаИменЭлементовКоллекций.НайтиСтроки(КлючПоиска);
Если НайденныеСтрокиКоллекций.Количество() > 0 Тогда
СтрокаОписанияВида = НайденныеСтрокиКоллекций[0];
Если НайденныеСтрокиКоллекций.Количество() > 1 Тогда
#Если Клиент Тогда
Если Истина
И СтрокаОписанияВида.ИмяКоллекции = "ПодчиненныеЭлементы"
И ТипЗнч(РодительскаяСтруктураТипа.Метаданные) = Тип("Форма")
Тогда
// Устранение неоднозначности одноименных типов "ЭлементыФормы" обычной и упрвляемой формы
СтрокаОписанияВида = НайденныеСтрокиКоллекций[1];
КонецЕсли;
#КонецЕсли
КонецЕсли;
КонецЕсли;
Если СтрокаОписанияВида = Неопределено Тогда
КлючПоиска.Удалить("ИмяОбщегоТипа");
НайденныеСтрокиКоллекций = ТаблицаИменЭлементовКоллекций.НайтиСтроки(КлючПоиска);
Если НайденныеСтрокиКоллекций.Количество() > 0 Тогда
СтрокаОписанияВида = НайденныеСтрокиКоллекций[0];
КонецЕсли;
КонецЕсли;
//// Исправление кривоты платформенной справки (неуникальные имена шаблона элемента коллекции между разными типами коллекций)
//Если ИмяЭлементаКоллекции = "<Имя элемента управления>" Тогда
// СтруктураОтбора = Новый Структура("ИмяЭлементаКоллекции, ИмяКоллекции", ИмяЭлементаКоллекции);
// Если ИмяОбщегоТипа = "ВсеЭлементыФормы" Тогда
// СтруктураОтбора.ИмяКоллекции = "Элементы";
// Иначе//Если ИмяОбщегоТипа = "ЭлементыФормы" Тогда
// СтруктураОтбора.ИмяКоллекции = "ЭлементыФормы";
// КонецЕсли;
// СтрокаОписанияВида = ТаблицаИменЭлементовКоллекций.НайтиСтроки(СтруктураОтбора)[0];
//ИначеЕсли ИмяЭлементаКоллекции = "<Имя колонки>" Тогда
// СтруктураОтбора = Новый Структура("ИмяЭлементаКоллекции, ИмяКоллекции", ИмяЭлементаКоллекции);
// Если ИмяОбщегоТипа = "Ячейки" Тогда
// СтруктураОтбора.ИмяКоллекции = "ОформленияЯчеек";
// Иначе//Если ИмяОбщегоТипа = "СтрокаТаблицыЗначений" Тогда
// СтруктураОтбора.ИмяКоллекции = "Колонки";
// КонецЕсли;
// СтрокаОписанияВида = ТаблицаИменЭлементовКоллекций.НайтиСтроки(СтруктураОтбора)[0];
//КонецЕсли;
Если Слово <> Неопределено Тогда
МассивФрагментов = ирОбщий.СтрРазделитьЛкс(СтрокаВида.Слово, ИмяЭлементаКоллекции);
НачалоТекущегоСлова = Лев(Слово, СтрДлина(МассивФрагментов[0]));
КонецТекущегоСлова = Прав(Слово, СтрДлина(МассивФрагментов[1]));
ИмяТекущегоСлова = Сред(Слово, СтрДлина(НачалоТекущегоСлова) + 1,
СтрДлина(Слово) - СтрДлина(КонецТекущегоСлова));
Если НачалоТекущегоСлова + ИмяЭлементаКоллекции + КонецТекущегоСлова <> СтрокаВида.Слово Тогда
Продолжить;
КонецЕсли;
КонецЕсли;
Если СтрокаОписанияВида = Неопределено Тогда
// Имя элемента коллекции не внесено в служебную таблицу
Продолжить;
КонецЕсли;
Если Истина
И СтрокаОписанияВида.ИмяКоллекции = "Предопределенные"
И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") //
Тогда
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ Т.Ссылка ИЗ " + МетаданныеРодителя.ПолноеИмя() + " КАК Т
|ГДЕ Т.Предопределенный
|";
Результат = Запрос.Выполнить().Выгрузить();
МенеджерТипа = ирОбщий.ПолучитьМенеджерЛкс(МетаданныеРодителя);
Для Каждого СтрокаРезультата Из Результат Цикл
СхемаКоллекции.Вставить(МенеджерТипа.ПолучитьИмяПредопределенного(СтрокаРезультата.Ссылка), Новый ОписаниеТипов(ирОбщий.ЗначенияВМассивЛкс(ТипЗнч(СтрокаРезультата.Ссылка))));
КонецЦикла;
ИначеЕсли Ложь
Или (Истина
И (Ложь
Или СтрокаОписанияВида.ИмяКоллекции = "Колонки"
Или СтрокаОписанияВида.ИмяКоллекции = "Поля")
И (Ложь
Или ТипЗнч(МетаданныеРодителя) = Тип("Структура")
Или ТипЗнч(МетаданныеРодителя) = Тип("РезультатЗапроса")
Или ТипЗнч(МетаданныеРодителя) = Тип("ТаблицаЗначений")
Или ТипЗнч(МетаданныеРодителя) = Тип("ДеревоЗначений")
Или ТипЗнч(МетаданныеРодителя) = Тип("ВыборкаИзРезультатаЗапроса")
Или ТипЗнч(МетаданныеРодителя) = Тип("СтрокаТаблицыЗначений")
Или ТипЗнч(МетаданныеРодителя) = Тип("СтрокаДереваЗначений")
))
Или (Истина
И СтрокаОписанияВида.ИмяЭлементаКоллекции = "<Имя колонки списка>"
И ТипЗнч(МетаданныеРодителя) = Тип("ТабличноеПоле"))
Тогда
Если ТипЗнч(МетаданныеРодителя) = Тип("Структура") Тогда
КоллекцияЗначений = МетаданныеРодителя;
ИначеЕсли Найти(ИмяОбщегоТипаРодителя, "Колон") = 0 Тогда // %%%% Некрасиво, но работает
Если СтрокаОписанияВида.ИмяЭлементаКоллекции = "<Имя колонки списка>" Тогда
ДинамическийСписок = МетаданныеРодителя.Значение;
ПостроительСписка = ПостроительЗапросаПоСтруктуреТипа(СтруктураТипаИзЗначения(ДинамическийСписок));
КоллекцияКолонок = ДинамическийСписок.Колонки;
Для Каждого Колонка Из КоллекцияКолонок Цикл
Если Колонка.Имя = "" Тогда
// Антибаг платформы 8.2.16
Продолжить;
КонецЕсли;
СхемаКоллекции.Вставить(Колонка.Имя, ПостроительСписка.ДоступныеПоля[Колонка.Имя].ТипЗначения);
КонецЦикла;
Иначе
Если Ложь
Или ТипЗнч(МетаданныеРодителя) = Тип("ВыборкаИзРезультатаЗапроса")
Или ТипЗнч(МетаданныеРодителя) = Тип("СтрокаТаблицыЗначений")
Или ТипЗнч(МетаданныеРодителя) = Тип("СтрокаДереваЗначений")
Тогда
Попытка
МетаОбъект = МетаданныеРодителя.Владелец();
Исключение
// Строка была удалена
МетаОбъект = Неопределено;
КонецПопытки;
Если МетаОбъект <> Неопределено Тогда
Для Каждого Колонка Из МетаОбъект.Колонки Цикл
Если Колонка.Имя = "" Тогда
// Строка таблицы/дерева при перетаскивании имеет такую колонку (вероятно ошибка платформы)
Продолжить;
КонецЕсли;
СхемаКоллекции.Вставить(Колонка.Имя, МетаданныеРодителя[Колонка.Имя]);
КонецЦикла;
КонецЕсли;
Иначе
Для Каждого Колонка Из МетаданныеРодителя.Колонки Цикл
СхемаКоллекции.Вставить(Колонка.Имя, Колонка.ТипЗначения);
КонецЦикла;
КонецЕсли;
КонецЕсли;
Иначе
Если Ложь
Или ТипЗнч(МетаданныеРодителя) = Тип("ВыборкаИзРезультатаЗапроса")
Или ТипЗнч(МетаданныеРодителя) = Тип("СтрокаТаблицыЗначений")
Или ТипЗнч(МетаданныеРодителя) = Тип("СтрокаДереваЗначений")
Тогда
КоллекцияЗначений = МетаданныеРодителя.Владелец().Колонки;
Иначе
КоллекцияЗначений = МетаданныеРодителя.Колонки;
КонецЕсли;
КонецЕсли;
ИначеЕсли Истина
И СтрокаОписанияВида.ИмяКоллекции = "Колонки"
И ЭтоМетаданныеТабличнойЧастиВнешнейОбработки
Тогда
Для Каждого Колонка Из МетаданныеРодителя.ВыгрузитьКолонки().Колонки Цикл
Если Колонка.Имя = "НомерСтроки" Тогда
Продолжить;
КонецЕсли;
СхемаКоллекции.Вставить(Колонка.Имя, Колонка.ТипЗначения);
КонецЦикла;
ИначеЕсли Истина
И ТипЗнч(МетаданныеРодителя) = Тип("ПостроительЗапроса")
И СтрокаОписанияВида.ИмяКоллекции = "Колонки"
Тогда
ПодготовитьМетаданныеПостроителяЗапроса(МетаданныеРодителя);
Если СтрокаВида.ТипЗначения <> "Произвольный" Тогда
Попытка
ОписаниеТиповЭлемента = Новый ОписаниеТипов(СтрокаВида.ТипЗначения);
Исключение
ОписаниеТиповЭлемента = Неопределено;
КонецПопытки;
КонецЕсли;
Для Каждого ВыбранноеПоле Из МетаданныеРодителя.ВыбранныеПоля Цикл
лДоступноеПоле = МетаданныеРодителя.ДоступныеПоля.Найти(ВыбранноеПоле.Имя);
Если СтрокаВида.ТипЗначения = "Произвольный" Тогда
ОписаниеТиповЭлемента = лДоступноеПоле.ТипЗначения;
КонецЕсли;
СхемаКоллекции.Вставить(ВыбранноеПоле.Имя, ОписаниеТиповЭлемента);
КонецЦикла;
ИначеЕсли Истина
И ТипЗнч(МетаданныеРодителя) = Тип("ПостроительЗапроса")
И СтрокаОписанияВида.ИмяКоллекции = "Поля"
Тогда
ПодготовитьМетаданныеПостроителяЗапроса(МетаданныеРодителя);
Для Каждого ДоступноеПоле Из МетаданныеРодителя.ДоступныеПоля Цикл
СхемаКоллекции.Вставить(ДоступноеПоле.Имя, ДоступноеПоле.ТипЗначения);
КонецЦикла;
ИначеЕсли Истина
И ТипЗнч(МетаданныеРодителя) = Тип("ПостроительЗапроса")
И СтрокаОписанияВида.ИмяКоллекции = "Структура"
Тогда
// Вроде бы мертвая ветка, т.к. для свойства "Параметры" всегда передается готовая структура вместо построителя
Для Каждого КлючИЗначение Из МетаданныеРодителя.Параметры Цикл
СхемаКоллекции.Вставить(ДоступноеПоле.Имя, ДоступноеПоле.ТипЗначения);
КонецЦикла;
ИначеЕсли Ложь
Или (Истина
И СтрокаОписанияВида.ИмяКоллекции = "Структура"
И ТипЗнч(МетаданныеРодителя) = Тип("Структура"))
Или (Истина
И СтрокаОписанияВида.ИмяКоллекции = "ФиксированнаяСтруктура"
И ТипЗнч(МетаданныеРодителя) = Тип("ФиксированнаяСтруктура"))
Или (Истина
И СтрокаОписанияВида.ИмяКоллекции = "НастройкаОформления"
И ТипЗнч(МетаданныеРодителя) = Тип("НастройкаОформления"))
Или (Истина
И СтрокаОписанияВида.ИмяКоллекции = "Отбор"
И ТипЗнч(МетаданныеРодителя) = Тип("Отбор"))
Тогда
КоллекцияЗначений = МетаданныеРодителя;
ИначеЕсли Истина
И СтрокаОписанияВида.ИмяКоллекции = "Колонки"
И (Ложь
Или ТипЗнч(МетаданныеРодителя) = Тип("ДоступноеПолеКомпоновкиДанных")
Или ТипЗнч(МетаданныеРодителя) = Тип("ДоступноеПолеОтбораКомпоновкиДанных"))
Тогда
Для Каждого ДоступноеПоле Из МетаданныеРодителя.Элементы Цикл
СхемаКоллекции.Вставить(ирОбщий.ПоследнийФрагментЛкс("" + ДоступноеПоле.Поле), ДоступноеПоле.ТипЗначения);
КонецЦикла;
ИначеЕсли Истина
И СтрокаОписанияВида.ИмяКоллекции = "ОбщиеРеквизиты"
И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных")
Тогда
Попытка
ОбщиеРеквизиты = Метаданные.ОбщиеРеквизиты;
Исключение
// Платформа 8.2.13 и ниже
ОбщиеРеквизиты = Новый Массив;
КонецПопытки;
СхемаКоллекции = Новый Массив();
Для Каждого ОбщийРеквизит Из ОбщиеРеквизиты Цикл
Если ирОбщий.ЛиОбщийРеквизитИспользуетсяВОбъектеМетаданныхЛкс(ОбщийРеквизит, МетаданныеРодителя) Тогда
СхемаКоллекции.Добавить(ОбщийРеквизит);
КонецЕсли;
КонецЦикла;
ИначеЕсли Истина
И СтрокаОписанияВида.ИмяКоллекции = "Картинки"
И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданныхКонфигурация")
Тогда
Если ЗначениеЗаполнено(Слово) Тогда
МетаКартинка = Метаданные.ОбщиеКартинки.Найти(Слово);
Если МетаКартинка <> Неопределено Тогда
СхемаКоллекции.Вставить(МетаКартинка.Имя, МетаКартинка);
КонецЕсли;
Иначе
// Долго
СхемаКоллекции = Новый Структура;
Для Каждого МетаКартинка Из Метаданные.ОбщиеКартинки Цикл
СхемаКоллекции.Вставить(МетаКартинка.Имя, МетаКартинка);
КонецЦикла;
КонецЕсли;
ИначеЕсли Истина //
И СтрокаОписанияВида.ИмяКоллекции = "Свойства"
И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектXDTO")
Тогда
КоллекцияЗначений = Новый Структура;
ОбъектXDTO = МетаданныеРодителя;
Для Каждого Свойство Из ОбъектXDTO.Свойства() Цикл
Если Истина
И ЗначениеЗаполнено(Свойство.Имя)
//И ОбъектXDTO.Установлено(Свойство.Имя)
Тогда
Если Свойство.ВерхняяГраница > 1 Или Свойство.ВерхняяГраница = -1 Тогда
ЗначениеСвойства = ОбъектXDTO.ПолучитьСписок(Свойство.Имя);
Иначе
ЗначениеСвойства = ОбъектXDTO.Получить(Свойство.Имя);
КонецЕсли;
КоллекцияЗначений.Вставить(Свойство.Имя, ЗначениеСвойства);
КонецЕсли;
КонецЦикла;
ИначеЕсли Истина
И СтрокаОписанияВида.ИмяКоллекции = "Свойства"
И ТипЗнч(МетаданныеРодителя) = Тип("СвойствоXDTO")
Тогда
КоллекцияЗначений = Новый Структура;
ОбъектXDTO = МетаданныеРодителя.ОбъектВладелец;
Свойство = МетаданныеРодителя;
Если ОбъектXDTO.Установлено(Свойство.Имя) Тогда
Если Свойство.ВерхняяГраница > 1 Или Свойство.ВерхняяГраница = -1 Тогда
ЗначениеСвойства = ОбъектXDTO.ПолучитьСписок(Свойство.Имя);
Иначе
ЗначениеСвойства = ОбъектXDTO.Получить(Свойство.Имя);
КонецЕсли;
КоллекцияЗначений.Вставить(Свойство.Имя, ЗначениеСвойства);
КонецЕсли;
ИначеЕсли Истина
И СтрокаОписанияВида.ИмяКоллекции = "Параметры"
И ТипЗнч(МетаданныеРодителя) = Тип("ТабличныйДокумент")
И МетаданныеРодителя.ВысотаТаблицы * МетаданныеРодителя.ШиринаТаблицы < 20000
Тогда
КоллекцияЗначений = Новый Структура;
СписокПараметров = ирОбщий.ПараметрыТабличногоДокументаЛкс(МетаданныеРодителя);
Для Каждого ЭлементСписка Из СписокПараметров Цикл
Попытка
КоллекцияЗначений.Вставить(ЭлементСписка.Значение);
Исключение
// Имена параметров могут содержать запрещенные символы
КонецПопытки;
КонецЦикла;
ИначеЕсли Истина
И СтрокаОписанияВида.ИмяКоллекции = "Свойства" // коллекция упр. формы
И (Ложь
Или ТипЗнч(МетаданныеРодителя) = Тип("ТаблицаЗначений")
Или ТипЗнч(МетаданныеРодителя) = Тип("ДеревоЗначений"))
Тогда
СхемаКоллекции = МетаданныеРодителя.Колонки;
ИначеЕсли Истина
И СтрокаОписанияВида.ИмяКоллекции = "Свойства" // коллекция упр. формы
И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных")
Тогда
СхемаКоллекции = ирКэш.ПоляТаблицыБДЛкс(ирКэш.ИмяТаблицыИзМетаданныхЛкс(МетаданныеРодителя.ПолноеИмя()), Истина);
ИначеЕсли Истина
И СтрокаОписанияВида.ИмяКоллекции = "Свойства" // коллекция упр. формы
И ТипЗнч(МетаданныеРодителя) = Тип("Структура")
И ирОбщий.СвойствоСтруктурыЛкс(МетаданныеРодителя, "Тип") <> ирОбщий.ТипУправляемаяФормаЛкс()
Тогда
СхемаКоллекции = МетаданныеРодителя;
#Если Клиент Тогда
ИначеЕсли Истина
И СтрокаОписанияВида.ИмяКоллекции = "Структура"
И ТипЗнч(МетаданныеРодителя) = Тип("Форма")
Тогда
КоллекцияЗначений = МетаданныеРодителя[РодительскаяСтруктураТипа.СтрокаОписания.Слово];
ИначеЕсли Истина
И СтрокаОписанияВида.ИмяКоллекции = "Реквизиты"
И ирОбщий.ЛиФормаИлиИмитаторЛкс(МетаданныеРодителя)
Тогда
Если ЗначениеЗаполнено(Слово) Тогда
ИмитаторФормы = МетаданныеРодителя;
Если ТипЗнч(МетаданныеРодителя) = ирОбщий.ТипУправляемаяФормаЛкс() Тогда
Попытка
ЗначениеРеквизита = МетаданныеРодителя[Слово];
Исключение
ИмитаторФормы = ирОбщий.СлужебныеДанныеФормыЛкс(МетаданныеРодителя);
КонецПопытки;
КонецЕсли;
Если ТипЗнч(ИмитаторФормы) = Тип("Структура") Тогда
СтруктураИмен = ИменаРеквизитовФормы(ИмитаторФормы, "").Все;
Если СтруктураИмен.Свойство(Слово) Тогда
ЗначениеСлова = СтруктураИмен[Слово];
СхемаКоллекции.Вставить(Слово, ЗначениеСлова);
ИначеЕсли Не ЛиВместеСЛокальнымКонтекстом Тогда
ДобавитьОтсутствиеЭлементаФормы(ИмитаторФормы, "Реквизит:" + Слово);
КонецЕсли;
Иначе
// Для ускорения особенно для управляемой формы
КоллекцияЗначений = Новый Структура;
Попытка
ЗначениеРеквизита = МетаданныеРодителя[Слово];
Исключение
ЗначениеРеквизита = Null;
КонецПопытки;
Если ЗначениеРеквизита <> Null Тогда
КоллекцияЗначений.Вставить(Слово, ЗначениеРеквизита);
КонецЕсли;
КонецЕсли;
Иначе
Если ТипЗнч(МетаданныеРодителя) = Тип("Форма") Тогда
ПутьКРодителю = Неопределено;
Иначе
ПутьКРодителю = "";
КонецЕсли;
СтруктураИмен = ИменаРеквизитовФормы(МетаданныеРодителя, ПутьКРодителю).Все;
Если ТипЗнч(МетаданныеРодителя) = Тип("Структура") Тогда
СхемаКоллекции = СтруктураИмен;
Иначе
КоллекцияЗначений = Новый Структура;
Для Каждого КлючИЗначение Из СтруктураИмен Цикл
Попытка
ЗначениеРеквизита = МетаданныеРодителя[КлючИЗначение.Ключ];
Исключение
Если КлючИЗначение.Значение <> Неопределено Тогда
// Добавленный реквизит был получен через буфер обмена, но пока отсутствует в натуральной форме
ЗначениеРеквизита = ТаблицаТиповИзОписанияТипов(КлючИЗначение.Значение);
Иначе
ЗначениеРеквизита = Неопределено;
КонецЕсли;
КонецПопытки;
КоллекцияЗначений.Вставить(КлючИЗначение.Ключ, ЗначениеРеквизита);
КонецЦикла;
КонецЕсли;
КонецЕсли;
ИначеЕсли Истина
И СтрокаОписанияВида.ИмяКоллекции = "Команды"
И ирОбщий.ЛиФормаИлиИмитаторЛкс(РодительскаяСтруктураТипа.ДержательМетаданных, Ложь)
Тогда
Форма = РодительскаяСтруктураТипа.ДержательМетаданных;
СлужебныеДанные = ирОбщий.СлужебныеДанныеФормыЛкс(Форма);
Если СлужебныеДанные <> Неопределено Тогда
СхемаКоллекции = СлужебныеДанные.Команды;
Если ЗначениеЗаполнено(Слово) И Не СхемаКоллекции.Свойство(Слово) Тогда
ДобавитьОтсутствиеЭлементаФормы(Форма, "Команда:" + Слово);
КонецЕсли;
Иначе
Если ТипЗнч(Форма) = ирОбщий.ТипУправляемаяФормаЛкс() Тогда
СхемаКоллекции = Форма.Команды;
КонецЕсли;
КонецЕсли;
ИначеЕсли Истина
И ТипЗнч(МетаданныеРодителя) = Тип("ДанныеФормыСтруктура")
И РодительскаяСтруктураТипа.СтрокаОписания.Слово = "Параметры"
Тогда
Форма = РодительскаяСтруктураТипа.ДержательМетаданных;
СлужебныеДанные = ирОбщий.СлужебныеДанныеФормыЛкс(Форма);
Если СлужебныеДанные <> Неопределено Тогда
СхемаКоллекции = СлужебныеДанные.Параметры;
// Параметры часто не описаны в структуре формы
//Если ЗначениеЗаполнено(Слово) И Не СхемаКоллекции.Свойство(Слово) Тогда
// ДобавитьОтсутствиеЭлементаФормы(Форма, "Параметр:" + Слово);
//КонецЕсли;
КонецЕсли;
ИначеЕсли Ложь
Или ТипЗнч(МетаданныеРодителя) = Тип("ДинамическийСписок")
Или ТипЗнч(МетаданныеРодителя) = Тип("ДанныеФормыДерево")
Или ТипЗнч(МетаданныеРодителя) = Тип("ДанныеФормыСтруктура")
Или ТипЗнч(МетаданныеРодителя) = Тип("ДанныеФормыСтруктураСКоллекцией")
Или ТипЗнч(МетаданныеРодителя) = Тип("ДанныеФормыКоллекция")
Или ТипЗнч(МетаданныеРодителя) = Тип("ДанныеФормыКоллекцияЭлементовДерева")
// Для следующих сериализация вызывает ошибку
//Или ТипЗнч(МетаданныеРодителя) = Тип("ДанныеФормыЭлементДерева")
//Или ТипЗнч(МетаданныеРодителя) = Тип("ДанныеФормыЭлементКоллекции")
Тогда
Форма = РодительскаяСтруктураТипа.ДержательМетаданных;
ЛиКоллекция = Ложь
Или ирОбщий.ЛиКоллекцияЛкс(МетаданныеРодителя)
Или ТипЗнч(МетаданныеРодителя) = Тип("ДанныеФормыДерево");
СтруктураИмен = ДочерниеСвойстваДанныхФормы(МетаданныеРодителя, ЛиКоллекция, Форма, Слово);
СхемаКоллекции = СтруктураИмен;
Если Не ЛиКоллекция Тогда
Для Каждого КлючИЗначение Из СтруктураИмен Цикл
ЗначениеСвойства = КлючИЗначение.Значение; // ОписаниеТипов
Если Ложь
Или ЗначениеСвойства = Неопределено
Или ЗначениеСвойства.Типы().Количество() = 0
Тогда
ЗначениеСвойства = ТаблицаТиповИзЗначения(МетаданныеРодителя[КлючИЗначение.Ключ]);
Иначе
ЗначениеСвойства = ТаблицаТиповИзОписанияТипов(ЗначениеСвойства);
КонецЕсли;
ЗначениеСвойства.ЗаполнитьЗначения(Форма, "ДержательМетаданных");
Если КоллекцияЗначений = Неопределено Тогда
КоллекцияЗначений = Новый Структура;
КонецЕсли;
КоллекцияЗначений.Вставить(КлючИЗначение.Ключ, ЗначениеСвойства);
КонецЦикла;
КонецЕсли;
ИначеЕсли Ложь
Или (Истина
И СтрокаОписанияВида.ИмяКоллекции = "ЭлементыФормы"
И ТипЗнч(МетаданныеРодителя) = Тип("Форма"))
Или (Истина
И СтрокаОписанияВида.ИмяКоллекции = "Элементы"
И ирОбщий.ЛиФормаИлиИмитаторЛкс(МетаданныеРодителя, Ложь))
Или (Истина
И СтрокаОписанияВида.ИмяКоллекции = "Страницы"
И ТипЗнч(МетаданныеРодителя) = Тип("Панель"))
Или (Истина
И СтрокаОписанияВида.ИмяКоллекции = "Колонки"
И ТипЗнч(МетаданныеРодителя) = Тип("ТабличноеПоле"))
Или (Истина
И СтрокаОписанияВида.ИмяКоллекции = "Кнопки"
И (Ложь
Или ТипЗнч(МетаданныеРодителя) = Тип("КнопкаКоманднойПанели")
Или ТипЗнч(МетаданныеРодителя) = Тип("КнопкиКоманднойПанели")))
Тогда
ДочерниеЭлементы = МетаданныеРодителя[СтрокаОписанияВида.ИмяКоллекции];
Если ИмяОбщегоТипаРодителя = "ОформленияЯчеек" Тогда
СхемаКоллекции = ДочерниеЭлементы;
Иначе
ИмитаторФормы = МетаданныеРодителя;
Если ТипЗнч(МетаданныеРодителя) = ирОбщий.ТипУправляемаяФормаЛкс() Тогда
КоллекцияЗначений = Новый Соответствие;
Для Каждого ЭлементФормы Из ДочерниеЭлементы Цикл
КоллекцияЗначений.Вставить(ЭлементФормы.Имя, ЭлементФормы);
КонецЦикла;
ИмитаторФормы = ирОбщий.СлужебныеДанныеФормыЛкс(МетаданныеРодителя);
ИначеЕсли ТипЗнч(ИмитаторФормы) = Тип("Структура") Тогда
КоллекцияЗначений = Новый Соответствие;
Иначе
КоллекцияЗначений = ДочерниеЭлементы;
КонецЕсли;
Если Истина
И ТипЗнч(ИмитаторФормы) = Тип("Структура")
И ИмитаторФормы.Свойство(СтрокаОписанияВида.ИмяКоллекции)
Тогда
// имитатор формы
Для Каждого КлючИЗначение Из ИмитаторФормы[СтрокаОписанияВида.ИмяКоллекции] Цикл
Если ЗначениеЗаполнено(Слово) И Не ирОбщий.СтрокиРавныЛкс(КлючИЗначение.Ключ, Слово) Тогда
Продолжить;
КонецЕсли;
Если КоллекцияЗначений[КлючИЗначение.Ключ] <> Неопределено Тогда
Продолжить;
КонецЕсли;
СтруктураЭлемента = КлючИЗначение.Значение;
ЗначениеЭлемента = Новый ОписаниеТипов(ирОбщий.ЗначенияВМассивЛкс(СтруктураЭлемента.Тип)); //
Если ЗначениеЗаполнено(Слово) Тогда
ЗначениеЭлемента = ТаблицаТиповИзОписанияТипов(ЗначениеЭлемента);
ЗначениеЭлемента[0].Метаданные = СтруктураЭлемента;
ЗначениеЭлемента[0].ДержательМетаданных = ИмитаторФормы;
ИмяОбщегоТипаРасширения = ИмяТипаРасширенияЭлементаФормы(ЗначениеЭлемента[0].ИмяОбщегоТипа, СтруктураЭлемента);
Если ИмяОбщегоТипаРасширения <> Неопределено Тогда
ЗначениеЭлемента[0].ИмяОбщегоТипа = ИмяОбщегоТипаРасширения;
КонецЕсли;
КонецЕсли;
КоллекцияЗначений.Вставить(КлючИЗначение.Ключ, ЗначениеЭлемента);
КонецЦикла;
Если ЗначениеЗаполнено(Слово) И КоллекцияЗначений[Слово] = Неопределено Тогда
ДобавитьОтсутствиеЭлементаФормы(ИмитаторФормы, "Элемент:" + Слово);
КонецЕсли;
КонецЕсли;
КонецЕсли;
ИначеЕсли Истина
И СтрокаОписанияВида.ИмяКоллекции = "ПодчиненныеЭлементы"
И (Ложь
Или ТипЗнч(МетаданныеРодителя) = ирОбщий.ТипУправляемаяФормаЛкс()
Или ТипЗнч(МетаданныеРодителя) = Тип("ТаблицаФормы")
Или ТипЗнч(МетаданныеРодителя) = Тип("ГруппаФормы"))
Тогда
КоллекцияЗначений = МетаданныеРодителя[СтрокаОписанияВида.ИмяКоллекции];
#КонецЕсли
ИначеЕсли ТипЗнч(МетаданныеРодителя) = Тип("НаборыДанныхСхемыКомпоновкиДанных") Тогда
КоллекцияЗначений = МетаданныеРодителя;
//ИначеЕсли СтрокаОписанияВида.ИмяКоллекции = "Оформление" Тогда
// Для Каждого МетаОбщийМодуль Из МетаданныеРодителя[СтрокаОписанияВида.ИмяКоллекции] Цикл
// Если МетаОбщийМодуль.Глобальный Тогда
// Продолжить;
// КонецЕсли;
// СхемаКоллекции.Вставить(МетаОбщийМодуль.Имя);
// КонецЦикла;
ИначеЕсли Истина
И СтрокаОписанияВида.ИмяКоллекции = "ОбщиеМодули"
И ИмяОбщегоТипаРодителя = "Глобальный"
И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданныхКонфигурация") //
Тогда
СхемаКоллекции = ирКэш.ДоступныеОбщиеМодулиЛкс(НаСервере, КлиентОбычноеПриложение, КлиентУправляемоеПриложение);
Если мДобавленныеОбщиеМодули.Количество() > 0 Тогда
ирОбщий.СкопироватьКоллекциюЛкс(мДобавленныеОбщиеМодули, СхемаКоллекции);
КонецЕсли;
Если Прав(Слово, 1) = "_" Тогда
ЭтоГруппаОбщихМодулей = Истина;
НачальныйФрагмент = НРег(ирОбщий.СтрокаБезКонцаЛкс(Слово));
Слово = Неопределено;
ТаблицаСлов.Очистить();
НоваяСхема = Новый Структура;
Для Каждого КлючИЗначение Из СхемаКоллекции Цикл
Если ирОбщий.СтрНачинаетсяСЛкс(КлючИЗначение.Ключ, НачальныйФрагмент) Тогда
НоваяСхема.Вставить(КлючИЗначение.Ключ, КлючИЗначение.Значение);
КонецЕсли;
КонецЦикла;
СхемаКоллекции = НоваяСхема;
ИначеЕсли Не ЗначениеЗаполнено(Слово) Тогда
СписокЗначений = Новый СписокЗначений;
НоваяСхема = Новый Структура;
Для Каждого КлючИЗначение Из СхемаКоллекции Цикл
СписокЗначений.Добавить(КлючИЗначение.Ключ);
НоваяСхема.Вставить(КлючИЗначение.Ключ, КлючИЗначение.Значение);
КонецЦикла;
СписокЗначений.СортироватьПоЗначению();
СхемаКоллекции = НоваяСхема;
ИмяГруппы = Неопределено;
ЧленыГруппы = Новый Массив;
Для Каждого ИмяМодуляЦикл Из СписокЗначений.ВыгрузитьЗначения() Цикл
Если Истина
И ИмяГруппы <> Неопределено
И ирОбщий.СтрНачинаетсяСЛкс(ИмяМодуляЦикл, ИмяГруппы, Истина)
Тогда
ЧленыГруппы.Добавить(ИмяМодуляЦикл);
Иначе
Если ЧленыГруппы.Количество() > 2 Тогда
СхемаКоллекции.Вставить(ИмяГруппы + "_");
КонецЕсли;
ИмяГруппы = ИмяМодуляЦикл;
ЧленыГруппы.Очистить();
КонецЕсли;
КонецЦикла;
КонецЕсли;
ИначеЕсли Истина
И СтрокаОписанияВида.ИмяКоллекции = "ВидыСубконто"
И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных")
Тогда
//! МетаданныеРодителя = 0; // ОбъектМетаданных: РегистрБухгалтерии
Для Счетчик = 1 По МетаданныеРодителя.ПланСчетов.МаксКоличествоСубконто Цикл
СхемаКоллекции.Вставить(Строка(Счетчик), МетаданныеРодителя.ПланСчетов.ВидыСубконто);
КонецЦикла;
ИначеЕсли СтрокаОписанияВида.ИмяКоллекции = "Движения" Тогда
Если ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") Тогда
//! МетаданныеРодителя = 0; // ОбъектМетаданных: Документ
Для Каждого МетаРегистр Из МетаданныеРодителя.Движения Цикл
МассивФрагментов = ирОбщий.СтрРазделитьЛкс(МетаРегистр.ПолноеИмя());
СхемаКоллекции.Вставить(МетаРегистр.Имя, Новый ОписаниеТипов(МассивФрагментов[0] + "НаборЗаписей." + МассивФрагментов[1]));
КонецЦикла;
ИначеЕсли ТипЗнч(МетаданныеРодителя) = Тип("КоллекцияДвижений") Тогда
Для Каждого НаборЗаписейРегистра Из МетаданныеРодителя Цикл // РегистрСведенийНаборЗаписей.КурсыВалют
СхемаКоллекции.Вставить(НаборЗаписейРегистра.Метаданные().Имя, НаборЗаписейРегистра);
КонецЦикла;
ИначеЕсли Истина
И Слово <> Неопределено
И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданныхКонфигурация") //
Тогда
МетаданныеРегистра = Метаданные.РегистрыСведений.Найти(Слово);
Если МетаданныеРегистра = Неопределено Тогда
МетаданныеРегистра = Метаданные.РегистрыНакопления.Найти(Слово);
КонецЕсли;
Если МетаданныеРегистра = Неопределено Тогда
МетаданныеРегистра = Метаданные.РегистрыБухгалтерии.Найти(Слово);
КонецЕсли;
Если МетаданныеРегистра = Неопределено Тогда
МетаданныеРегистра = Метаданные.РегистрыРасчета.Найти(Слово);
КонецЕсли;
Если МетаданныеРегистра <> Неопределено Тогда
МассивФрагментов = ирОбщий.СтрРазделитьЛкс(МетаданныеРегистра.ПолноеИмя());
СхемаКоллекции.Вставить(МассивФрагментов[1], Новый ОписаниеТипов(МассивФрагментов[0] + "НаборЗаписей." + МассивФрагментов[1]));
КонецЕсли;
КонецЕсли;
ИначеЕсли Истина
И СтрокаОписанияВида.ИмяКоллекции = "ТочкиМаршрута"
И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных")
Тогда
КоллекцияЗначений = ирОбщий.ПолучитьМенеджерЛкс(МетаданныеРодителя)[СтрокаОписанияВида.ИмяКоллекции];
ИначеЕсли Истина
И СтрокаОписанияВида.ИмяКоллекции = "<Имя коллекции метаданных>"
И (Ложь
Или ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных")
Или ТипЗнч(МетаданныеРодителя) = Тип("КоллекцияОбъектовМетаданных")
Или ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданныхКонфигурация"))
Тогда
Если ТипЗнч(МетаданныеРодителя) = Тип("КоллекцияОбъектовМетаданных") Тогда
КоллекцияЗначений = МетаданныеРодителя;
Иначе
ИмяКоллекцииОбъектовМетаданных = ирОбщий.ТекстМеждуМаркерамиЛкс(ИмяОбщегоТипаРодителя, МаркерКоллекцииОбъектовМетаданных + ": ", , Ложь);
Если ЗначениеЗаполнено(ИмяКоллекцииОбъектовМетаданных) Тогда
СтрокаКорневогоТипа = ОписаниеТипаМетаОбъектов(, ИмяКоллекцииОбъектовМетаданных);
Если СтрокаКорневогоТипа <> Неопределено Тогда
//КоллекцияЗначений = МетаданныеРодителя[ИмяКоллекцииОбъектовМетаданных];
Попытка
КоллекцияЗначений = МетаданныеРодителя[РодительскаяСтруктураТипа.СтрокаОписания.Слово];
Исключение
ИнформацияОбОшибке = ИнформацияОбОшибке(); // Для отладки
КонецПопытки;
КонецЕсли;
КонецЕсли;
КонецЕсли;
ИначеЕсли Истина
//И СтрокаОписанияВида.ИмяКоллекции = "<Имя коллекции метаданных>"
И ЭтоИнтеграция
И (Ложь
Или ТипЗнч(МетаданныеРодителя) = Тип("СправочникСсылка.КонфигурацииМетаданныхИис")
Или ТипЗнч(МетаданныеРодителя) = Тип("СправочникСсылка.МетаданныеИис"))
Тогда
Если СтрокаОписанияВида.ИмяКоллекции = "<Имя коллекции метаданных>" Тогда
ИмяКоллекцииОбъектовМетаданных = ирОбщий.ТекстМеждуМаркерамиЛкс(ИмяОбщегоТипаРодителя, МаркерКоллекцииОбъектовМетаданных + ": ", , Ложь);
Иначе
ИмяКоллекцииОбъектовМетаданных = СтрокаОписанияВида.ИмяКоллекции;
КонецЕсли;
Если ЗначениеЗаполнено(ИмяКоллекцииОбъектовМетаданных) Тогда
СтрокаКорневогоТипа = ОписаниеТипаМетаОбъектов(, ИмяКоллекцииОбъектовМетаданных);
Запрос = Новый Запрос;
Если СтрокаКорневогоТипа <> Неопределено Тогда
//лИмяКоллекции = РодительскаяСтруктураТипа.СтрокаОписания.Слово;
Если ИмяКоллекцииОбъектовМетаданных = "Реквизиты" Тогда
ТекстЗапроса = "ВЫБРАТЬ Наименование КАК Имя, Типы Как Значение ИЗ Справочник.СвойстваМетаданныхИис
|ГДЕ КонфигурацияМетаданных = &Владелец И Вид <> ЗНАЧЕНИЕ(Перечисление.ВидыСвойствМетаданныхИис.Свойство)";
Запрос.Текст = ТекстЗапроса;
Запрос.УстановитьПараметр("Владелец", МетаданныеРодителя);
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
СхемаКоллекции[Выборка.Имя] = Выборка.Значение.Выгрузить().ВыгрузитьКолонку("Тип");
КонецЦикла;
Иначе
ТекстЗапроса = "ВЫБРАТЬ Имя, Ссылка КАК Значение ИЗ Справочник.МетаданныеИис
|ГДЕ КонфигурацияМетаданных = &Владелец И ТипМетаданных.ИмяМножественное = &ИмяРодителя";
Запрос.УстановитьПараметр("ИмяРодителя", ИмяКоллекцииОбъектовМетаданных);
Запрос.Текст = ТекстЗапроса;
Запрос.УстановитьПараметр("Владелец", МетаданныеРодителя);
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
СхемаКоллекции[Выборка.Имя] = Выборка.Значение;
КонецЦикла;
КонецЕсли;
КонецЕсли;
Иначе
//КоллекцияЗначений = МетаданныеРодителя;
КонецЕсли;
ИначеЕсли Истина
И ТипЗнч(МетаданныеРодителя) = Тип("ОбщийМодуль")
Тогда
// Платформа пока не дает узнать имя модуля
Иначе
Если мМассивИсключенийИменКоллекций.НайтиПоЗначению(СтрокаОписанияВида.ИмяКоллекции) <> Неопределено Тогда
Продолжить;
КонецЕсли;
СхемаКоллекции = МетаданныеРодителя;
Если ТипЗнч(МетаданныеРодителя) <> Тип("КоллекцияОбъектовМетаданных") Тогда
ЦелевойТип = Неопределено;
Если Найти(СтрокаОбщегоТипа.ИмяОбщегоТипа, "<") = 0 Тогда
Попытка
ЦелевойТип = Тип(СтрокаОбщегоТипа.ИмяОбщегоТипа);
Исключение
КонецПопытки;
КонецЕсли;
Попытка
Если ТипЗнч(МетаданныеРодителя) = ЦелевойТип Тогда
СхемаКоллекции = МетаданныеРодителя;
Иначе
СхемаКоллекции = МетаданныеРодителя[СтрокаОписанияВида.ИмяКоллекции];
КонецЕсли;
Исключение
Продолжить;
КонецПопытки;
КонецЕсли;
КонецЕсли;
Если КоллекцияЗначений = Неопределено Тогда
КоллекцияЗначений = СхемаКоллекции;
Если Слово <> Неопределено Тогда
ЭлементСхемы = Неопределено;
Если Ложь
Или ТипЗнч(КоллекцияЗначений) = Тип("ФиксированнаяСтруктура")
Или ТипЗнч(КоллекцияЗначений) = Тип("ФиксированноеСоответствие")
Или ТипЗнч(КоллекцияЗначений) = Тип("Структура")
Или ТипЗнч(КоллекцияЗначений) = Тип("Соответствие")
Тогда
//Для Каждого ЭлементКоллекции Из КоллекцияЗначений Цикл
// Если ЭлементКоллекции.Ключ = ИмяТекущегоСлова Тогда
// ЭлементСхемы = ЭлементКоллекции.Значение;
// Прервать;
// КонецЕсли;
//КонецЦикла;
Попытка
ЭлементСхемы = КоллекцияЗначений[ИмяТекущегоСлова];
Исключение
КонецПопытки;
Иначе
ЭлементСхемы = Null;
Если ТипЗнч(КоллекцияЗначений) <> Тип("Массив") Тогда
Попытка
ЭлементСхемы = КоллекцияЗначений.Найти(ИмяТекущегоСлова);
Исключение
КонецПопытки;
КонецЕсли;
Если ЭлементСхемы = Null Тогда
ЭлементСхемы = Неопределено;
Для Каждого ЭлементКоллекции Из КоллекцияЗначений Цикл
Если ЭлементКоллекции.Имя = ИмяТекущегоСлова Тогда
ЭлементСхемы = ЭлементКоллекции;
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЕсли;
КоллекцияЗначений = Новый Соответствие;
Если ЭлементСхемы <> Неопределено Тогда
КоллекцияЗначений.Вставить(ИмяТекущегоСлова, ЭлементСхемы);
КонецЕсли;
КонецЕсли;
Иначе
Если Слово <> Неопределено Тогда
Попытка
ЭлементСхемы = КоллекцияЗначений[ИмяТекущегоСлова];
Исключение
ЭлементСхемы = Null;
КонецПопытки;
КоллекцияЗначений = Новый Соответствие;
Если ЭлементСхемы <> Null Тогда
КоллекцияЗначений.Вставить(ИмяТекущегоСлова, ЭлементСхемы);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если КоллекцияЗначений = Неопределено Тогда
КоллекцияЗначений = Новый Массив();
КонецЕсли;
ЭтоСубконто = Найти(СтрокаВида.Слово, "Субконто") = 1;
ПредыдущаяТаблицаТипов = Неопределено;
ВычислятьТипыЦикл = ВычислятьТипы Или КоллекцияЗначений.Количество() < 100;
ИмяКолонкиФлага = ИмяКолонкиФлагаВнутриТаблицы();
Если ЗначениеЗаполнено(СтрокаВида.ТипЗначения) Тогда
ТипЗначенияСлова = "," + СтрокаВида.ТипЗначения;
ТипЗначенияСлова = СтрЗаменить(ТипЗначенияСлова, ",Произвольный", "");
Иначе
ТипЗначенияСлова = "";
КонецЕсли;
Для Каждого ЭлементКоллекции Из КоллекцияЗначений Цикл
Если ЭлементКоллекции = Неопределено Тогда
// ПараметрыМакетаТабличногоДокумента
Продолжить;
КонецЕсли;
Если ТипЗнч(ЭлементКоллекции) = Тип("КлючИЗначение") Тогда
ИмяСвойства = ЭлементКоллекции.Ключ;
ЗначениеСвойства = ЭлементКоллекции.Значение;
Иначе
ИмяСвойства = ЭлементКоллекции.Имя;
ЗначениеСвойства = ЭлементКоллекции;
КонецЕсли;
КонечноеСлово = СтрЗаменить(СтрокаВида.Слово, ИмяЭлементаКоллекции, ИмяСвойства);
ТаблицаТипов = Неопределено;
Если ВычислятьТипыЦикл Тогда
Если ЭтоСубконто И ПредыдущаяТаблицаТипов <> Неопределено Тогда
ТаблицаТипов = ПредыдущаяТаблицаТипов;
ИначеЕсли Истина
И ТипЗнч(ЗначениеСвойства) = Тип("ТаблицаЗначений")
И ЗначениеСвойства.Количество() > 0
И ЗначениеСвойства.Колонки.Найти(ИмяКолонкиФлага) <> Неопределено
//И ЗначениеСвойства.Колонки.Найти("ИмяОбщегоТипа") <> Неопределено
Тогда
ТаблицаТипов = ЗначениеСвойства;
Иначе
ТаблицаТипов = НоваяТаблицаТипов();
ПредыдущаяТаблицаТипов = ТаблицаТипов;
МассивТипов = Новый Массив;
Квалификаторы = Неопределено;
ОписаниеТиповЗначения = Неопределено;
Если СхемаКоллекции.Количество() > 0 Тогда
Если Ложь
Или СтрокаВида.ТипЗначения = ""
Или СтрокаВида.ТипЗначения = "Произвольный"
Или СтрокаВида.ТипЗначения = "Набор записей регистра"
Или Найти(СтрокаВида.ТипЗначения, "<") > 0
Или ЛиТипСКвалификаторами
Тогда
Если ТипЗнч(ЗначениеСвойства) = Тип("ОписаниеТипов") Тогда
ОписаниеТиповЗначения = ЗначениеСвойства;
КонецЕсли;
Если Истина
И ЯзыкПрограммы = 1
И РодительскаяСтруктураТипа.ТипЯзыка <> "ЗначениеВЗапросе"
//И КорневойТипРодителя <> Неопределено
//И КорневойТипРодителя <> "ВнешнийИсточникДанных"
И ПостроительЗапросаРодителя <> Неопределено
Тогда
ДоступноеПолеСлова = ПостроительЗапросаРодителя.ДоступныеПоля.Найти(НРег(КонечноеСлово));
Если ДоступноеПолеСлова = Неопределено Тогда
Продолжить;
КонецЕсли;
Если ДоступноеПолеСлова.ТипЗначения <> Новый ОписаниеТипов("ТаблицаЗначений") Тогда
ОписаниеТиповЗначения = ДоступноеПолеСлова.ТипЗначения;
КонецЕсли;
КонецЕсли;
Если Истина
И ОписаниеТиповЗначения = Неопределено
И СтрокаОписанияВида.ИмяКоллекции <> "КритерииОтбора"
И СтрокаОписанияВида.ИмяКоллекции <> "ПланыВидовХарактеристик"
И ИмяОбщегоТипаРодителя <> "Константа"
Тогда
Попытка
ОписаниеТиповЗначения = ЗначениеСвойства.Тип;
Исключение
Попытка
ОписаниеТиповЗначения = ЗначениеСвойства.ТипЗначения;
Исключение
КонецПопытки;
КонецПопытки;
Если ТипЗнч(ОписаниеТиповЗначения) <> Тип("ОписаниеТипов") Тогда
ОписаниеТиповЗначения = Неопределено;
КонецЕсли;
КонецЕсли;
Если ТипЗнч(ОписаниеТиповЗначения) = Тип("ОписаниеТипов") Тогда
МассивТипов = ОписаниеТиповЗначения.Типы();
Квалификаторы = ОписаниеТиповЗначения;
ИначеЕсли ТипЗнч(ЗначениеСвойства) = Тип("Массив") Тогда
МассивТипов = ЗначениеСвойства;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Истина
И МассивТипов.Количество() = 0
И (Ложь
Или СхемаКоллекции.Количество() = 0
//Или ОписаниеТиповЗначения = Неопределено И СтрокаВида.ТипЗначения = "Произвольный"
)
Тогда
МассивТипов.Добавить(ТипЗнч(ЗначениеСвойства));
КонецЕсли;
Если Истина
//И ОписаниеТиповЗначения <> Неопределено
И МассивТипов.Количество() > 0
И СтрокаОписанияВида.ИмяКоллекции <> "<Имя коллекции метаданных>"
И (Ложь
Или СтрокаОписанияВида.ИмяКоллекции <> "Константы"
Или ЯзыкПрограммы = 1)
Тогда
ШаблонСтруктурыТипа = Новый Структура("СтрокаОписания, ТипЯзыка, Метаданные, ДержательМетаданных, Квалификаторы");
ШаблонСтруктурыТипа.СтрокаОписания = СтрокаВида;
ШаблонСтруктурыТипа.ТипЯзыка = РодительскаяСтруктураТипа.ТипЯзыка;
Если ТипЗнч(МетаданныеРодителя) = ирОбщий.ТипУправляемаяФормаЛкс() Тогда
ШаблонСтруктурыТипа.ДержательМетаданных = МетаданныеРодителя;
Иначе
ШаблонСтруктурыТипа.ДержательМетаданных = РодительскаяСтруктураТипа.ДержательМетаданных;
КонецЕсли;
ШаблонСтруктурыТипа.Квалификаторы = Квалификаторы;
//ШаблонСтруктурыТипа.Метаданные = МетаданныеРодителя;
ПередаватьЗначениеСвойства = ТипЗнч(ЗначениеСвойства) = Тип("ОбъектМетаданных");
ПередаватьМетаданныеРодителя = НЕ (ИмяОбщегоТипаРодителя = "Структура" И ТипЗнч(МетаданныеРодителя) = Тип("Структура"));
Если МассивТипов.Количество() > МаксЧислоТиповДляАнализа Тогда
СтруктураТипаСвойства = СтруктураТипаИзКонкретногоТипа(МассивТипов[0], ЯзыкПрограммы, ШаблонСтруктурыТипа);
СтруктураОбщегоТипа = НоваяСтруктураТипа(СтруктураТипаСвойства.ИмяОбщегоТипа);
ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураОбщегоТипа);
Иначе
МассивНакопления = Новый Массив;
Для Каждого Тип Из МассивТипов Цикл
Если Истина
И Тип = ТипЗнч(ЗначениеСвойства)
//И (Ложь
// Или мМассивТиповСМетаданными.Найти(Тип) <> Неопределено
// Или мМассивТиповЭлементовУправления.Найти(Тип) <> Неопределено)
Тогда
МетаданныеЭлемента = МетаданныеЭлементов[ИмяСвойства];
Если МетаданныеЭлемента = Неопределено Тогда
МетаданныеЭлемента = ЗначениеСвойства;
КонецЕсли;
ШаблонСтруктурыТипа.Метаданные = МетаданныеЭлемента;
СтруктураТипаСвойства = СтруктураТипаИзЗначения(ЗначениеСвойства, ЯзыкПрограммы, ШаблонСтруктурыТипа);
Иначе
Если ПередаватьЗначениеСвойства Тогда
ШаблонСтруктурыТипа.Метаданные = ЗначениеСвойства;
ИначеЕсли ПередаватьМетаданныеРодителя Тогда
ШаблонСтруктурыТипа.Метаданные = МетаданныеРодителя;
КонецЕсли;
СтруктураТипаСвойства = СтруктураТипаИзКонкретногоТипа(Тип, ЯзыкПрограммы, ШаблонСтруктурыТипа);
КонецЕсли;
МассивНакопления.Добавить(СтруктураТипаСвойства);
КонецЦикла;
ДобавитьВТаблицуТипов(ТаблицаТипов, МассивНакопления);
КонецЕсли;
Иначе
СтруктураТипаСвойства = НоваяСтруктураТипа();
ЗаполнитьЗначенияСвойств(СтруктураТипаСвойства, РодительскаяСтруктураТипа, "ТипЯзыка");
Если ТипЗнч(МетаданныеРодителя) = ирОбщий.ТипУправляемаяФормаЛкс() Тогда
СтруктураТипаСвойства.ДержательМетаданных = МетаданныеРодителя;
Иначе
СтруктураТипаСвойства.ДержательМетаданных = РодительскаяСтруктураТипа.ДержательМетаданных;
КонецЕсли;
Если РодительскаяСтруктураТипа.ТипЯзыка = "ИмяТипа" Тогда
СтруктураТипаСвойства.ИмяОбщегоТипа = СтрокаВида.Слово;
Если СтрокаВида.ТипКонтекста <> "" Тогда
СтруктураТипаСвойства.ИмяОбщегоТипа = СтрокаВида.ТипКонтекста + "." + СтруктураТипаСвойства.ИмяОбщегоТипа;
КонецЕсли;
Иначе
СтруктураТипаСвойства.ИмяОбщегоТипа = СтрокаВида.ТипЗначения;
СтруктураТипаСвойства.СтрокаОписания = СтрокаВида;
КонецЕсли;
СтруктураТипаСвойства.Метаданные = ЗначениеСвойства;
//Если ПустаяСтрока(СтруктураТипаСвойства.ИмяОбщегоТипа) Тогда
//КонецЕсли;
ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипаСвойства);
КонецЕсли;
КонецЕсли;
Иначе
//
КонецЕсли;
ДобавитьВТаблицуСлов(ТаблицаСлов, КонечноеСлово, СтрокаВида.ТипСлова, ТаблицаТипов, "??" + ТипЗначенияСлова, "Метаданные");
КонецЦикла;
Если ЭтоГруппаОбщихМодулей Тогда
Прервать;
КонецЕсли;
КонецЦикла;
Если ЭтоГруппаОбщихМодулей Тогда
Прервать;
КонецЕсли;
// Модуль
Если Истина
И (Ложь
Или РодительскаяСтруктураТипа.ТипЯзыка = ""
Или СтрокаОбщегоТипа.ИмяОбщегоТипа <> "Глобальный")
И (Ложь
Или ЯзыкПрограммы = 0
Или ЯзыкПрограммы = 2)
Тогда
Если СтрокаОбщегоТипа.ИмяОбщегоТипа = "Глобальный" Тогда
ДобавитьВТаблицуСловЭлементыГлобальныхМодулей(СтрокаОбщегоТипа, Слово, ТипСлова, ВычислятьТипы, ВычислятьТипыМетодовМодулей, Не ЭтоЛокальныйКонтекст,
КлиентОбычноеПриложение, КлиентУправляемоеПриложение, НаСервере, ТаблицаСлов);
Иначе
МодульМетаданныхКомпонента = МодульМетаданныхДинамический;
Если МодульМетаданныхКомпонента = Неопределено И ИмяОбщегоТипаРодителя <> "Неизвестный контекст" Тогда
СтруктураТипаМодуля = НоваяСтруктураТипа(ИмяОбщегоТипаРодителя);
СтруктураТипаМодуля.ДержательМетаданных = РодительскаяСтруктураТипа.ДержательМетаданных; // Имя расширения конфигурации
СтруктураТипаМодуля.Метаданные = МетаданныеРодителя;
МодульМетаданныхКомпонента = ПодготовитьМодульМетаданных(СтруктураТипаМодуля);
КонецЕсли;
Если МодульМетаданныхКомпонента <> Неопределено Тогда
РасширениеМодуля = "";
Если Истина
И МодульМетаданныхКомпонента.СтруктураТипа <> Неопределено
И ТипЗнч(МодульМетаданныхКомпонента.СтруктураТипа.ДержательМетаданных) = Тип("Строка")
И ЗначениеЗаполнено(МодульМетаданныхКомпонента.СтруктураТипа.ДержательМетаданных)
Тогда
РасширениеМодуля = МодульМетаданныхКомпонента.СтруктураТипа.ДержательМетаданных;
КонецЕсли;
Если Ложь
Или Не ЗначениеЗаполнено(РасширениеМодуля) // методы конфигурации всегда видны расширению
Или БазовоеРасширениеКонфигурации = "*" // методы конфигурации всегда видны внешнему модулю
Или РасширениеМодуля = БазовоеРасширениеКонфигурации
Или РасширениеМодуля = ПолноеИмяПодсистемыИР // расширение ИР видно всем
Тогда
ДобавитьВТаблицуСловЭлементыМодуляМетаданных(СтрокаОбщегоТипа, Слово, ТипСлова, ТаблицаСлов, МодульМетаданныхКомпонента, ВычислятьТипыМетодовМодулей, ВычислятьТипы, Не ЭтоЛокальныйКонтекст,
ФлагиКомпиляции, ВнутриГруппыОбщихМодулей);
КонецЕсли;
ВидимыеРасширения = Новый Массив;
Если Истина
И ТипЗнч(РасширениеМодуля) = Тип("Строка")
И ЗначениеЗаполнено(РасширениеМодуля)
И (Ложь
Или ТипЗнч(МетаданныеРодителя) <> Тип("ОбъектМетаданных")
Или МетаданныеРодителя.РасширениеКонфигурации() = Неопределено)
Тогда
// Для расширения модуля добавляем базовый модуль
ВидимыеРасширения.Добавить(Неопределено);
ИначеЕсли БазовоеРасширениеКонфигурации = "*" Тогда
// При вызове из внешнего модуля, добавляем расширение модуля этого расширения
Для Каждого РасширениеКонфигурации Из ирКэш.РасширенияКонфигурацииЛкс() Цикл
ВидимыеРасширения.Добавить(РасширениеКонфигурации.Ключ.Имя);
КонецЦикла;
ИначеЕсли ЗначениеЗаполнено(БазовоеРасширениеКонфигурации) Тогда
// При вызове из модулях расширения, добавляем расширение модуля этого расширения
ВидимыеРасширения.Добавить(БазовоеРасширениеКонфигурации);
КонецЕсли;
Для Каждого ВидимоеРасширение Из ВидимыеРасширения Цикл
СтруктураТипаМодуля = НоваяСтруктураТипа(ИмяОбщегоТипаРодителя);
СтруктураТипаМодуля.ДержательМетаданных = ВидимоеРасширение;
СтруктураТипаМодуля.Метаданные = МетаданныеРодителя;
МодульМетаданныхРасширение = ПодготовитьМодульМетаданных(СтруктураТипаМодуля);
Если МодульМетаданныхРасширение <> Неопределено Тогда
ДобавитьВТаблицуСловЭлементыМодуляМетаданных(СтрокаОбщегоТипа, Слово, ТипСлова, ТаблицаСлов, МодульМетаданныхРасширение, ВычислятьТипыМетодовМодулей, ВычислятьТипы, Не ЭтоЛокальныйКонтекст,
ФлагиКомпиляции, ВнутриГруппыОбщихМодулей);
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЕсли;
#Если Клиент Тогда
Если Истина
И (Ложь
Или ТипЗнч(МетаданныеРодителя) = Тип("COMОбъект")
Или ТипЗнч(МетаданныеРодителя) = Тип("ВнешнийОбъект"))
И ЛиИмяТипаComОбъекта(ИмяОбщегоТипаРодителя)
Тогда
ИмяБиблиотеки = "";
ИнфоТипа = ПолучитьИнфоТипаCOMОбъекта(МетаданныеРодителя, ИмяОбщегоТипаРодителя, ИмяБиблиотеки);
Если ИнфоТипа <> Неопределено Тогда
МассивИнфоТипа = ИнтерфейсыCOMОбъекта(ИнфоТипа, ИмяОбщегоТипаРодителя);
Для Каждого ИнфоТипа Из МассивИнфоТипа Цикл
Для Каждого Член Из ИнфоТипа.Members Цикл
Если Член.AttributeMask = 1 Тогда
// Это члены IDispatch
Продолжить;
КонецЕсли;
ИмяЧлена = Член.Name;
Если Член.InvokeKind = 1 Или Член.Parameters.Count > 0 Тогда
лТипСлова = "Метод";
Иначе
лТипСлова = "Свойство";
КонецЕсли;
Если Слово <> Неопределено Тогда
Если Не ирОбщий.СтрокиРавныЛкс(Слово, ИмяЧлена) Тогда
Продолжить;
КонецЕсли;
Если Не ирОбщий.СтрокиРавныЛкс(ТипСлова, лТипСлова) Тогда
Продолжить;
КонецЕсли;
КонецЕсли;
СтруктураТипа = НоваяСтруктураТипа();
СтруктураТипа.ИмяОбщегоТипа = ПолучитьТипЗначенияЧленаИнтерфейса(Член.ReturnType, ИмяБиблиотеки, ИнфоТипа.Parent);
СтруктураТипа.СтрокаОписания = Член;
СтруктураТипа.Метаданные = МетаданныеРодителя;
ТаблицаТипов = ДобавитьВТаблицуТипов(, СтруктураТипа);
ДобавитьВТаблицуСлов(ТаблицаСлов, ИмяЧлена, лТипСлова, ТаблицаТипов,, "Метаданные");
КонецЦикла;
КонецЦикла;
КонецЕсли;
КонецЕсли;
#КонецЕсли
КонецЕсли;
КонецЦикла;
Если Истина
И Слово <> Неопределено
И ИмяОбщегоТипаРодителя <> "Глобальный" // Для того, чтобы постоянно не присваивался тип <ОбщийМодуль>
И ТаблицаСлов.Количество() = 0
И НайденныеСтроки.Количество() = 1
И ТаблицаОбщихТиповСтруктурыТипа.Количество() = 1
Тогда
// Шаблон только один. Берем его даже если имя элемента коллекции не подошло.
СтрокаВида = НайденныеСтроки[0];
Если Истина
// Иначе при вычислении результата метода модуля менеджера все локальные переменные будут срабатывать
И Найти(СтрокаВида.Слово, "<Имя предопределенного") = 0
И Найти(СтрокаВида.Слово, "<Имя значения перечисления") = 0
Тогда
СтруктураТипа = НоваяСтруктураТипа();
СтруктураТипа.ИмяОбщегоТипа = СтрокаВида.ТипЗначения;
СтруктураТипа.СтрокаОписания = СтрокаВида;
СтруктураТипа.Метаданные = МетаданныеРодителя;
ТаблицаТипов = ДобавитьВТаблицуТипов(, СтруктураТипа);
ДобавитьВТаблицуСлов(ТаблицаСлов, СтрокаВида.Слово, СтрокаВида.ТипСлова, ТаблицаТипов,, "Метаданные");
КонецЕсли;
КонецЕсли;
Возврат ТаблицаСлов;
КонецФункции
// Функция - Добавить в таблицу слов элементы глобальных модулей
//
// Параметры:
// СтрокаОбщегоТипа - см. ТаблицаОбщихТиповИзСтруктурыТипа()[0] -
//
Функция ДобавитьВТаблицуСловЭлементыГлобальныхМодулей(Знач СтрокаОбщегоТипа, Знач Слово = Неопределено, Знач ТипСлова = Неопределено, Знач ВычислятьТипы = Истина, Знач ВычислятьТипыМетодовМодулей = Ложь,
Знач ТолькоЭкспорт = Истина, Знач КлиентОбычноеПриложение = Истина, Знач КлиентУправляемоеПриложение = Истина, Знач НаСервере = Ложь, Знач ТаблицаСлов = Неопределено) Экспорт
Если ТаблицаСлов = Неопределено Тогда
ТаблицаСлов = НоваяТаблицаСвойствТипа();
КонецЕсли;
Если ПустаяСтрока(ТипСлова) Или ТипСлова = "Метод" Тогда
// Глобальные общие модули
СтруктураТипаМодуля = НоваяСтруктураТипа();
СтруктураТипаМодуля.ИмяОбщегоТипа = "ОбщийМодуль";
Для Каждого ОбщийМодульМД Из Метаданные.ОбщиеМодули Цикл
#Если Сервер И Не Сервер Тогда
ОбщийМодульМД = Метаданные.ОбщиеМодули.ирОбщий;
#КонецЕсли
Если Ложь
Или Не ОбщийМодульМД.Глобальный
Или (Истина
И НаСервере
И Не ОбщийМодульМД.Сервер)
Или (Истина
И КлиентОбычноеПриложение
И Не ОбщийМодульМД.КлиентОбычноеПриложение)
Или (Истина
И КлиентУправляемоеПриложение
И Не ОбщийМодульМД.КлиентУправляемоеПриложение)
Или (Истина
И Не НаСервере
И Не ОбщийМодульМД.ВызовСервера
И Не (Ложь
Или (Истина
И КлиентОбычноеПриложение
И ОбщийМодульМД.КлиентОбычноеПриложение)
Или (Истина
И КлиентУправляемоеПриложение
И ОбщийМодульМД.КлиентУправляемоеПриложение)
)
)
Тогда
Продолжить;
КонецЕсли;
СтруктураТипаМодуля.Метаданные = ОбщийМодульМД;
МодульМетаданныхКомпонента = ПодготовитьМодульМетаданных(СтруктураТипаМодуля);
ДобавитьВТаблицуСловЭлементыМодуляМетаданных(СтрокаОбщегоТипа, Слово, "Метод", ТаблицаСлов, МодульМетаданныхКомпонента, ВычислятьТипыМетодовМодулей, ВычислятьТипы, ТолькоЭкспорт);
КонецЦикла;
КонецЕсли;
СтруктураТипаМодуля = НоваяСтруктураТипа(СтрокаОбщегоТипа.ИмяОбщегоТипа);
СтруктураТипаМодуля.Метаданные = СтрокаОбщегоТипа.Метаданные;
Если КлиентОбычноеПриложение Тогда
МодульМетаданныхКомпонента = ПодготовитьМодульМетаданных(СтруктураТипаМодуля, "МодульОбычногоПриложения");
ДобавитьВТаблицуСловЭлементыМодуляМетаданных(СтрокаОбщегоТипа, Слово, ТипСлова, ТаблицаСлов, МодульМетаданныхКомпонента, ВычислятьТипыМетодовМодулей, ВычислятьТипы, ТолькоЭкспорт);
КонецЕсли;
Если КлиентУправляемоеПриложение Тогда
МодульМетаданныхКомпонента = ПодготовитьМодульМетаданных(СтруктураТипаМодуля, "МодульУправляемогоПриложения");
ДобавитьВТаблицуСловЭлементыМодуляМетаданных(СтрокаОбщегоТипа, Слово, ТипСлова, ТаблицаСлов, МодульМетаданныхКомпонента, ВычислятьТипыМетодовМодулей, ВычислятьТипы, ТолькоЭкспорт);
КонецЕсли;
Возврат ТаблицаСлов;
КонецФункции
//.
// Параметры:
// ИмяОбщегоТипаРодителя - Неопределено -
// Возвращаемое значение:
// Массив[Неопределено] -
Функция ИнтерфейсыCOMОбъекта(Знач ИнфоТипа, Знач ИмяОбщегоТипаРодителя) Экспорт
Если Найти(ИмяОбщегоТипаРодителя, " {") > 0 Тогда
ИнфоТипа = ИнфоТипа.Parent.TypeInfos.NamedItem(ирОбщий.ПервыйФрагментЛкс(ИмяОбщегоТипаРодителя, " {"));
КонецЕсли;
//Если ИмяCOMКласса = "" Тогда
// Если Описатель.Parent.Name = "V" + ирКэш.НомерИзданияПлатформыЛкс() Тогда
// ИмяОбщегоТипа = "COM-соединитель";
// КонецЕсли;
//КонецЕсли;
Если НРег(ИнфоТипа.TypeKindString) = "coclass" Тогда
МассивИнфоТипа = ИнфоТипа.Interfaces;
Иначе
МассивИнфоТипа = Новый Массив;
МассивИнфоТипа.Добавить(ИнфоТипа);
Для Каждого ИнтерфейсОбъекта Из ИнфоТипа.ImpliedInterfaces Цикл
МассивИнфоТипа.Добавить(ИнтерфейсОбъекта);
КонецЦикла;
КонецЕсли;
Возврат МассивИнфоТипа;
КонецФункции
// Помогает обновлять кэш управляемой формы из конфигуратора при следующем вызове автодополнения
// Параметры:
// ФормаИлиСтруктура - Форма, Структура -
// Ключ - Строка -
Процедура ДобавитьОтсутствиеЭлементаФормы(Знач ФормаИлиСтруктура, Знач Ключ) Экспорт
СлужебныеДанные = ирОбщий.СлужебныеДанныеФормыЛкс(ФормаИлиСтруктура);
ОтсутствуютЭлементы = Неопределено;
Если Не СлужебныеДанные.Свойство("ОтсутствуютЭлементы", ОтсутствуютЭлементы) Тогда
ОтсутствуютЭлементы = Новый Соответствие;
СлужебныеДанные.Вставить("ОтсутствуютЭлементы", ОтсутствуютЭлементы);
КонецЕсли;
Если ОтсутствуютЭлементы[Ключ] = Неопределено Тогда
ОтсутствуютЭлементы[Ключ] = 1;
СлужебныеДанные.Вставить("ДатаОбновления", Дата(1,1,1));
КонецЕсли;
КонецПроцедуры
Функция ТаблицаТиповЭлементовКоллекции(Знач РодительскаяСтруктураТипа, Знач ТекстИндексаЭлемента = "", Знач ЯзыкПрограммы = 0, Знач ТаблицаТипов = Неопределено) Экспорт
НужнаПроверкаТипов = Истина;
МетаданныеКоллекции = РодительскаяСтруктураТипа.Метаданные; // Массив
Если Истина
И ТипЗнч(МетаданныеКоллекции) = Тип("Массив")
И МетаданныеКоллекции.Количество() > 0
И (Ложь
Или ирОбщий.ПервыйФрагментЛкс(РодительскаяСтруктураТипа.ИмяОбщегоТипа, "[") = "Массив"
Или ирОбщий.ПервыйФрагментЛкс(РодительскаяСтруктураТипа.ИмяОбщегоТипа, "[") = "ФиксированныйМассив")
Тогда
ТаблицаТипов = ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипаИзЗначения(МетаданныеКоллекции[0]));
ИначеЕсли Истина
И (Ложь
Или РодительскаяСтруктураТипа.ИмяОбщегоТипа = "СписокЗначений"
Или РодительскаяСтруктураТипа.ИмяОбщегоТипа = "Соответствие")
И ТипЗнч(МетаданныеКоллекции) = Тип(РодительскаяСтруктураТипа.ИмяОбщегоТипа)
И МетаданныеКоллекции.Количество() > 0
Тогда
СтруктураТипаЭлемента = Новый Структура("Значение");
ЗаполнитьЗначенияСвойств(СтруктураТипаЭлемента, МетаданныеКоллекции[0]);
ТаблицаТипов = ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипаИзЗначения(СтруктураТипаЭлемента));
Иначе
ТипыЭлементовКоллекции = ТипыЭлементовКоллекции(РодительскаяСтруктураТипа, ЯзыкПрограммы, НужнаПроверкаТипов);
Если ТипыЭлементовКоллекции.Количество() > 0 Тогда
Если ТаблицаТипов = Неопределено Тогда
ТаблицаТипов = НоваяТаблицаТипов();
КонецЕсли;
Для Каждого БазовыйТипЭлемента Из ТипыЭлементовКоллекции Цикл
Попытка
КонкретныйТип = Тип(БазовыйТипЭлемента);
Исключение
КонкретныйТип = Неопределено;
КонецПопытки;
Если КонкретныйТип <> Неопределено Тогда
СтруктураТипаЭлемента = СтруктураТипаИзКонкретногоТипа(КонкретныйТип);
Иначе
СтруктураТипаЭлемента = НоваяСтруктураТипа();
СтруктураТипаЭлемента.ИмяОбщегоТипа = БазовыйТипЭлемента;
СтруктураТипаЭлемента.Метаданные = мМетаданные;
КонецЕсли;
Если ТипЗнч(СтруктураТипаЭлемента.Метаданные) = Тип("ОбъектМетаданныхКонфигурация") Тогда
СтруктураТипаЭлемента.Метаданные = МетаданныеКоллекции;
КонецЕсли;
СтруктураТипаЭлемента.ДержательМетаданных = РодительскаяСтруктураТипа.ДержательМетаданных;
Если КонкретныйТип = Неопределено И НужнаПроверкаТипов Тогда
СтруктураКлюча = Новый Структура("БазовыйТип, ЯзыкПрограммы", БазовыйТипЭлемента, ЯзыкПрограммы);
НайденныеСтроки = ТаблицаОбщихТипов.НайтиСтроки(СтруктураКлюча);
Если НайденныеСтроки.Количество() > 0 Тогда
СтруктураТипаЭлемента.СтрокаОписания = НайденныеСтроки[0];
СтруктураТипаЭлемента.ИмяОбщегоТипа = НайденныеСтроки[0].Слово;
Если ТипЗнч(МетаданныеКоллекции) <> Тип("КоллекцияОбъектовМетаданных") Тогда
СтруктураТипаЭлемента.Метаданные = МетаданныеКоллекции;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ТипЗнч(МетаданныеКоллекции) = Тип("ПостроительЗапроса") Тогда
ПостроительЗапроса = МетаданныеКоллекции;
Попытка
ИндексВПакете = Число(ТекстИндексаЭлемента);
Исключение
ИндексВПакете = Неопределено;
КонецПопытки;
Если ИндексВПакете <> Неопределено Тогда
ТекстыЗапросов = РазбитьГрубоТекстПакетногоЗапросаНаЗапросы(МетаданныеКоллекции.Текст);
#Если Сервер И Не Сервер Тогда
ТекстыЗапросов = Новый Массив;
#КонецЕсли
ПостроительЗапроса = ПостроительПакетаЗапросовДоИндекса(ТекстыЗапросов, ИндексВПакете);
Если ПостроительЗапроса <> Неопределено Тогда
СтруктураТипаЭлемента.Метаданные = ПостроительЗапроса;
МенеджерВременныхТаблиц = РодительскаяСтруктураТипа.ДержательМетаданных; // см. Обработки.ирКлсПолеТекстаПрограммы.Создать().НовыйМенеджерВременныхТаблиц()
ПоследнийПакетЗапросов = МенеджерВременныхТаблиц.ПакетыЗапросов[МенеджерВременныхТаблиц.ПакетыЗапросов.ВГраница()]; // см. Обработки.ирКлсПолеТекстаПрограммы.Создать().НовыйПакетЗапросов()
ПоследнийПакетЗапросов = ирОбщий.СкопироватьКоллекциюЛкс(ПоследнийПакетЗапросов);
ПоследнийПакетЗапросов.Вставить("ИндексВПакете", ИндексВПакете);
СтруктураТипаЭлемента.ДержательМетаданных = ПоследнийПакетЗапросов;
КонецЕсли;
КонецЕсли;
КонецЕсли;
ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипаЭлемента);
КонецЦикла;
Иначе
ТаблицаТипов = ДобавитьВТаблицуТипов(ТаблицаТипов, НоваяСтруктураТипа());
КонецЕсли;
КонецЕсли;
Возврат ТаблицаТипов;
КонецФункции
Функция ПараметрыИзТекстаЗапроса(Знач ТекстЗапроса, Знач ВВидеСтруктуры = Ложь, Знач СтруктураПриемник = Неопределено) Экспорт
Запрос = Новый Запрос(ТекстЗапроса);
Попытка
ПараметрыЗапроса = Запрос.НайтиПараметры();
Исключение
ПараметрыЗапроса = Новый Массив;
КонецПопытки;
Если ВВидеСтруктуры Тогда
Результат = СтруктураПриемник;
Если СтруктураПриемник = Неопределено Тогда
Результат = Новый Структура;
КонецЕсли;
Если ПараметрыЗапроса <> Неопределено Тогда
Для Каждого ОписаниеПараметра Из ПараметрыЗапроса Цикл
Результат.Вставить(ОписаниеПараметра.Имя);
КонецЦикла;
КонецЕсли;
Иначе
Результат = ПараметрыЗапроса;
КонецЕсли;
Возврат Результат;
КонецФункции
//.
// Параметры:
// ТекстЗапроса - Строка -
// Возвращаемое значение:
// ПостроительЗапроса -
Функция ПостроительЗапросаИзТекстаДляТипа(Знач ТекстЗапроса, Знач ПостроительЗапроса = Неопределено) Экспорт
Если ПостроительЗапроса = Неопределено Тогда
ПостроительЗапроса = Новый ПостроительЗапроса;
КонецЕсли;
Попытка
ПостроительЗапроса.Текст = ТекстЗапроса;
Исключение
// Даже если текст некорректный, он сохраняется в свойстве
КонецПопытки;
ПараметрыИзТекстаЗапроса(ТекстЗапроса, Истина, ПостроительЗапроса.Параметры);
Возврат ПостроительЗапроса;
КонецФункции
// Функция - Построитель пакета запросов до индекса включительно
//
// Параметры:
// ТекстыЗапросов - -
// ИндексЭлемента - -
//
// Возвращаемое значение:
// -
//
Функция ПостроительПакетаЗапросовДоИндекса(Знач ТекстыЗапросов, Знач ИндексЭлемента) Экспорт
ТекстЗапроса = "";
Если ТекстыЗапросов.Количество() > ИндексЭлемента Тогда
ТекстЗапроса = ирОбщий.СтрСоединитьЛкс(ТекстыЗапросов, Символы.ПС, ИндексЭлемента + 1);
Если Лев(ТекстЗапроса, 1) = """" Тогда
ТекстЗапроса = ирОбщий.ТекстИзВстроенногоЯзыкаЛкс(ТекстЗапроса);
КонецЕсли;
КонецЕсли;
Если ЗначениеЗаполнено(ТекстЗапроса) Тогда
ПостроительЗапроса = Новый ПостроительЗапроса;
Попытка
ПостроительЗапроса.Текст = ТекстЗапроса;
//ПостроительЗапроса.ЗаполнитьНастройки();
Исключение
КонецПопытки;
ПодготовитьМетаданныеПостроителяЗапроса(ПостроительЗапроса);
КонецЕсли;
Возврат ПостроительЗапроса;
КонецФункции
// Процедура - Подготовить выбранные поля построителя
//
// Параметры:
// ПостроительЗапроса - ПостроительЗапроса -
// ДержательМетаданных - см. ОбработкаОбъект.ирКлсПолеТекстаПрограммы.НовыйМенеджерВременныхТаблиц() -
//
Процедура ПодготовитьМетаданныеПостроителяЗапроса(Знач ПостроительЗапроса, Знач ДержательМетаданных = Неопределено) Экспорт
Если ПостроительЗапроса.ВыбранныеПоля.Количество() = 0 Тогда
Попытка
ПостроительЗапроса.ЗаполнитьНастройки();
Исключение
КонецПопытки;
КонецЕсли;
Если ПостроительЗапроса.ВыбранныеПоля.Количество() = 0 И ирКэш.ДоступноСхемаЗапросаЛкс() Тогда
Текст = ПостроительЗапроса.Текст;
Если Истина
И ДержательМетаданных <> Неопределено
И ДержательМетаданных.Тип = Тип("МенеджерВременныхТаблиц")
//И ДержательМетаданных.Активен
Тогда
ТекстыПакетов = Новый Массив;
Для Индекс = 0 По ДержательМетаданных.ПакетыЗапросов.ВГраница() - 1 Цикл
ТекстыПакетов.Добавить(ирОбщий.ТекстИзВстроенногоЯзыкаЛкс(ДержательМетаданных.ПакетыЗапросов[Индекс].Текст));
КонецЦикла;
ТекстыПакетов.Добавить(Текст);
Текст = ирОбщий.СтрСоединитьЛкс(ТекстыПакетов, ";" + Символы.ПС);
КонецЕсли;
Попытка
ПустаяТаблица = ирОбщий.ПустаяТаблицаЗначенийИзТекстаЗапросаЛкс(Текст,, Истина);
Исключение
Возврат;
КонецПопытки;
ПостроительЗапроса.ИсточникДанных = Новый ОписаниеИсточникаДанных(ПустаяТаблица);
ПостроительЗапроса.ЗаполнитьНастройки();
КонецЕсли;
КонецПроцедуры
Функция ЛиИмяТипаComОбъекта(ИмяОбщегоТипа) Экспорт
Результат = Ложь
Или ирОбщий.СтрокиРавныЛкс(ИмяОбщегоТипа, "COMОбъект")
Или Найти(ИмяОбщегоТипа, " {") > 0;
Возврат Результат;
КонецФункции
Функция ДобавитьВТаблицуСловЭлементыМодуляМетаданных(Знач СтруктураТипаМини, Знач Слово = Неопределено, Знач ТипСлова = Неопределено, Знач ВнутренняяТаблицаСлов = Неопределено,
Знач МодульМетаданных, Знач ВычислятьТипыМетодовМодулей = Ложь, Знач ВычислятьТипы = Истина, Знач ТолькоЭкспорт = Истина, Знач ФлагиКомпиляции = Неопределено,
Знач ВнутриГруппыОбщихМодулей = Ложь) Экспорт
Если ВнутренняяТаблицаСлов = Неопределено Тогда
ВнутренняяТаблицаСлов = НоваяТаблицаСвойствТипа();
КонецЕсли;
МетаданныеРодителя = СтруктураТипаМини.Метаданные; // см. Метаданные.ОбщиеМодули[0]
ОтборСловМодуля = Новый Структура;
Если ТолькоЭкспорт Тогда
ОтборСловМодуля.Вставить("ЛиЭкспорт", Истина);
КонецЕсли;
Если ЗначениеЗаполнено(Слово) Тогда
ОтборСловМодуля.Вставить("НИмя", НРег(Слово));
КонецЕсли;
Если Истина
И (Ложь
Или ФлагиКомпиляции = Неопределено
Или Не ФлагиКомпиляции.БезКонтекста)
И (Ложь
Или ТипСлова = Неопределено
Или ТипСлова = "Свойство")
Тогда
ПеременныеМодуля = МодульМетаданных.Переменные;
#Если Сервер И Не Сервер Тогда
ПеременныеМодуля = Новый ТаблицаЗначений;
#КонецЕсли
Если ОтборСловМодуля.Количество() > 0 Тогда
ПодходящиеПеременные = ПеременныеМодуля.НайтиСтроки(ОтборСловМодуля);
Иначе
ПодходящиеПеременные = ПеременныеМодуля;
КонецЕсли;
КомпонентаПодсказки = Неопределено;
ТаблицаТипов = Неопределено;
Для Каждого ПеременнаяМодуля Из ПодходящиеПеременные Цикл
Если ВычислятьТипы Тогда
Если ВычислятьТипыМетодовМодулей Тогда
ПодготовитьТипЗначенияПеременнойМодуля(ПеременнаяМодуля, МодульМетаданных, КомпонентаПодсказки);
КонецЕсли;
ТаблицаТипов = ТаблицаТиповСловаМодуля(ПеременнаяМодуля, МодульМетаданных);
КонецЕсли;
ДобавитьВТаблицуСлов(ВнутренняяТаблицаСлов, ПеременнаяМодуля.Имя, "Свойство", ТаблицаТипов,, "Метаданные");
КонецЦикла;
КонецЕсли;
Если Истина
И Не ТолькоЭкспорт И ФлагиКомпиляции <> Неопределено
И ирОбщий.СтрКончаетсяНаЛкс(МодульМетаданных.Имя, ".Форма.Модуль")
Тогда
//Если ФлагиКомпиляции.Сервер Тогда
// ОтборСловМодуля.Вставить("Сервер", Истина);
//КонецЕсли;
//Если ФлагиКомпиляции.КлиентОбычноеПриложение Или ФлагиКомпиляции.КлиентУправляемоеПриложение Тогда
// ОтборСловМодуля.Вставить("Клиент", Истина);
//КонецЕсли;
Если Не (ФлагиКомпиляции.КлиентОбычноеПриложение Или ФлагиКомпиляции.КлиентУправляемоеПриложение) Тогда
ОтборСловМодуля.Вставить("Клиент", Ложь);
КонецЕсли;
Если ФлагиКомпиляции.БезКонтекста Тогда
ОтборСловМодуля.Вставить("БезКонтекста", Истина);
КонецЕсли;
КонецЕсли;
Если Ложь
Или ТипСлова = Неопределено
Или ТипСлова = "Метод"
Тогда
МетодыМодуля = МодульМетаданных.Методы;
#Если Сервер И Не Сервер Тогда
МетодыМодуля = Новый ТаблицаЗначений;
#КонецЕсли
Если ОтборСловМодуля.Количество() > 0 Тогда
ПодходящиеМетоды = МетодыМодуля.НайтиСтроки(ОтборСловМодуля);
Если Истина
И ПодходящиеМетоды.Количество() = 0
И ЗначениеЗаполнено(Слово)
И СтруктураТипаМини.ИмяОбщегоТипа <> "Глобальный"
Тогда
ОтборСловМодуля.Вставить("НИмя", "<>");
ПодходящиеМетоды = МетодыМодуля.НайтиСтроки(ОтборСловМодуля);
КонецЕсли;
Иначе
ПодходящиеМетоды = МетодыМодуля;
КонецЕсли;
ВычислятьТипы = Ложь
Или ЗначениеЗаполнено(Слово)
Или ВычислятьТипы;
Если ЗначениеЗаполнено(Слово) Тогда
ВычислятьТипыМетодовМодулей = Истина;
КонецЕсли;
Если ВычислятьТипыМетодовМодулей И ПодходящиеМетоды.Количество() > 100 Тогда
Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(ПодходящиеМетоды.Количество(), "Вычисление типов функций");
Иначе
Индикатор = Неопределено;
КонецЕсли;
ТаблицаТипов = Неопределено;
РазделительВариантаКонтекста = РазделительВариантаКонтекста();
Для Каждого МетодМодуля Из ПодходящиеМетоды Цикл
Если Индикатор <> Неопределено Тогда
ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
КонецЕсли;
ИмяМетода = МетодМодуля.Имя;
Если ИмяМетода = "<>" И Не ЗначениеЗаполнено(Слово) Тогда
Продолжить;
КонецЕсли;
Если ВычислятьТипы Тогда
Если ВычислятьТипыМетодовМодулей Тогда
ПодготовитьТипРезультатаМетода(МетодМодуля, МодульМетаданных);
КонецЕсли;
ТаблицаТипов = ТаблицаТиповСловаМодуля(МетодМодуля, МодульМетаданных);
КонецЕсли;
Если ВнутриГруппыОбщихМодулей Тогда
ИмяМетода = ИмяМетода + " - " + МетаданныеРодителя.Имя;
КонецЕсли;
ДобавитьВТаблицуСлов(ВнутренняяТаблицаСлов, ИмяМетода, "Метод", ТаблицаТипов, МетодМодуля.ТипЗначения, "Метаданные");
КонецЦикла;
Если Индикатор <> Неопределено Тогда
ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
КонецЕсли;
КонецЕсли;
Возврат ВнутренняяТаблицаСлов;
КонецФункции
Функция РазделительВариантаКонтекста() Экспорт
Возврат " - ";
КонецФункции
//.
// Параметры:
// МетодМодуля - СтрокаТаблицыЗначений -
// Возвращаемое значение:
// ТаблицаЗначений -
Функция ТаблицаТиповСловаМодуля(СловоМодуля, МодульМетаданных) Экспорт
Если СловоМодуля.ТаблицаТипов <> Неопределено Тогда
ТаблицаТипов = СловоМодуля.ТаблицаТипов.Скопировать(); // Мультиметка4529884 против циклической ссылки
#Если Сервер И Не Сервер Тогда
ТаблицаТипов = Новый ТаблицаЗначений;
#КонецЕсли
Иначе
ТаблицаТипов = НоваяТаблицаТипов();
КонецЕсли;
Если ТаблицаТипов.Количество() = 0 Тогда
СтруктураТипа = ТаблицаТипов.Добавить();
Если ЗначениеЗаполнено(СловоМодуля.ТипЗначения) Тогда
Если СловоМодуля.Имя = "<>" Тогда
СтруктураТипа.ИмяОбщегоТипа = СловоМодуля.ТипЗначения;
Иначе
СтруктураТипа.ИмяОбщегоТипа = "??"; // в этом варианте некрасиво выглядит тип результата ирОбщий.НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс()
//СтруктураТипа.ИмяОбщегоТипа = "?"; // так сломается вычисление типов методов в Обработка.ирКлсПолеТекстаПрограммы.Форма.МетодыМодулей
КонецЕсли;
КонецЕсли;
ОбновитьДетальностьСтруктурыТипа(СтруктураТипа);
КонецЕсли;
ТаблицаТипов.ЗаполнитьЗначения(СловоМодуля, "СтрокаОписания"); // Мультиметка4529884 против циклической ссылки
СловоМодуля.ИмяМодуля = МодульМетаданных.Имя;
Возврат ТаблицаТипов;
КонецФункции
Функция ПодготовитьМодульМетаданных(Знач СтруктураТипа, Знач ТипМодуля = "", выхИмяФайлаМодуляБезРасширения = "", Знач НовыйТекст = Неопределено, Знач ТекущаяПозиция = Неопределено) Экспорт
ВерсияФормата = 13; // Метка91237881041 Каждый раз при изменении структуры увеличиваем на 1
СтрокаСозданияРодителя = "";
ФлагиКомпиляции = Неопределено; // см. НовыеФлагиКомпиляции()
выхИмяФайлаМодуляБезРасширения = ИмяФайлаМодуляБезРасширения(СтруктураТипа, ТипМодуля, СтрокаСозданияРодителя, ФлагиКомпиляции);
Если ЗначениеЗаполнено(выхИмяФайлаМодуляБезРасширения) Тогда
Если мМодулиМетаданных = Неопределено Тогда
мМодулиМетаданных = Новый Соответствие;
КонецЕсли;
МодульМетаданных = МодульМетаданныхИзКэша(выхИмяФайлаМодуляБезРасширения); // см. МодульМетаданных()
Если Ложь
Или МодульМетаданных = Неопределено
Или НовыйТекст <> Неопределено И МодульМетаданных.Текст <> НовыйТекст
Тогда
//ПроверитьСтруктуруФайловогоКэша();
#Если Сервер И Не Сервер Тогда
ПапкаКэшаМодулей = Новый Файл;
#КонецЕсли
ФайлМодуля = ФайлМодуляИзКраткогоИмени(выхИмяФайлаМодуляБезРасширения);
ТекстовыйДокумент = Новый ТекстовыйДокумент;
СтарыйТекст = Неопределено;
Если НовыйТекст <> Неопределено Тогда
Если МодульМетаданных <> Неопределено Тогда
СтарыйТекст = МодульМетаданных.Текст;
КонецЕсли;
Если СтарыйТекст = Неопределено И ФайлМодуля.Существует() Тогда
ТекстовыйДокумент.Прочитать(ФайлМодуля.ПолноеИмя);
СтарыйТекст = ТекстовыйДокумент.ПолучитьТекст();
КонецЕсли;
Если СтарыйТекст <> НовыйТекст Тогда
ТекстовыйДокумент.УстановитьТекст(НовыйТекст);
Для Счетчик = 1 По 2 Цикл
Попытка
Если ирКэш.НомерРежимаСовместимостиЛкс() > 803018 Тогда
ТекстовыйДокумент.ЗаписатьАсинх(ФайлМодуля.ПолноеИмя);
Иначе
ТекстовыйДокумент.Записать(ФайлМодуля.ПолноеИмя);
КонецЕсли;
Прервать;
Исключение
Если Счетчик = 2 Тогда
ВызватьИсключение;
КонецЕсли;
СоздатьКаталог(ФайлМодуля.Путь); // Нужно для подкаталогов расширений 23мс
КонецПопытки;
КонецЦикла;
КонецЕсли;
КонецЕсли;
ФайлОписанияМодуля = ФайлМодуляИзКраткогоИмени(выхИмяФайлаМодуляБезРасширения, "ixd");
ОбновитьФайлОписания = Истина;
Если СтарыйТекст = НовыйТекст И ФайлОписанияМодуля.Существует() Тогда
ОбновитьФайлОписания = Истина
И ФайлМодуля.Существует()
И ФайлМодуля.ПолучитьВремяИзменения() > ФайлОписанияМодуля.ПолучитьВремяИзменения();
Если Не ОбновитьФайлОписания Тогда
МодульМетаданных = ирОбщий.ЗагрузитьЗначениеИзФайлаЛкс(ФайлОписанияМодуля.ПолноеИмя); // см. МодульМетаданных()
Если Ложь
Или ТипЗнч(МодульМетаданных) <> Тип("Структура")
Или ирОбщий.СвойствоСтруктурыЛкс(МодульМетаданных, "ВерсияФормата") <> ВерсияФормата
Или МодульМетаданных.Имя <> выхИмяФайлаМодуляБезРасширения // Антибаг ИР. В старых версиях где то писалось пустое имя в кэш
Тогда
// Старый формат кэша
ОбновитьФайлОписания = Истина;
МодульМетаданных = Неопределено;
Иначе
МодульМетаданных.Текст = НовыйТекст;
КонецЕсли;
КонецЕсли;
КонецЕсли;
СтарыйМодуль = Неопределено;
Если ОбновитьФайлОписания Тогда
Если Не ФайлМодуля.Существует() Тогда
Если СообщениеОНеобходимостиОбновитьКэшМодулейВыводилось <> Истина Тогда
// Может выводиться неоправданно, если модуль пуст. В этом случае конфигуратор не выгружает файл. Поэтому уведомляем только о полной пустоте кэша
ФайлыМодулей = НайтиФайлы(ПапкаКэшаМодулей.ПолноеИмя, ИмяКонтрольногоФайлаКэшаМодулей());
Если ФайлыМодулей.Количество() = 0 Тогда
#Если Клиент Тогда
ирКлиент.ОткрытьНастройкиПоляТекстаПрограммыНаЗаднемПланеЛкс();
#КонецЕсли
КонецЕсли;
СообщениеОНеобходимостиОбновитьКэшМодулейВыводилось = Истина;
КонецЕсли;
МодульМетаданных = МодульМетаданных("", СтруктураТипа, выхИмяФайлаМодуляБезРасширения);
Иначе
Если НовыйТекст = Неопределено Тогда
ТекстовыйДокумент.Прочитать(ФайлМодуля.ПолноеИмя);
МодульМетаданных = МодульМетаданных(ТекстовыйДокумент.ПолучитьТекст(), СтруктураТипа, выхИмяФайлаМодуляБезРасширения);
МодульМетаданных.СтруктураТипа = Неопределено;
ЗаписатьМодульВКэш(МодульМетаданных);
Иначе
СтарыйМодуль = МодульМетаданных;
МодульМетаданных = МодульМетаданных(НовыйТекст, СтруктураТипа, выхИмяФайлаМодуляБезРасширения, Ложь, МодульМетаданных, ТекущаяПозиция);
// Т.к. в этом сценарии часто будет обновление текста модуля происходить, то не будем тратить время на обновление индекса в файле, но удалим его чтобы потом дату изменения не сверять
УдалитьФайлы(ПапкаКэшаМодулей.ПолноеИмя, выхИмяФайлаМодуляБезРасширения + ".i*"); // Все расширения файлов индексов начинаются с "i"
Если мВызовыВсехСловПоМодулям <> Неопределено Тогда
мВызовыВсехСловПоМодулям[КлючКэшаВызововСловаПоМодулю(выхИмяФайлаМодуляБезРасширения, Истина)] = Неопределено;
мВызовыВсехСловПоМодулям[КлючКэшаВызововСловаПоМодулю(выхИмяФайлаМодуляБезРасширения, Ложь)] = Неопределено;
КонецЕсли;
КонецЕсли;
//ирОбщий.СообщитьЛкс(ФайлМодуля.ПолноеИмя); // Отладка
//УдалитьФайлы(ФайлМодуля.ПолноеИмя);
КонецЕсли;
КонецЕсли;
мМодулиМетаданных[НРег(выхИмяФайлаМодуляБезРасширения)] = МодульМетаданных;
Если МодульМетаданных <> Неопределено И СтарыйМодуль <> МодульМетаданных Тогда
#Если Сервер И Не Сервер Тогда
МетодыМодуля = Новый ТаблицаЗначений;
#КонецЕсли
МодульМетаданных.Вставить("СтруктураТипа", СтруктураТипа);
МодульМетаданных.Вставить("ФлагиКомпиляции", ФлагиКомпиляции);
МодульМетаданных.Вставить("СтрокаСоздания", СтрокаСозданияРодителя);
МодульМетаданных.Вставить("ТипМодуля", ТипМодуля);
МодульМетаданных.Вставить("ВерсияФормата", ВерсияФормата);
БазовыйТип = ирОбщий.ПервыйФрагментЛкс(СтруктураТипа.ИмяОбщегоТипа);
Если Истина
И МодульМетаданных <> мПустойМодуль
И (Ложь
Или ирОбщий.СтрКончаетсяНаЛкс(БазовыйТип, "Объект")
Или ирОбщий.ЛиИмяТипаФормыЛкс(БазовыйТип, Истина))
Тогда
// Добавим в переменные модуля реквизиты объекта с изменяемыми метаданными, чтобы уточнять их тип по коду
МодульВременный = МодульМетаданных("",, "кэш");
МодульВременный.Переменные.Очистить(); // Иногда там остаются какие то переменные
//ТаблицаСлов = ТаблицаСловИзСтруктурыТипа(СтруктураТипа,,,, Ложь,, "Свойство",,, МодульВременный);
ИнициацияОписанияМетодовИСвойств();
ТаблицаСлов = СловаКонтекстаМетаданные(СтруктураТипа,, "Свойство",,,,,,, МодульВременный);
Для Каждого СтрокаСлова Из ТаблицаСлов Цикл // TODO добавить фильтр по типу
Если ЛиДетальностьТиповДостаточна(СтрокаСлова.ТаблицаТипов) Тогда
Продолжить;
КонецЕсли;
СтрокаПеременной = МодульМетаданных.Переменные.Добавить();
СтрокаПеременной.Имя = СтрокаСлова.Слово;
СтрокаПеременной.НИмя = Нрег(СтрокаПеременной.Имя);
СтрокаПеременной.ЛиЭкспорт = Истина;
КонецЦикла;
КонецЕсли;
КонецЕсли;
Иначе
МодульМетаданных.Имя = выхИмяФайлаМодуляБезРасширения; // Нужно для единого пустого модуля, чтобы виртуальные методы в нем имели правильное имя модуля
КонецЕсли;
КонецЕсли;
Возврат МодульМетаданных;
КонецФункции
Функция ПеречислениеТипСлова() Экспорт
Структура = Новый Структура("Свойство, Метод, Конструктор");
Возврат ирОбщий.ЗаполнитьЗначенияКлючамиВСтруктуреЛкс(Структура);
КонецФункции
// Возращает таблицу вызовов слова через точку.
// Параметры:
// Модуль - Строка -
// ТекстовыйДокумент - ТекстовыйДокумент -
// Файл - Файл -
// ПолеТекстаПрограммы - ОбработкаОбъект.ирКлсПолеТекстаПрограммы
// Возвращаемое значение:
// ТаблицаЗначений -
Функция НепрямыеВызовыСловаВМодуле(Знач Модуль, Знач ТекстовыйДокумент, Знач Файл, Знач ПолеТекстаПрограммы, Знач ИскатьСлово, Знач ЛиМетод = Истина) Экспорт
_РежимОтладки = Ложь;
Если ЛиМетод Тогда
ШаблонВнешнегоВызова = ПолеТекстаПрограммы.шПредИмяПрямое+"(?:"+ПолеТекстаПрограммы.шИмяСТочками+"\.)("+шИмя+")\s*\((?:(?:"+ПолеТекстаПрограммы.шВыражениеПрограммы+")?"+шРазделитель+"*(?=[,\)])|,)*\)";
Расширение = "icl";
Иначе
ШаблонВнешнегоВызова = ПолеТекстаПрограммы.шПредИмяПрямое+"(?:"+ПолеТекстаПрограммы.шИмяСТочками+"\.)("+шИмя+")(?!\s*[\(])"+ПолеТекстаПрограммы.шПостИмяСвойства;
Расширение = "ipr";
КонецЕсли;
Если мВызовыВсехСловПоМодулям = Неопределено Тогда
мВызовыВсехСловПоМодулям = Новый Соответствие;
КонецЕсли;
КлючКэша = КлючКэшаВызововСловаПоМодулю(Модуль, ЛиМетод);
ИндексВызововМодуля = мВызовыВсехСловПоМодулям[КлючКэша];
Если ИндексВызововМодуля = Неопределено Тогда
ВерсияФорматаИндекса = 6;
ФайлИндекса = ФайлМодуляИзКраткогоИмени(Модуль, Расширение);
ОбновитьИндекс = Не ФайлИндекса.Существует();
Если Не ОбновитьИндекс Тогда
ИндексВызововМодуля = ирОбщий.ЗагрузитьЗначениеИзФайлаЛкс(ФайлИндекса.ПолноеИмя); // см. ирОбщий.НайтиРегВыражениеЛкс
Если Ложь
Или ТипЗнч(ИндексВызововМодуля) <> Тип("Структура")
Или ИндексВызововМодуля.ВерсияФормата <> ВерсияФорматаИндекса
Тогда
// Старый формат кэша
ОбновитьИндекс = Истина;
ИндексВызововМодуля = Неопределено;
КонецЕсли;
КонецЕсли;
Если ОбновитьИндекс Тогда
ТекстМодуля = ТекстовыйДокумент.ПолучитьТекст();
//ТаблицаВызовов = ирОбщий.НайтиРегВыражениеЛкс(ТекстМодуля, ШаблонВнешнегоВызова,,,,,, Истина);
//ТаблицаВызовов.Колонки.Добавить("Слово", Новый ОписаниеТипов("Строка"));
//Если _РежимОтладки Тогда // Можно менять на Истина в точке останова, например условием ирОбщий.Пр(_РежимОтладки, 1, 1)
// // Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
// Для Каждого СтрокаВызова Из ТаблицаВызовов Цикл
// СтрокаВызова.Слово = СтрокаВызова.Подгруппы.SubMatches(0);
// КонецЦикла;
//Иначе
// // Однострочный код использован для ускорения при разрешенной отладке. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика"
// Для Каждого СтрокаВызова Из ТаблицаВызовов Цикл   СтрокаВызова.Слово = НРег(СтрокаВызова.Подгруппы.SubMatches(0));   КонецЦикла;  
//КонецЕсли;
//ТаблицаВызовов.Колонки.Удалить("Подгруппы");
//ТаблицаВызовов.Колонки.Удалить("ТекстВхождения");
//
РегВыражение = ирКэш.ВычислительРегВыраженийЛкс();
РегВыражение.IgnoreCase = Истина;
РегВыражение.Global = Истина;
РегВыражение.Pattern = ШаблонВнешнегоВызова;
Вхождения = РегВыражение.НайтиВхождения(ТекстМодуля);
ТаблицаВызовов = Новый ТаблицаЗначений;
ТаблицаВызовов.Колонки.Добавить("ПозицияВхождения", Новый ОписаниеТипов("Число"));
ТаблицаВызовов.Колонки.Добавить("ДлинаВхождения", Новый ОписаниеТипов("Число"));
ТаблицаВызовов.Колонки.Добавить("Слово", Новый ОписаниеТипов("Строка"));
Если _РежимОтладки Тогда // Можно менять на Истина в точке останова, например условием ирОбщий.Пр(_РежимОтладки, 1, 1)
// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
Для Каждого Вхождение Из Вхождения Цикл
СтрокаРезультата = ТаблицаВызовов.Добавить();
СтрокаРезультата.ПозицияВхождения = Вхождение.FirstIndex;
СтрокаРезультата.ДлинаВхождения = Вхождение.Length;
СтрокаРезультата.Слово = Вхождение.SubMatches(0);
КонецЦикла;
Иначе
// Однострочный код использован для ускорения при разрешенной отладке. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика"
Для Каждого Вхождение Из Вхождения Цикл   СтрокаРезультата = ТаблицаВызовов.Добавить();   СтрокаРезультата.ПозицияВхождения = Вхождение.FirstIndex;   СтрокаРезультата.ДлинаВхождения = Вхождение.Length;   СтрокаРезультата.Слово = Вхождение.SubMatches(0);   КонецЦикла;  
КонецЕсли;
ирОбщий.ДобавитьИндексВТаблицуЛкс(ТаблицаВызовов, "Слово");
МассивСлов = ирОбщий.РазличныеЗначенияКолонкиТаблицыЛкс(ТаблицаВызовов, "Слово");
НомерСлова = 1;
СтруктураСлов = Новый Структура;
ТаблицаВызовов.Колонки.Добавить("НомерСлова", Новый ОписаниеТипов("Число"));
Для Каждого Слово Из МассивСлов Цикл
СтруктураСлов.Вставить(Слово, НомерСлова);
ВызовыСлова = ТаблицаВызовов.НайтиСтроки(Новый Структура("Слово", Слово));
Если _РежимОтладки Тогда // Можно менять на Истина в точке останова, например условием ирОбщий.Пр(_РежимОтладки, 1, 1)
// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
Для Каждого СтрокаВызова Из ВызовыСлова Цикл
СтрокаВызова.НомерСлова = НомерСлова;
КонецЦикла;
Иначе
// Однострочный код использован для ускорения при разрешенной отладке. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика"
Для Каждого СтрокаВызова Из ВызовыСлова Цикл   СтрокаВызова.НомерСлова = НомерСлова;   КонецЦикла;  
КонецЕсли;
НомерСлова = НомерСлова + 1;
КонецЦикла;
ТаблицаВызовов.Колонки.Удалить("Слово");
ИндексВызововМодуля = Новый Структура;
ИндексВызововМодуля.Вставить("ВерсияФормата", ВерсияФорматаИндекса);
ИндексВызововМодуля.Вставить("Вызовы", ТаблицаВызовов);
ИндексВызововМодуля.Вставить("СтруктураСлов", СтруктураСлов);
ирОбщий.СохранитьЗначениеВФайлЛкс(ИндексВызововМодуля, ФайлИндекса.ПолноеИмя);
КонецЕсли;
ирОбщий.ДобавитьИндексВТаблицуЛкс(ИндексВызововМодуля.Вызовы, "НомерСлова");
мВызовыВсехСловПоМодулям[КлючКэша] = ИндексВызововМодуля;
КонецЕсли;
НомерСлова = 0;
Результат = Новый Массив;
Если ИндексВызововМодуля.СтруктураСлов.Свойство(ИскатьСлово, НомерСлова) Тогда
Результат = ИндексВызововМодуля.Вызовы.НайтиСтроки(Новый Структура("НомерСлова", НомерСлова));
КонецЕсли;
Возврат Результат;
КонецФункции
Функция КлючКэшаВызововСловаПоМодулю(Знач Модуль, Знач ЛиМетод) Экспорт
Возврат НРег(Модуль) + "." + ЛиМетод;
КонецФункции
// Возвращаемое значение:
// Строка -
Функция ИмяКонтрольногоФайлаКэшаМодулей() Экспорт
Возврат "КонтрольныйФайл.ixd";
КонецФункции
Функция ИмяДинамическогоМодуля() Экспорт
Возврат "Динамический.Модуль";
КонецФункции
Функция ИмяМетодаИнициация() Экспорт
Возврат "<Инициация>";
КонецФункции
//.
// Параметры:
// МодульМетаданных - Структура -
// ОбнулятьВычисляемое - Булево - немного дольше, но гарантирует успех
Процедура ЗаписатьМодульВКэш(Знач МодульМетаданных, Знач ЧерезКопию = Ложь) Экспорт
Если МодульМетаданных <> мПустойМодуль Тогда
ФайлОписанияМодуля = ФайлМодуляИзКраткогоИмени(МодульМетаданных.Имя, "ixd");
Если ЧерезКопию Тогда
КопияМодуля = ирОбщий.СкопироватьКоллекциюЛкс(МодульМетаданных);
КопияМодуля.Текст = Неопределено;
КопияМодуля.СтруктураТипа = Неопределено;
КопияМодуля.ТекущийМетод = Неопределено;
КопияМодуля.Переменные = КопияМодуля.Переменные.Скопировать();
КопияМодуля.Методы = КопияМодуля.Методы.Скопировать();
КопияМодуля.Методы.ЗаполнитьЗначения(Неопределено, "КэшПоиска, ТелоБезВозвратов");
СброситьКэшТиповВыраженийМодуля(КопияМодуля);
МодульМетаданных = КопияМодуля;
КонецЕсли;
ирОбщий.СохранитьЗначениеВФайлЛкс(МодульМетаданных, ФайлОписанияМодуля.ПолноеИмя);
КонецЕсли;
КонецПроцедуры
//.
// Параметры:
// выхИмяФайлаМодуляБезРасширения - Строка -
// Возвращаемое значение:
// см. ПодготовитьМодульМетаданных() -
Функция МодульМетаданныхИзКэша(Знач ИмяФайлаМодуляБезРасширения) Экспорт
МодульМетаданных = мМодулиМетаданных[НРег(СтрЗаменить(ИмяФайлаМодуляБезРасширения, " ", "\"))];
Возврат МодульМетаданных;
КонецФункции
Процедура СброситьКэшиТиповВыраженийМодулей(Знач КромеМодуля = "") Экспорт
Для Каждого КлючИЗначение Из мМодулиМетаданных Цикл
Если КлючИЗначение.Ключ = НРег(КромеМодуля) Тогда
Продолжить;
КонецЕсли;
СброситьКэшТиповВыраженийМодуля(КлючИЗначение.Значение);
КонецЦикла;
КонецПроцедуры
//.
// Параметры:
// Модуль - см. МодульМетаданных() -
// Методы - Строка, ТаблицаЗначений -
Процедура СброситьКэшТиповВыраженийМодуля(Знач Модуль) Экспорт
Переменные = Модуль.Переменные;
Переменные.ЗаполнитьЗначения(Ложь, "Вычислено"); // Чтобы не отслеживать зависимости
Переменные.ЗаполнитьЗначения(, "ТаблицаТипов"); // Чтобы не отслеживать зависимости
Методы = Модуль.Методы;
Методы.ЗаполнитьЗначения(Ложь, "Вычислено"); // Чтобы не отслеживать зависимости
Методы.ЗаполнитьЗначения(, "ТаблицаТипов, ТипыВыражений"); // Чтобы не отслеживать зависимости. ТипыВыражений - самые тяжелые
_РежимОтладки = Ложь;
Если _РежимОтладки Тогда // Можно менять на Истина в точке останова, например условием ирОбщий.Пр(_РежимОтладки, 1, 1)
// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
Для Каждого СтрокаМетода Из Методы Цикл
Если ТипЗнч(СтрокаМетода.Параметры) = Тип("ТаблицаЗначений") Тогда
СтрокаМетода.Параметры.ЗаполнитьЗначения(, "ТаблицаТипов");
КонецЕсли;
КонецЦикла;
Иначе
// Однострочный код использован для ускорения при разрешенной отладке. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика"
Для Каждого СтрокаМетода Из Методы Цикл   Если ТипЗнч(СтрокаМетода.Параметры) = Тип("ТаблицаЗначений") Тогда   СтрокаМетода.Параметры.ЗаполнитьЗначения(, "ТаблицаТипов");   КонецЕсли;   КонецЦикла;  
КонецЕсли;
//Для Каждого СтрокаМетода Из Методы Цикл
// Если ТипЗнч(СтрокаМетода.Параметры) = Тип("ТаблицаЗначений") Тогда
// СтрокаМетода.Параметры.ЗаполнитьЗначения(, "ТаблицаТипов");
// КонецЕсли;
// Если СтрокаМетода.ТаблицаТипов <> Неопределено Тогда
// СтрокаМетода.ТаблицаТипов = Неопределено;
// КонецЕсли;
// Если СтрокаМетода.ТипыВыражений <> Неопределено Тогда
// СтрокаМетода.ТипыВыражений = Неопределено;
// КонецЕсли;
//КонецЦикла;
КонецПроцедуры
//.
// Параметры:
// выхИмяФайлаМодуляБезРасширения - Примитивный -
// Возвращаемое значение:
// Файл -
Функция ФайлМодуляИзКраткогоИмени(Знач ИмяФайлаМодуляБезРасширения, Знач Расширение = "txt", Знач ЗаменитьНедопустимыеСимволы = Ложь) Экспорт
Если ЗаменитьНедопустимыеСимволы Тогда
ИмяФайлаМодуляБезРасширения = ирОбщий.ЗаменитьНедопустимыеСимволыВИмениФайлаЛкс(ИмяФайлаМодуляБезРасширения, "_");
КонецЕсли;
ФайлМодуля = Новый Файл(ПапкаКэшаМодулей.ПолноеИмя + ирОбщий.РазделительПутиКФайлуЛкс() + ИмяФайлаМодуляБезРасширения + "." + Расширение);
Возврат ФайлМодуля;
КонецФункции
// Функция - Имя файла модуля без расширения
//
// Параметры:
// СтруктураТипа - -
// ТипМодуля - Строка - входное значение имеет смысл только для модулей приложения (безобъектных)
// СтрокаСозданияРодителя - -
// ФлагиКомпиляции - Структура - выход, заполняется если ТипМодуля на входе пустой
//
// Возвращаемое значение:
// Строка -
//
Функция ИмяФайлаМодуляБезРасширения(Знач СтруктураТипа, ТипМодуля = "", СтрокаСозданияРодителя = "", ФлагиКомпиляции = Неопределено) Экспорт
ИмяОбщегоТипа = СтруктураТипа.ИмяОбщегоТипа;
МетаданныеРодителя = СтруктураТипа.Метаданные;
ТипыМетаОбъектов = ирКэш.ТипыМетаОбъектов();
Результат = "";
ФлагиКомпиляции = НовыеФлагиКомпиляции(Ложь, Ложь, Ложь);
Если ТипМодуля = "МодульОбычногоПриложения" Тогда
ФлагиКомпиляции.Вставить("КлиентОбычноеПриложение", Истина);
ИначеЕсли ТипМодуля = "МодульУправляемогоПриложения" Тогда
ФлагиКомпиляции.Вставить("КлиентУправляемоеПриложение", Истина);
ИначеЕсли ТипМодуля = "МодульСеанса" Тогда
ФлагиКомпиляции.Вставить("Сервер", Истина);
Иначе
ФлагиКомпиляции = НовыеФлагиКомпиляции();
КонецЕсли;
Если ИмяОбщегоТипа = "Глобальный" Тогда
//Если ИмяОбщегоТипа = "ОбъектМетаданныхКонфигурация" Тогда
//#Если ТолстыйКлиентОбычноеПриложение Тогда
// ТипМодуля = "МодульОбычногоПриложения";
//#Иначе
// ТипМодуля = "МодульУправляемогоПриложения";
//#КонецЕсли
Если Не ЗначениеЗаполнено(ТипМодуля) Тогда
ВызватьИсключение "Требуется передача типа модуля конфигурации";
КонецЕсли;
ИначеЕсли Ложь
Или ИмяОбщегоТипа = "Команда"
Или ИмяОбщегоТипа = "ОбщаяКоманда"
Тогда
ТипМодуля = "МодульКоманды";
ИначеЕсли Ложь
Или ИмяОбщегоТипа = "WebСервис"
Или ИмяОбщегоТипа = "HttpСервис"
Или ИмяОбщегоТипа = "ОбщийМодуль"
Тогда
ТипМодуля = "Модуль";
Если ИмяОбщегоТипа = "ОбщийМодуль" Тогда
Если ТипЗнч(МетаданныеРодителя) = Тип("Строка") Тогда
// Добавленный/переименованный объект метаданных
Фрагменты = ирОбщий.СтрРазделитьЛкс(МетаданныеРодителя);
МетаданныеРодителя = Новый Структура;
МетаданныеРодителя.Вставить("ВызовСервера", Истина);
МетаданныеРодителя.Вставить("Сервер", Истина);
МетаданныеРодителя.Вставить("КлиентУправляемоеПриложение", Истина);
МетаданныеРодителя.Вставить("КлиентОбычноеПриложение", Истина);
МетаданныеРодителя.Вставить("Имя", Фрагменты[1]);
//МетаданныеРодителя.Вставить("ИмяРасширения", СтруктураТипа.ДержательМетаданных);
мДобавленныеОбщиеМодули.Вставить(Фрагменты[1], МетаданныеРодителя);
КонецЕсли;
Если Ложь
Или ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных")
Или ТипЗнч(МетаданныеРодителя) = Тип("Структура")
Тогда
ФлагиКомпиляции.Сервер = МетаданныеРодителя.Сервер;
ФлагиКомпиляции.КлиентОбычноеПриложение = МетаданныеРодителя.КлиентОбычноеПриложение;
ФлагиКомпиляции.КлиентУправляемоеПриложение = МетаданныеРодителя.КлиентУправляемоеПриложение;
СтрокаСозданияРодителя = МетаданныеРодителя.Имя;
Результат = ИмяОбщегоТипа + "." + МетаданныеРодителя.Имя + "." + ТипМодуля;
Иначе
// Если ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданныхКонфигурация") Тогда
// см. ОбработкаОбъект.ирКлсПолеТекстаПрограммы.СтруктураТипаМодуля
КонецЕсли;
Иначе
ФлагиКомпиляции.КлиентОбычноеПриложение = Ложь;
ФлагиКомпиляции.КлиентУправляемоеПриложение = Ложь;
КонецЕсли;
ИначеЕсли ирОбщий.ЛиИмяТипаФормыЛкс(ИмяОбщегоТипа, Истина) Тогда
Если Ложь
#Если Клиент Тогда
Или ТипЗнч(МетаданныеРодителя) = Тип("Форма")
#КонецЕсли
Тогда
СлужебныеДанныеФормы = ирОбщий.СлужебныеДанныеФормыЛкс(МетаданныеРодителя);
Если СлужебныеДанныеФормы.Свойство("ИмяФормы") Тогда
МетаданныеРодителя = СлужебныеДанныеФормы.ИмяФормы;
КонецЕсли;
ИначеЕсли ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") Тогда
МетаданныеРодителя = МетаданныеРодителя.ПолноеИмя();
ИначеЕсли ирОбщий.ЛиФормаИлиИмитаторЛкс(МетаданныеРодителя, Ложь) Тогда
МетаданныеРодителя = МетаданныеРодителя.ИмяФормы;
КонецЕсли;
ТипМодуля = "Модуль";
Если ТипЗнч(МетаданныеРодителя) = Тип("Строка") Тогда
МетаданныеРодителя = МетаданныеРодителя + ".Форма";
КонецЕсли;
ИначеЕсли Истина
И ТипЗнч(МетаданныеРодителя) = Тип("Структура")
И (Ложь
Или ИмяОбщегоТипа = "ВнешняяОбработкаОбъект.<Имя внешней обработки>"
Или ИмяОбщегоТипа = "ВнешнийОтчетОбъект.<Имя внешнего отчета>")
Тогда
// Нужно для некомпилируемых внешних объектов
МетаданныеРодителя = ирОбщий.ПервыйФрагментЛкс(ИмяОбщегоТипа, "Объект.", Ложь) + "." + МетаданныеРодителя.Имя;
ТипМодуля = "МодульОбъекта";
Иначе
КорневойТипОбъекта = ирОбщий.ПервыйФрагментЛкс(ИмяОбщегоТипа, "Объект.", Ложь);
Если ЗначениеЗаполнено(КорневойТипОбъекта) Тогда
ТипМодуля = "МодульОбъекта";
СтрокаТипаМетаОбъекта = ТипыМетаОбъектов.Найти(КорневойТипОбъекта, "Единственное");
Если Истина
И СтрокаТипаМетаОбъекта <> Неопределено
И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных")
Тогда
Множественное = СтрокаТипаМетаОбъекта.Множественное;
Если СтрокаТипаМетаОбъекта.Категория = 1 Тогда
СтрокаСозданияРодителя = Множественное + "." + МетаданныеРодителя.Имя + ".Создать()";
ИначеЕсли СтрокаТипаМетаОбъекта.Категория = 0 Тогда
СтрокаСозданияРодителя = Множественное + "." + МетаданныеРодителя.Имя + ".ПустаяСсылка().ПолучитьОбъект()";
КонецЕсли;
КонецЕсли;
ИначеЕсли ЗначениеЗаполнено(ирОбщий.ПервыйФрагментЛкс(ИмяОбщегоТипа, "НаборЗаписей.", Ложь)) Тогда
ТипМодуля = "МодульНабораЗаписей";
КорневойТип = ирОбщий.ПервыйФрагментЛкс(ИмяОбщегоТипа, "НаборЗаписей");
СтрокаТипаМетаОбъекта = ТипыМетаОбъектов.Найти(КорневойТип, "Единственное");
Если Истина
И СтрокаТипаМетаОбъекта <> Неопределено
И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных")
Тогда
Множественное = СтрокаТипаМетаОбъекта.Множественное;
СтрокаСозданияРодителя = Множественное + "." + МетаданныеРодителя.Имя + ".СоздатьНаборЗаписей()";
КонецЕсли;
ИначеЕсли ЗначениеЗаполнено(ирОбщий.ПервыйФрагментЛкс(ИмяОбщегоТипа, "МенеджерЗначения.", Ложь)) Тогда
ТипМодуля = "МодульМенеджераЗначения";
Если ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") Тогда
СтрокаСозданияРодителя = "Константы." + МетаданныеРодителя.Имя + ".СоздатьМенеджерЗначения()";
КонецЕсли;
ИначеЕсли ЗначениеЗаполнено(ирОбщий.ПервыйФрагментЛкс(ИмяОбщегоТипа, "Менеджер.", Ложь)) Тогда
ТипМодуля = "МодульМенеджера";
КорневойТип = ирОбщий.ПервыйФрагментЛкс(ИмяОбщегоТипа, "Менеджер");
СтрокаТипаМетаОбъекта = ТипыМетаОбъектов.Найти(КорневойТип, "Единственное");
Если Истина
И СтрокаТипаМетаОбъекта <> Неопределено
И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных")
Тогда
Множественное = СтрокаТипаМетаОбъекта.Множественное;
СтрокаСозданияРодителя = Множественное + "." + МетаданныеРодителя.Имя;
КонецЕсли;
Иначе
// Тип объекта не имеет модуля
ТипМодуля = Неопределено;
КонецЕсли;
КонецЕсли;
Если Не ЗначениеЗаполнено(Результат) Тогда
Если ЗначениеЗаполнено(ТипМодуля) Тогда
Если ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданныхКонфигурация") Тогда
Результат = "Конфигурация" + "." + ТипМодуля;
Иначе
Если ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") Тогда
МетаданныеРодителя = МетаданныеРодителя.ПолноеИмя();
КонецЕсли;
Если ТипЗнч(МетаданныеРодителя) = Тип("Строка") Тогда
Результат = МетаданныеРодителя + "." + ТипМодуля;
КонецЕсли;
КонецЕсли;
Если Найти(Результат, ":") > 0 Тогда // для ускорения
Результат = ирОбщий.ЗаменитьНедопустимыеСимволыВИмениФайлаЛкс(Результат, "_");
КонецЕсли;
ИначеЕсли ТипЗнч(МетаданныеРодителя) = Тип("Строка") Тогда
Результат = МетаданныеРодителя;
КонецЕсли;
КонецЕсли;
Если Истина
И ирКэш.НомерВерсииПлатформыЛкс() >= 803008
И СтруктураТипа.ДержательМетаданных = Неопределено
Тогда
Если ТипЗнч(СтруктураТипа.Метаданные) = Тип("ОбъектМетаданных") Тогда
МетаданныеРасширения = СтруктураТипа.Метаданные.РасширениеКонфигурации();
ИначеЕсли ирОбщий.ЛиФормаИлиИмитаторЛкс(СтруктураТипа.Метаданные) Тогда
МетаданныеРасширения = ирОбщий.ОбъектМДПоПолномуИмениЛкс(ирОбщий.ПолноеИмяФормыЛкс(СтруктураТипа.Метаданные));
Если МетаданныеРасширения <> Неопределено Тогда
МетаданныеРасширения = МетаданныеРасширения.РасширениеКонфигурации();
КонецЕсли;
КонецЕсли;
Если МетаданныеРасширения <> Неопределено Тогда
СтруктураТипа.ДержательМетаданных = МетаданныеРасширения.Имя;
КонецЕсли;
КонецЕсли;
Если ТипЗнч(СтруктураТипа.ДержательМетаданных) = Тип("Строка") Тогда
Результат = СтруктураТипа.ДержательМетаданных + "\" + Результат;
КонецЕсли;
Возврат Результат;
КонецФункции
// Функция - Обновить кэш структуры формы из буфера
//
// Параметры:
// СлужебныеДанные - см. ирОбщий.СлужебныеДанныеФормыЛкс() -
// ТекстБуфераОбмена - -
// Форма - -
//
// Возвращаемое значение:
// -
//
Функция ОбновитьКэшСтруктурыФормыИзБуфера(Знач СлужебныеДанные, Знач ТекстБуфераОбмена, Знач Форма = Неопределено) Экспорт
Если СлужебныеДанные.Свойство("КорневыеИменаРеквизитов") Тогда
СлужебныеДанные.Удалить("КорневыеИменаРеквизитов");
КонецЕсли;
ИмитаторФормы = Новый Структура("ВерсияФормата, Элементы, Параметры, Команды, ДинамическиеСписки, ИменаОбработчиков, Реквизиты",
ВерсияФорматаСтруктурыФормы(), Новый Структура, Новый Структура, Новый Структура, Новый Структура, Новый Массив);
ЛиОбычнаяФорма = Ложь;
Попытка
ДвоичныеДанные = Base64Значение(ирОбщий.ТекстМеждуМаркерамиЛкс(ТекстБуфераОбмена, "#base64:", "}"));
Текст = Новый ТекстовыйДокумент;
Текст.Прочитать(ДвоичныеДанные.ОткрытьПотокДляЧтения());
ТекстФайла = Текст.ПолучитьТекст();
ЛиОбычнаяФорма = Лев(ТекстФайла, 1) <> "{";
Если ЛиОбычнаяФорма Тогда
СлужебныеДанные.Тип = Тип("Форма");
// Обычная форма
ВызватьИсключение "ОбычнаяФорма";
КонецЕсли;
XMLСтрока = ирОбщий.СтрокаВнутрВХМЛТелоЛкс(ТекстФайла); // Если ошибка, то обычная форма
ДокументDOM = ирОбщий.ТекстВДокументDOMЛкс(XMLСтрока); // Если ошибка, то не поддерживаемый формат управляемой формы. Например Обработка.упРМПланированиеРейсов.ФормаРедактированияРейса
Исключение
ОписаниеОшибки = ОписаниеОшибки();
ДополнитьСлужебныеДанныеИзКэшаФормы(СлужебныеДанные, ИмитаторФормы, ТекущаяДата());
Если Не ЛиОбычнаяФорма И ЗначениеЗаполнено(ТекстБуфераОбмена) Тогда
ирОбщий.СообщитьЛкс("Ошибка разбора буферного описания формы " + ирОбщий.ПолноеИмяФормыЛкс(СлужебныеДанные) + ": " + ОписаниеОшибки);
КонецЕсли;
Возврат Ложь;
КонецПопытки;
Разыменователь = Новый РазыменовательПространствИмен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.ТекстовоеСодержимое);
ОписаниеРеквизита = Новый Структура;
РеквизитыКоллекции = НоваяТаблицаРеквизитовФормы();
НомерУзлаВложенных = 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", ПолучитьПолноеИмяПредопределенногоЗначения(ВидПоляФормы.ПолеПланировщика));
ПутиКРодителям = Новый Соответствие;
//Выражение = "/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 = НаборУзлов.ПолучитьСледующий();
КонецЦикла;
КонецЦикла;
// параметры
Выражение = "/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 = НаборУзлов.ПолучитьСледующий();
КонецЦикла;
ФайлФормы = ФайлМодуляИзКраткогоИмени(СлужебныеДанные.ИмяФормы, "xml", Истина);
ирОбщий.СохранитьЗначениеВФайлЛкс(ИмитаторФормы, ФайлФормы.ПолноеИмя);
ДополнитьСлужебныеДанныеИзКэшаФормы(СлужебныеДанные, ИмитаторФормы, ТекущаяДата());
Возврат Истина;
КонецФункции
Функция ВерсияФорматаСтруктурыФормы()
Возврат 3; // Каждый раз при изменении структуры увеличиваем на 1
КонецФункции
Процедура ДополнитьСлужебныеДанныеИзКэшаФормы(Знач СлужебныеДанные, Знач ИмитаторФормы, Знач ДатаОбновления) Экспорт
Если Ложь
Или Не СлужебныеДанные.Свойство("Элементы")
Или ИмитаторФормы.Элементы.Количество() > 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""" Тогда
Тип = Тип("Строка");
ИначеЕсли РодТипа.ТекстовоеСодержимое = """B""" Тогда
Тип = Тип("Булево");
ИначеЕсли РодТипа.ТекстовоеСодержимое = """N""" Тогда
Тип = Тип("Число");
ИначеЕсли РодТипа.ТекстовоеСодержимое = """D""" Тогда
Тип = Тип("Число");
ИначеЕсли РодТипа.ТекстовоеСодержимое = """#""" Тогда
ИДТипа = УзелТипа.ДочерниеУзлы[1].ДочерниеУзлы[1].ТекстовоеСодержимое;
Попытка
Тип = ЗначениеИзСтрокиВнутр("{""T""," + ИДТипа + "}");
Исключение
КонецПопытки;
Иначе
Пустышка = 0;
КонецЕсли;
КонецЕсли;
Возврат новый ОписаниеТипов(ирОбщий.ЗначенияВМассивЛкс(Тип));
КонецФункции
// Возвращаемое значение:
// Структура -
Функция НовыеФлагиКомпиляции(Знач Сервер = Истина, Знач КлиентОбычноеПриложение = Истина, Знач КлиентУправляемоеПриложение = Истина, Знач БезКонтекста = Ложь) Экспорт
ФлагиКомпиляции = Новый Структура;
ФлагиКомпиляции.Вставить("Сервер", Сервер);
ФлагиКомпиляции.Вставить("КлиентОбычноеПриложение", КлиентОбычноеПриложение);
ФлагиКомпиляции.Вставить("КлиентУправляемоеПриложение", КлиентУправляемоеПриложение);
ФлагиКомпиляции.Вставить("БезКонтекста", БезКонтекста);
Возврат ФлагиКомпиляции;
КонецФункции
Функция ОписаниеМетодаМодуля(ПолноеИмяМетода) Экспорт
СтруктураТипа = НоваяСтруктураТипа();
СтруктураТипа.ИмяОбщегоТипа = "ОбщийМодуль";
СтруктураТипа.Метаданные = Метаданные.ОбщиеМодули[ирОбщий.ПервыйФрагментЛкс(ПолноеИмяМетода)];
МодульМетаданных = ПодготовитьМодульМетаданных(СтруктураТипа);
Если МодульМетаданных = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
МетодыМодуля = МодульМетаданных.Методы;
#Если Сервер И Не Сервер Тогда
МетодыМодуля = Новый ТаблицаЗначений;
#КонецЕсли
ОписаниеМетода = МетодыМодуля.Найти(ирОбщий.ПоследнийФрагментЛкс(ПолноеИмяМетода), "Имя");
Возврат ОписаниеМетода;
КонецФункции
Функция ПолучитьРазделыМодуля1С(Знач ТекстМодуля = "") Экспорт
#Если Сервер И Не Сервер Тогда
RegExp = Обработки.ирОболочкаРегВыражение.Создать();
#КонецЕсли
Шаблоны = ШаблоныДляАнализаВстроенногоЯзыка();
RegExp.IgnoreCase = Истина;
RegExp.MultiLine = Ложь;
RegExp.Global = Истина;
RegExp.Pattern = Шаблоны.ЭлементОбластиМетодов;
ВхожденияМетодов = RegExp.НайтиВхождения(ТекстМодуля);
ПозицияНачалаПервогоМетода = 1;
ПозицияКонцаПоследнегоМетода = 1;
Для Индекс = 0 По ВхожденияМетодов.Количество() - 1 Цикл
Вхождение = ВхожденияМетодов[Индекс];
Если Вхождение.SubMatches(1) <> Неопределено Тогда
ПозицияНачалаПервогоМетода = Вхождение.FirstIndex + 1;
Прервать;
КонецЕсли;
КонецЦикла;
Для Индекс = 1 - ВхожденияМетодов.Количество() По 0 Цикл // Обратный обход
Вхождение = ВхожденияМетодов[-Индекс];
Если Вхождение.SubMatches(1) <> Неопределено Тогда
ПозицияКонцаПоследнегоМетода = Вхождение.FirstIndex + Вхождение.Length + 1;
Прервать;
КонецЕсли;
КонецЦикла;
Если ПозицияКонцаПоследнегоМетода = 1 Тогда
RegExp.Pattern = Шаблоны.ОписаниеСтрокиПеременных;
ВхожденияПеременных = RegExp.НайтиВхождения(ТекстМодуля);
Для Индекс = 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|$)
// + <шСтруктураКомментаПарам> = Параметры(?:\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|$))*)
// + <шКомментМетода> = ((?:[\f\r\t\v]*//[^\n]*\n)+)(?:Функция|Процедура)<шРазделитель>*(<шИмя>)
// + <шОписаниеПеременной> = (<шИмя>)(<шРазделитель>+Экспорт)?
// + <шСтрокаПеременныхБезКомментов> = <шПустоеНачалоСтроки>Перем((?:<шРазделитель>*<шОписаниеПеременной><шРазделитель>*[;,])+)
// + <шСтрокаПеременных> = <шСтрокаПеременныхБезКомментов>([^\n\S]*//[^\n]*)?
// + <шСтрокаПрограммы> = "(?:(?:"")|[^"\n])*(?:<шРазделитель>*\|(?:(?:"")|[^"\n])*)*(?:"|$)
// + <шПараметрыМетода> = <шРазделитель>*(Знач\s)?<шРазделитель>*(<шИмя>)<шРазделитель>*=?((?:<шРазделитель>*|(<шСтрокаПрограммы>)|(?:[^,\n]*))+)(?:,|$)
// + <шДирективаПрепроцессора> = (?:\n\s*)?<шПустоеНачалоСтроки>[#&][^\n]*(?=\n|$)
// + <шБлокКомментов> = <шКомментарий>(?:<шПустоеНачалоСтроки><шКомментарий>)*(?=(?:\n|$))
// + <шМетодЧистый> = ([\t ]*(?:Асинх\s+)?(Процедура|Функция)<шРазделитель>*(<шИмя>)<шРазделитель>*\(([^\)]*)\)(<шРазделитель>*Экспорт)?(?:\s*?(?=\n))?(?:\n\s*Перем .*(?=\n))*)((?:<шСтрокаПрограммы>|<шБлокКомментов>|\.Конец(?:Процедуры|Функции)|(?:\r|\n|.)(?!Конец(?:Процедуры|Функции)))*)(?:$|[^а-яё_a-z0-9\."]Конец(?:Процедуры|Функции)(?=(?:<шКомментарий>|[^а-яё_a-z0-9\."]|$)))
// + <шМетодСПредКомментом> = (?:(<шБлокКомментов>\n)|\n|^)[\t ]*<шМетодЧистый>
// + <шЭлементОбластиМетодов> = <шМетодСПредКомментом>|(<шБлокКомментов>)|(<шДирективаПрепроцессора>)
// {Шаблон.Конец}
шИмя = ЭтотОбъект.шИмя;
шПустоеНачалоСтроки = ЭтотОбъект.шПустоеНачалоСтроки;
шКомментарий = ЭтотОбъект.шКомментарий;
шРазделитель = ЭтотОбъект.шРазделитель;
шСтрокаПрограммы = ЭтотОбъект.шСтрокаПрограммы;
шСтруктураКомментаПарам = "Параметры(?:\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)+)(?:Функция|Процедура)" + шРазделитель + "+(" + шИмя + ")";
шОписаниеПеременной = "(" + шИмя + ")(" + шРазделитель + "+Экспорт)?";
шСтрокаПеременныхБезКомментов = "Перем((?:" + шРазделитель + "*" + шОписаниеПеременной + "" + шРазделитель + "*[;,])+)";
шСтрокаПеременных = "" + шПустоеНачалоСтроки + шСтрокаПеременныхБезКомментов + "([^\n\S]*//[^\n]*)?";
шПараметрыМетода = "" + шРазделитель + "*(Знач\s)?" + шРазделитель + "*(" + шИмя + ")" + шРазделитель + "*=?((?:" + шРазделитель + "*|(" + шСтрокаПрограммы + ")|(?:[^,\n]*))+)(?:,|$)";
шДирективаПрепроцессора = "(?:\n\s*)?" + шПустоеНачалоСтроки + "[#&][^\n]*(?=\n|$)";
шБлокКомментов = "" + шКомментарий + "(?:" + шПустоеНачалоСтроки + "" + шКомментарий + ")*(?=(?:\n|$))";
шМетодЧистый = "([\t ]*(?:Асинх\s+)?(Процедура|Функция)" + шРазделитель + "+(" + шИмя + ")" + шРазделитель + "*\(([^\)]*)\)(" + шРазделитель + "*Экспорт)?(?:\s*?(?=\n))?(?:\n\s*Перем .*(?=\n))*)"
+ "((?:" + шСтрокаПрограммы + "|" + шБлокКомментов + "|\.Конец(?:Процедуры|Функции)|(?:\r|\n|.)(?!Конец(?:Процедуры|Функции)))*)(?:$|[^а-яё_a-z0-9\.""]Конец(?:Процедуры|Функции)(?=(?:" + шКомментарий + "|[^а-яё_a-z0-9\.""]|$)))";
шМетодСПредКомментом = "(?:(" + шБлокКомментов + "\n)|\n|^)" + шМетодЧистый + "";
шЭлементОбластиМетодов = "" + шМетодСПредКомментом + "|(" + шБлокКомментов + ")|(" + шДирективаПрепроцессора + ")";
// {ОписаниеРегулярногоВыражения.Конец}
Результат = Новый Структура;
Результат.Вставить("СтрокаПрограммы", шСтрокаПрограммы);
Результат.Вставить("ДирективаПрепроцессора", шДирективаПрепроцессора);
Результат.Вставить("БлокКомментариев", шБлокКомментов);
Результат.Вставить("ОписаниеМетодаСКомментарием", шМетодСПредКомментом);
Результат.Вставить("ОписаниеМетодаЧистое", шМетодЧистый);
Результат.Вставить("ЭлементОбластиМетодов", шЭлементОбластиМетодов);
Результат.Вставить("ОписаниеПеременной", шОписаниеПеременной);
Результат.Вставить("ОписаниеСтрокиПеременных", шСтрокаПеременных);
Результат.Вставить("ОписаниеСтрокиПеременныхБезКомментов", шСтрокаПеременныхБезКомментов);
Результат.Вставить("КомментарийОписаниеМетода", шКомментМетода);
Результат.Вставить("ПараметрыМетода", шПараметрыМетода);
Результат.Вставить("СтруктураКомментарияВозвр", шСтруктураКомментаВозвр);
Результат.Вставить("СтруктураКомментарияПарам", шСтруктураКомментаПарам);
Результат.Вставить("СтруктураКомментарияОписаниеПараметров", шСтруктураКомментаОписаниеПараметров);
Результат.Вставить("Возврат", шВозврат);
Результат.Вставить("ОписаниеПараметра", ".*(?:\n(?://)?(?:[\t ]{5,}|[\t ]+\*).*)*");
мШаблоныДляАнализаВстроенногоЯзыка = Результат;
Возврат Результат;
КонецФункции
// Функция - Модуль метаданных. Для пустого текста и НЕ пустого имени возращает единый модуль с именем "<Пустой>"!
//
// Параметры:
// ТекстМодуля - Строка -
// СтруктураТипа - см. НоваяСтруктураТипа() -
// ИмяМодуля - Строка -
// ПодготовитьОписанияРезультатовМетодов - Булево -
// СтарыйМодуль - -
// ТекущийМетод - см. НоваяТаблицаМетодовМодуля()[0] -
//
// Возвращаемое значение:
// Структура -
//
Функция МодульМетаданных(Знач ТекстМодуля, Знач СтруктураТипа = Неопределено, Знач ИмяМодуля = "", Знач ПодготовитьОписанияРезультатовМетодов = Истина, Знач СтарыйМодуль = Неопределено,
Знач ТекущаяПозиция = 0) Экспорт
РазрешитьЕдиныйПустойМодуль = Истина
И ПустаяСтрока(ТекстМодуля)
И ИмяМодуля <> ИмяДинамическогоМодуля()
И ЗначениеЗаполнено(ИмяМодуля);
Если РазрешитьЕдиныйПустойМодуль И мПустойМодуль <> Неопределено Тогда
// Для ускорения заполнения списка в Обработка.ирКлсПолеТекстаПрограммы.Форма.МетодыМодулей
Возврат мПустойМодуль;
КонецЕсли;
ЛиНачальныйДиапазонСовпал = Ложь;
ЛиКонечныйДиапазонСовпал = Ложь;
Если Истина
И СтарыйМодуль <> Неопределено
//И СтарыйМодуль.Свойство("Текст")
И ЗначениеЗаполнено(ТекущаяПозиция)
И ирКэш.НомерРежимаСовместимостиЛкс() >= 803006 // СтрНайти()
Тогда
МетодыСтарые = СтарыйМодуль.Методы;
ТекущийМетод = СтарыйМодуль.ТекущийМетод; // см. МетодыСтарые.Добавить()
Если ТекущийМетод <> Неопределено Тогда
Если Ложь
Или МетодыСтарые.Индекс(ТекущийМетод) = -1
Или ТекущийМетод.ПозицияСОписанием - ТекущаяПозиция > 1000
Или ТекущаяПозиция - (ТекущийМетод.ПозицияСОписанием + ТекущийМетод.ДлинаСОписанием) > 1000
Тогда
ТекущийМетод = Неопределено;
КонецЕсли;
КонецЕсли;
ИндексТекущегоМетода = -1;
Если ТекущийМетод <> Неопределено Тогда
ИндексТекущегоМетода = МетодыСтарые.Индекс(ТекущийМетод);
КонецЕсли;
Если ИндексТекущегоМетода = -1 Тогда
ИндексТекущегоМетода = МетодыСтарые.Количество();
Для Каждого Метод Из МетодыСтарые Цикл
Если Метод.ПозицияСОписанием = 0 Тогда
Продолжить;
КонецЕсли;
Если Метод.ПозицияСОписанием + Метод.ДлинаСОписанием + 100 > ТекущаяПозиция Тогда
ИндексТекущегоМетода = МетодыСтарые.Индекс(Метод);
ТекущийМетод = Метод;
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если ТекущийМетод <> Неопределено Тогда
ПозицияНачалаСтарая = ТекущийМетод.ПозицияСОписанием;
ПозицияКонцаСтарая = ПозицияНачалаСтарая + ТекущийМетод.ДлинаСОписанием;
ЧастьДоМетодаСтарая = Лев(СтарыйМодуль.Текст, ПозицияНачалаСтарая);
ЧастьДоМетодаНовая = Лев(ТекстМодуля, ПозицияНачалаСтарая);
Если ЧастьДоМетодаСтарая = ЧастьДоМетодаНовая Тогда
ЛиНачальныйДиапазонСовпал = Истина;
Если ТекущийМетод <> Неопределено Тогда
Если ТекущийМетод.ТипЗначения = Неопределено Тогда
МаркерКонца = Символы.ПС + "КонецПроцедуры";
Иначе
МаркерКонца = Символы.ПС + "КонецФункции";
КонецЕсли;
ПозицияКонцаНовая = ирОбщий.СтрНайтиЛкс(ТекстМодуля, МаркерКонца,, ПозицияНачалаСтарая) + СтрДлина(МаркерКонца);
Иначе
ПозицияКонцаНовая = ирОбщий.СтрНайтиЛкс(ТекстМодуля, Символы.ПС,, ПозицияНачалаСтарая + 1);
КонецЕсли;
ЧастьПослеМетодаНовая = Сред(ТекстМодуля, ПозицияКонцаНовая);
ЧастьПослеМетодаСтарая = Сред(СтарыйМодуль.Текст, ПозицияКонцаСтарая);
ЛиКонечныйДиапазонСовпал = ЧастьПослеМетодаНовая = ЧастьПослеМетодаСтарая;
СмещениеКонечногоДиапазона = ПозицияКонцаНовая - ПозицияКонцаСтарая;
КонецЕсли;
КонецЕсли;
КонецЕсли;
НачальнаяПозицияДиапазона = 0;
Если ЛиНачальныйДиапазонСовпал Тогда
Модуль = СтарыйМодуль;
СброситьКэшТиповВыраженийМодуля(Модуль);
Методы = Модуль.Методы;
НачальнаяПозицияДиапазона = ТекущийМетод.ПозицияСОписанием - 1;
Если ЛиКонечныйДиапазонСовпал Тогда
ТекущийМетод.КэшПоиска = Неопределено;
ОпределениеСОписанием = Сред(ТекстМодуля, ТекущийМетод.ПозицияСОписанием, ТекущийМетод.ДлинаСОписанием + СмещениеКонечногоДиапазона);
ВхожденияМетодов = ПолучитьРазделыМодуля1С(ОпределениеСОписанием).ВхожденияМетодов;
Для ИндексМетодаЦикл = ИндексТекущегоМетода + 1 По Методы.Количество() - 1 Цикл
СтрокаМетода = Методы[ИндексМетодаЦикл];
Если СтрокаМетода.ПозицияСОписанием = 0 Тогда
Продолжить; // Возможно даже Прервать
КонецЕсли;
СтрокаМетода.ПозицияСОписанием = СтрокаМетода.ПозицияСОписанием + СмещениеКонечногоДиапазона;
СтрокаМетода.ПозицияОпределения = СтрокаМетода.ПозицияОпределения + СмещениеКонечногоДиапазона;
СтрокаМетода.ПозицияТела = СтрокаМетода.ПозицияТела + СмещениеКонечногоДиапазона;
КонецЦикла;
Модуль.ПозицияПрограммы = Модуль.ПозицияПрограммы + СмещениеКонечногоДиапазона;
Иначе
КонечныйДиапазон = Сред(ТекстМодуля, ТекущийМетод.ПозицияСОписанием);
РазделыМодуля = ПолучитьРазделыМодуля1С(КонечныйДиапазон);
Модуль.Программа = РазделыМодуля.Программа;
Модуль.ПозицияПрограммы = ТекущийМетод.ПозицияСОписанием + РазделыМодуля.ПозицияПрограммы;
ВхожденияМетодов = РазделыМодуля.ВхожденияМетодов;
Пока Методы.Количество() > ИндексТекущегоМетода Цикл
Методы.Удалить(ИндексТекущегоМетода);
КонецЦикла;
ТекущийМетод = Неопределено;
КонецЕсли;
Модуль.Текст = ТекстМодуля;
Иначе
ТекущийМетод = Неопределено;
Модуль = ПолучитьРазделыМодуля1С(ТекстМодуля);
Модуль.Вставить("СтруктураТипа", СтруктураТипа); // Обычно передается сначала пустая, чтобы не было проблем с сериализацией
Модуль.Вставить("Имя", ИмяМодуля);
Модуль.Вставить("ФлагиКомпиляции");
Модуль.Вставить("СтрокаСоздания");
Модуль.Вставить("ТекущийМетод");
Шаблоны = ШаблоныДляАнализаВстроенногоЯзыка();
RegExp.IgnoreCase = Истина;
RegExp.Multiline = Ложь;
// При добавлении колонок нужно увеличивать версию формата Метка91237881041
Переменные = Новый ТаблицаЗначений;
Переменные.Колонки.Добавить("Имя", Новый ОписаниеТипов("Строка"));
Переменные.Колонки.Добавить("НИмя", Новый ОписаниеТипов("Строка"));
Переменные.Колонки.Добавить("ЛиЭкспорт", Новый ОписаниеТипов("Булево"));
Переменные.Колонки.Добавить("Вычислено", Новый ОписаниеТипов("Булево")); // вычислено по коду
Переменные.Колонки.Добавить("ПозицияСОписанием", Новый ОписаниеТипов("Число")); // Начиная с 1.
Переменные.Колонки.Добавить("ПозицияОпределения", Новый ОписаниеТипов("Число")); // Начиная с 1.
Переменные.Колонки.Добавить("ТипЗначения", Новый ОписаниеТипов("Строка"));
Переменные.Колонки.Добавить("Описание", Новый ОписаниеТипов("Строка"));
Переменные.Колонки.Добавить("ИмяМодуля", Новый ОписаниеТипов("Строка"));
Переменные.Колонки.Добавить("ТаблицаТипов");
//RegExp.Pattern = Шаблоны.ОписаниеСтрокиПеременных + "|(" + Шаблоны.БлокКомментариев + ")|(" + Шаблоны.ДирективаПрепроцессора + ")";
RegExp.Pattern = Шаблоны.ОписаниеСтрокиПеременных + "|(" + Шаблоны.БлокКомментариев + ")|(" + Шаблоны.ДирективаПрепроцессора + ")";
Вхождения = RegExp.НайтиВхождения(Модуль.ПеременныеТекст);
Для Каждого Вхождение Из Вхождения Цикл
Если Вхождение.SubMatches(0) <> Неопределено Тогда
ТекстСтроки = Вхождение.SubMatches(0);
ОписаниеСтроки = ОчиститьТекстМодуляОтПрефиксаКомментария(Вхождение.SubMatches(3));
ПозицияСОписанием = Вхождение.FirstIndex + 2;
Если Найти(ТекстСтроки, ",") = 0 Тогда
// Одна переменная в строке
ИмяПеременной = ирОбщий.ПервыйФрагментЛкс(Вхождение.SubMatches(1));
ЭкспортПеременной = ?(Вхождение.SubMatches(2) = Неопределено, Ложь, Истина);
ДобавитьПеременную(Переменные, ИмяПеременной, ЭкспортПеременной, ОписаниеСтроки, ПозицияСОписанием);
Иначе
// Несколько переменных в строке
RegExp2.Pattern = Шаблоны.ОписаниеПеременной + "|\s*(?:;|,)";
Результат2 = RegExp2.НайтиВхождения(ТекстСтроки); // тяжелая операция
Для Каждого Вхождение2 Из Результат2 Цикл
Если Вхождение2.SubMatches(0) <> Неопределено Тогда
ИмяПеременной = Вхождение2.SubMatches(0);
ЭкспортПеременной = ?(Вхождение2.SubMatches(1) = Неопределено, Ложь, Истина);
ДобавитьПеременную(Переменные, ИмяПеременной, ЭкспортПеременной, ОписаниеСтроки, ПозицияСОписанием);
КонецЕсли;
КонецЦикла;
КонецЕсли;
//ИначеЕсли Вхождение.SubMatches(4) <> Неопределено Тогда
// СтрокаПеременной.Тип = "Комментарий";
//ИначеЕсли Вхождение.SubMatches(5) <> Неопределено Тогда
// СтрокаПеременной.Тип = "Директива";
КонецЕсли;
КонецЦикла;
Модуль.Удалить("ПеременныеТекст");
Модуль.Вставить("Переменные", Переменные);
Методы = НоваяТаблицаМетодовМодуля();
ВхожденияМетодов = Модуль.ВхожденияМетодов;
Если СтруктураТипа <> Неопределено Тогда
СтрокаМетода = Методы.Добавить();
СтрокаМетода.Сервер = Истина;
СтрокаМетода.Клиент = Истина;
СтрокаМетода.ЛиЭкспорт = Истина;
СтрокаМетода.Вычислено = Истина;
СтрокаМетода.Имя = "<>";
СтрокаМетода.ТипЗначения = "Неизвестный контекст";
ирОбщий.ОбновитьКопиюСвойстваВНижнемРегистреЛкс(СтрокаМетода);
КонецЕсли;
КонецЕсли;
ПоследняяАннотация = "";
ПоследнееОписание = "";
ПорогДлиныМаркераТела = 20;
Для Каждого Вхождение Из ВхожденияМетодов Цикл
ПозицияВхождения = Вхождение.FirstIndex + 1 + НачальнаяПозицияДиапазона;
Заголовок = Вхождение.SubMatches(1);
Если Заголовок <> Неопределено Тогда
Если ТекущийМетод <> Неопределено Тогда
СтрокаМетода = ТекущийМетод;
СтрокаМетода.ОписаниеРезультата = Неопределено;
СтрокаМетода.ТелоБезВозвратов = Неопределено;
Иначе
СтрокаМетода = Методы.Добавить();
КонецЕсли;
ОписаниеМетода = Вхождение.SubMatches(0);
ДлинаОписания = СтрДлина(ОписаниеМетода);
ОпределениеБезОписания = Сред(Вхождение.Value, ДлинаОписания + 1);
Если Лев(ОпределениеБезОписания, 1) = Символы.ПС Тогда
ОпределениеБезОписания = Сред(ОпределениеБезОписания, 2);
ДлинаОписания = ДлинаОписания + 1;
КонецЕсли;
СтрокаМетода.ПозицияСОписанием = ПозицияВхождения;
СтрокаМетода.ДлинаСОписанием = Вхождение.Length;
СтрокаМетода.ПозицияОпределения = СтрокаМетода.ПозицияСОписанием + ДлинаОписания;
СтрокаМетода.ДлинаОпределения = СтрДлина(ОпределениеБезОписания);
//СтрокаМетода.Индекс = Вхождение.FirstIndex + Смещение;
СтрокаМетода.Имя = Вхождение.SubMatches(3);
СтрокаМетода.НИмя = Нрег(СтрокаМетода.Имя);
ТекстПараметров = Вхождение.SubMatches(4);
ТекстЭкспорта = Вхождение.SubMatches(5);
ЛиЭкспорт = ?(ТекстЭкспорта = Неопределено, Ложь, Истина);
Тело = Вхождение.SubMatches(6);
ПерваяСтрокаТела = ирОбщий.ПервыйФрагментЛкс(Тело, Символы.ПС);
ПозицияЭкспортаВТеле = Найти(ПерваяСтрокаТела, ") Экспорт");
Если ПозицияЭкспортаВТеле > 0 Тогда
// Сработал ложный конец секции параметров из-за ")" в значении по умолчанию
ТекстПараметров = ТекстПараметров + ")" + Лев(ПерваяСтрокаТела, ПозицияЭкспортаВТеле - 1);
ЛиЭкспорт = Истина;
КонецЕсли;
СтрокаМетода.ЛиЭкспорт = ЛиЭкспорт;
Тело = Сред(Тело, 2); // Мультиметка38422941 Сдвиг добавлен после вынужденного переноса символа "переноса строки" из заголовка в тело
СтрокаМетода.ДлинаТела = СтрДлина(Тело);
МаркерНачалаТела = Тело;
//Если СтрДлина(МаркерНачалаТела) < ПорогДлиныМаркераТела Тогда
// МаркерНачалаТела = МаркерНачалаТела + Символы.ПС;
//КонецЕсли;
МаркерНачалаТела = Лев(МаркерНачалаТела, ПорогДлиныМаркераТела);
СтрокаМетода.ПозицияТела = СтрокаМетода.ПозицияОпределения + Найти(ОпределениеБезОписания, МаркерНачалаТела) - 2; // Мультиметка38422941
Если ЗначениеЗаполнено(ПоследняяАннотация) И Не ЗначениеЗаполнено(ОписаниеМетода) Тогда
ОписаниеМетода = ПоследнееОписание;
КонецЕсли;
ПоследнееОписание = "";
СтрокаМетода.Описание = ОписаниеМетода;
СтрокаМетода.Аннотация = ПоследняяАннотация;
Если НРег(Вхождение.SubMatches(2)) = "функция" Тогда
СтрокаМетода.ТипЗначения = "??";
КонецЕсли;
СтрокаМетода.Параметры = ТекстПараметров; // Сначала тип "Строка". Позже разбираем их в ПараметрыМетодаМодуля()
Если ПодготовитьОписанияРезультатовМетодов Тогда
// очень небольшая экономия времени
ПодготовитьОписаниеРезультатаМетода(СтрокаМетода);
КонецЕсли;
Если ЗначениеЗаполнено(ПоследняяАннотация) Тогда
СтрокаМетода.РасширяемыйМетод = ирОбщий.ТекстМеждуМаркерамиЛкс(ПоследняяАннотация, "(""", """)", Ложь);
КонецЕсли;
ПоследняяАннотация = НРег(ПоследняяАннотация);
СтрокаМетода.Сервер = ПустаяСтрока(ПоследняяАннотация) Или Найти(ПоследняяАннотация, "насервере") > 0;
СтрокаМетода.Клиент = ПустаяСтрока(ПоследняяАннотация) Или Найти(ПоследняяАннотация, "наклиенте") > 0;
СтрокаМетода.БезКонтекста = Найти(ПоследняяАннотация, "безконтекста") > 0;
СтрокаМетода.ЛиАсинх = НРег(Лев(Заголовок, 1)) = "а";
Если СтарыйМодуль <> Неопределено Тогда
//СтарыйМетод = СтарыйМодуль.Методы.Найти(СтрокаМетода.НИмя, "НИмя");
//Если Истина
// //И СтарыйМетод.Вычислено
// И ТипЗнч(СтарыйМетод.Параметры) <> Тип("Строка")
// И Сред(СтарыйМодуль.Текст, СтарыйМетод.ПозицияСОписанием, СтарыйМетод.ДлинаСОписанием) = Вхождение.Value
// И СтарыйМетод.Аннотация = СтрокаМетода.Аннотация
//Тогда
// СтрокаМетода.Параметры = СтарыйМетод.Параметры;
// СтрокаМетода.Параметры.ЗаполнитьЗначения(, "ТаблицаТипов");
// СтрокаМетода.ОписаниеРезультата = СтарыйМетод.ОписаниеРезультата;
// СтрокаМетода.ТипЗначения = СтарыйМетод.ТипЗначения;
//КонецЕсли;
КонецЕсли;
ПоследняяАннотация = "";
ИначеЕсли Вхождение.SubMatches(7) <> Неопределено Тогда
Если Модуль.ПозицияМетодов > ПозицияВхождения Тогда
Продолжить;
КонецЕсли;
ПоследнееОписание = Вхождение.SubMatches(7);
ИначеЕсли Вхождение.SubMatches(8) <> Неопределено Тогда
НоваяАннотация = Вхождение.SubMatches(8);
Если СтрЧислоСтрок(НоваяАннотация) = 3 Тогда
ПоследнееОписание = "";
КонецЕсли;
НоваяАннотация = СокрЛП(НоваяАннотация);
Если Лев(НоваяАннотация, 1) = "&" Тогда
ПоследняяАннотация = НоваяАннотация;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Модуль.Удалить("МетодыТекст");
Модуль.Удалить("ВхожденияМетодов");
Модуль.Вставить("Методы", Методы);
Модуль.Вставить("Текст", ТекстМодуля);
Методы.Индексы.Добавить("ЛиЭкспорт");
Методы.Индексы.Добавить("ЛиЭкспорт, НИмя");
Методы.Индексы.Добавить("НИмя");
Если РазрешитьЕдиныйПустойМодуль Тогда
Модуль.Имя = "<Пустой>";
мПустойМодуль = Модуль;
КонецЕсли;
Возврат Модуль;
КонецФункции
// Функция - Новая таблица методов модуля
//
// Возвращаемое значение:
// ТаблицаЗначений - :
// * Параметры - Строка, см. ПараметрыМетодаМодуля
// * ТаблицаТипов - см. НоваяТаблицаТипов
// * КлючевыеПараметры - Структура
//
Функция НоваяТаблицаМетодовМодуля() Экспорт
// При добавлении колонок нужно увеличивать версию формата Метка91237881041
Методы = Новый ТаблицаЗначений;
Методы.Колонки.Добавить("Имя", Новый ОписаниеТипов("Строка"));
//Методы.Колонки.Добавить("Тип", Новый ОписаниеТипов("Строка"));
//Методы.Колонки.Добавить("Индекс", Новый ОписаниеТипов("Число"));
Методы.Колонки.Добавить("НИмя", Новый ОписаниеТипов("Строка"));
Методы.Колонки.Добавить("Аннотация", Новый ОписаниеТипов("Строка"));
Методы.Колонки.Добавить("РасширяемыйМетод", Новый ОписаниеТипов("Строка"));
Методы.Колонки.Добавить("Параметры");
Методы.Колонки.Добавить("ПозицияСОписанием", Новый ОписаниеТипов("Число")); // Начиная с 1.
Методы.Колонки.Добавить("ДлинаСОписанием", Новый ОписаниеТипов("Число"));
Методы.Колонки.Добавить("ПозицияОпределения", Новый ОписаниеТипов("Число")); // Начиная с 1. Может содержать непечатное смещение от начала строки
Методы.Колонки.Добавить("ДлинаОпределения", Новый ОписаниеТипов("Число"));
Методы.Колонки.Добавить("ПозицияТела", Новый ОписаниеТипов("Число")); // Начиная с 1
Методы.Колонки.Добавить("ДлинаТела", Новый ОписаниеТипов("Число"));
Методы.Колонки.Добавить("ТелоБезВозвратов");
Методы.Колонки.Добавить("Описание", Новый ОписаниеТипов("Строка"));
Методы.Колонки.Добавить("ОписаниеРезультата");
Методы.Колонки.Добавить("ТипЗначения");
Методы.Колонки.Добавить("ТаблицаТипов");
Методы.Колонки.Добавить("Сервер", Новый ОписаниеТипов("Булево"));
Методы.Колонки.Добавить("Клиент", Новый ОписаниеТипов("Булево"));
Методы.Колонки.Добавить("БезКонтекста", Новый ОписаниеТипов("Булево"));
Методы.Колонки.Добавить("ЛиЭкспорт", Новый ОписаниеТипов("Булево"));
Методы.Колонки.Добавить("ЛиАсинх", Новый ОписаниеТипов("Булево"));
Методы.Колонки.Добавить("Вычислено", Новый ОписаниеТипов("Булево")); // вычислено по коду
Методы.Колонки.Добавить("ИмяМодуля", Новый ОписаниеТипов("Строка"));
Методы.Колонки.Добавить("КлючевыеПараметры");
Методы.Колонки.Добавить("КэшПоиска");
Методы.Колонки.Добавить("ТипыВыражений");
Возврат Методы;
КонецФункции
//.
// Параметры:
// Переменные - ТаблицаЗначений -
// ИмяПеременной - ? -
// ЭкспортПеременной - ? -
// ОписаниеСтроки - Строка -
// ПозицияСОписанием - ? -
Процедура ДобавитьПеременную(Переменные, ИмяПеременной, ЭкспортПеременной, Знач ОписаниеСтроки, Знач ПозицияСОписанием) Экспорт
СтрокаПеременной = Переменные.Добавить();
СтрокаПеременной.Имя = ИмяПеременной;
СтрокаПеременной.НИмя = Нрег(СтрокаПеременной.Имя);
СтрокаПеременной.ЛиЭкспорт = ЭкспортПеременной;
СтрокаПеременной.ПозицияСОписанием = ПозицияСОписанием;
СтрокаПеременной.ПозицияОпределения = ПозицияСОписанием;
СтрокаПеременной.Описание = ОписаниеСтроки;
КонецПроцедуры
//.
// Параметры:
// RegExp2 - ОбработкаОбъект.ирОболочкаРегВыражение -
// СтрокаМетода - см. НоваяТаблицаМетодовМодуля()[0] -
// Шаблоны - Структура -
// шИмя - Примитивный -
// Возвращаемое значение:
// ТаблицаЗначений -
Функция ПараметрыМетодаМодуля(СтрокаМетода, выхБылиИзменения = Ложь) Экспорт
Если СтрокаМетода = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
Результат = СтрокаМетода.Параметры;
Если ТипЗнч(Результат) = Тип("Строка") Тогда
выхБылиИзменения = Истина;
СтрокаМетода.Описание = ОчиститьТекстМодуляОтПрефиксаКомментария(СтрокаМетода.Описание);
Если Не ЗначениеЗаполнено(СтрокаМетода.Параметры) Тогда
Результат = Неопределено;
Иначе
Шаблоны = ШаблоныДляАнализаВстроенногоЯзыка();
RegExp2.Global = Истина;
RegExp2.Pattern = Шаблоны.ПараметрыМетода;
РезультатПараметров = RegExp2.НайтиВхождения(СтрокаМетода.Параметры);
Если РезультатПараметров.Количество() > 0 Тогда
Результат = Новый ТаблицаЗначений;
Результат.Колонки.Добавить("Имя", Новый ОписаниеТипов("Строка"));
Результат.Колонки.Добавить("НИмя", Новый ОписаниеТипов("Строка"));
Результат.Колонки.Добавить("ТипЗначения", Новый ОписаниеТипов("Строка"));
Результат.Колонки.Добавить("Описание", Новый ОписаниеТипов("Строка"));
Результат.Колонки.Добавить("Значение");
Результат.Колонки.Добавить("Знач", Новый ОписаниеТипов("Булево"));
Результат.Колонки.Добавить("ТаблицаТипов");
Для Каждого ВхождениеПараметра Из РезультатПараметров Цикл
СтрокаПраметра = Результат.Добавить();
СтрокаПраметра.Имя = ВхождениеПараметра.SubMatches(1);
СтрокаПраметра.НИмя = НРег(СтрокаПраметра.Имя);
СтрокаПраметра.Знач = ?(ВхождениеПараметра.SubMatches(0) = Неопределено, Ложь, Истина);
СтрокаПраметра.Значение = ВхождениеПараметра.SubMatches(2);
КонецЦикла;
Если ЗначениеЗаполнено(СтрокаМетода.Описание) Тогда
ОписанияПараметровЗагружены = Ложь;
Если СтрЧислоСтрок(СтрокаМетода.Описание) = 1 Тогда
СсылкаНаОписание = СтрокаМетода.Описание;
Если УдалитьПрефиксИзТекстаТипов(СсылкаНаОписание) Тогда
// Ссылка на описание друго метода. Параметры сопоставляются по позиции.
//СтрокаМетода.Описание = СтрокаБазовогоМетода.Описание;
Методы = Неопределено;
Если Найти(СсылкаНаОписание, ".") = 0 Тогда
Методы = СтрокаМетода.Владелец();
Иначе
Если Прав(СсылкаНаОписание, 1) = "." Тогда
СсылкаНаОписание = СокрП(ирОбщий.СтрокаБезКонцаЛкс(СсылкаНаОписание));
КонецЕсли;
КраткоеИмяМодуля = ирОбщий.СтрокаБезПоследнегоФрагментаЛкс(СсылкаНаОписание);
Анализатор = ирКэш.ПолеТекстаМодуляБезСтруктурыТипаЛкс("");
ТаблицаТиповМодуля = Анализатор.ВычислитьТипЗначенияВыражения(КраткоеИмяМодуля,,,,,, Ложь);
Если ТаблицаТиповМодуля.Количество() > 0 Тогда
Модуль = ПодготовитьМодульМетаданных(ТаблицаТиповМодуля[0]);
Если Модуль <> Неопределено Тогда
Методы = Модуль.Методы;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Методы <> Неопределено Тогда
ИмяБазовогоМетода = ирОбщий.ПервыйФрагментЛкс(ирОбщий.ПоследнийФрагментЛкс(СсылкаНаОписание), "(");
СтрокаБазовогоМетода = Методы.Найти(НРег(ИмяБазовогоМетода), "НИмя");
Если СтрокаБазовогоМетода <> Неопределено Тогда
ПараметрыБазовогоМетода = ПараметрыМетодаМодуля(СтрокаБазовогоМетода);
Если ПараметрыБазовогоМетода <> Неопределено Тогда
Для Индекс = 0 По Мин(ПараметрыБазовогоМетода.Количество(), Результат.Количество()) - 1 Цикл
Результат[Индекс].Описание = ПараметрыБазовогоМетода[Индекс].Описание;
Результат[Индекс].ТипЗначения = ПараметрыБазовогоМетода[Индекс].ТипЗначения;
КонецЦикла;
КонецЕсли;
ОписанияПараметровЗагружены = Истина;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Не ОписанияПараметровЗагружены Тогда
ВхожденияОписаний = ПараметрыМетодаИзКомментария(СтрокаМетода.Описание, Шаблоны);
Для каждого ВхождениеОписания Из ВхожденияОписаний Цикл
СтрокаПараметра = Результат.Найти(НРег(ВхождениеОписания.Имя));
Если СтрокаПараметра <> Неопределено Тогда
Если ВхождениеОписания.ТипЗначения = Неопределено Тогда
ИмяТипа = СокрЛП(ВхождениеОписания.Описание);
Попытка
Пустышка = Тип(ИмяТипа);
ЭтоТип = Истина;
Исключение
ЭтоТип = Ложь;
КонецПопытки;
Если ЭтоТип Тогда
СтрокаПараметра.ТипЗначения = ИмяТипа;
Иначе
СтрокаПараметра.Описание = ВхождениеОписания.Описание;
КонецЕсли;
Иначе
СтрокаПараметра.Описание = ВхождениеОписания.Описание;
СтрокаПараметра.ТипЗначения = ВхождениеОписания.ТипЗначения;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
СтрокаМетода.Параметры = Результат;
КонецЕсли;
Возврат Результат;
КонецФункции
// Вызывается из других конфигураций!
// Параметры:
// ОписаниеМетода - Строка -
// Шаблоны - Структура - для ускорения
// Возвращаемое значение:
// ТаблицаЗначений -
Функция ПараметрыМетодаИзКомментария(Знач ОписаниеМетода, Шаблоны = Неопределено) Экспорт
Если Шаблоны = Неопределено Тогда
Шаблоны = ШаблоныДляАнализаВстроенногоЯзыка();
КонецЕсли;
шРазделительВнутриСтроки = "[-]"; // Здесь 2 разных символа
шОписаниеПараметра = "\n\s{0,8}(" + шИмя + ")\*?\s*(?:" + шРазделительВнутриСтроки + "\s*([^-\n]*)\s*)?" + шРазделительВнутриСтроки + "\s*?(" + Шаблоны.ОписаниеПараметра + ")[\.;]?";
ВхожденияОписаний = ирОбщий.НайтиРегВыражениеЛкс(ОписаниеМетода, шОписаниеПараметра, "Имя, ТипЗначения, Описание",,, Ложь, Ложь);
Возврат ВхожденияОписаний;
КонецФункции
Функция ОчиститьТекстМодуляОтПрефиксаКомментария(Знач ТекстМодуля)
Если Не ЗначениеЗаполнено(ТекстМодуля) Тогда
Возврат "";
КонецЕсли;
RegExp.Global = Истина;
RegExp.Pattern = шПустоеНачалоСтроки + "(?:/){2,}";
Результат = RegExp.Заменить(ТекстМодуля, Символы.ПС);
Если Лев(Результат, 1) = Символы.ПС Тогда
Результат = Сред(Результат, 2); // Отрезаем начальный перенос строки
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПодготовитьТипРезультатаМетода(МетодМодуля, ИмяИлиМодуль, ПолеТекстаМодуляКэш = Неопределено, Знач СФактическимиПараметрами = Ложь, Знач ДляСвойства = "") Экспорт
Если МетодМодуля.ТипЗначения = Неопределено Тогда
// тип метода - "процедура"
Возврат Неопределено;
КонецЕсли;
Если МетодМодуля.ТаблицаТипов = Неопределено Тогда
МетодМодуля.ТаблицаТипов = НоваяТаблицаТипов();
КонецЕсли;
ПодготовитьОписаниеРезультатаМетода(МетодМодуля);
ПолеТекстаМодуляКэш = ПолеТекстаМодуля(ИмяИлиМодуль, ПолеТекстаМодуляКэш);
ПолеТекстаМодуляКэш.ЗагрузитьМетодМодуля(МетодМодуля, Истина);
ТаблицаТипов = ПодготовитьТипЗначенияСловаМодуля(ПолеТекстаМодуляКэш.ИмяПеременнойВозвращаемогоЗначения(), ПолеТекстаМодуляКэш, МетодМодуля, ИмяИлиМодуль, МетодМодуля,
МетодМодуля.ОписаниеРезультата, СФактическимиПараметрами, Истина, ДляСвойства);
Возврат ТаблицаТипов;
КонецФункции
//.
// Параметры:
// СтрокаОпределения - СтрокаТаблицыЗначений -
Процедура ПодготовитьОписаниеРезультатаМетода(СтрокаОпределения) Экспорт
Если Истина
И ЗначениеЗаполнено(СтрокаОпределения.Описание)
И СтрокаОпределения.ОписаниеРезультата = Неопределено
И СтрокаОпределения.ТипЗначения <> Неопределено
Тогда
Шаблоны = ШаблоныДляАнализаВстроенногоЯзыка();
ШаблонОписанияРезультата = "(?:Возвращаемое\s+значение|Результат)[:-]\s*(?:([^-:\n]+)\s*(?=[-:\n]))?\s*(" + Шаблоны.ОписаниеПараметра + ")";
ВхожденияОписаний = ирОбщий.НайтиРегВыражениеЛкс(СтрокаОпределения.Описание, ШаблонОписанияРезультата, "ТипЗначения, Описание", Ложь,, Ложь, Ложь);
Если ВхожденияОписаний.Количество() > 0 Тогда
ВхождениеОписания = ВхожденияОписаний[ВхожденияОписаний.Количество() - 1];
ТекстТипаЗначения = СокрЛ(СтрЗаменить(ВхождениеОписания.ТипЗначения, "//", ""));
КопияТекстТипаЗначения = ТекстТипаЗначения;
Если УдалитьПрефиксИзТекстаТипов(КопияТекстТипаЗначения) Тогда
СтрокаОпределения.ТипЗначения = ТекстТипаЗначения;
ИначеЕсли ЗначениеЗаполнено(ТекстТипаЗначения) Тогда
СтрокаОпределения.ТипЗначения = СтрокаОпределения.ТипЗначения + ", " + ТекстТипаЗначения; // TODO удаление дублей
КонецЕсли;
ОписаниеРезультата = СокрЛП(ВхождениеОписания.Описание);
СтрокаОпределения.ОписаниеРезультата = ОчиститьТекстМодуляОтПрефиксаКомментария(ОписаниеРезультата);
Иначе
СтрокаОпределения.ОписаниеРезультата = "";
КонецЕсли;
КонецЕсли;
КонецПроцедуры
// Функция - Удалить префикс из текста типов
//
// Параметры:
// Текст - -
//
// Возвращаемое значение:
// Булево - является ли именем типа
//
Функция УдалитьПрефиксИзТекстаТипов(Текст) Экспорт
Текст = СокрЛП(Текст);
МаркерСм = "см.";
Если ирОбщий.СтрНачинаетсяСЛкс(Текст, МаркерСм) Тогда
Текст = СокрЛ(Сред(Текст, СтрДлина(МаркерСм) + 1));
Возврат Истина;
КонецЕсли;
Если Найти(Текст, "(") > 0 И Найти(Текст, " ") = 0 Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ПодготовитьТипЗначенияПеременнойМодуля(СтрокаОпределения, ИмяИлиМодуль, Знач ПолеТекстаМодуляКэш = Неопределено) Экспорт
Если Не СтрокаОпределения.Вычислено Тогда
Если СтрокаОпределения.ТаблицаТипов = Неопределено Тогда
СтрокаОпределения.ТаблицаТипов = НоваяТаблицаТипов();
КонецЕсли;
СтрокаОпределения.ТипЗначения = ирОбщий.ПервыйФрагментЛкс(СтрокаОпределения.Описание, "-");
СтрокаОпределения.Описание = Сред(СтрокаОпределения.Описание, СтрДлина(СтрокаОпределения.ТипЗначения));
ПолеТекстаМодуляКэш = ПолеТекстаМодуля(ИмяИлиМодуль, ПолеТекстаМодуляКэш);
ПодготовитьТипЗначенияСловаМодуля(СтрокаОпределения.Имя, ПолеТекстаМодуляКэш,, ИмяИлиМодуль, СтрокаОпределения, СтрокаОпределения.Описание);
КонецЕсли;
КонецФункции
Функция ПодготовитьТипЗначенияСловаМодуля(Знач ИмяПеременной, Знач ПолеТекстаМодуляКэш, Знач МетодМодуля, Знач ИмяИлиМодуль, Знач СтрокаОпределения, Знач ОписаниеТипа = "",
Знач СФактическимиПараметрами = Ложь, Знач ЭтоПрисвоенноеВыражение = Ложь, Знач ДляСвойства = "")
Если ПустаяСтрока(ИмяПеременной) Тогда
ВызватьИсключение "Э";
КонецЕсли;
Если СФактическимиПараметрами Тогда
//ЭлементыКлюча = Новый СписокЗначений;
//Для Каждого КлючИЗначение Из СтрокаОпределения.КлючевыеПараметры Цикл
// КлючЗначения = КлючИЗначение.Значение[0].Метаданные;
// КлючЗначения = XMLСтрока(КлючЗначения);
// ЭлементыКлюча.Добавить(КлючИЗначение.Ключ + "=" + КлючЗначения);
//КонецЦикла;
//ЭлементыКлюча.СортироватьПоЗначению();
//ДопКлючКэша = ирОбщий.СтрСоединитьЛкс(ЭлементыКлюча, ";");
ДопКлючКэша = Неопределено;
ТаблицаТипов = ПолеТекстаМодуляКэш.ВычислитьТипЗначенияВыражения(ИмяПеременной,,,,,,, МетодМодуля = Неопределено, НоваяТаблицаТипов(), Истина,,, ДопКлючКэша, ДляСвойства);
Иначе
Если Не СтрокаОпределения.Вычислено Тогда
Если Не ЗначениеЗаполнено(ДляСвойства) Тогда
СтрокаОпределения.Вычислено = Истина;
КонецЕсли;
// Обогащаем таблицу структур типов из текстового описания типа
ТаблицаТипов = ПолеТекстаМодуляКэш.ТаблицаТиповИзТекста(СтрокаОпределения.ТипЗначения, ОписаниеТипа);
ДобавитьВТаблицуТипов(СтрокаОпределения.ТаблицаТипов, ТаблицаТипов);
Если Истина
И Найти(НРег(СтрокаОпределения.ТипЗначения), "см.") > 0
И ЛиДетальностьТиповДостаточна(ТаблицаТипов)
Тогда
//
Иначе
ТаблицаТипов = ПолеТекстаМодуляКэш.ВычислитьТипЗначенияВыражения(ИмяПеременной,,,,,,, МетодМодуля = Неопределено, НоваяТаблицаТипов(), Истина,,,, ДляСвойства);
Если ТаблицаТипов.Количество() > 0 Тогда
// Мультиметка4529884 против циклической ссылки
Для Каждого СтрокаТипа Из ТаблицаТипов.НайтиСтроки(Новый Структура("СтрокаОписания", СтрокаОпределения)) Цикл
Если СтрокаТипа.Метаданные = Неопределено Тогда
ТаблицаТипов.Удалить(СтрокаТипа);
Иначе
СтрокаТипа.СтрокаОписания = Неопределено;
КонецЕсли;
КонецЦикла;
ДобавитьВТаблицуТипов(СтрокаОпределения.ТаблицаТипов, ТаблицаТипов);
Иначе
СтруктураТипа = НоваяСтруктураТипа();
СтруктураТипа.ИмяОбщегоТипа = "Произвольный";
ДобавитьВТаблицуТипов(СтрокаОпределения.ТаблицаТипов, СтруктураТипа);
КонецЕсли;
//СтрокаОпределения.ТаблицаТипов.ЗаполнитьЗначения(СтрокаОпределения, "СтрокаОписания"); // Мультиметка4529884 Была циклическая ссылка ! Теперь заполняем ссылку позже уже в копии таблицы
Если Не ЗначениеЗаполнено(ДляСвойства) Тогда
СтрокаОпределения.ТипЗначения = ПредставлениеМассиваСтруктурТипов(СтрокаОпределения.ТаблицаТипов);
КонецЕсли;
КонецЕсли;
КонецЕсли;
ТаблицаТипов = СтрокаОпределения.ТаблицаТипов;
КонецЕсли;
Возврат ТаблицаТипов;
КонецФункции
//.
// Параметры:
// ИмяИлиМодуль - Структура -
// ПолеТекстаМодуляКэш - ОбработкаОбъект.ирКлсПолеТекстаПрограммы, Неопределено -
// Возвращаемое значение:
// ОбработкаОбъект.ирКлсПолеТекстаПрограммы, Неопределено -
Функция ПолеТекстаМодуля(Знач ИмяИлиМодуль, ПолеТекстаМодуляКэш = Неопределено) Экспорт
Если ПолеТекстаМодуляКэш = Неопределено Тогда
Если ТипЗнч(ИмяИлиМодуль) = Тип("Строка") Тогда
ИмяМодуля = ИмяИлиМодуль;
Иначе
ИмяМодуля = ИмяИлиМодуль.Имя
КонецЕсли;
ПолеТекстаМодуляКэш = ирКэш.ПолеТекстаМодуляЛкс(ИмяМодуля);
ПолеТекстаМодуляКэш = ПолеТекстаМодуляКэш.КопияКомпоненты(); // Иначе при вызовах в рамках одного модуля будет переиспользоваться один объект и портиться контекст
Если ТипЗнч(ИмяИлиМодуль) = Тип("Структура") Тогда
НовыйМодуль = ИмяИлиМодуль;
Иначе
НовыйМодуль = МодульМетаданныхИзКэша(ИмяМодуля);
КонецЕсли;
Если НовыйМодуль <> Неопределено Тогда
ПолеТекстаМодуляКэш.мМодульМетаданных = НовыйМодуль;
ПолеТекстаМодуляКэш.мОригинальныйТекст = НовыйМодуль.Текст;
КонецЕсли;
КонецЕсли;
Возврат ПолеТекстаМодуляКэш;
КонецФункции
// Получает представление массива типов.
//
// Параметры:
// ТаблицаТиповКонтекста - ТаблицаЗначений.
//
// Возвращаемое значение:
// Строка - представление массива типов.
//
Функция ПредставлениеМассиваСтруктурТипов(ТаблицаТиповКонтекста, БезДублей = Ложь, МаксКоличествоТипов = 10) Экспорт
#Если Сервер И Не Сервер Тогда
ТаблицаТиповКонтекста = Новый ТаблицаЗначений;
#КонецЕсли
ПредставлениеТипаКонтекста = "";
Если ТаблицаТиповКонтекста <> Неопределено Тогда
Если ТаблицаТиповКонтекста.Количество() = 0 Тогда
ИначеЕсли ТаблицаТиповКонтекста.Количество() = 1 Тогда
ПредставлениеТипаКонтекста = ИмяТипаИзСтруктурыТипа(ТаблицаТиповКонтекста[0]);
Иначе
СписокОбрезан = Неопределено;
СписокИменТипов = ТаблицаТиповДляПользователя(ТаблицаТиповКонтекста, БезДублей, МаксКоличествоТипов, СписокОбрезан);
Если СписокОбрезан Тогда
СписокИменТипов.Добавить().Имя = "...";
КонецЕсли;
ПредставлениеТипаКонтекста = ирОбщий.СтрСоединитьЛкс(СписокИменТипов.ВыгрузитьКолонку("Имя"), ", ");
ПредставлениеТипаКонтекста = СтрЗаменить(ПредставлениеТипаКонтекста, "?, ", "");
КонецЕсли;
КонецЕсли;
Возврат ПредставлениеТипаКонтекста;
КонецФункции
Функция ТаблицаТиповДляПользователя(Знач ТаблицаТиповКонтекста, Знач БезДублей = Истина, Знач МаксКоличествоТипов = 0, выхСписокОбрезан = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
ТаблицаТиповКонтекста = Новый ТаблицаЗначений;
#КонецЕсли
Счетчик = 0;
выхСписокОбрезан = Ложь;
СписокИменТипов = Новый ТаблицаЗначений;
СписокИменТипов.Колонки.Добавить("Имя");
СписокИменТипов.Колонки.Добавить("СтруктураТипа");
СтруктураТипаНеопределено = Неопределено;
Для Каждого СтруктураТипаКонтекста Из ТаблицаТиповКонтекста Цикл
Счетчик = Счетчик + 1;
Если МаксКоличествоТипов > 0 И Счетчик > МаксКоличествоТипов Тогда
выхСписокОбрезан = Истина;
Прервать;
КонецЕсли;
ИмяТипа = ИмяТипаИзСтруктурыТипа(СтруктураТипаКонтекста);
Если Не ЗначениеЗаполнено(ИмяТипа) Тогда
Продолжить;
КонецЕсли;
Если ИмяТипа = "Неопределено" Тогда
СтруктураТипаНеопределено = СтруктураТипаКонтекста;
Продолжить;
КонецЕсли;
СтрокаИменТипов = СписокИменТипов.Добавить();
СтрокаИменТипов.Имя = ИмяТипа;
СтрокаИменТипов.СтруктураТипа = СтруктураТипаКонтекста;
КонецЦикла;
Если БезДублей Тогда
СписокИменТипов.Свернуть("Имя");
КонецЕсли;
СписокИменТипов.Сортировать("Имя");
Если СтруктураТипаНеопределено <> Неопределено Тогда
// Чтобы Неопределено всегда шло последним
СтрокаИменТипов = СписокИменТипов.Добавить();
СтрокаИменТипов.Имя = "Неопределено";
СтрокаИменТипов.СтруктураТипа = СтруктураТипаНеопределено;
КонецЕсли;
Возврат СписокИменТипов;
КонецФункции
// Функция - Отбор параметров метода
//
// Параметры:
// СтрокаОписания - СтрокаТаблицыЗначений - строка таблицы ТаблицаКонтекстов
//
// Возвращаемое значение:
// -
//
Функция ОтборПараметровМетода(Знач СтрокаОписания) Экспорт
ОтборПараметров = Новый Структура;
ОтборПараметров.Вставить("ТипКонтекста", СтрокаОписания.ТипКонтекста);
Если СтрокаОписания.ТипСлова = "Конструктор" Тогда
ОтборПараметров.Вставить("Слово", "<Новый>");
Иначе
ОтборПараметров.Вставить("Слово", СтрокаОписания.Слово);
КонецЕсли;
ОтборПараметров.Вставить("ЯзыкПрограммы", СтрокаОписания.ЯзыкПрограммы);
Возврат ОтборПараметров;
КонецФункции
// Функция - Таблица параметров метода для всех вариантов синтаксиса
//
// Параметры:
// СтрокаОписания - СтрокаТаблицыЗначений - строка глобальной таблицы ТаблицаКонтекстов
// ОтборПараметров - -
//
// Возвращаемое значение:
// -
//
Функция ПараметрыМетодаПлатформы(Знач СтрокаОписания) Экспорт
ОтборПараметров = ОтборПараметровМетода(СтрокаОписания);
КоличествоПараметров = 0;
Если Не ЗначениеЗаполнено(СтрокаОписания.Описание) Тогда // Мультиметка443985642
СинтаксПомощник = СинтаксПомощник();
#Если Сервер И Не Сервер Тогда
СинтаксПомощник = Обработки.ирСинтаксПомощник.Создать();
#КонецЕсли
МассивВариантов = Новый Массив;
Если СтрокаОписания.ТипСлова = "Конструктор" Тогда
Отбор = Новый Структура("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка"); // индекс
ЗаполнитьЗначенияСвойств(Отбор, СтрокаОписания);
Для Каждого СтрокаВарианта Из ТаблицаКонтекстов.НайтиСтроки(Отбор) Цикл
МассивВариантов.Добавить(СтрокаВарианта);
КонецЦикла;
Иначе
МассивВариантов.Добавить(СтрокаОписания);
КонецЕсли;
Для Каждого ВариантМетода Из МассивВариантов Цикл
ПутьКЭлементуАрхива = ВариантМетода.ПутьКОписанию;
НовыйАдрес = СинтаксПомощник.РаспаковатьФайлАрхиваСинтаксПомощника(ПутьКЭлементуАрхива);
КоличествоПараметров = 100;
Если НовыйАдрес <> Неопределено Тогда
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.Прочитать(ирОбщий.ПервыйФрагментЛкс(НовыйАдрес, "#"));
ТекстДокумента = ТекстовыйДокумент.ПолучитьТекст();
КоличествоПараметров = СинтаксПомощник.ЗагрузитьОписаниеМетода(ВариантМетода.ТипКонтекста, ВариантМетода.Слово, ТекстДокумента, ВариантМетода.ТипСлова, ВариантМетода.ЯзыкПрограммы,,, ВариантМетода);
КонецЕсли;
КонецЦикла;
КонецЕсли;
СтрокиПараметров = ТаблицаПараметров.Скопировать(ОтборПараметров);
Пока Истина
И КоличествоПараметров > 0
И КоличествоПараметров < СтрокиПараметров.Количество()
И СтрокиПараметров[0].ВариантСинтаксиса = СтрокиПараметров[КоличествоПараметров].ВариантСинтаксиса
Цикл
// Удаляем дубли параметров виртуальных таблиц регистра бухгалтерии https://www.hostedredmine.com/issues/952173
СтрокиПараметров.Удалить(КоличествоПараметров);
КонецЦикла;
Возврат СтрокиПараметров;
КонецФункции
Функция ПолучитьТипЗначенияЧленаИнтерфейса(ОписаниеРезультата, ИмяБиблиотеки = "", _БиблиотекаТипов = Неопределено) Экспорт
//Тест = ПолучитьИмяТипаCOMVariant(Член);
ИнфоТипаРезультата = ОписаниеРезультата.TypeInfo;
Если ИнфоТипаРезультата <> Неопределено Тогда
ТипЗначенияРезультата = ПолноеИмяТипаCOMОбъектаИзИнфоТипа(ИнфоТипаРезультата, ИмяБиблиотеки);
Иначе
НомерТипа = ОписаниеРезультата.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Объект, Знач ИмяОбщегоТипа = Неопределено, выхПолноеИмяОсновногоКласса = "") Экспорт
ПолучитьCOMНавигатор();
Если COMНавигатор = "Отказ" Тогда
Возврат Неопределено;
КонецЕсли;
Если ТипЗнч(выхCOMОбъект) = Тип("COMОбъект") Тогда
Попытка
COMНавигатор.ResolveAliases = Ложь; // Тут бывает кривой объект без свойств и методов и при выводе строки эта ошибка очень раздражает
//ИнфоКласса = COMНавигатор.ClassInfoFromObject(выхCOMОбъект); // Этот способ не поддерживается в большинстве классов
ИнфоИнтерфейса = COMНавигатор.InterfaceInfoFromObject(выхCOMОбъект); // // Тут возникает ошибка для некоторых объектов, например V83.Application, ADODB.Recorset.Fields(*).Precision
Исключение
ОписаниеОшибки = ОписаниеОшибки();
//ирОбщий.СообщитьЛкс(ОписаниеОшибки);
Возврат Неопределено;
КонецПопытки;
КонецЕсли;
Если ЗначениеЗаполнено(ИмяОбщегоТипа) Тогда
выхПолноеИмяОсновногоКласса = ирОбщий.ТекстМеждуМаркерамиЛкс(ИмяОбщегоТипа, "{", "}", Ложь);
ИмяОбщегоТипа = ирОбщий.ПервыйФрагментЛкс(ИмяОбщегоТипа, " ");
КонецЕсли;
Если Не ЗначениеЗаполнено(выхПолноеИмяОсновногоКласса) Тогда
Если ТипЗнч(вых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Объектов[КлючКэша];
// Закомментировал т.к. замедляет работу анализатора кода например для V83.Application
//Если Результат <> Неопределено Тогда
// ИнфоИнтерфейса = ПолучитьИнфоТипаCOMОбъекта(Результат,, ПолноеИмяОсновногоКлассаCOM);
// Если ИнфоИнтерфейса = Неопределено Тогда
// // Объект испорчен
// Результат = Неопределено;
// КонецЕсли;
//КонецЕсли;
Если Результат = Неопределено Тогда
Попытка
Результат = Новый COMОбъект(ПолноеИмяОсновногоКлассаCOM);
Исключение
Возврат Неопределено;
КонецПопытки;
мОбразцыCOMОбъектов[КлючКэша] = Результат;
КонецЕсли;
Возврат Результат;
КонецФункции
// Получает новый экземпляр ком-объекта парсера.
//
// Параметры:
// Нет.
//
// Возвращаемое значение:
// Com-объект, Неопределено.
//
Функция ПолучитьCOMНавигатор() Экспорт
Если COMНавигатор = "НеИнициализирован" Тогда
COMНавигатор = ПолучитьCOMОбъектИзМакета("TLBINF32", "TLI.TLIApplication");
КонецЕсли;
Возврат COMНавигатор;
КонецФункции
Функция ТипыЭлементовКоллекции(Знач СтруктураТипаКоллекции, Знач ЯзыкПрограммы = 0, выхНужнаПроверкаТипов = Истина) Экспорт
выхНужнаПроверкаТипов = Истина;
ТипыЭлементовКоллекции = Новый Массив();
ИмяОбщегоТипаКоллекции = ирОбщий.ПервыйФрагментЛкс(СтруктураТипаКоллекции.ИмяОбщегоТипа, "[");
Если Ложь
Или ИмяОбщегоТипаКоллекции = "Массив"
Или ИмяОбщегоТипаКоллекции = "ФиксированныйМассив"
Тогда
выхНужнаПроверкаТипов = Ложь;
ТекстТипыЭлементов = ирОбщий.ТекстМеждуМаркерамиЛкс(СтруктураТипаКоллекции.ИмяОбщегоТипа, "[", "]", Ложь);
Если ЗначениеЗаполнено(ТекстТипыЭлементов) Тогда
ТипыЭлементовКоллекции = ирОбщий.СтрРазделитьЛкс(ТекстТипыЭлементов, ", ");
КонецЕсли;
ИначеЕсли ЛиИмяТипаComОбъекта(СтруктураТипаКоллекции.ИмяОбщегоТипа) Тогда
ИмяОбщегоТипа = СтруктураТипаКоллекции.ИмяОбщегоТипа;
ТаблицаСтруктурТипаЭлемента = НоваяТаблицаТипов();
ИмяБиблиотеки = "";
МетаданныеОбъекта = СтруктураТипаКоллекции.Метаданные;
ИнфоТипа = ПолучитьИнфоТипаCOMОбъекта(МетаданныеОбъекта, ИмяОбщегоТипа, ИмяБиблиотеки);
Если ИнфоТипа = Неопределено Тогда
Возврат ТаблицаСтруктурТипаЭлемента;
КонецЕсли;
МассивИнфоТипа = ИнтерфейсыCOMОбъекта(ИнфоТипа, ИмяОбщегоТипа);
Для Каждого ИнфоТипа Из МассивИнфоТипа Цикл
Для Каждого Член Из ИнфоТипа.Members Цикл
Если Истина
//И Член.InvokeKind = 1 // метод // почему то иногда у него стоит 2 (например ADODB.Fields)
И ирОбщий.СтрокиРавныЛкс(Член.Name, "Item")
Тогда
ИнфоТипаЭлемента = Член.ReturnType.TypeInfo;
ИмяОбщегоТипаЭлемента = ПолучитьТипЗначенияЧленаИнтерфейса(Член.ReturnType, ИмяБиблиотеки, ИнфоТипа.Parent);
ТипыЭлементовКоллекции.Добавить(ИмяОбщегоТипаЭлемента);
Прервать;
КонецЕсли;
КонецЦикла;
КонецЦикла;
Иначе
СтруктураКлюча = Новый Структура("Слово, ЯзыкПрограммы", СтруктураТипаКоллекции.ИмяОбщегоТипа, ЯзыкПрограммы);
НайденныеСтроки = ТаблицаОбщихТипов.НайтиСтроки(СтруктураКлюча);
Если НайденныеСтроки.Количество() > 0 Тогда
Если НайденныеСтроки[0].ТипЭлементаКоллекции <> "" Тогда
ТипыЭлементовКоллекции = ирОбщий.СтрРазделитьЛкс(НайденныеСтроки[0].ТипЭлементаКоллекции, ",", Истина);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат ТипыЭлементовКоллекции;
КонецФункции
// Добавляет и заполяет строку в таблицу слов при условии отсутствия там строк по ключу (Слово, ТипСлова)
//
// Параметры:
// ТаблицаСлов - ТаблицаЗначений - НоваяТаблицаСвойствТипа();
// Слово - Строка;
// ТипСлова - Строка;
// ТаблицаТипов - ТаблицаЗначений.
//
Функция ДобавитьВТаблицуСлов(Знач ТаблицаСлов, Знач Слово, Знач ТипСлова, Знач ТаблицаТипов = Неопределено, Знач ТипЗначения = "??", Знач Определение = "") Экспорт
#Если Сервер И Не Сервер Тогда
ТаблицаСлов = Новый ТаблицаЗначений
#КонецЕсли
КлючПоиска = Новый Структура("Слово, ТипСлова", Слово, ТипСлова);
Если ТипСлова <> "Метод" Тогда // Для ускорения, т.к. платформа не позволяет перегружать методы
НайденныеСтроки = ТаблицаСлов.НайтиСтроки(КлючПоиска);
Если НайденныеСтроки.Количество() > 0 Тогда
Если ТаблицаТипов <> Неопределено Тогда
ДобавитьВТаблицуТипов(НайденныеСтроки[0].ТаблицаТипов, ТаблицаТипов);
КонецЕсли;
Возврат НайденныеСтроки[0];
КонецЕсли;
КонецЕсли;
СтрокаСлова = ТаблицаСлов.Добавить();
ЗаполнитьЗначенияСвойств(СтрокаСлова, КлючПоиска);
СтрокаСлова.ТипЗначения = ТипЗначения;
СтрокаСлова.Определение = Определение;
Если ТаблицаТипов <> Неопределено Тогда
СтрокаСлова.ТаблицаТипов = ТаблицаТипов;
Попытка
ТипЗначенияВложенный = ТаблицаТипов[0].СтрокаОписания.ТипЗначения;
Исключение
ТипЗначенияВложенный = Неопределено;
КонецПопытки;
Если Ложь
//Или ТипЗначенияВложенный = Неопределено // Отключил, чтобы вычисление представлений примитивных типов не откладывалось
//Или ТипЗначенияВложенный = "Произвольный"
Тогда
ТипЗначенияВложенный = "??";
КонецЕсли;
СтрокаСлова.МожноУточнитьТип = Ложь
Или (Истина
И ТипЗначенияВложенный <> "??" // Нужно чтобы вычисляемые по коду свойства и функции не вычислялись сразу при заполнении списка автодополнения
И Лев(ТипЗначения, 2) = "??")
Или Найти(ТипЗначения, "<") > 0;
КонецЕсли;
Возврат СтрокаСлова;
КонецФункции
// Получает таблицу слов указанной структуры типа.
//
// Параметры:
// СтруктураТипа - Структура - описание типа.
// БазовоеРасширениеКонфигурации - Строка - "" - основная конфигурация, "*" - все расширения
//
// Возвращаемое значение:
// ТаблицаЗначений - с колонками "Слово", "ТипСлова", "ТаблицаТипов", "Определение".
//
Функция ТаблицаСловИзСтруктурыТипа(СтруктураТипа, ЯзыкПрограммы = 0, Конфигурация = Неопределено, ВнешниеФункцииКомпоновкиДанных = Истина, Знач ВычислятьТипы = Истина,
Знач ВнутриГруппыОбщихМодулей = Ложь, ТипСлова = Неопределено, Знач ФлагиКомпиляции = Неопределено, Знач Слово = Неопределено, Знач МодульМетаданных = Неопределено,
Знач ВычислятьТипыМетодовМодулей = Ложь, Знач ТаблицаСвойств = Неопределено, Знач ЭтоЛокальныйКонтекст = Ложь, Знач мНаборыСлов = Неопределено, Знач БазовоеРасширениеКонфигурации = "") Экспорт
ИнициацияОписанияМетодовИСвойств();
Если ФлагиКомпиляции = Неопределено Тогда
ФлагиКомпиляции = НовыеФлагиКомпиляции();
КонецЕсли;
Если Не ВнутриГруппыОбщихМодулей Тогда
ТаблицаСвойств = СловаКонтекстаПредопределенные(СтруктураТипа, Слово, ТипСлова,, ЯзыкПрограммы, Конфигурация, ВычислятьТипы, ФлагиКомпиляции, ТаблицаСвойств, ЭтоЛокальныйКонтекст, мНаборыСлов,
БазовоеРасширениеКонфигурации);
КонецЕсли;
ТаблицаСвойств = СловаКонтекстаМетаданные(СтруктураТипа, Слово, ТипСлова, ВнутриГруппыОбщихМодулей, ЯзыкПрограммы,, ВнешниеФункцииКомпоновкиДанных, ВычислятьТипы, ФлагиКомпиляции,
МодульМетаданных, ТаблицаСвойств, ВычислятьТипыМетодовМодулей, ЭтоЛокальныйКонтекст,, БазовоеРасширениеКонфигурации);
Возврат ТаблицаСвойств;
КонецФункции
Функция ИмяКолонкиФлагаВнутриТаблицы() Экспорт
Возврат "ДержательМетаданных";
КонецФункции
// Получает новую структуру типа.
//
// Параметры:
// Нет.
//
// Возвращаемое значение:
// Структура - "ИмяОбщегоТипа", "Метаданные", "СтрокаОписания", "ТипЯзыка", "ВиртуальнаяТаблица".
//
Функция НоваяТаблицаДополнительныхТипов() Экспорт
ТаблицаСтруктурТипа = Новый ТаблицаЗначений;
ТаблицаСтруктурТипа.Колонки.Добавить("ИмяОбщегоТипа", Новый ОписаниеТипов("Строка"));
ТаблицаСтруктурТипа.Колонки.Добавить("Метаданные");
//ТаблицаСтруктурТипа.Колонки.Добавить("ВключатьСвойства", Новый ОписаниеТипов("Булево"));
ТаблицаСтруктурТипа.Колонки.Добавить("НеВключатьМетоды", Новый ОписаниеТипов("Булево"));
Возврат ТаблицаСтруктурТипа;
КонецФункции
// Получает допустимые типы (строку) из таблицы структур типа.
//
// Параметры:
// ТаблицаТипов - ТаблицаЗначений.
//
// Возвращаемое значение:
// Строка.
//
Функция ДопустимыеТипыИзТаблицыСтруктурТипа(ТаблицаТипов) Экспорт
СтрокаСериализованныхТипов = "";
Для Каждого СтруктураТипа Из ТаблицаТипов Цикл
СтрокаСериализованныхТипов = СтрокаСериализованныхТипов + ";" + СтруктураТипаВСтрокуВнутр(СтруктураТипа);
КонецЦикла;
СтрокаСериализованныхТипов = Сред(СтрокаСериализованныхТипов, 2);
Возврат СтрокаСериализованныхТипов;
КонецФункции
Функция ДопустимыеТипыИзОписанияТипов(ОписаниеТипов) Экспорт
ТаблицаТипов = ТаблицаТиповИзОписанияТипов(ОписаниеТипов);
ДопустимыеТипы = ДопустимыеТипыИзТаблицыСтруктурТипа(ТаблицаТипов);
Возврат ДопустимыеТипы;
КонецФункции
// Получает представление допустимых типов.
//
// Параметры:
// ДопустимыеТипы - Строка.
//
// Возвращаемое значение:
// СтрокаПредставления - Строка.
//
Функция ПредставлениеДопустимыхТипов(ДопустимыеТипы) Экспорт
ТаблицаТипов = ТаблицаТиповИзДопустимыхТипов(ДопустимыеТипы);
СтрокаПредставления = "";
Для Каждого СтруктураТипа Из ТаблицаТипов Цикл
СтрокаПредставления = СтрокаПредставления + ", " + ИмяТипаИзСтруктурыТипа(СтруктураТипа);
ТипМетаданных = ТипЗнч(СтруктураТипа.Метаданные);
Если ТипМетаданных = Тип("КвалификаторыДаты") Тогда
Квалификаторы = СтруктураТипа.Метаданные;
Если Квалификаторы.ЧастиДаты = ЧастиДаты.Время Тогда
ПредставлениеСоставаДаты = "В";
ИначеЕсли Квалификаторы.ЧастиДаты = ЧастиДаты.Дата Тогда
ПредставлениеСоставаДаты = "Д";
ИначеЕсли Квалификаторы.ЧастиДаты = ЧастиДаты.ДатаВремя Тогда
ПредставлениеСоставаДаты = "ДВ";
КонецЕсли;
СтрокаПредставления = СтрокаПредставления + "(" + ПредставлениеСоставаДаты + ")";
ИначеЕсли ТипМетаданных = Тип("КвалификаторыСтроки") Тогда
Квалификаторы = СтруктураТипа.Метаданные;
СтрокаПредставления = СтрокаПредставления + "("
+ Квалификаторы.Длина + ","
+ ?(Квалификаторы.ДопустимаяДлина = ДопустимаяДлина.Фиксированная, "Ф", "П") + ")";
ИначеЕсли ТипМетаданных = Тип("КвалификаторыЧисла") Тогда
Квалификаторы = СтруктураТипа.Метаданные;
СтрокаПредставления = СтрокаПредставления + "("
+ ?(Квалификаторы.ДопустимыйЗнак = ДопустимыйЗнак.Неотрицательный, "Н", "")
+ Квалификаторы.Разрядность + ","
+ Квалификаторы.РазрядностьДробнойЧасти + ")";
КонецЕсли;
КонецЦикла;
СтрокаПредставления = Сред(СтрокаПредставления, 3);
Возврат СтрокаПредставления;
КонецФункции // ПредставлениеДопустимыхТипов()
// Получает структуру типа из значения.
//
// Параметры:
// Значение - Произвольный;
// *ЯзыкПрограммы - Число, *0;
// *ШаблонСтруктурыТипа - Структура, СтрокаТаблицыЗначений, *Неопределено - содержит значения по умолчанию для новой структуры типа.
//
// Возвращаемое значение:
// см. НоваяСтруктураТипа() -
//
Функция СтруктураТипаИзЗначения(Значение, ЯзыкПрограммы = 0, ШаблонСтруктурыТипа = Неопределено) Экспорт
Если мМассивТиповСМетаданными.Найти(ТипЗнч(Значение)) <> Неопределено Тогда
Если ШаблонСтруктурыТипа = Неопределено Тогда
ШаблонСтруктурыТипа = Новый Структура;
КонецЕсли;
Если ТипЗнч(ШаблонСтруктурыТипа) = Тип("Структура") Тогда
Если Ложь
Или Не ШаблонСтруктурыТипа.Свойство("Метаданные")
Или ШаблонСтруктурыТипа.Метаданные = Неопределено
Тогда
ШаблонСтруктурыТипа.Вставить("Метаданные", Значение);
КонецЕсли;
КонецЕсли;
КонецЕсли;
СтруктураТипа = СтруктураТипаИзКонкретногоТипа(ТипЗнч(Значение), ЯзыкПрограммы, ШаблонСтруктурыТипа);
Если СтруктураТипа.ИмяОбщегоТипа = "COMОбъект" Тогда
СтруктураТипа.ИмяОбщегоТипа = ПолноеИмяТипаCOMОбъекта(Значение);
//ИначеЕсли СтруктураТипа.ИмяОбщегоТипа = "ПеречислимоеСвойствоОбъектовМетаданных" Тогда
// // Не работает. Оказывается одно ПеречислимоеСвойствоОбъектовМетаданных может иметь много экземпляров
// СтрокиСвойствПеречислений = ТаблицаКонтекстов.НайтиСтроки(Новый Структура("ТипКонтекста", "ПеречислимыеСвойстваОбъектовМетаданных"));
// Для Каждого СтрокиСвойстваПеречисления Из СтрокиСвойствПеречислений Цикл
// Если Метаданные.СвойстваОбъектов[СтрокиСвойстваПеречисления.Слово] = Значение Тогда
// СтруктураТипа.ИмяОбщегоТипа = "ПеречислениеМетаданных: " + СтрокиСвойстваПеречисления.Слово;
// Прервать;
// КонецЕсли;
// КонецЦикла;
КонецЕсли;
ИмяОбщегоТипа = СтруктураТипа.ИмяОбщегоТипа;
//Если Ложь
// Или (Истина
// И ИмяОбщегоТипа = "СтрокаТаблицыЗначений"
// И ТипЗнч(СтруктураТипа.Метаданные) <> Тип("ТаблицаЗначений"))
// Или (Истина
// И ИмяОбщегоТипа = "СтрокаДереваЗначений"
// И ТипЗнч(СтруктураТипа.Метаданные) <> Тип("ДеревоЗначений"))
// Или (Истина
// И ИмяОбщегоТипа = "ВыборкаИзРезультатаЗапроса"
// И ТипЗнч(СтруктураТипа.Метаданные) <> Тип("РезультатЗапроса"))
//Тогда
// Попытка
// СтруктураТипа.Метаданные = Значение.Владелец();
// Исключение
// // Строка была удалена из коллекции
// КонецПопытки;
//КонецЕсли;
Если Ложь
Или ИмяОбщегоТипа = "ВнешняяОбработкаОбъект.<Имя внешней обработки>"
Или ИмяОбщегоТипа = "ВнешнийОтчетОбъект.<Имя внешнего отчета>"
Тогда
МетаданныеЗначения = Значение.Метаданные();
ЛиНеУчитыватьПодтип = (ЯзыкПрограммы <> 0) И СтруктураТипа.ТипЯзыка <> "ЗначениеВЗапросе";
ИмяОбщегоТипа = ИмяОбщегоТипаИзТипаЗначенияСМетаданными(ТипЗнч(Значение), МетаданныеЗначения, ЛиНеУчитыватьПодтип);
СтруктураТипа.Метаданные = МетаданныеЗначения;
КлючПоиска = Новый Структура("Слово", ИмяОбщегоТипа);
НайденныеСтроки = ТаблицаОбщихТипов.НайтиСтроки(КлючПоиска);
Если НайденныеСтроки.Количество() > 0 Тогда
СтруктураТипа.ИмяОбщегоТипа = НайденныеСтроки[0].Слово;
Если СтруктураТипа.СтрокаОписания = Неопределено Тогда
СтруктураТипа.СтрокаОписания = НайденныеСтроки[0];
КонецЕсли;
КонецЕсли;
КонецЕсли;
МаркерРасширений = "Расширение ";
Если Ложь
Или ИмяОбщегоТипа = "Форма"
Или ИмяОбщегоТипа = "ПолеВвода"
//Или ИмяОбщегоТипа = "КолонкаТабличногоПоля" // в другом месте делаем
Или ИмяОбщегоТипа = "ТабличноеПоле"
Или ИмяОбщегоТипа = "УправляемаяФорма"
Или ИмяОбщегоТипа = "ФормаКлиентскогоПриложения"
Или ИмяОбщегоТипа = "ДекорацияФормы"
Или ИмяОбщегоТипа = "ПолеФормы"
Или ИмяОбщегоТипа = "ГруппаФормы"
Или ИмяОбщегоТипа = "ТаблицаФормы"
Тогда
ИмяОбщегоТипаРасширения = ИмяТипаРасширенияЭлементаФормы(ИмяОбщегоТипа, Значение);
Если ИмяОбщегоТипаРасширения <> Неопределено Тогда
СтруктураТипа.ИмяОбщегоТипа = ИмяОбщегоТипаРасширения;
КонецЕсли;
КонецЕсли;
Если ИмяОбщегоТипа = "Форма" Тогда
СтруктураТипа.ДержательМетаданных = Значение;
КонецЕсли;
Возврат СтруктураТипа;
КонецФункции
//. Мультиметка638663811
// Параметры:
// Значение - ? -
// ИмяОбщегоТипа - Строка, Строка -
// Возвращаемое значение:
// ? -
Функция ИмяТипаРасширенияЭлементаФормы(БазовоеИмяОбщегоТипа, ЭлементИлиФорма = Неопределено) Экспорт
ИмяОбщегоТипаРасширения = Неопределено;
РасширяющийТип = Неопределено;
Если Ложь
Или БазовоеИмяОбщегоТипа = "УправляемаяФорма"
Или БазовоеИмяОбщегоТипа = "ФормаКлиентскогоПриложения"
Тогда
БазовоеИмяОбщегоТипа = "ФормаКлиентскогоПриложения";
КлючОсновногоОбъекта = ирОбщий.КлючОсновногоОбъектаФормыЛкс(ЭлементИлиФорма);
Если КлючОсновногоОбъекта <> Неопределено Тогда
СтруктураРасширяющегоТипа = СтруктураТипаИзЗначения(КлючОсновногоОбъекта);
ИмяОбщегоТипаОбъекта = СтруктураРасширяющегоТипа.ИмяОбщегоТипа;
Если Найти(ИмяОбщегоТипаОбъекта, "Ссылка.") > 0 Тогда
Если Ложь
Или ирОбщий.СтрНачинаетсяСЛкс(ИмяОбщегоТипаОбъекта, "Справочник")
Или ирОбщий.СтрНачинаетсяСЛкс(ИмяОбщегоТипаОбъекта, "Документ")
Или ирОбщий.СтрНачинаетсяСЛкс(ИмяОбщегоТипаОбъекта, "ПланВидовХарактеристик")
Или ирОбщий.СтрНачинаетсяСЛкс(ИмяОбщегоТипаОбъекта, "Задача")
Или ирОбщий.СтрНачинаетсяСЛкс(ИмяОбщегоТипаОбъекта, "БизнесПроцесс")
Тогда
РасширяющийТип = СтрЗаменить(ИмяОбщегоТипаОбъекта, "Ссылка.", "Объект.");
Иначе
РасширяющийТип = "СсылочныйОбъект";
КонецЕсли;
Иначе
РасширяющийТип = СтрЗаменить(СтруктураРасширяющегоТипа.ИмяОбщегоТипа, "КлючЗаписи.", "Запись.");
КонецЕсли;
Иначе
Попытка
Пустышка = ЭлементИлиФорма.Параметры.РежимВыбора;
ЭтоФормаДинамическогоСписка = ТипЗнч(ЭлементИлиФорма.Список) = Тип("ДинамическийСписок");
Исключение
ЭтоФормаДинамическогоСписка = Ложь;
КонецПопытки;
Если ЭтоФормаДинамическогоСписка Тогда
РасширяющийТип = "ДинамическийСписок";
КонецЕсли;
КонецЕсли;
ИначеЕсли Ложь
Или БазовоеИмяОбщегоТипа = "ДекорацияФормы"
Или БазовоеИмяОбщегоТипа = "ПолеФормы"
Или БазовоеИмяОбщегоТипа = "ГруппаФормы"
Тогда
Если ТипЗнч(ЭлементИлиФорма.Вид) <> Тип("Строка") Тогда
ИмяВида = ПолучитьПолноеИмяПредопределенногоЗначения(ЭлементИлиФорма.Вид);
Иначе
ИмяВида = ЭлементИлиФорма.Вид;
КонецЕсли;
РасширяющийТип = ирОбщий.ПоследнийФрагментЛкс(ИмяВида);
ИначеЕсли БазовоеИмяОбщегоТипа = "ТаблицаФормы" Тогда
РасширяющийТип = ирОбщий.ОбщийТипДанныхТабличногоПоляЛкс(ЭлементИлиФорма);
Если РасширяющийТип = "Список" Тогда
РасширяющийТип = "ДинамическийСписок";
КонецЕсли;
ИначеЕсли БазовоеИмяОбщегоТипа = "Форма" Тогда
#Если Клиент Тогда
ОсновнойРеквизитФормы = ИмяОсновногоРеквизитаФормы(ЭлементИлиФорма);
Если ЗначениеЗаполнено(ОсновнойРеквизитФормы) Тогда
СтруктураРасширяющегоТипа = СтруктураТипаИзЗначения(ЭлементИлиФорма[ОсновнойРеквизитФормы]);
РасширяющийТип = СтруктураРасширяющегоТипа.ИмяОбщегоТипа;
КонецЕсли;
#КонецЕсли
Иначе
Попытка
ДанныеЭлементаФормы = ЭлементИлиФорма.Значение;
Исключение
// Случается из-за особенностей платформы. Иногда она убирает это свойство из элемента управления.
КонецПопытки;
СтруктураРасширяющегоТипа = СтруктураТипаИзЗначения(ДанныеЭлементаФормы);
РасширяющийТип = СтруктураРасширяющегоТипа.ИмяОбщегоТипа;
Если ирОбщий.СтрКончаетсяНаЛкс(РасширяющийТип, ".<Имя табличной части>") Тогда
РасширяющийТип = "ТабличнаяЧасть";
КонецЕсли;
Попытка
Пустышка = Тип("Перечисление" + СтруктураРасширяющегоТипа.ИмяОбщегоТипа);
РасширяющийТип = "Системное перечисление";
Исключение
КонецПопытки;
КонецЕсли;
Если РасширяющийТип <> Неопределено Тогда
Если РасширяющийТип = "ВнешняяОбработкаОбъект.<Имя внешней обработки>" Тогда
РасширяющийТип = "ОбработкаОбъект.<Имя обработки>";
ИначеЕсли РасширяющийТип = "ВнешнийОтчетОбъект.<Имя внешнего отчета>" Тогда
РасширяющийТип = "ОтчетОбъект.<Имя отчета>";
КонецЕсли;
СтруктураКлюча = Новый Структура("РасширяющийТип, ОсновнойТип", РасширяющийТип, БазовоеИмяОбщегоТипа);
МассивНайденных = ТаблицаРасширенийТипов.НайтиСтроки(СтруктураКлюча);
Если МассивНайденных.Количество() > 0 Тогда
ИмяОбщегоТипаРасширения = МассивНайденных[0].Расширение;
КонецЕсли;
КонецЕсли;
Возврат ИмяОбщегоТипаРасширения;
КонецФункции
// <Описание функции>
//
// Параметры:
// <Параметр1> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>.
//
// Возвращаемое значение:
// - <Тип.Вид> - <описание значения>
// <продолжение описания значения>;
// <Значение2> - <Тип.Вид> - <описание значения>
// <продолжение описания значения>.
//
Функция УникальныйИдентификаторИзСтроки(Текст) Экспорт
Цифра = "[a-fA-F0-9]";
RegExp.Pattern = "(" + ирОбщий.СтрокаПовторомЛкс(Цифра, 32) + ")|("
+ ирОбщий.СтрокаПовторомЛкс(Цифра, 8) + "-"
+ ирОбщий.СтрокаПовторомЛкс(Цифра, 4) + "-"
+ ирОбщий.СтрокаПовторомЛкс(Цифра, 4) + "-"
+ ирОбщий.СтрокаПовторомЛкс(Цифра, 4) + "-"
+ ирОбщий.СтрокаПовторомЛкс(Цифра, 12) + ")";
Вхождения = RegExp.НайтиВхождения(Текст);
Если Вхождения.Количество() > 0 Тогда
Вхождение = Вхождения[0];
Если Не ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(Вхождение.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;
// *ШаблонСтруктурыТипа - Структура, *Неопределено - содержит значения по умолчанию для новой структуры типа.
//
// Возвращаемое значение:
// см. НоваяСтруктураТипа() -
//
Функция СтруктураТипаИзКонкретногоТипа(КонкрентыйТип, ЯзыкПрограммы = 0, ШаблонСтруктурыТипа = Неопределено) Экспорт
СтруктураТипа = НоваяСтруктураТипа();
СтруктураТипа.Метаданные = мМетаданные;
Если ШаблонСтруктурыТипа <> Неопределено Тогда
ЗаполнитьЗначенияСвойств(СтруктураТипа, ШаблонСтруктурыТипа);
КонецЕсли;
Если ЯзыкПрограммы = 1 И КонкрентыйТип = Тип("ТаблицаЗначений") Тогда
СтруктураТипа.ИмяОбщегоТипа = "ВременнаяТаблица";
ИначеЕсли КонкрентыйТип = Тип("ОбъектМетаданных") Тогда
Если Истина
И ШаблонСтруктурыТипа <> Неопределено // было закомментировано
И ТипЗнч(ШаблонСтруктурыТипа.Метаданные) = Тип("ОбъектМетаданных")
Тогда
МассивФрагментов = ирОбщий.СтрРазделитьЛкс(ШаблонСтруктурыТипа.Метаданные.ПолноеИмя());
// Исключения из общего правила
Если МассивФрагментов[0] = "ОбщаяФорма" Тогда
МассивФрагментов[0] = "Форма";
ИначеЕсли МассивФрагментов[0] = "ОбщийМакет" Тогда
МассивФрагментов[0] = "Макет";
КонецЕсли;
СтруктураТипа.ИмяОбщегоТипа = МаркерОбъектаМетаданных + ": " + МассивФрагментов[МассивФрагментов.ВГраница() - 1];
Иначе
СтруктураТипа.ИмяОбщегоТипа = "ОбъектМетаданных";
КонецЕсли;
ИначеЕсли Истина
И КонкрентыйТип = Тип("КоллекцияОбъектовМетаданных")
И ШаблонСтруктурыТипа <> Неопределено
И СтруктураТипа.ИмяОбщегоТипа <> "Неизвестный контекст"
Тогда
//
Иначе
Если Истина
И ТипЗнч(КонкрентыйТип) = Тип("Тип")
И КонкрентыйТип <> Тип("КонстантыНабор") // Антибаг платформы http://partners.v8.1c.ru/forum/thread.jsp?id=876094#876094
Тогда
МетаданныеТипа = мМетаданные.НайтиПоТипу(КонкрентыйТип);
КонецЕсли;
Если МетаданныеТипа = Неопределено Тогда
ПредставлениеТипа = Строка(КонкрентыйТип);
Если Найти(ПредставлениеТипа, ":") = 0 Тогда
ИдентификаторТипа = ирОбщий.ИдентификаторТипаЛкс(КонкрентыйТип);
Иначе
// Внешние метаданные
ИдентификаторТипа = "";
ПредставлениеТипа = ирОбщий.ПервыйФрагментЛкс(ПредставлениеТипа, ":");
Если НРег(ПредставлениеТипа) = Нрег("External data processor") Тогда
ПредставлениеТипа = "Внешняя обработка";
ИначеЕсли НРег(ПредставлениеТипа) = Нрег("External data processor tabular section") Тогда
ПредставлениеТипа = "Внешняя обработка табличная часть";
КонецЕсли;
КонецЕсли;
Если ИдентификаторТипа <> "" Тогда
КлючПоиска = Новый Структура("ИД", ИдентификаторТипа);
Иначе
//КлючПоиска = Новый Структура("Представление, ТипТипа", ирОбщий.ПервыйФрагментЛкс(ПредставлениеТипа, ":"), "Основной");
КлючПоиска = Новый Структура("Представление", ирОбщий.ПервыйФрагментЛкс(ПредставлениеТипа, ":"));
КонецЕсли;
Иначе
ЛиНеУчитыватьПодтип = (ЯзыкПрограммы <> 0) И СтруктураТипа.ТипЯзыка <> "ЗначениеВЗапросе";
ИмяОбщегоТипа = ИмяОбщегоТипаИзТипаЗначенияСМетаданными(КонкрентыйТип, МетаданныеТипа, ЛиНеУчитыватьПодтип);
СтруктураТипа.Метаданные = МетаданныеТипа;
КлючПоиска = Новый Структура("Слово, ТипТипа", ИмяОбщегоТипа, "Основной");
КонецЕсли;
НайденныеСтроки = ТаблицаОбщихТипов.НайтиСтроки(КлючПоиска);
Если НайденныеСтроки.Количество() > 0 Тогда
СтруктураТипа.ИмяОбщегоТипа = НайденныеСтроки[0].Слово;
Если СтруктураТипа.СтрокаОписания = Неопределено Тогда
СтруктураТипа.СтрокаОписания = НайденныеСтроки[0];
КонецЕсли;
ИначеЕсли Найти(КонкрентыйТип, " ") = 0 Тогда
СтруктураТипа.ИмяОбщегоТипа = Строка(КонкрентыйТип);
Иначе
//ирОбщий.СообщитьЛкс("Невозможно восстановить имя типа """ + КонкрентыйТип + """", СтатусСообщения.Важное);
КонецЕсли;
КонецЕсли;
Возврат СтруктураТипа;
КонецФункции
// Получает таблицу структур типов из описания типов.
//
// Параметры:
// ОписаниеТипов - ОписаниеТипов -
// *ТаблицаТипов - ТаблицаЗначений, *Неопределено - существующая таблица.
//
// Возвращаемое значение:
// ТаблицаЗначений - структур типов.
//
Функция ТаблицаТиповИзОписанияТипов(ОписаниеТипов, ТаблицаТипов = Неопределено) Экспорт
Если ТаблицаТипов = Неопределено Тогда
ТаблицаТипов = НоваяТаблицаТипов();
КонецЕсли;
Типы = ОписаниеТипов.Типы();
СлишкомМногоТипов = Типы.Количество() > МаксЧислоТиповДляАнализа();
Для Каждого Тип Из Типы Цикл
СтруктураТипа = СтруктураТипаИзКонкретногоТипа(Тип);
СтруктураТипа.Квалификаторы = ОписаниеТипов;
ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа);
Если СлишкомМногоТипов Тогда
Прервать;
КонецЕсли;
КонецЦикла;
Возврат ТаблицаТипов;
КонецФункции
Функция МаксЧислоТиповДляАнализа() Экспорт
Возврат 100;
КонецФункции
Функция ТаблицаТиповИзЗначения(Значение, ТаблицаТипов = Неопределено, ЯзыкПрограммы = 0) Экспорт
Если ТаблицаТипов = Неопределено Тогда
ТаблицаТипов = НоваяТаблицаТипов();
КонецЕсли;
СтруктураТипа = СтруктураТипаИзЗначения(Значение, ЯзыкПрограммы);
ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа);
Возврат ТаблицаТипов;
КонецФункции
// Получает объект по ссылке, кэшируя результат в соответствии.
//
// Параметры:
// Ссылка - Ссылка;
// ПринудительноОбновить - Булево, *Ложь.
//
// Возвращаемое значение:
// Объект.
//
Функция КэшОбъект(Ссылка, ПринудительноОбновить = Ложь) Экспорт
ТипСсылки = ТипЗнч(Ссылка);
Кэш = КэшОбъектов[ТипСсылки];
Если Кэш = Неопределено Тогда
Кэш = Новый Соответствие;
КэшОбъектов[ТипСсылки] = Кэш;
КонецЕсли;
Если Не ПринудительноОбновить Тогда
Результат = Кэш[Ссылка];
КонецЕсли;
Если Результат = Неопределено Тогда
Результат = Ссылка.ПолучитьОбъект();
Кэш[Ссылка] = Результат;
КонецЕсли;
Возврат Результат;
КонецФункции
// Получает строку конкретного типа.
//
// Параметры:
// СтруктураТипа - Структура - описание типа.
//
// Возвращаемое значение:
// Строка - конкрентого типа.
//
Функция ИмяТипаИзСтруктурыТипа(Знач СтруктураТипа, Знач Подробное = Истина) Экспорт
КонкретныйТип = СтруктураТипа.ИмяОбщегоТипа;
МаркерРасширенияФормы = "Расширение формы";
Если Лев(КонкретныйТип, СтрДлина(МаркерРасширенияФормы)) = МаркерРасширенияФормы Тогда
КонкретныйТип = "Форма";
КонецЕсли;
Если Подробное Тогда
Если КонкретныйТип = "Форма" И ирОбщий.ЛиФормаИлиИмитаторЛкс(СтруктураТипа.Метаданные) Тогда
КонкретныйТип = КонкретныйТип + "[" + ирОбщий.ПолноеИмяФормыЛкс(СтруктураТипа.Метаданные) + "]";
ИначеЕсли КонкретныйТип = "ОбщийМодуль" И ТипЗнч(СтруктураТипа.Метаданные) = Тип("ОбъектМетаданных") Тогда
КонкретныйТип = КонкретныйТип + "[" + СтруктураТипа.Метаданные.Имя + "]";
КонецЕсли;
КонецЕсли;
//Если Лев(КонкретныйТип, СтрДлина(МаркерКоллекцииМетаданных)) = МаркерКоллекцииМетаданных Тогда
// КонкретныйТип = МаркерКоллекцииМетаданных;
//КонецЕсли;
ОбъектМД = СтруктураТипа.Метаданные;
Если Истина
И ТипЗнч(ОбъектМД) = Тип("КоллекцияОбъектовМетаданных")
И ОбъектМД.Количество() > 0
Тогда
ОбъектМД = ОбъектМД[0].Родитель();
КонецЕсли;
ТипМетаданных = ТипЗнч(ОбъектМД);
Если ТипМетаданных = Тип("ОбъектМетаданных") Тогда
ПолноеИмя = ОбъектМД.ПолноеИмя();
МассивФрагментов = ирОбщий.СтрРазделитьЛкс(ПолноеИмя);
Если МассивФрагментов[0] = "ТабличнаяЧасть" Тогда
// Баг платформы. У внешних метаданных полное имя не включает сам внешний метаобъект
МассивФрагментов.Вставить(0, "Имя");
МассивФрагментов.Вставить(0, "");
КонецЕсли;
Для Счетчик = 0 По МассивФрагментов.Количество() / 2 - 1 Цикл
ИмяЭлементаКоллекции = ирОбщий.ТекстМеждуМаркерамиЛкс(КонкретныйТип, "<", ">", Ложь, Истина);
КонкретныйТип = СтрЗаменить(КонкретныйТип, ИмяЭлементаКоллекции, МассивФрагментов[Счетчик * 2 + 1]);
КонецЦикла;
ИначеЕсли Истина
И ЭтоИнтеграция
И (Ложь
Или ТипМетаданных = Тип("СправочникСсылка.ОбъектыМетаданных2iS")
Или ТипМетаданных = Тип("СправочникСсылка.СвойстваМетаданных2iS"))
Тогда
ОбъектМД = КэшОбъект(ОбъектМД);
ПолноеИмя = ОбъектМД.ПолноеИмя;
МассивФрагментов = ирОбщий.СтрРазделитьЛкс(ПолноеИмя);
Если МассивФрагментов[0] = "ТабличнаяЧасть" Тогда
// Баг платформы. У внешних метаданных полное имя не включает сам внешний метаобъект
МассивФрагментов.Вставить(0, "Имя");
МассивФрагментов.Вставить(0, "");
КонецЕсли;
Для Счетчик = 0 По МассивФрагментов.Количество() / 2 - 1 Цикл
ИмяЭлементаКоллекции = ирОбщий.ТекстМеждуМаркерамиЛкс(КонкретныйТип, "<", ">", Ложь, Истина);
КонкретныйТип = СтрЗаменить(КонкретныйТип, ИмяЭлементаКоллекции, МассивФрагментов[Счетчик * 2 + 1]);
КонецЦикла;
//ИначеЕсли ТипЗнч(СтруктураТипа.Метаданные) = Тип("Соответствие") Тогда
// Для Каждого ЭлементВида Из СтруктураТипа.Метаданные Цикл
// КонкретныйТип = СтрЗаменить(КонкретныйТип, ЭлементВида.Ключ, ЭлементВида.Значение);
// КонецЦикла;
ИначеЕсли Ложь
Или КонкретныйТип = "Неизвестный контекст"
Или КонкретныйТип = "Произвольный"
Тогда
КонкретныйТип = "?";
КонецЕсли;
Попытка
Квалификаторы = СтруктураТипа.Квалификаторы;
Исключение
Квалификаторы = Неопределено;
КонецПопытки;
Если Истина
И Квалификаторы <> Неопределено
И ирОбщий.ЛиИмяТипаСКвалификаторамиЛкс(КонкретныйТип)
Тогда
ирОбщий.ДобавитьКвалификаторыВПредставлениеТипаЛкс(КонкретныйТип, Тип(КонкретныйТип), СтруктураТипа.Квалификаторы);
КонецЕсли;
Возврат КонкретныйТип;
КонецФункции
// Получает новую структуру типа.
//
// Параметры:
// ИмяОбщегоТипа - Строка -
//
// Возвращаемое значение:
// Структура - :
// *ИмяОбщегоТипа - Строка
// *Метаданные
// *СтрокаОписания - СтрокаТаблицыЗначений
// *ТипЯзыка - Строка
// *ВиртуальнаяТаблица - Структура
//
Функция НоваяСтруктураТипа(ИмяОбщегоТипа = "Неизвестный контекст") Экспорт
// Мультиметка73327878378078
Возврат Новый Структура("ИмяОбщегоТипа, Метаданные, СтрокаОписания, ТипЯзыка, Конструктор, ВиртуальнаяТаблица, ДополнительныеТипы, ДержательМетаданных, Квалификаторы",
ИмяОбщегоТипа, Неопределено, Неопределено, "", Ложь, Новый Структура("Выражение, НомерСтроки", "", 0));
КонецФункции
// Десериализатор структуры типа из неполной сериализации.
//
// Параметры:
// СтрокаСтруктурыТипа - Строка.
//
// Возвращаемое значение:
// СтруктураТипа - Структура.
//
Функция СтруктураТипаИзСтрокиВнутр(СтрокаСтруктурыТипа) Экспорт
СтруктураТипа = НоваяСтруктураТипа();
Если ПустаяСтрока(СтрокаСтруктурыТипа) Тогда
Возврат СтруктураТипа;
КонецЕсли;
Успех = Ложь;
Попытка
ОписательТипа = ЗначениеИзСтрокиВнутр(СтрокаСтруктурыТипа);
Успех = Истина;
Исключение
ОписательТипа = НоваяСтруктураТипа();
ОписательТипа.ИмяОбщегоТипа = "<Ошибка преобразования>";
КонецПопытки;
Если Успех Тогда
СтруктураТипа.ИмяОбщегоТипа = ОписательТипа.ИмяОбщегоТипа;
Если ТипЗнч(ОписательТипа.Метаданные) = Тип("Строка") Тогда
СтруктураТипа.Метаданные = ирКэш.ОбъектМДПоПолномуИмениЛкс(ОписательТипа.Метаданные);
ИначеЕсли ТипЗнч(ОписательТипа.Метаданные) = Тип("ХранилищеЗначения") Тогда
Поток = Новый ЧтениеXML;
Поток.УстановитьСтроку(ОписательТипа.Метаданные.Получить());
// Тут тормоз
СтруктураТипа.Метаданные = СериализаторXDTO.ПрочитатьXML(Поток);
Иначе
СтруктураТипа.Метаданные = ОписательТипа.Метаданные;
КонецЕсли;
КонецЕсли;
Возврат СтруктураТипа;
КонецФункции // СтруктураТипаВСтрокуВнутр()
Функция НоваяТаблицаТипов() Экспорт
Возврат мТаблицаТипов.СкопироватьКолонки();
КонецФункции
// Добавляет структуру типа в таблицу структур типов с поглощением.
//
// Параметры:
// ТаблицаПриемник - ТаблицаЗначений - ;
// ОписаниеТипов - Структура, ТаблицаЗначений, ОписаниеТипов, Массив[Структура] - считаем что внутри этой коллекции типы не пересекаются.
//
Функция ДобавитьВТаблицуТипов(ТаблицаПриемник = Неопределено, Знач ОписаниеТипов, Знач ПередаватьДополнительныеТипы = Ложь) Экспорт
Если ТаблицаПриемник = Неопределено Тогда
ТаблицаПриемник = НоваяТаблицаТипов();
КонецЕсли;
ТипОписания = ТипЗнч(ОписаниеТипов);
Если ТипОписания = Тип("ОписаниеТипов") Тогда
//! ОписаниеТипов=0 // ОписаниеТипов
ТаблицаИсточник = Новый Массив;
Для Каждого Тип Из ОписаниеТипов.Типы() Цикл
СтруктураТипа = СтруктураТипаИзКонкретногоТипа(Тип); // Циклическая ссылка СтрокаОписания
СтруктураТипа.Вставить("Детальность");
ТаблицаИсточник.Добавить(СтруктураТипа);
КонецЦикла;
ИначеЕсли Истина
И ТипОписания <> Тип("ТаблицаЗначений")
И ТипОписания <> Тип("Массив")
Тогда
ТаблицаИсточник = Новый Массив;
ТаблицаИсточник.Добавить(ОписаниеТипов);
Иначе
ТаблицаИсточник = ОписаниеТипов; // см. НоваяТаблицаТипов()
КонецЕсли;
КоличествоТипов = ТаблицаИсточник.Количество();
Если КоличествоТипов > МаксЧислоТиповДляАнализа() Тогда
// Для подстраховки. Нужно в вызывающем контексте это контролировать
Возврат ТаблицаПриемник;
КонецЕсли;
НужноВытеснять = КоличествоТипов > 0;
Детальность = Неопределено;
Для Каждого СтрокаИсточника Из ТаблицаИсточник Цикл
Если Истина
//И НужноВытеснять
И СтрокаИсточника.ИмяОбщегоТипа = "Неизвестный контекст"
И СтрокаИсточника.СтрокаОписания = Неопределено
Тогда
Продолжить;
КонецЕсли;
Если Истина
И ТипЗнч(СтрокаИсточника) = Тип("Структура")
И Не СтрокаИсточника.Свойство("Детальность", Детальность)
Тогда
СтрокаИсточника.Вставить("Детальность", Неопределено);
Иначе
Детальность = СтрокаИсточника.Детальность;
КонецЕсли;
Если Детальность = Неопределено Тогда
ОбновитьДетальностьСтруктурыТипа(СтрокаИсточника);
КонецЕсли;
Если НужноВытеснять Тогда
Если Найти(СтрокаИсточника.ИмяОбщегоТипа, "Массив") = 1 Тогда
ДобавлятьТип = Истина;
Для Каждого СтрокаПриемника Из ТаблицаПриемник Цикл
Если Найти(СтрокаПриемника.ИмяОбщегоТипа, "Массив") = 1 Тогда
ЕстьВложенныеИсточника = Найти(СтрокаИсточника.ИмяОбщегоТипа, "[") > 0;
ЕстьВложенныеПриемника = Найти(СтрокаПриемника.ИмяОбщегоТипа, "[") > 0;
Если Истина
И ЕстьВложенныеИсточника
И ЕстьВложенныеПриемника
Тогда
ТипыЭлементовИсточника = ТипыЭлементовКоллекции(СтрокаИсточника,, Ложь);
СписокЗначений = Новый СписокЗначений;
СписокЗначений.ЗагрузитьЗначения(ТипыЭлементовИсточника);
ТипыЭлементовПриемника = ТипыЭлементовКоллекции(СтрокаПриемника,, Ложь);
Для Каждого ИмяТипа Из ТипыЭлементовПриемника Цикл
Если СписокЗначений.НайтиПоЗначению(ИмяТипа) = Неопределено Тогда
СписокЗначений.Добавить(ИмяТипа);
КонецЕсли;
КонецЦикла;
СписокЗначений.СортироватьПоЗначению();
СтрокаПриемника.ИмяОбщегоТипа = "Массив[" + ирОбщий.СтрСоединитьЛкс(СписокЗначений.ВыгрузитьЗначения()) + "]";
ИначеЕсли ЕстьВложенныеИсточника Тогда
СтрокаПриемника.ИмяОбщегоТипа = СтрокаИсточника.ИмяОбщегоТипа;
КонецЕсли;
ДобавлятьТип = Ложь;
Прервать;
КонецЕсли;
КонецЦикла;
Если Не ДобавлятьТип Тогда
Прервать;
КонецЕсли;
Иначе
ИменаПоиска = "ИмяОбщегоТипа";
КлючПоиска = Новый Структура(ИменаПоиска);
ЗаполнитьЗначенияСвойств(КлючПоиска, СтрокаИсточника, ИменаПоиска);
Найденные = ТаблицаПриемник.НайтиСтроки(КлючПоиска);
Если СтрокаИсточника.Детальность > 0 Тогда
Для Каждого СтрокаПриемника Из ТаблицаПриемник.НайтиСтроки(Новый Структура("Детальность", 0)) Цикл
ТаблицаПриемник.Удалить(СтрокаПриемника);
КонецЦикла;
Если ирОбщий.СтрНачинаетсяСЛкс(СтрокаИсточника.ИмяОбщегоТипа, "Расширение формы", Истина) Тогда // Учитывам регистр для ускорения
НайденныеФормы = ТаблицаПриемник.НайтиСтроки(Новый Структура("ИмяОбщегоТипа", "Форма"));
ирОбщий.ДополнитьМассивЛкс(Найденные, НайденныеФормы);
КонецЕсли;
КонецЕсли;
Если Найденные.Количество() > 0 Тогда
СтрокаПриемника = Найденные[0];
// Считаем что "Найденные" всегда содержит не более одной строки
Если Ложь
Или СтрокаПриемника.Метаданные = СтрокаИсточника.Метаданные
Или ТипЗнч(СтрокаПриемника.Метаданные) = Тип("ОбъектМетаданныхКонфигурация") И ТипЗнч(СтрокаИсточника.Метаданные) = Тип("ОбъектМетаданныхКонфигурация") // Почему то часто равенство значений не выполняется
Или СтрокаПриемника.Детальность > СтрокаИсточника.Детальность
Тогда
Продолжить;
КонецЕсли;
Если СтрокаПриемника.Детальность < СтрокаИсточника.Детальность Тогда
ТаблицаПриемник.Удалить(СтрокаПриемника);
Иначе
// Далее детальности равны
Если Ложь
Или ТаблицаПриемник.Количество() > 10
Или СтрокаПриемника.ИмяОбщегоТипа = "Строка" // Для ускорения вычисления типа результата ИмяФайлаМодуляБезРасширения()
Или СтрокаПриемника.ИмяОбщегоТипа = "Число"
Или СтрокаПриемника.ИмяОбщегоТипа = "Булево"
Или СтрокаПриемника.ИмяОбщегоТипа = "Тип"
Тогда
Продолжить;
КонецЕсли;
Если Ложь
Или (Истина
И ТипЗнч(СтрокаИсточника.Метаданные) = Тип("ТаблицаЗначений")
И ТипЗнч(СтрокаПриемника.Метаданные) = Тип("ТаблицаЗначений"))
Или (Истина
И ТипЗнч(СтрокаИсточника.Метаданные) = Тип("ДеревоЗначений")
И ТипЗнч(СтрокаПриемника.Метаданные) = Тип("ДеревоЗначений"))
Тогда
ирОбщий.СкопироватьКолонкиКоллекцииЛкс(СтрокаИсточника.Метаданные, СтрокаПриемника.Метаданные);
Продолжить;
КонецЕсли;
Если Истина
И ТипЗнч(СтрокаИсточника.Метаданные) = Тип("ТаблицаЗначений")
И ТипЗнч(СтрокаПриемника.Метаданные) = Тип("Структура")
Тогда
Для Каждого Колонка Из СтрокаИсточника.Метаданные.Колонки Цикл
Если Не СтрокаПриемника.Метаданные.Свойство(Колонка.Имя) Тогда
СтрокаПриемника.Метаданные.Вставить(Колонка.Имя, ТаблицаТиповИзОписанияТипов(Колонка.ТипЗначения));
КонецЕсли;
КонецЦикла;
Продолжить;
КонецЕсли;
Если Ложь
Или (Истина
И ТипЗнч(СтрокаИсточника.Метаданные) = Тип("Структура")
И ТипЗнч(СтрокаПриемника.Метаданные) = Тип("Структура"))
Или (Истина
И ТипЗнч(СтрокаИсточника.Метаданные) = Тип("Массив")
И ТипЗнч(СтрокаПриемника.Метаданные) = Тип("Массив"))
Тогда
ирОбщий.СкопироватьКоллекциюЛкс(СтрокаИсточника.Метаданные, СтрокаПриемника.Метаданные);
Продолжить;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
ИсключаемыеСвойства = Неопределено;
Если Не ПередаватьДополнительныеТипы Тогда
ИсключаемыеСвойства = "ДополнительныеТипы";
КонецЕсли;
ЗаполнитьЗначенияСвойств(ТаблицаПриемник.Добавить(), СтрокаИсточника, , ИсключаемыеСвойства);
КонецЦикла;
Возврат ТаблицаПриемник;
КонецФункции
Функция ОбновитьДетальностьСтруктурыТипа(СтруктураТипа) Экспорт
ТипМетаданных = ТипЗнч(СтруктураТипа.Метаданные);
ИмяОбщегоТипа = СтруктураТипа.ИмяОбщегоТипа;
Если Ложь
//Или ИмяОбщегоТипа = "??" // такого не должно быть
Или ИмяОбщегоТипа = "Неизвестный контекст"
Тогда
Результат = 0;
ИначеЕсли Ложь
Или ИмяОбщегоТипа = "" // Процедура
Или ИмяОбщегоТипа = "Произвольный"
Или ИмяОбщегоТипа = "Неопределено"
Тогда
Результат = 1;
Если ИмяОбщегоТипа = "Неопределено" Тогда
СтруктураТипа.Метаданные = Неопределено; // Чтобы раньше склеивались типы в ДобавитьВТаблицуТипов
КонецЕсли;
ИначеЕсли Ложь
Или ИмяОбщегоТипа = "Строка"
Или ИмяОбщегоТипа = "Число"
Или ИмяОбщегоТипа = "Булево"
Или ИмяОбщегоТипа = "Дата"
Или ИмяОбщегоТипа = "Null"
Или ИмяОбщегоТипа = "Тип"
//Или ИмяОбщегоТипа = "Примитивный"
Тогда
Если ТипМетаданных = Тип(ИмяОбщегоТипа) Тогда
Результат = 3;
Иначе
Результат = 2;
Если Истина
И ИмяОбщегоТипа = "Строка"
И ТипМетаданных = Тип("ТаблицаЗначений")
Тогда
Результат = 5;
КонецЕсли;
КонецЕсли;
ИначеЕсли Ложь
Или ТипМетаданных = Тип("Неопределено")
Или ТипМетаданных = Тип("ОбъектМетаданныхКонфигурация")
Или ТипМетаданных = Тип("КоллекцияОбъектовМетаданных")
Или ТипМетаданных = Тип("ОбщийМодуль") // Пока платформа не позволяет узнать его имя
Тогда
Результат = 3;
ИначеЕсли ТипМетаданных = Тип("ОбъектМетаданных") Тогда
Результат = 4;
ИначеЕсли Ложь
#Если Клиент Тогда
Или ТипМетаданных = Тип("Форма")
Или ТипМетаданных = Тип("УправляемаяФорма")
#КонецЕсли
Тогда
Результат = 6;
ИначеЕсли ТипМетаданных = Тип("ПостроительЗапроса") Тогда
Результат = 7;
Иначе
Результат = 5;
КонецЕсли;
СтруктураТипа.Детальность = Результат;
Возврат Результат;
КонецФункции
//.
// Параметры:
// ТаблицаТипов - ТаблицаЗначений -
// МинДетальность - Число - минимальное достаточное значение детальности
// Возвращаемое значение:
// Булево -
Функция ЛиДетальностьТиповДостаточна(ТаблицаТипов, Знач МинДетальность = 3, Знач ВыбратьЛучшийТип = Ложь, выхЛучшийТип = Неопределено, Знач УчитыватьПримитивные = Истина) Экспорт
Если ТаблицаТипов.Количество() > 0 Тогда
Счетчик = 1;
МинДетальность = МинДетальность - 1;
Для Индекс = 1 - ТаблицаТипов.Количество() По 0 Цикл // Обратный обход
СтрокаТипа = ТаблицаТипов[-Индекс];
Если Ложь
Или СтрокаТипа.Детальность > МинДетальность
Или (Истина
И УчитыватьПримитивные
И (Ложь
Или СтрокаТипа.ИмяОбщегоТипа = "Строка"
Или СтрокаТипа.ИмяОбщегоТипа = "Число"
Или СтрокаТипа.ИмяОбщегоТипа = "Булево" // почему закомментировал?
))
Тогда
выхЛучшийТип = СтрокаТипа;
МинДетальность = СтрокаТипа.Детальность;
Если Не ВыбратьЛучшийТип Тогда
Прервать;
КонецЕсли;
КонецЕсли;
Если Счетчик = 3 Тогда
// Проверяем не больше 3-х, т.к. бесполезных типов обычно очень мало указывают в описании, например Неопределено, Null
Прервать;
КонецЕсли;
Счетчик = Счетчик + 1;
КонецЦикла;
КонецЕсли;
Возврат выхЛучшийТип <> Неопределено;
КонецФункции
// Получает массив структур типов из строки допустимых типов.
//
// Параметры:
// ДопустимыеТипы - Строка;
// *ШаблонСтруктурыТипа - Структура, *Неопределено - содержит значения по умолчанию для новой структуры типа.
//
// Возвращаемое значение:
// Структура - структура типа.
//
Функция ТаблицаТиповИзДопустимыхТипов(ДопустимыеТипы, ШаблонСтруктурыТипа = Неопределено) Экспорт
ТаблицаТипов = НоваяТаблицаТипов();
Если ПустаяСтрока(ДопустимыеТипы) Тогда
Возврат ТаблицаТипов;
КонецЕсли;
МассивСериализованныхТипов = ирОбщий.СтрРазделитьЛкс(ДопустимыеТипы, ";");
Для Каждого СериализованныйТип Из МассивСериализованныхТипов Цикл
СтруктураТипа = СтруктураТипаИзСтрокиВнутр(СериализованныйТип);
Если ШаблонСтруктурыТипа <> Неопределено Тогда
ЗаполнитьЗначенияСвойств(СтруктураТипа, ШаблонСтруктурыТипа);
КонецЕсли;
ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа);
КонецЦикла;
Возврат ТаблицаТипов;
КонецФункции
// Получает описание типов из допустимых типов.
//
// Параметры:
// ДопустимыеТипы - Строка;
// ТипЗначенияЭУ - ОписаниеТипов - все возможные типы из элемента управления.
//
// Возвращаемое значение:
// ОписаниеТипов.
//
Функция ОписаниеТиповИзДопустимыхТипов(ДопустимыеТипы, ТипЗначенияЭУ = Неопределено) Экспорт
ТаблицаТипов = ТаблицаТиповИзДопустимыхТипов(ДопустимыеТипы);
ОписаниеТипов = ОписаниеТиповИзТаблицыСтруктурТипов(ТаблицаТипов, ТипЗначенияЭУ);
Возврат ОписаниеТипов;
КонецФункции
// Получает описание типов из таблицы структур типов.
//
// Параметры:
// ДопустимыеТипы - Строка;
// ТипЗначенияЭУ - ОписаниеТипов - все возможные типы из элемента управления.
//
// Возвращаемое значение:
// ОписаниеТипов.
//
Функция ОписаниеТиповИзТаблицыСтруктурТипов(ТаблицаТипов, ТипЗначенияЭУ = Неопределено) Экспорт
Если ТаблицаТипов = Неопределено Тогда
Возврат Новый ОписаниеТипов;
КонецЕсли;
МассивТипов = Новый Массив;
Для Каждого СтруктураТипа Из ТаблицаТипов Цикл
СтрокаКонкретногоТипа = ИмяТипаИзСтруктурыТипа(СтруктураТипа);
Попытка
ТекущийТип = Тип(СтрокаКонкретногоТипа);
Исключение
Продолжить;
КонецПопытки;
ТипМетаданных = ТипЗнч(СтруктураТипа.Метаданные);
Если ТипМетаданных = Тип("КвалификаторыСтроки") Тогда
КвалификаторыСтроки = СтруктураТипа.Метаданные;
ИначеЕсли ТипМетаданных = Тип("КвалификаторыЧисла") Тогда
КвалификаторыЧисла = СтруктураТипа.Метаданные;
ИначеЕсли ТипМетаданных = Тип("КвалификаторыДаты") Тогда
КвалификаторыДаты = СтруктураТипа.Метаданные;
КонецЕсли;
Если ТипЗначенияЭУ <> Неопределено Тогда
Если Не ТипЗначенияЭУ.СодержитТип(ТекущийТип) Тогда
Продолжить;
КонецЕсли;
КонецЕсли;
МассивТипов.Добавить(ТекущийТип);
КонецЦикла;
ОписаниеТипов = Новый ОписаниеТипов(МассивТипов, КвалификаторыЧисла, КвалификаторыСтроки, КвалификаторыСтроки);
Возврат ОписаниеТипов;
КонецФункции
// Получает строку типа метаобъектов по единственному или множественному числу.
//
// Параметры:
// *Единственное - Строка, *Неопределено - единственное число типа;
// *Множественное - Строка, *Неопределено - множественное число типа.
// *Категория - Число, *Неопределено.
//
// Возвращаемое значение:
// СтрокаТаблицыЗначений - найденная строка типа;
// Неопределено - корневой тип не найден.
//
Функция ОписаниеТипаМетаОбъектов(Знач Единственное = Неопределено, Знач Множественное = Неопределено, Категория = Неопределено) Экспорт
СтруктураПоиска = Новый Структура;
Если Категория <> Неопределено Тогда
СтруктураПоиска.Вставить("Категория", Категория);
КонецЕсли;
Если Единственное <> Неопределено Тогда
СтруктураПоиска.Вставить("НЕдинственное", НРег(Единственное));
КонецЕсли;
Если Множественное <> Неопределено Тогда
СтруктураПоиска.Вставить("НМножественное", НРег(Множественное));
КонецЕсли;
НайденныеСтроки = ТаблицаТиповМетаОбъектов.НайтиСтроки(СтруктураПоиска);
Если НайденныеСтроки.Количество() = 0 Тогда
Результат = Неопределено;
Иначе
Результат = НайденныеСтроки[0];
КонецЕсли;
Возврат Результат;
КонецФункции
Процедура ПроверитьЗагрузитьКэшМДСеанса()
ПереданныйКэш = ирКэш.ПараметрыСеансаЛкс().ПереданныйКэш;
КэшМДСеанса = Неопределено;
Если ЗначениеЗаполнено(ПереданныйКэш) Тогда
КэшМДСеанса = ПолучитьИзВременногоХранилища(ПереданныйКэш);
КонецЕсли;
Если КэшМДСеанса = Неопределено Тогда
СостояниеРасчета = ирКэш.СостояниеПодготовкиКэшМДСеансаЛкс();
Если СостояниеРасчета <> Неопределено Тогда
ФоновоеЗадание = ФоновыеЗадания.НайтиПоУникальномуИдентификатору(СостояниеРасчета.ИдентификаторЗадания);
КонецЕсли;
Если ФоновоеЗадание <> Неопределено Тогда
Если ФоновоеЗадание.Состояние = СостояниеФоновогоЗадания.Активно Тогда
ирОбщий.ОжидатьЗавершенияФоновойОперацииЛкс(ФоновоеЗадание);
КонецЕсли;
Если ФоновоеЗадание.Состояние = СостояниеФоновогоЗадания.Завершено Тогда
КэшМДСеанса = ирОбщий.ПрочитатьРезультатФоновогоЗаданияЛкс(СостояниеРасчета.АдресРезультата, СостояниеРасчета.ФормаРезультата);
Если КэшМДСеанса = Null Тогда
КэшМДСеанса = Неопределено;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если КэшМДСеанса <> Неопределено Тогда
#Если Сервер И Не Сервер Тогда
КэшМДСеанса = Новый Структура;
#КонецЕсли
мТаблицаВсехТаблицБД = КэшМДСеанса.ТаблицаВсехТаблицБД;
Если КэшМДСеанса.Свойство("ДеревоОбъектовМД") Тогда
мДеревоОбъектовМД = КэшМДСеанса.ДеревоОбъектовМД;
КонецЕсли;
Возврат;
КонецЕсли;
КонецПроцедуры
Функция ДеревоОбъектовМД() Экспорт
ПроверитьЗагрузитьКэшМДСеанса();
Если мДеревоОбъектовМД <> Неопределено Тогда
#Если Сервер И Не Сервер Тогда
мДеревоОбъектовМД = Новый ДеревоЗначений;
#КонецЕсли
#Если Клиент Тогда
Если мДеревоОбъектовМД.Колонки.Найти("КоличествоСтрок") = Неопределено Тогда
мДеревоОбъектовМД.Колонки.Добавить("КоличествоСтрок", Новый ОписаниеТипов("Строка, Число"));
КонецЕсли;
#КонецЕсли
Возврат мДеревоОбъектовМД;
КонецЕсли;
ДеревоОбъектовМД = Новый ДеревоЗначений;
ДеревоОбъектовМД.Колонки.Добавить("Имя", Новый ОписаниеТипов("Строка"));
ДеревоОбъектовМД.Колонки.Добавить("Представление", Новый ОписаниеТипов("Строка"));
ДеревоОбъектовМД.Колонки.Добавить("ПолноеИмяОбъекта", Новый ОписаниеТипов("Строка"));
ДеревоОбъектовМД.Колонки.Добавить("ИндексКартинки", Новый ОписаниеТипов("Число"));
ДеревоОбъектовМД.Колонки.Добавить("ЕстьДоступ", Новый ОписаниеТипов("Булево"));
ДеревоОбъектовМД.Колонки.Добавить("ПравоПросмотр", Новый ОписаниеТипов("Булево"));
ДеревоОбъектовМД.Колонки.Добавить("ТипТаблицы", Новый ОписаниеТипов("Строка"));
АнализаторКода = ирОбщий.НовыйАнализаторКодаЛкс();
#Если Сервер И Не Сервер Тогда
АнализаторКода = Обработки.ирКлсПолеТекстаПрограммы.Создать();
#КонецЕсли
мТаблицаВсехТаблицБД = АнализаторКода.ДоступныеТаблицы.ВыгрузитьКолонки();
мТаблицаВсехТаблицБД.Колонки.Удалить("ПородившийЗапрос"); // Для экономии памяти
мТаблицаВсехТаблицБД.Колонки.Добавить("ТипСсылки");
//ТаблицаВсехТаблицБД.Колонки.Добавить("СтруктураКлюча");
Если Метаданные.Константы.Количество() > 0 Тогда
ирОбщий.ДобавитьДоступнуюТаблицуБДЛкс(мТаблицаВсехТаблицБД, ирОбщий.ПеревестиСтроку("Константы"),, "Константы"); // Мультиметка0012741388 опираемся на то, что эта таблица БД идет первой в списке
КонецЕсли;
КоллекцияКорневыхТипов = Новый Массив;
СтрокиМетаОбъектов = ТаблицаТиповМетаОбъектов.НайтиСтроки(Новый Структура("Категория", 0));
Для Каждого СтрокаТаблицыМетаОбъектов Из СтрокиМетаОбъектов Цикл
КоллекцияКорневыхТипов.Добавить(СтрокаТаблицыМетаОбъектов.Единственное);
КонецЦикла;
Если ирКэш.ДоступныВнешниеИсточникДанныхЛкс() Тогда
Для Каждого МетаВнешнийИсточникДанных Из Метаданные.ВнешниеИсточникиДанных Цикл
КоллекцияКорневыхТипов.Добавить(МетаВнешнийИсточникДанных.ПолноеИмя());
КонецЦикла;
КонецЕсли;
КоллекцияКорневыхТипов.Добавить("Отчет");
КоллекцияКорневыхТипов.Добавить("Обработка");
КоллекцияКорневыхТипов.Добавить("Роль");
КоллекцияКорневыхТипов.Добавить("Подсистема");
КоллекцияКорневыхТипов.Добавить("РегламентноеЗадание");
КоллекцияКорневыхТипов.Добавить("HTTPСервис");
КоллекцияКорневыхТипов.Добавить("WebСервис");
КоллекцияКорневыхТипов.Добавить("ОбщаяКоманда");
ИмяДвиженияССубконто = ирОбщий.ПеревестиСтроку("ДвиженияССубконто");
ИмяГраницы = ирОбщий.ПеревестиСтроку("Границы");
ИмяЗадачиПоИсполнителю = ирОбщий.ПеревестиСтроку("ЗадачиПоИсполнителю");
ИмяКонстанта = ирОбщий.ПеревестиСтроку("Константа");
ИмяОбороты = ирОбщий.ПеревестиСтроку("Обороты");
ИмяОборотыДтКт = ирОбщий.ПеревестиСтроку("ОборотыДтКт");
ИмяОстатки = ирОбщий.ПеревестиСтроку("Остатки");
ИмяОстаткиИОбороты = ирОбщий.ПеревестиСтроку("ОстаткиИОбороты");
ИмяСрезПервых = ирОбщий.ПеревестиСтроку("СрезПервых");
ИмяСрезПоследних = ирОбщий.ПеревестиСтроку("СрезПоследних");
ИмяСубконто = ирОбщий.ПеревестиСтроку("Субконто");
ИмяТабличнаяЧасть = ирОбщий.ПеревестиСтроку("ТабличнаяЧасть");
ИмяТочки = ирОбщий.ПеревестиСтроку("Точки");
ИндексКартинкиТЧ = мОписаниеТипаМДТабличнаяЧасть.ИндексКартинкиЕдинственное;
ИндикаторТиповМД = ирОбщий.ПолучитьИндикаторПроцессаЛкс(КоллекцияКорневыхТипов.Количество(), "Анализ конфигурации");
Для Каждого КорневойТип Из КоллекцияКорневыхТипов Цикл
ирОбщий.ОбработатьИндикаторЛкс(ИндикаторТиповМД);
ОписаниеКорневогоТипа = ОписаниеТипаМетаОбъектов(КорневойТип);
Если ОписаниеКорневогоТипа = Неопределено Тогда
Если Найти(КорневойТип, ".") = 0 Тогда
// В текущей версии платформы нет поддержки такого типа метаданных
Продолжить;
КонецЕсли;
// Внешний источник данных
ОписаниеКорневогоТипа = мОписаниеТипаМДВнешнийИсточникДанных;
ОбъектМДКорневогоТипа = ирКэш.ОбъектМДПоПолномуИмениЛкс(КорневойТип);
МножественноеКорневогоТипа = КорневойТип;
ЕдинственноеКорневогоТипа = ОбъектМДКорневогоТипа.Имя;
ПредставлениеКатегории = ОбъектМДКорневогоТипа.Представление();
ЕстьДоступ = ПравоДоступа("Использование", ОбъектМДКорневогоТипа);
СхемаТаблиц = ОбъектМДКорневогоТипа.Имя;
ТипТаблицы = "Внешняя";
КоллекцияМетаОбъектов = ОбъектМДКорневогоТипа.Таблицы;
ЕстьТаблицаБД = Истина;
Иначе
МножественноеКорневогоТипа = ОписаниеКорневогоТипа.Множественное;
ЕдинственноеКорневогоТипа = ОписаниеКорневогоТипа.Единственное;
ПредставлениеКатегории = ирОбщий.ПредставлениеИзИдентификатораЛкс(МножественноеКорневогоТипа);
ЕстьДоступ = Истина;
СхемаТаблиц = "";
//Если КорневойТип = "КритерийОтбора" Тогда
// ТипТаблицы = "ВиртуальнаяТаблица";
//Иначе
ТипТаблицы = КорневойТип;
//КонецЕсли;
Если КорневойТип = "Перерасчет" Тогда
КоллекцияМетаОбъектов = Новый Массив;
Для Каждого МетаРегистрРасчета Из Метаданные.РегистрыРасчета Цикл
Для Каждого Перерасчет Из МетаРегистрРасчета.Перерасчеты Цикл
КоллекцияМетаОбъектов.Добавить(Перерасчет);
КонецЦикла;
КонецЦикла;
Иначе
КоллекцияМетаОбъектов = Метаданные[МножественноеКорневогоТипа];
КонецЕсли;
ЕстьТаблицаБД = Истина
И (Ложь
Или КорневойТип <> "Константа"
Или ирКэш.ДоступныТаблицыКонстантЛкс())
И (Ложь
Или КорневойТип = "Константа"
Или КорневойТип = "КритерийОтбора"
Или КорневойТип = "ЖурналДокументов"
Или ирОбщий.ЛиКорневойТипПеречисленияЛкс(КорневойТип)
Или ирОбщий.ЛиКорневойТипСсылочногоОбъектаБДЛкс(КорневойТип)
Или ирОбщий.ЛиКорневойТипРегистраБДЛкс(КорневойТип)
Или ирОбщий.ЛиКорневойТипПоследовательностиЛкс(КорневойТип));
КонецЕсли;
Если КоллекцияМетаОбъектов.Количество() = 0 Тогда
Продолжить;
КонецЕсли;
СтрокаТипаМетаданных = ДеревоОбъектовМД.Строки.Добавить();
СтрокаТипаМетаданных.Представление = ПредставлениеКатегории;
СтрокаТипаМетаданных.Имя = ЕдинственноеКорневогоТипа;
СтрокаТипаМетаданных.ПолноеИмяОбъекта = МножественноеКорневогоТипа;
СтрокаТипаМетаданных.ИндексКартинки = ОписаниеКорневогоТипа.ИндексКартинкиМножественное;
СтрокаТипаМетаданных.ЕстьДоступ = ЕстьДоступ;
ЛиКорневойТипОбъектаСТабличнымиЧастями = ирОбщий.ЛиКорневойТипСсылочногоОбъектаБДЛкс(КорневойТип);
ИндикаторОбъектовМД = ирОбщий.ПолучитьИндикаторПроцессаЛкс(КоллекцияМетаОбъектов.Количество(), "Анализ " + КорневойТип);
Для Каждого ОбъектМД Из КоллекцияМетаОбъектов Цикл
#Если Сервер И Не Сервер Тогда
ОбъектМД = Метаданные.Справочники.ирАлгоритмы;
#КонецЕсли
ирОбщий.ОбработатьИндикаторЛкс(ИндикаторОбъектовМД);
ПолноеИмяМД = ОбъектМД.ПолноеИмя();
ПредставлениеМД = ОбъектМД.Представление();
ПолноеИмяТаблицыБД = ирКэш.ИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД,, Ложь);
ФрагментыИмениТаблицы = ирОбщий.СтрРазделитьЛкс(ПолноеИмяТаблицыБД);
ИмяОбъектаМД = ОбъектМД.Имя;
Если КорневойТип = "Перерасчет" Тогда
МетаРегистрРасчета = ОбъектМД.Родитель();
ИмяОбъектаМД = МетаРегистрРасчета.Имя + "." + ИмяОбъектаМД;
ПредставлениеМД = МетаРегистрРасчета.Представление() + "." + ПредставлениеМД;
КонецЕсли;
СтрокаОбъектаМД = ДобавитьСтрокуДереваМД(СтрокаТипаМетаданных, ПолноеИмяТаблицыБД, ИмяОбъектаМД, ПредставлениеМД, ТипТаблицы, ОписаниеКорневогоТипа.ИндексКартинкиЕдинственное,
ЕстьТаблицаБД, мТаблицаВсехТаблицБД, ПолноеИмяМД, ОбъектМД.Имя, ПредставлениеМД, СхемаТаблиц, ОбъектМД,, ФрагментыИмениТаблицы);
Попытка
СтрокаОбъектаМД.ПравоПросмотр = ПравоДоступа("Просмотр", ОбъектМД);
Исключение
СтрокаОбъектаМД.ПравоПросмотр = Истина;
КонецПопытки;
Если ЛиКорневойТипОбъектаСТабличнымиЧастями Тогда
СтруктураТЧ = ирОбщий.ТабличныеЧастиОбъектаЛкс(ОбъектМД, ФрагментыИмениТаблицы);
Для Каждого КлючИЗначение Из СтруктураТЧ Цикл
СтрокаТЧВДереве = ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + КлючИЗначение.Ключ, КлючИЗначение.Ключ, КлючИЗначение.Значение, "ТабличнаяЧасть", ИндексКартинкиТЧ,
ЕстьТаблицаБД, мТаблицаВсехТаблицБД, ПолноеИмяМД + "." + ИмяТабличнаяЧасть + "." + КлючИЗначение.Ключ,, ПредставлениеМД + "." + КлючИЗначение.Значение,, ОбъектМД);
МетаТЧ = ОбъектМД.ТабличныеЧасти.Найти(КлючИЗначение.Ключ);
Если МетаТЧ <> Неопределено Тогда
СтрокаТЧВДереве.ПравоПросмотр = ПравоДоступа("Просмотр", МетаТЧ);
КонецЕсли;
КонецЦикла;
Если КорневойТип = "БизнесПроцесс" Тогда
//! ОбъектМД = Метаданные.БизнесПроцессы[0]
ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяТочки, "Точки", "Точки", "Точки", ИндексКартинкиТЧ,
ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Точки",, ОбъектМД);
КонецЕсли;
Если КорневойТип = "Задача" Тогда
//! ОбъектМД = Метаданные.Задачи[0]
Если ОбъектМД.Адресация <> Неопределено Тогда
ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяЗадачиПоИсполнителю, "ЗадачиПоИсполнителю", "Задачи по исполнителю", "ВиртуальнаяТаблица", ИндексКартинкиТЧ,
ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Задачи по исполнителю",, ОбъектМД, 1);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если КорневойТип = "РегистрСведений" Тогда
//! ОбъектМД = Метаданные.РегистрыСведений[0]
Если ОбъектМД.ПериодичностьРегистраСведений <> Метаданные.СвойстваОбъектов.ПериодичностьРегистраСведений.Непериодический Тогда
ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяСрезПоследних, "СрезПоследних", "срез последних", "ВиртуальнаяТаблица", ИндексКартинкиТЧ,
ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Срез последних",, ОбъектМД, 1);
ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяСрезПервых, "СрезПервых", "срез первых", "ВиртуальнаяТаблица", ИндексКартинкиТЧ,
ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Срез первых",, ОбъектМД, 1);
КонецЕсли;
ИначеЕсли КорневойТип = "РегистрНакопления" Тогда
//! ОбъектМД = Метаданные.РегистрыНакопления[0]
ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяОбороты, "Обороты", "Обороты", "ВиртуальнаяТаблица", ИндексКартинкиТЧ,
ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Обороты",, ОбъектМД, 3);
Если ОбъектМД.ВидРегистра = Метаданные.СвойстваОбъектов.ВидРегистраНакопления.Остатки Тогда
ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяОстатки, "Остатки", "Остатки", "ВиртуальнаяТаблица", ИндексКартинкиТЧ,
ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Остатки",, ОбъектМД, 1);
ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяОстаткиИОбороты, "ОстаткиИОбороты", "Остатки и обороты", "ВиртуальнаяТаблица", ИндексКартинкиТЧ,
ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Остатки и обороты",, ОбъектМД, 4);
КонецЕсли;
ИначеЕсли КорневойТип = "РегистрБухгалтерии" Тогда
//! ОбъектМД = Метаданные.РегистрыБухгалтерии[0]
ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяОбороты, "Обороты", "Обороты", "ВиртуальнаяТаблица", ИндексКартинкиТЧ,
ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Обороты",, ОбъектМД, 5);
ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяОстатки, "Остатки", "Остатки", "ВиртуальнаяТаблица", ИндексКартинкиТЧ,
ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Остатки",, ОбъектМД, 3);
ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяОстаткиИОбороты, "ОстаткиИОбороты", "Остатки и обороты", "ВиртуальнаяТаблица", ИндексКартинкиТЧ,
ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Остатки и обороты",, ОбъектМД, 6);
ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяДвиженияССубконто, "ДвиженияССубконто", "Движения с субконто", "ДвиженияССубконто", ИндексКартинкиТЧ,
ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Движения с субконто",, ОбъектМД, 2);
Если ОбъектМД.ПланСчетов.МаксКоличествоСубконто > 0 Тогда
ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяСубконто, "Субконто", "Субконто", "Субконто", ИндексКартинкиТЧ,
ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Субконто",, ОбъектМД);
КонецЕсли;
Если ОбъектМД.Корреспонденция Тогда
ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяОборотыДтКт, "ОборотыДтКт", "Обороты Дт Кт", "ВиртуальнаяТаблица", ИндексКартинкиТЧ,
ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Обороты Дт Кт",, ОбъектМД, 7);
КонецЕсли;
ИначеЕсли КорневойТип = "Последовательность" Тогда
//! ОбъектМД = Метаданные.Последовательности[0]
ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяГраницы, "Границы", "Границы", "ВиртуальнаяТаблица", ИндексКартинкиТЧ,
ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Границы",, ОбъектМД);
КонецЕсли;
Если ирОбщий.ЕстьТаблицаИзмененийОбъектаМетаданных(ОбъектМД) Тогда
ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ирКэш.ИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД, Истина, Ложь), "Изменения", "Изменения", "Изменения", ИндексКартинкиТЧ,
ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Изменения",, ОбъектМД);
КонецЕсли;
КонецЦикла;
ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
Если СтрокаТипаМетаданных.Строки.Количество() = 0 Тогда
ДеревоОбъектовМД.Строки.Удалить(СтрокаТипаМетаданных);
КонецЕсли;
КонецЦикла;
ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
мТаблицаВсехТаблицБД.Индексы.Добавить("НПолноеИмя");
//мТаблицаВсехТаблицБД.Сортировать("НПолноеИмя"); // Вроде бы сортировка хранения уже не используется
мДеревоОбъектовМД = ДеревоОбъектовМД;
Возврат мДеревоОбъектовМД;
КонецФункции
Функция ДобавитьСтрокуДереваМД(СтрокаРодителяМД, ПолноеИмяТаблицы, Имя, Представление, ТипТаблицы = "", ИндексКартинки = 0, ЕстьТаблицаБД = Ложь, мТаблицаВсехТаблицБД = Неопределено,
ПолноеИмяМД ="", ИмяТаблицы = "", ПредставлениеТаблицы = "", СхемаТаблицы = "", ОбъектМД = Неопределено, ИндексПараметраОтбора = Неопределено, ФрагментыИмениТаблицы = Неопределено)
ДочерняяТаблица = СтрокаРодителяМД.Строки.Добавить();
ДочерняяТаблица.Имя = Имя;
ДочерняяТаблица.Представление = Представление;
ДочерняяТаблица.ПолноеИмяОбъекта = ПолноеИмяТаблицы;
ДочерняяТаблица.ИндексКартинки = ИндексКартинки;
ДочерняяТаблица.ПравоПросмотр = СтрокаРодителяМД.ПравоПросмотр;
ДочерняяТаблица.ТипТаблицы = ТипТаблицы;
Если ЕстьТаблицаБД Тогда
ОписаниеТаблицы = ирОбщий.ДобавитьДоступнуюТаблицуБДЛкс(мТаблицаВсехТаблицБД, ПолноеИмяТаблицы, ПолноеИмяМД, ТипТаблицы, ИмяТаблицы, ПредставлениеТаблицы, СхемаТаблицы,, ОбъектМД,
ИндексПараметраОтбора, ФрагментыИмениТаблицы);
ДочерняяТаблица.ЕстьДоступ = ОписаниеТаблицы.ЕстьДоступ;
Иначе
ДочерняяТаблица.ЕстьДоступ = СтрокаРодителяМД.ЕстьДоступ;
КонецЕсли;
Возврат ДочерняяТаблица;
КонецФункции
Функция ТаблицаВсехТаблицБД() Экспорт
ПроверитьЗагрузитьКэшМДСеанса();
Если мТаблицаВсехТаблицБД <> Неопределено Тогда
Возврат мТаблицаВсехТаблицБД;
КонецЕсли;
ДеревоОбъектовМД();
Возврат мТаблицаВсехТаблицБД;
КонецФункции
// Проверяет общий тип на агрегатность.
//
// Параметры:
// ИмяОбщегоТипа - Строка;
// *ЯзыкПрограммы - *Число, 0.
//
// Возвращаемое значение:
// Булево.
//
Функция ЭтоАгрегатныйОбщийТип(Знач ИмяОбщегоТипа, Знач ЯзыкПрограммы = 0) Экспорт
Если ИмяОбщегоТипа = "" Тогда
Возврат Ложь;
КонецЕсли;
ИмяОбщегоТипа = ирОбщий.ПервыйФрагментЛкс(ИмяОбщегоТипа, "[");
СтруктураКлюча = Новый Структура("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка", ИмяОбщегоТипа, ЯзыкПрограммы, ""); // 2021 добавил ТипЯзыка для попадания в индекс
Если Ложь
Или ирОбщий.СтрокиРавныЛкс(ИмяОбщегоТипа, "COMОбъект")
Или (Истина
И ТаблицаКонтекстов.НайтиСтроки(СтруктураКлюча).Количество() = 0
И ТаблицаШаблоновКонтекстов.НайтиСтроки(СтруктураКлюча).Количество() = 0
//И Не ЛиИмяТипаComОбъекта(ИмяОбщегоТипа)
)
Тогда
Результат = Ложь;
Иначе
Результат = Истина;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция БазовыйФайлРедактора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Лкс(ирОбщий.ОбъектВСтрокуXMLЛкс(ДанныеФормы));
СоответствиеПИ = Новый Соответствие;
СоответствиеПИ.Вставить("t", "http://v8.1c.ru/8.2/uobjects");
СоответствиеПИ.Вставить("xs", "http://www.w3.org/2001/XMLSchema");
СоответствиеПИ.Вставить("xsi", "http://www.w3.org/2001/XMLSchema-instance");
Разыменователь = Новый РазыменовательПространствИменDOM(СоответствиеПИ);
Выражение = "/*[last()]/t:type[1]/text()";
ПутьКРодителю = ДокументДОМ.ВычислитьВыражениеXPath(Выражение, ДокументДОМ, Разыменователь, ТипРезультатаDOMXPath.Строка).СтроковоеЗначение;
СтруктураИмен = Новый Структура;
Если Найти(ПутьКРодителю, "root.") = 1 Тогда
ПутьКРодителю = Сред(ПутьКРодителю, СтрДлина("root.") + 1);
СтруктураИмен = ИменаРеквизитовФормы(Форма, ПутьКРодителю, ЛиДляКоллекции,, ДокументДОМ).Все;
Если ЗначениеЗаполнено(ИмяСвойства) И Не СтруктураИмен.Свойство(ИмяСвойства) Тогда
ДобавитьОтсутствиеЭлементаФормы(Форма, "Реквизит:" + ПутьКРодителю + "." + ИмяСвойства);
КонецЕсли;
Иначе
// parameters - там почему то всегда пусто
КонецЕсли;
Возврат СтруктураИмен;
КонецФункции
// Позволяет пользователю выбрать один из возможных вариантов описания слова.
//
// Параметры:
// СтруктураЦикла - Соответствие - где ключи - имена ветвей дерева, а значения - таблицы структур типов;
// *ВключатьПутьКОписаниюТипаЗначения - Булево, *Неопределено - признак добавления в список выбора тип значения слова.
//
// Возвращаемое значение:
// СтрокаТаблицыЗначений, Структура - описание слова.
//
Функция ВыбратьСтрокуОписанияИзМассиваСтруктурТипов(СтруктураЦикла, ВключатьПутьКОписаниюТипаЗначения = Ложь, ВладелецФормы = Неопределено, Слово = "",
НомерПараметраМетода = 0, БезусловнаяАктивизацияРезультатов = Истина, выхФормаВыбора = Неопределено, КоличествоФактПараметровМетода = 0) Экспорт
ДеревоВыбора = Новый ДеревоЗначений;
ДеревоВыбора.Колонки.Добавить("Ключ");
ДеревоВыбора.Колонки.Добавить("Представление");
ДеревоВыбора.Колонки.Добавить("ТипСлова");
СчетчикСтрокВторогоУровня = 0;
НачальнаяСтрокаВыбора = Неопределено;
Для Каждого ЭлементЦикла Из СтруктураЦикла Цикл
СтрокаЭлементаЦикла = ДеревоВыбора.Строки.Добавить();
СтрокаЭлементаЦикла.Представление = ЭлементЦикла.Ключ;
КонецЦикла;
ДеревоВыбора.Строки.Сортировать("Представление");
Для Каждого СтрокаЭлементаЦикла Из ДеревоВыбора.Строки Цикл
Для Каждого СтруктураТипаКонтекста Из СтруктураЦикла[СтрокаЭлементаЦикла.Представление] Цикл
//Если СтруктураТипаКонтекста.СтрокаОписания = Неопределено Тогда
// Продолжить;
//КонецЕсли;
Если СтруктураТипаКонтекста.ИмяОбщегоТипа = "Неизвестный контекст" Тогда
Продолжить;
КонецЕсли;
СтрокаОписания = СтруктураТипаКонтекста.СтрокаОписания;
// Ранее среди параметров были: ПутьКСлову = "", ТекущееСлово = "",
//// Добавим строку описания слова
//ЭтоИмяТипа = Ложь;
//Попытка
// Если СтрокаОписания.ТипЯзыка = "ИмяТипа" Тогда
// ЭтоИмяТипа = Истина;
// КонецЕсли;
//Исключение
//КонецПопытки;
//
//Если ЭтоИмяТипа Тогда
//
// Если Прав(ПутьКСлову, 1) = "(" Тогда
// ЧистыйПутьКСлову = Лев(ПутьКСлову, СтрДлина(ПутьКСлову) - 1);
// Иначе
// ЧистыйПутьКСлову = ТекущееСлово;
// КонецЕсли;
//
// БазовыйТип = ирОбщий.ПервыйФрагментЛкс(ЧистыйПутьКСлову);
// Если БазовыйТип = "" Тогда
// // Неизвестный контекст
// СтрокаОписания = Неопределено;
// Иначе
// СтрокаОписания = ТаблицаОбщихТипов.Найти(БазовыйТип, "БазовыйТип");
// КонецЕсли;
//КонецЕсли;
Если Истина
И СтрокаОписания <> Неопределено
И ТипЗнч(СтрокаОписания) <> Тип("COMОбъект")
И СтрокаЭлементаЦикла.Строки.Найти(СтрокаОписания, "Ключ") = Неопределено
И СтрокаОписания.Владелец().Колонки.Найти("ЛиЭкспорт") = Неопределено
И (Ложь
Или СтрокаОписания.Владелец().Колонки.Найти("ТипЯзыка") = Неопределено
Или СтрокаОписания.ТипЯзыка <> "ИмяТипа")
Тогда
ПредставлениеТипа = СтрокаОписания.Слово;
Если Истина
И СтрокаОписания.Владелец().Колонки.Найти("ТипКонтекста") <> Неопределено
И ЗначениеЗаполнено(СтрокаОписания.ТипКонтекста)
Тогда
ПредставлениеТипа = СтрокаОписания.ТипКонтекста + "." + ПредставлениеТипа;
КонецЕсли;
СтрокаДереваВыбора = СтрокаЭлементаЦикла.Строки.Добавить();
СтрокаДереваВыбора.Ключ = СтрокаОписания;
Попытка
СтрокаДереваВыбора.ТипСлова = СтрокаОписания.ТипСлова;
Исключение
СтрокаДереваВыбора.ТипСлова = "Тип";
КонецПопытки;
СтрокаДереваВыбора.Представление = ПредставлениеТипа;
КонецЕсли;
Если ВключатьПутьКОписаниюТипаЗначения Тогда
// Добавим строку описания типа значения
СтрокаОписанияТипаЗначения = ТаблицаОбщихТипов.Найти(НРег(СтруктураТипаКонтекста.ИмяОбщегоТипа), "НСлово");
Если СтрокаОписанияТипаЗначения <> Неопределено Тогда
Если СтрокаЭлементаЦикла.Строки.Найти(СтрокаОписанияТипаЗначения, "Ключ") = Неопределено Тогда
ПредставлениеТипа = СтрокаОписанияТипаЗначения.Слово;
СтрокаДереваВыбора = СтрокаЭлементаЦикла.Строки.Добавить();
СтрокаДереваВыбора.Ключ = СтрокаОписанияТипаЗначения;
СтрокаДереваВыбора.ТипСлова = "Тип";
СтрокаДереваВыбора.Представление = ПредставлениеТипа;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЦикла;
СчетчикСтрокВторогоУровня = СчетчикСтрокВторогоУровня + СтрокаЭлементаЦикла.Строки.Количество();
Если Истина
И НачальнаяСтрокаВыбора = Неопределено
И СтрокаЭлементаЦикла.Строки.Количество() > 0
Тогда
Если СтрокаДереваВыбора.ТипСлова = "Конструктор" Тогда
Отбор = Новый Структура;
Отбор.Вставить("ТипКонтекста", СтрокаОписания.ТипКонтекста);
Отбор.Вставить("Слово", "<Новый>");
Отбор.Вставить("ЯзыкПрограммы", 0);
ТаблицаВариантов = ТаблицаПараметров.Скопировать(Отбор);
НовыйТекущийВариант = ПодобратьВариантСинтаксисаМетода(ТаблицаВариантов, КоличествоФактПараметровМетода);
Для Каждого СтрокаВарианта Из СтрокаЭлементаЦикла.Строки Цикл
Если НовыйТекущийВариант = СтрокаВарианта.Ключ.Слово Тогда
НачальнаяСтрокаВыбора = СтрокаВарианта;
Прервать;
КонецЕсли;
КонецЦикла;
Иначе
НачальнаяСтрокаВыбора = СтрокаЭлементаЦикла.Строки[0];
КонецЕсли;
КонецЕсли;
СтрокаЭлементаЦикла.Строки.Сортировать("Представление");
КонецЦикла;
Если выхФормаВыбора = Неопределено Тогда
выхФормаВыбора = ирКлиент.ПолучитьФормуЛкс("Обработка.ирСинтаксПомощник.Форма");
КонецЕсли;
Если СчетчикСтрокВторогоУровня > 0 Или выхФормаВыбора.Открыта() Тогда
выхФормаВыбора.ДеревоТиповСлова = ДеревоВыбора;
выхФормаВыбора.ИскомоеСлово = Слово;
выхФормаВыбора.ПоискСУчетомТипаСлова = Истина;
выхФормаВыбора.НомерИскомогоПараметра = НомерПараметраМетода;
выхФормаВыбора.ВладелецФормы = ВладелецФормы;
выхФормаВыбора.ЗакрыватьПриЗакрытииВладельца = Ложь;
Если НачальнаяСтрокаВыбора <> Неопределено Тогда
выхФормаВыбора.ВыбратьИскомуюСтроку(НачальнаяСтрокаВыбора, БезусловнаяАктивизацияРезультатов);
КонецЕсли;
выхФормаВыбора.ВладелецФормы = Неопределено; // Перенес в саму форму
КонецЕсли;
Если Ложь
Или СчетчикСтрокВторогоУровня = 1
Или (Истина
И СчетчикСтрокВторогоУровня = 2
И ДеревоВыбора.Строки[0].Строки.Количество() = 1
И НачальнаяСтрокаВыбора.Ключ = ДеревоВыбора.Строки[1].Строки[0].Ключ)
Тогда
ВыбранныйЭлементТипа = НачальнаяСтрокаВыбора;
ИначеЕсли СчетчикСтрокВторогоУровня > 1 Тогда
//ФормаВыбора = ПолучитьФорму("ФормаВыбораСправкиПоСлову");
//ФормаВыбора.ДеревоТиповСлова = ДеревоВыбора;
//ФормаВыбора.НачальноеЗначениеВыбора = НачальнаяСтрокаВыбора;
//ВыбранныйЭлементТипа = ФормаВыбора.ОткрытьМодально();
ВыбранныйЭлементТипа = НачальнаяСтрокаВыбора;
Иначе
ВыбранныйЭлементТипа = Неопределено;
КонецЕсли;
Если ВыбранныйЭлементТипа = Неопределено Тогда
СтрокаОписания = Неопределено;
Иначе
СтрокаОписания = ВыбранныйЭлементТипа.Ключ;
КонецЕсли;
Возврат СтрокаОписания;
КонецФункции
Функция НайтиИмяМетодаСтрокиМодуля(Знач ИмяМодуля, Знач НомерСтроки, Знач СодержаниеСтроки = Неопределено, ТекстыМодулей = Неопределено, СтароеИмяФайлаМодуляБезРасширения = "",
Знач ЧислоСтрокДляПоискаИмениМетода = 1000) Экспорт
Если Не ЗначениеЗаполнено(ИмяМодуля) Тогда
// Динамический код
Возврат "";
КонецЕсли;
ОписаниеМодуля = ирКлиент.ОписаниеМодуляПоИмениЛкс(ИмяМодуля);
ИмяМетода = НайтиИмяМетодаСтрокиФайлаМодуля(ОписаниеМодуля.ИмяФайлаМодуля, НомерСтроки, СодержаниеСтроки, ТекстыМодулей, СтароеИмяФайлаМодуляБезРасширения, ЧислоСтрокДляПоискаИмениМетода);
Возврат ИмяМетода;
КонецФункции
Функция НайтиИмяМетодаСтрокиФайлаМодуля(Знач ИмяФайла, Знач НомерСтроки, Знач СодержаниеСтроки = Неопределено, ТекстыМодулей = Неопределено, СтароеИмяФайлаМодуляБезРасширения = "",
Знач ЧислоСтрокДляПоискаИмениМетода = 2000, выхСмещениеСтрокиМетода = 0, Знач ПолеТекстаМодуля = Неопределено) Экспорт
Если ПолеТекстаМодуля = Неопределено Тогда
ПолеТекстаМодуля = ирКлиент.ПолеТекстаМодуляБезСтруктурыТипаЛкс(ИмяФайла);
КонецЕсли;
Если ПолеТекстаМодуля = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
Если Ложь
Или СодержаниеСтроки = Неопределено
Или СокрЛП(ПолеТекстаМодуля.ПолеТекста.ПолучитьСтроку(НомерСтроки)) = СодержаниеСтроки
Тогда
Если ТекстыМодулей = Неопределено Тогда
ТекстыМодулей = Новый Соответствие;
КонецЕсли;
КэшРазметкиМодулей = ТекстыМодулей[ИмяФайла];
Если КэшРазметкиМодулей = Неопределено Тогда
Методы = Новый ТаблицаЗначений;
Методы.Колонки.Добавить("Метод");
Методы.Индексы.Добавить("Метод");
Методы.Колонки.Добавить("НачальнаяСтрока");
Методы.Колонки.Добавить("КонечнаяСтрока", Новый ОписаниеТипов("Число"));
КэшРазметкиМодулей = Новый Структура("Методы", Методы);
ТекстыМодулей[ИмяФайла] = КэшРазметкиМодулей;
Методы = Неопределено;
КонецЕсли;
НужноеОписаниеМетода = Неопределено;
Если ирКэш.РежимОтладкиЛкс() Тогда
// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
Для Каждого ОписаниеМетода Из КэшРазметкиМодулей.Методы Цикл
Если Истина
И ОписаниеМетода.НачальнаяСтрока <= НомерСтроки
И ОписаниеМетода.КонечнаяСтрока >= НомерСтроки
Тогда
НужноеОписаниеМетода = ОписаниеМетода;
Прервать;
КонецЕсли;
КонецЦикла;
Иначе
// Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru)
Для Каждого ОписаниеМетода Из КэшРазметкиМодулей.Методы Цикл   Если Истина   И ОписаниеМетода.НачальнаяСтрока <= НомерСтроки   И ОписаниеМетода.КонечнаяСтрока >= НомерСтроки   Тогда   НужноеОписаниеМетода = ОписаниеМетода;   Прервать;   КонецЕсли;   КонецЦикла;  
КонецЕсли;
Если НужноеОписаниеМетода = Неопределено Тогда
РегВыражение = ирКэш.ВычислительРегВыраженийЛкс();
#Если Сервер И Не Сервер Тогда
РегВыражение = Обработки.ирОболочкаРегВыражение.Создать();
#КонецЕсли
РегВыражение.Global = Истина;
РегВыражение.Pattern = "(?:" + шПустоеНачалоСтроки + "(?:Процедура|Функция)" + шРазделитель + "+(" + шИмя + ")" + шРазделитель + "*\()"
+ "|(?:" + шПустоеНачалоСтроки + "(?:КонецПроцедуры|КонецФункции)" + шРазделитель + "+?(?=\n))";
НачальнаяСтрокаДиапазона = Макс(1, НомерСтроки - ЧислоСтрокДляПоискаИмениМетода);
ПолеТекстаМодуля.ПолеТекста.УстановитьГраницыВыделения(НомерСтроки + 1, 1, НачальнаяСтрокаДиапазона, 1);
Вхождения = РегВыражение.НайтиВхождения(ПолеТекстаМодуля.ВыделенныйТекст(), Истина);
Если Вхождения.Количество() > 0 Тогда
Вхождение = Вхождения[Вхождения.Количество() - 1];
ИмяМетода = Вхождение.SubMatches(0);
Если ИмяМетода = Неопределено Тогда
ИмяМетода = ИмяМетодаИнициация();
КонецЕсли;
НужноеОписаниеМетода = КэшРазметкиМодулей.Методы.Найти(ИмяМетода, "Метод");
Если НужноеОписаниеМетода = Неопределено Тогда
НужноеОписаниеМетода = КэшРазметкиМодулей.Методы.Вставить(0);
НужноеОписаниеМетода.Метод = ИмяМетода;
НужноеОписаниеМетода.НачальнаяСтрока = НачальнаяСтрокаДиапазона + СтрЧислоСтрок(Лев(ПолеТекстаМодуля.ВыделенныйТекст(), Вхождение.FirstIndex + Вхождение.Length)) - 1;
Если ИмяМетода = ИмяМетодаИнициация() Тогда
НужноеОписаниеМетода.КонечнаяСтрока = 100000000;
КонецЕсли;
КонецЕсли;
Иначе
Пустышка = 0; // Для отладки
КонецЕсли;
Иначе
ИмяМетода = НужноеОписаниеМетода.Метод;
КонецЕсли;
Если НужноеОписаниеМетода <> Неопределено Тогда
выхСмещениеСтрокиМетода = НомерСтроки - НужноеОписаниеМетода.НачальнаяСтрока;
Если НомерСтроки > НужноеОписаниеМетода.КонечнаяСтрока Тогда
НужноеОписаниеМетода.КонечнаяСтрока = НомерСтроки;
КонецЕсли;
КонецЕсли;
Иначе
Пустышка = 0; // Для отладки
КонецЕсли;
Возврат ИмяМетода;
КонецФункции
Функция ЗаполнитьСписокИнструментов() Экспорт
Если СписокИнструментов.Количество() = 0 Тогда
ТабличныйДокумент = ПолучитьМакет("СписокИнструментов");
СписокИнструментов.Загрузить(ирОбщий.ТаблицаЗначенийИзТабличногоДокументаЛкс(ТабличныйДокумент,,,, Истина));
КонецЕсли;
Возврат СписокИнструментов;
КонецФункции
// Инициализирует полное дерево типов платформы.
//
// Параметры:
// Нет.
//
Процедура ИнициироватьДеревоТипов() Экспорт
ИнициацияОписанияМетодовИСвойств();
Состояние("Инициализация дерева типов...");
Если ДеревоТипов <> Неопределено Тогда
Возврат;
КонецЕсли;
ДеревоТипов = Новый ДеревоЗначений;
ДеревоТипов.Колонки.Добавить("Пометка", Новый ОписаниеТипов("Булево"));
ДеревоТипов.Колонки.Добавить("Имя");
ДеревоТипов.Колонки.Добавить("ИндексКартинки", Новый ОписаниеТипов("Число"));
ДеревоТипов.Колонки.Добавить("СтруктураТипа");
лТаблицаТипов = ТаблицаОбщихТипов.Скопировать(Новый Структура("ЯзыкПрограммы", 0), "Слово");
лТаблицаТипов.Колонки.Слово.Имя = "Имя";
Для Каждого СтрокаТипа Из лТаблицаТипов Цикл
ЗаполнитьЗначенияСвойств(ДеревоТипов.Строки.Добавить(), СтрокаТипа);
КонецЦикла;
СтруктураТипа = НоваяСтруктураТипа();
СтруктураТипа.Метаданные = мМетаданные;
СтруктураТипа.ТипЯзыка = "ИмяТипа";
СтруктураТипа.ИмяОбщегоТипа = "";
ОбработатьСтрокиДереваТипов(ДеревоТипов.Строки, СтруктураТипа);
ДеревоТипов.Строки.Сортировать("Имя", Истина);
ВсеТипы.Сортировать("Имя");
МассивВажныхТипов = Новый Массив;
// Порядок обратный
МассивВажныхТипов.Добавить("Массив");
МассивВажныхТипов.Добавить("Булево");
МассивВажныхТипов.Добавить("Дата");
МассивВажныхТипов.Добавить("Строка");
МассивВажныхТипов.Добавить("Число");
Для Каждого ВажныйТип Из МассивВажныхТипов Цикл
СтрокаТипа = ВсеТипы.Найти(ВажныйТип, "Имя");
ВсеТипы.Сдвинуть(СтрокаТипа, -ВсеТипы.Индекс(СтрокаТипа));
СтрокаТипа = ДеревоТипов.Строки.Найти(ВажныйТип, "Имя");
ДеревоТипов.Строки.Сдвинуть(СтрокаТипа, -ДеревоТипов.Строки.Индекс(СтрокаТипа));
КонецЦикла;
Состояние("");
КонецПроцедуры
Процедура ОбработатьСтрокиДереваТипов(Строки, КорневаяСтруктураТипа = Неопределено, ОкончаниеСтрокиТипа = "", _МетаданныеТипа = Неопределено) Экспорт
МассивСтрокКУдалению = Новый Массив;
Для Каждого СтрокаТипа Из Строки Цикл
ТекущееИмяТипа = СтрокаТипа.Имя;
СтрокаТипа.Имя = СтрокаТипа.Имя + ОкончаниеСтрокиТипа;
Уровень = СтрокаТипа.Уровень();
ФрагментыОбщегоТипа = Неопределено;
Если Уровень = 0 Тогда
Если Найти(ТекущееИмяТипа, ".") > 0 Тогда
ФрагментыОбщегоТипа = ирОбщий.СтрРазделитьЛкс(ТекущееИмяТипа);
ТекущееИмяТипа = ФрагментыОбщегоТипа[0];
КонецЕсли;
СтрокаТипаМетаОбъектов = ОписаниеТипаМетаОбъектов(ТекущееИмяТипа);
Если СтрокаТипаМетаОбъектов <> Неопределено Тогда
СтрокаТипа.ИндексКартинки = СтрокаТипаМетаОбъектов.ИндексКартинкиЕдинственное;
КонецЕсли;
Уровень = 0;
//СтрокаТипа.ИмяОбщегоТипа = ТекущееИмяТипа;
Иначе
Если КорневаяСтруктураТипа <> Неопределено Тогда
КорневаяСтруктураТипа.Свойство("ФрагментыОбщегоТипа", ФрагментыОбщегоТипа);
КонецЕсли;
СтрокаТипа.ИндексКартинки = Строки.Родитель.ИндексКартинки;
КонецЕсли;
Если ФрагментыОбщегоТипа <> Неопределено Тогда
Если ФрагментыОбщегоТипа.ВГраница() > Уровень Тогда
ТекущийФрагмент = ФрагментыОбщегоТипа[Уровень + 1];
КонецЕсли;
Если Найти(ТекущийФрагмент, "<") > 0 Тогда
Если Истина
И КорневаяСтруктураТипа = Неопределено
Тогда
КорневаяСтруктураТипа = НоваяСтруктураТипа();
КорневаяСтруктураТипа.Метаданные = мМетаданные;
КорневаяСтруктураТипа.ТипЯзыка = "ИмяТипа";
КорневаяСтруктураТипа.ИмяОбщегоТипа = СтрокаТипа.Имя;
КонецЕсли;
Если Уровень = 0 Тогда
КорневаяСтруктураТипа.Вставить("ФрагментыОбщегоТипа", ФрагментыОбщегоТипа);
СтруктураТипа = НоваяСтруктураТипа();
ЗаполнитьЗначенияСвойств(СтруктураТипа, КорневаяСтруктураТипа);
СтруктураТипа.ИмяОбщегоТипа = ТекущееИмяТипа;
Иначе
СтруктураТипа = СтрокаТипа.СтруктураТипа;
КонецЕсли;
Попытка
ВнутренняяТаблицаСлов = СловаКонтекстаМетаданные(СтруктураТипа, , "Свойство");
Исключение
ВнутренняяТаблицаСлов = Новый ТаблицаЗначений;
КонецПопытки;
Если Истина
И Уровень > 0
И ВнутренняяТаблицаСлов.Количество() = 0
Тогда
МассивСтрокКУдалению.Добавить(СтрокаТипа);
Продолжить;
Иначе
ОкончаниеСтрокиТипаВниз = "";
Для Счетчик = Уровень + 2 По ФрагментыОбщегоТипа.ВГраница() Цикл
Фрагмент = ФрагментыОбщегоТипа[Счетчик];
ОкончаниеСтрокиТипаВниз = ОкончаниеСтрокиТипаВниз + "." + Фрагмент;
КонецЦикла;
Для Каждого СтрокаСлова Из ВнутренняяТаблицаСлов Цикл
НоваяСтрока = СтрокаТипа.Строки.Добавить();
СтруктураТипаВниз = СтрокаСлова.ТаблицаТипов[0];
НоваяСтрока.СтруктураТипа = СтруктураТипаВниз;
//НоваяСтрока.Имя = ИмяТипаИзСтруктурыТипа(СтруктураТипаВниз);
НоваяСтрока.Имя = ТекущееИмяТипа + "." + СтруктураТипаВниз.Метаданные.Имя;
КонецЦикла;
ОбработатьСтрокиДереваТипов(СтрокаТипа.Строки, КорневаяСтруктураТипа, ОкончаниеСтрокиТипаВниз);
КонецЕсли;
КонецЕсли;
КонецЕсли;
//ЗаполнитьЗначенияСвойств(СтруктураТипа, КорневаяСтруктураТипа, "ИмяОбщегоТипа");
ЗаполнитьЗначенияСвойств(ВсеТипы.Добавить(), СтрокаТипа);
КонецЦикла;
РодительСтрок = Строки.Родитель;
Для Каждого СтрокаКУдалению Из МассивСтрокКУдалению Цикл
РодительСтрок.Строки.Удалить(СтрокаКУдалению);
КонецЦикла;
КонецПроцедуры
// Открыть диалог для редактирования допустимых типов.
//
// Параметры:
// ДопустимыеТипы - Строка - сериализованные допустимые типы;
// *ТолькоПросмотр - Булево, *Истина - открыть только для просмотра.
//
// Возвращаемое значение:
// Строка - сериализованных допустимых типов;
// Неопределено - отмена.
//
Функция РедактироватьДопустимыеТипы(ДопустимыеТипы, ТолькоПросмотр = Ложь) Экспорт
ФормаВыбора = ПолучитьФорму("ВыборДопустимыхТипов");
ФормаВыбора.ДопустимыеТипы = ДопустимыеТипы;
ФормаВыбора.ТолькоПросмотр = ТолькоПросмотр;
Если ФормаВыбора.ОткрытьМодально() = Истина Тогда
Возврат ФормаВыбора.ДопустимыеТипы;
Иначе
Возврат Неопределено;
КонецЕсли;
КонецФункции
// Убирает из строки лишние кавычки.
//
// Параметры:
// ПервичнаяСтрока - Строка.
//
// Возвращаемое значение:
// Строка.
//
Функция ИзвлечьСтрокуШаблонаТекста(ПервичнаяСтрока)
RegExp.Global = Истина;
СтрокаБезГраниц = Сред(ПервичнаяСтрока, 2, СтрДлина(ПервичнаяСтрока) - 2);
RegExp.Pattern = "([^""]*"")""";
Результат = RegExp.Заменить(СтрокаБезГраниц, "$1");
Возврат Результат;
КонецФункции // ИзвлечьСтрокуШаблонаТекста ()
// Загружает шаблоны текста из файла.
//
// Параметры:
// Нет.
//
// Возвращаемое значение:
// Булево - успешность операции.
//
Функция ПолучитьТаблицуШаблоновТекста(ИмяКласса, _мСообщенияЧерезПредупреждения = Ложь, ПринудительноОбновить = Ложь) Экспорт
Если Истина
И Не ПринудительноОбновить
И ТаблицаШаблоновТекста <> Неопределено
Тогда
Возврат ТаблицаШаблоновТекста;
КонецЕсли;
ТаблицаШаблоновТекста = Новый ТаблицаЗначений;
ТаблицаШаблоновТекста.Колонки.Добавить("Шаблон");
ТаблицаШаблоновТекста.Колонки.Добавить("Замена");
ТаблицаШаблоновТекста.Индексы.Добавить("Шаблон");
ФайлШаблонов = ирОбщий.ВосстановитьЗначениеЛкс(ИмяКласса + ".ФайлШаблоновТекста");
Файл = Новый Файл(ФайлШаблонов);
Если Не Файл.Существует() Тогда
Если ЗначениеЗаполнено(ФайлШаблонов) Тогда
ирОбщий.СообщитьСУчетомМодальностиЛкс("Не обнаружен файл шаблонов текста """ + ФайлШаблонов + """, указанный в настройках компоненты ""Контекстная подсказка""");
КонецЕсли;
Возврат Неопределено;
КонецЕсли;
Парсер = мПолучитьПарсер("ГрамматикаФайлаШаблоновТекста");
Если Парсер = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
ТекстовыйДокументФайла = Новый ТекстовыйДокумент;
ТекстовыйДокументФайла.Прочитать(ФайлШаблонов);
Состояние("Идет загрузка файла шаблонов текста...");
gpMsgReduction = 2;
gpMsgAccept = 3;
gpMsgNotLoadedError = 4;
gpMsgLexicalError = 5;
gpMsgSyntaxError = 6;
gpMsgInternalError = 8;
Парсер.OpenTextString(ТекстовыйДокументФайла.ПолучитьТекст());
Закончили = Ложь;
ТекущаяСтрокаТаблицыШаблоновТекста = Неопределено;
Пока Не Закончили Цикл
Ответ = Парсер.Parse();
Если Ложь
Или Ответ = gpMsgLexicalError
Или Ответ = gpMsgSyntaxError
Или Ответ = gpMsgInternalError
Или Ответ = gpMsgNotLoadedError
Или Ответ = gpMsgAccept
Тогда
Закончили = Истина;
ИначеЕсли Ответ = gpMsgReduction Тогда
ИмяПравила = Парсер.CurrentReduction.ParentRule.RuleNonterminal.Text;
Если ИмяПравила = "<Match>" Тогда
СтартовыйТокен = Парсер.CurrentReduction.Tokens(0);
ТекущаяСтрокаТаблицыШаблоновТекста = ТаблицаШаблоновТекста.Добавить();
ТекущаяСтрокаТаблицыШаблоновТекста.Шаблон = Нрег(ИзвлечьСтрокуШаблонаТекста(СтартовыйТокен.Data));
ИначеЕсли ИмяПравила = "<Replacement>" Тогда
СтартовыйТокен = Парсер.CurrentReduction.Tokens(0);
ТекущаяСтрокаТаблицыШаблоновТекста.Замена = ИзвлечьСтрокуШаблонаТекста(СтартовыйТокен.Data);
КонецЕсли;
КонецЕсли;
КонецЦикла;
Состояние();
Если Ответ <> gpMsgAccept Тогда
ирОбщий.СообщитьСУчетомМодальностиЛкс("Указан неправильный файл шаблонов """ + ФайлШаблонов + """");
ТаблицаШаблоновТекста = Неопределено;
КонецЕсли;
Возврат ТаблицаШаблоновТекста;
КонецФункции // ЗагрузитьШаблоныТекста()
// .
// Параметры:
// Параметры - ТаблицаЗначений - колонки "ИмяПараметра, ЗначениеПараметра"
// ТипЗапроса - Строка, *"Построитель" - "Обычный", "Компоновка", "Построитель"
Функция РедактироватьЗапрос(Текст, Параметры = Неопределено, Знач ТипЗапроса = "Построитель", ПараметрыADO = Неопределено, ПараметрыWMI = Неопределено,
ВыделениеДвумерное = Неопределено) Экспорт
СтруктураЗапроса = Новый Структура;
СтруктураЗапроса.Вставить("ТекстЗапроса", Текст);
СтруктураЗапроса.Вставить("Параметры", Параметры);
Если ПараметрыADO <> Неопределено Тогда
СтруктураЗапроса.Вставить("ПараметрыADO", ПараметрыADO);
КонецЕсли;
Если ПараметрыWMI <> Неопределено Тогда
СтруктураЗапроса.Вставить("ПараметрыWMI", ПараметрыWMI);
КонецЕсли;
СтруктураЗапроса.Вставить("ТипЗапроса", ТипЗапроса);
СтруктураЗапроса.Вставить("Имя", "Запрос");
СтруктураЗапроса.Вставить("ВыделениеДвумерное", ВыделениеДвумерное);
КонсольЗапросов = ирОбщий.СоздатьОбъектПоИмениМетаданныхЛкс("Обработка.ирКонсольЗапросов");
#Если Сервер И Не Сервер Тогда
КонсольЗапросов = Обработки.ирКонсольЗапросов.Создать();
#КонецЕсли
РезультатФормы = КонсольЗапросов.РедактироватьСтруктуруЗапроса(, СтруктураЗапроса);
Результат = РезультатФормы <> Неопределено;
Если Результат Тогда
Текст = РезультатФормы.ТекстЗапроса;
Параметры = РезультатФормы.Параметры;
ПараметрыADO = РезультатФормы.ПараметрыADO;
ПараметрыWMI = РезультатФормы.ПараметрыWMI;
ВыделениеДвумерное = РезультатФормы.ВыделениеДвумерное;
КонецЕсли;
Возврат Результат;
КонецФункции
#КонецЕсли
////////////////////////////////////////////////////////////////////////////////
// РАБОТА С АЛГОРИТМАМИ
// Выполняет текст программы.
//
// Параметры:
// ТекстДляВыполнения - Строка;
// *ЛиСинтаксическийКонтроль - Булево, *Ложь - признак вызова только для синтаксического контроля.
//
Функция ВыполнитьЛокально(ТекстДляВыполнения, ЛиСинтаксическийКонтроль = Ложь) Экспорт
Если ЛиСинтаксическийКонтроль Тогда
ирОбщий.ВыполнитьАлгоритмБезРезультата(ТекстДляВыполнения);
Иначе
Результат = ирОбщий.ВыполнитьАлгоритм(ТекстДляВыполнения);
КонецЕсли;
Возврат Результат;
КонецФункции
// Выполняет программный код в контексте.
//
// Параметры:
// ТекстДляВыполнения - Строка;
// *ЛиСинтаксическийКонтроль - Булево, *Ложь - признак вызова только для синтаксического контроля.
//
Функция ВыполнитьПрограммныйКодВКонтексте(КонтекстВыполнения, МетодВыполнения = "ВыполнитьЛокально", ТекстДляВыполнения, ЛиСинтаксическийКонтроль = Ложь) Экспорт
Если ПустаяСтрока(МетодВыполнения) Тогда
ВызватьИсключение "Не указан метод выполнения";
КонецЕсли;
Если КонтекстВыполнения = Неопределено Тогда
ИнформацияОбОшибке = Вычислить(МетодВыполнения + "(ТекстДляВыполнения, ЛиСинтаксическийКонтроль)");
Иначе
ИнформацияОбОшибке = Вычислить("КонтекстВыполнения." + МетодВыполнения + "(ТекстДляВыполнения, ЛиСинтаксическийКонтроль)");
КонецЕсли;
Возврат ИнформацияОбОшибке;
КонецФункции
// Получает новый экземпляр ком-объекта парсера.
//
// Параметры:
// Нет.
//
// Возвращаемое значение:
// Com-объект, Неопределено.
//
Функция ПолучитьADOUtils(_ПытатьсяУстанавливать = Ложь, Знач СмещениеГодаADO = Неопределено, Знач Типизировать1С = Ложь, Знач БинарныеВСтроку = Ложь) Экспорт
Если мADOUtils = Неопределено Тогда
ИдентификаторКласса = "GameWithFire.ADOUtils";
ИмяОбъекта = "ADOUtils";
ПодключитьВнешнююКомпоненту(ИдентификаторКласса);
Попытка
мADOUtils = Новый ("AddIn." + ИмяОбъекта);
мADOUtils.BinaryDataAs1C = Истина; // Для проверки актуальности версии библиотеки
Исключение
мADOUtils = Неопределено;
КонецПопытки;
Если Истина
И мADOUtils = Неопределено
//И ПытатьсяУстанавливать
И Ложь
Тогда
ИмяМакетаДополнительнойБиблиотеки = "Zlib1";
ИмяМакетаКомпоненты = "GameWithFire";
ПолучитьCOMОбъектИзМакета(ИмяМакетаКомпоненты, ИдентификаторКласса,, ИмяМакетаДополнительнойБиблиотеки, ИмяОбъекта);
ПодключитьВнешнююКомпоненту(ИдентификаторКласса);
Попытка
мADOUtils = Новый ("AddIn." + ИмяОбъекта);
мADOUtils.BinaryDataAs1C = Истина; // Для проверки актуальности версии библиотеки
Исключение
КонецПопытки;
КонецЕсли;
// такой способ почему то не работает
//мADOUtils = ПолучитьОбъектВнешнейКомпонентыИзМакета(ИмяМакетаКомпоненты, , ИдентификаторКласса, ТипВнешнейКомпоненты.COM, ИмяМакетаДополнительнойБиблиотеки);
КонецЕсли;
Если мADOUtils <> Неопределено Тогда
мADOUtils.BinaryDataAsStrings = БинарныеВСтроку;
м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";
ПортСервераОтладки = ирОбщий.ПоследнийФрагментЛкс(Результат, ":", Ложь);
Если ПортСервераОтладки = "" Тогда
ПортСервераОтладки = Неопределено;
КонецЕсли;
RegExp.Global = Истина;
шСоединениеССерверомОтладки = "TCP(?:\s+)(" + шАдресIP4 +"):(?:\d+)(?:\s+)" + шАдресIP4 + ":" + ПортСервераОтладки +"(?:\s+)ESTABLISHED(?:\s+)";
RegExp.Pattern = шСоединениеССерверомОтладки + Формат(ИдентификаторЭтогоПроцесса, "ЧГ=");
Вхождения = RegExp.НайтиВхождения(ТекстРезультата);
Для Каждого Вхождение Из Вхождения Цикл
ЛокальныйАдрес4 = Вхождение.SubMatches(0);
Прервать;
КонецЦикла;
RegExp.Pattern = шСоединениеССерверомОтладки + "(\d+)";
Вхождения = RegExp.НайтиВхождения(ТекстРезультата);
Для Каждого Вхождение Из Вхождения Цикл
ИдентификаторОтладчика = Вхождение.SubMatches(1);
Если Истина
И ИдентификаторОтладчика <> Формат(ИдентификаторЭтогоПроцесса, "ЧГ=")
И выхИдентификаторыОтладчиков.Найти(ИдентификаторОтладчика) = Неопределено
Тогда
ПроцессОС = ирОбщий.ПолучитьПроцессОСЛкс(ИдентификаторОтладчика);
Если Истина
И ирОбщий.СтрокиРавныЛкс(ПроцессОС.Name, ирОбщий.ИмяИсполняемогоФайлаКлиентаПлатформыЛкс(Ложь))
И ирОбщий.ЛиПроцессОСКонфигуратораЛкс(ПроцессОС)
Тогда
выхИдентификаторыОтладчиков.Добавить(ИдентификаторОтладчика);
КонецЕсли;
КонецЕсли;
КонецЦикла;
выхИдентификаторыОтладчиков.Добавить("0"); // Чтобы неоднозначность сохранялась и с одним найденным отладчиком
Иначе
выхПротокол = "tcp";
RegExp.Global = Истина;
RegExp.Pattern = "TCP(?:\s+)0\.0\.0\.0:(\d+)(?:\s+)" + шАдресIP4 + ":(\d+)(?:\s+)LISTENING(?:\s+)" + Формат(ИдентификаторЭтогоПроцесса, "ЧГ=");
Вхождения = RegExp.НайтиВхождения(ТекстРезультата);
МассивСлушающихПортов = Новый Массив;
СтрокаПоиска = "";
// Т.к. неясно какой из портов для отладки, используем все
Для Каждого Вхождение Из Вхождения Цикл
МассивСлушающихПортов.Добавить(Вхождение.SubMatches(0));
СтрокаПоиска = СтрокаПоиска + "|" + Вхождение.SubMatches(0);
КонецЦикла;
Если МассивСлушающихПортов.Количество() = 0 Тогда
Результат = Неопределено;
Возврат Результат;
КонецЕсли;
СтрокаПоиска = Сред(СтрокаПоиска, 2);
ЛокальныйАдрес = ирОбщий.ПодготовитьТекстДляРегВыраженияЛкс("127.0.0.1");
RegExp.Pattern = "TCP(?:\s+)" + ЛокальныйАдрес + ":(?:\d+)(?:\s+)" + ЛокальныйАдрес + ":(" + СтрокаПоиска + ")(?:\s+)ESTABLISHED(?:\s+)(\d+)";
Вхождения = RegExp.НайтиВхождения(ТекстРезультата);
Для Каждого Вхождение Из Вхождения Цикл
ИдентификаторКорреспондента = Вхождение.SubMatches(1);
Если ИдентификаторКорреспондента <> Формат(ИдентификаторЭтогоПроцесса, "ЧГ=") Тогда
выхИдентификаторыОтладчиков.Добавить(ИдентификаторКорреспондента);
Иначе
МассивСлушающихПортов.Удалить(МассивСлушающихПортов.Найти(Вхождение.SubMatches(0)));
КонецЕсли;
КонецЦикла;
Если МассивСлушающихПортов.Количество() > 0 Тогда
Результат = "tcp://127.0.0.1:" + МассивСлушающихПортов[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;
Если Форма <> Неопределено Тогда
СлужебныеДанные = ирОбщий.СлужебныеДанныеФормыЛкс(Форма);
Иначе
Пустышка = 0; // Для отладки. Желательно чтобы сюда не было приходов
КонецЕсли;
Если СлужебныеДанные = Неопределено Тогда
// Редко. Открытая форма. Фактически не используем кэш
СлужебныеДанные = Новый Структура;
КонецЕсли;
Если СлужебныеДанные.Свойство("КорневыеИменаРеквизитов") Тогда
КорневыеИменаРеквизитов = СлужебныеДанные.КорневыеИменаРеквизитов.Все;
КонецЕсли;
Если ДокументДОМ = Неопределено И СлужебныеДанные.Свойство("ДокументДОМ") Тогда
ДокументДОМ = СлужебныеДанные.ДокументДОМ;
КонецЕсли;
Если ТипЗнч(Форма) = ТипУправляемаяФорма И ДокументДОМ = Неопределено Тогда
СтруктураТипа = НоваяСтруктураТипа("ФормаКлиентскогоПриложения");
СтруктураТипа.Метаданные = Форма;
//МодульФормы = ПодготовитьМодульМетаданных(СтруктураТипа); // Раньше кэш ДокументДОМ хранился тут
ЛюбыеДанныеФормы = Неопределено;
КорневыеИменаРеквизитов = Новый Структура;
ИмяФайлаМодуляБезРасширения = ИмяФайлаМодуляБезРасширения(СтруктураТипа);
КандидатыИменРеквизитов = ирОбщий.КандидатыИменОбъектныхРеквизитовФормыЛкс(Форма);
ПолеТекстаПрограммы = Неопределено;
МодульПроанализирован = Ложь;
Пока Истина Цикл
Для Каждого ИмяРеквизита Из КандидатыИменРеквизитов Цикл
Попытка
ЗначениеРеквизита = Форма[ИмяРеквизита];
Исключение
Продолжить;
КонецПопытки;
КорневыеИменаРеквизитов.Вставить(ИмяРеквизита);
Если Истина
И ТипЗнч(ЗначениеРеквизита) <> Тип("СписокЗначений")
И мМассивТиповСМетаданными.Найти(ТипЗнч(ЗначениеРеквизита)) <> Неопределено
Тогда
ЛюбыеДанныеФормы = ЗначениеРеквизита;
Перейти ~Конец;
КонецЕсли;
КонецЦикла;
Если МодульПроанализирован Тогда
Прервать;
КонецЕсли;
Для Каждого ЭлементФормы Из Форма.Элементы Цикл
ИмяРеквизита = ирОбщий.ПервыйФрагментЛкс(ирОбщий.ПутьКДаннымЭлементаУправляемойФормыЛкс(ЭлементФормы,, Форма));
Если Истина
И ЗначениеЗаполнено(ИмяРеквизита)
И Не КорневыеИменаРеквизитов.Свойство(ИмяРеквизита)
Тогда
КорневыеИменаРеквизитов.Вставить(ИмяРеквизита);
ЗначениеРеквизита = Форма[ИмяРеквизита];
ТипЗначения = ТипЗнч(ЗначениеРеквизита);
Если мМассивТиповСМетаданными.Найти(ТипЗначения) <> Неопределено Тогда
ИмяТипа = ирОбщий.ИмяТипаЛкс(ТипЗначения);
Если МассивУправляемыхЭлементовУправления.Найти(ИмяТипа) = Неопределено Тогда
ЛюбыеДанныеФормы = ЗначениеРеквизита;
Перейти ~Конец;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если ЛюбыеДанныеФормы = Неопределено Тогда
// Самый долгий способ
ПолеТекстаМодуля = ПолеТекстаМодуля(ИмяФайлаМодуляБезРасширения);
#Если Сервер И Не Сервер Тогда
ПолеТекстаМодуля = Обработки.ирКлсПолеТекстаПрограммы.Создать();
#КонецЕсли
ТаблицаТипов = ДобавитьВТаблицуТипов(, СтруктураТипаИзКонкретногоТипа(ирОбщий.ТипУправляемаяФормаЛкс()));
ПолеТекстаМодуля.ЗаполнитьТаблицуСлов(ТаблицаТипов,,, Ложь, Ложь);
ПолеТекстаМодуля.ЗаполнитьЛокальныеСвойстваИМетодыПоТексту(Ложь, Ложь,,,,,, Истина);
ПолеТекстаМодуля.мРодительскийКонтекст = "ЭтаФорма"; // TODO добавить слова от ЭтотОбъект
ПолеТекстаМодуля.ЗаполнитьЛокальныеСвойстваИМетодыПоТексту(Ложь, Ложь, Истина, Ложь,,,, Истина);
КандидатыИменРеквизитов = ПолеТекстаМодуля.ТаблицаСлов.Выгрузить(Новый Структура("Определение", "Статистический")).ВыгрузитьКолонку("НСлово");
ВредныйКандидат = КандидатыИменРеквизитов.Найти(НРег("ЭтаФорма"));
Если ВредныйКандидат <> Неопределено Тогда
КандидатыИменРеквизитов.Удалить(ВредныйКандидат);
КонецЕсли;
ВредныйКандидат = КандидатыИменРеквизитов.Найти(НРег("ЭтотОбъект"));
Если ВредныйКандидат <> Неопределено Тогда
КандидатыИменРеквизитов.Удалить(ВредныйКандидат);
КонецЕсли;
КонецЕсли;
МодульПроанализирован = Истина;
КонецЦикла;
~Конец:
Если ЛюбыеДанныеФормы <> Неопределено Тогда
ДокументДОМ = ирОбщий.ТекстВДокументDOMЛкс(ирОбщий.ОбъектВСтрокуXMLЛкс(ЛюбыеДанныеФормы)); // Обычно выполняется достаточно быстро
КонецЕсли;
КонецЕсли;
Если ПутьКРодителю = "" И Не ЛиДляКоллекции Тогда
ИменаРеквизитов = КорневыеИменаРеквизитов;
КонецЕсли;
Если ИменаРеквизитов = Неопределено Тогда
ИменаРеквизитов = Новый Структура;
КонецЕсли;
Если СлужебныеДанные.Свойство("Реквизиты") Тогда
ТаблицаРеквизитов = СлужебныеДанные.Реквизиты; // см. НоваяТаблицаРеквизитовФормы
Если ТаблицаРеквизитов <> Неопределено Тогда
УспехРеквизита = Истина;
Для Каждого ИмяРодителя Из ирОбщий.СтрРазделитьЛкс(НРег(ПутьКРодителю),,, Ложь) Цикл
СтрокаРодителя = ТаблицаРеквизитов.Найти(ИмяРодителя, "НИмя");
Если СтрокаРодителя = Неопределено Тогда
УспехРеквизита = Ложь;
Прервать;
КонецЕсли;
ТаблицаРеквизитов = СтрокаРодителя.Реквизиты;
КонецЦикла;
ЭтоКоллекция = Истина
И СтрокаРодителя <> Неопределено
И ТипЗнч(СтрокаРодителя.Значение) <> Тип("Структура"); // Мультиметка7726614
Если Истина
И УспехРеквизита
И (Ложь
Или ЛиДляКоллекции И ЭтоКоллекция
Или Не ЛиДляКоллекции И Не ЭтоКоллекция)
Тогда
Для Каждого СтрокаРеквизита Из ТаблицаРеквизитов Цикл
ОписаниеТипов = СтрокаРеквизита.ОписаниеТипов; // ОписаниеТипов
Если СтрокаРеквизита.Значение = Неопределено Тогда
Если ОписаниеТипов = Неопределено Тогда
//ОписаниеТипов = Новый ОписаниеТипов;
Иначе
Типы = ОписаниеТипов.Типы();
Если Типы.Количество() > 0 Тогда
ТипЗначения = Типы[0];
Если Ложь
Или ирОбщий.ЛиНаборЗаписейРегистраЛкс(ТипЗначения)
//Или ирОбщий.ЛиТипОбъектаБДЛкс(ТипЗначения) // TODO сделать для объектов генерацию структуры их свойств
Тогда
ОписаниеТипов = ТаблицаТиповИзОписанияТипов(ОписаниеТипов);
ОписаниеТипов[0].ИмяОбщегоТипа = "ДанныеФормыСтруктураСКоллекцией";
КонецЕсли;
КонецЕсли;
КонецЕсли;
Иначе
Если ТипЗнч(СтрокаРеквизита.Значение) = Тип("ТаблицаЗначений") Тогда
СтруктураТипа = НоваяСтруктураТипа("ДанныеФормыКоллекция");
ИначеЕсли ТипЗнч(СтрокаРеквизита.Значение) = Тип("ДеревоЗначений") Тогда
СтруктураТипа = НоваяСтруктураТипа("ДанныеФормыДерево");
Иначе
СтруктураТипа = СтруктураТипаИзЗначения(СтрокаРеквизита.Значение);
КонецЕсли;
СтруктураТипа.Метаданные = СтрокаРеквизита.Значение;
ОписаниеТипов = ДобавитьВТаблицуТипов(, СтруктураТипа);
КонецЕсли;
ИменаРеквизитов.Вставить(СтрокаРеквизита.Имя, ОписаниеТипов);
КонецЦикла;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ДокументДОМ <> Неопределено Тогда
Если ЗначениеЗаполнено(ПутьКРодителю) Тогда
ПутьКРодителю = "." + ПутьКРодителю;
КонецЕсли;
СоответствиеПИ = Новый Соответствие;
СоответствиеПИ.Вставить("t", "http://v8.1c.ru/8.2/uobjects");
СоответствиеПИ.Вставить("xs", "http://www.w3.org/2001/XMLSchema");
СоответствиеПИ.Вставить("xsi", "http://www.w3.org/2001/XMLSchema-instance");
Разыменователь = Новый РазыменовательПространствИменDOM(СоответствиеПИ);
Если ЛиДляКоллекции Тогда
ПутьКРодителю = ПутьКРодителю + ".item";
КонецЕсли;
Выражение = "/*/*/*[@name=""root" + ПутьКРодителю + """]/*";
НаборУзлов = ДокументДОМ.ВычислитьВыражениеXPath(Выражение, ДокументДОМ, Разыменователь, ТипРезультатаDOMXPath.Любой);
УзелDOM = НаборУзлов.ПолучитьСледующий();
Пока УзелDOM <> Неопределено Цикл
ИмяРеквизита = УзелDOM.Атрибуты.ПолучитьИменованныйЭлемент("nameRu");
Если ИмяРеквизита = Неопределено Тогда
ИмяРеквизита = УзелDOM.Атрибуты.ПолучитьИменованныйЭлемент("name");
КонецЕсли;
Если ИмяРеквизита <> Неопределено Тогда
ИмяРеквизита = ИмяРеквизита.ТекстовоеСодержимое;
Если Истина
И Найти(ИмяРеквизита, ".") = 0 // Защита от нахождения "root" + ПутьКРодителю
И УзелDOM.ПервыйДочерний <> Неопределено
Тогда
Типы = Новый Массив;
УзелТипаЗначения = УзелDOM.ПервыйДочерний.ПервыйДочерний;
Если УзелТипаЗначения <> Неопределено Тогда
ИменаТипов = ирОбщий.СтрРазделитьЛкс(УзелТипаЗначения.ТекстовоеСодержимое, " ");
Если ИменаТипов.Количество() < 11 Тогда
Для Каждого ИДТипа Из ИменаТипов Цикл
Попытка
Тип = ЗначениеИзСтрокиВнутр("{""T""," + ИДТипа + "}");
Исключение
Тип = Неопределено;
КонецПопытки;
Если Тип <> Неопределено Тогда
Типы.Добавить(Тип);
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЕсли;
Если Истина
И ПутьКРодителю = ""
И Типы.Количество() = 0
И ТипЗнч(Форма) = ТипУправляемаяФорма
Тогда
Типы.Добавить(ТипЗнч(Форма[ИмяРеквизита]));
КонецЕсли;
ИменаРеквизитов.Вставить(ИмяРеквизита, Новый ОписаниеТипов(Типы));
выхИдентификаторыРеквизитов.Вставить(Узел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);
КонецЕсли;
КонецЕсли;
Результат = Новый Структура;
Результат.Вставить("Основной", ИмяОсновногоРеквизита);
Результат.Вставить("Все", ИменаРеквизитов);
Если СлужебныеДанные <> Неопределено И Не ЗначениеЗаполнено(ПутьКРодителю) Тогда
СлужебныеДанные.Вставить("КорневыеИменаРеквизитов", Результат);
КонецЕсли;
Возврат Результат;
КонецФункции
// Функция - Получить макет компоненты
//
// Параметры:
// Компонента - ОбработкаОбъект, ОбработкаОбъект.ирКлсПолеТабличногоДокумента -
//
// Возвращаемое значение:
// Форма -
//
Функция ПолучитьМакетКомпоненты(Компонента) Экспорт
Макет = 0;
Если Не МакетыКомпонент.Свойство(Компонента.ИмяКласса, Макет) Тогда
Макет = Компонента.ПолучитьФорму("ФормаМакет");
Попытка
Пустышка = Макет.мПлатформа;
Успех = Истина;
Исключение
Успех = Ложь;
КонецПопытки;
Если Успех Тогда
ирОбщий.СообщитьЛкс("Образована циклическая ссылка на ирПлатформа", СтатусСообщения.Внимание);
КонецЕсли;
МакетыКомпонент.Вставить(Компонента.ИмяКласса, Макет);
КонецЕсли;
Возврат Макет;
КонецФункции
// <Описание функции>
//
// Параметры:
// <Параметр1> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>.
//
// Возвращаемое значение:
// - <Тип.Вид> - <описание значения>
// <продолжение описания значения>;
// <Значение2> - <Тип.Вид> - <описание значения>
// <продолжение описания значения>.
//
Функция ПолучитьТекстМодуляВнешнейОбработкиАлгоритма(ФайлВнешнейОбработки) Экспорт
Если Не ФайлВнешнейОбработки.Существует() Тогда
Возврат Неопределено;
КонецЕсли;
ТекстМодуля = ТекстМодуляСгенерированнойВнешнейОбработки(ФайлВнешнейОбработки);
Если ТекстМодуля = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
ТекстАлгоритма = ирОбщий.ТекстМеждуМаркерамиЛкс(ТекстМодуля, МаркерНачалаАлгоритма, МаркерКонцаАлгоритма);
Результат = "";
ТекстАлгоритмаТД = Новый ТекстовыйДокумент;
ТекстАлгоритмаТД.УстановитьТекст(ТекстАлгоритма);
Для Счетчик = 1 По ТекстАлгоритмаТД.КоличествоСтрок() Цикл
СтрокаАлгоритма = ТекстАлгоритмаТД.ПолучитьСтроку(Счетчик);
Если Лев(СтрокаАлгоритма, 1) = Символы.Таб Тогда
СтрокаАлгоритма = Сред(СтрокаАлгоритма, 2);
КонецЕсли;
Результат = Результат + СтрокаАлгоритма + Символы.ПС;
КонецЦикла;
Возврат Результат;
КонецФункции // ПолучитьТекстМодуляВнешнейОбработкиАлгоритма()
// <Описание функции>
//
// Параметры:
// <Параметр1> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>.
//
// Возвращаемое значение:
// - <Тип.Вид> - <описание значения>
// <продолжение описания значения>;
// <Значение2> - <Тип.Вид> - <описание значения>
// <продолжение описания значения>.
//
Функция ТекстМодуляСгенерированнойВнешнейОбработки(ФайлВнешнейОбработки) Экспорт
#Если Сервер И Не Сервер Тогда
ФайлВнешнейОбработки = Новый Файл;
#КонецЕсли
ИспользоватьБыструюРаспаковку = ЛиИспользоватьБыструюРаспаковкуВнешнейОбработки();
Если Не ИспользоватьБыструюРаспаковку Тогда
// Штатный способ платформы, но работает только на 8.3.8+
ТекстЛога = Неопределено;
ИмяВременногоФайла = ПолучитьИмяВременногоФайла();
Если Не ирОбщий.ВыполнитьКомандуКонфигуратораЛкс("/DumpExternalDataProcessorOrReportToFiles """ + ИмяВременногоФайла + """ """ + ФайлВнешнейОбработки.ПолноеИмя + """",, ТекстЛога, Истина) Тогда
УдалитьФайлы(ИмяВременногоФайла);
ирОбщий.СообщитьЛкс(ТекстЛога);
Возврат Ложь;
КонецЕсли;
Файлы = НайтиФайлы(ИмяВременногоФайла, "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 - если указан, будет открываться только в заданном процессе;
// *Переоткрыть - Булево, *Истина - переоткрыть, если уже открыт
//
Процедура ОткрытьМодульВнешнейОбработкиВКонфигураторе(ПолноеИмяФайла, НомерСтрокиВМодуле = 0, ИдентификаторПроцесса = 0, _Переоткрыть = Истина, ВнутреннееИмя = "") Экспорт
ФайлВнешнейОбработки = Новый Файл(ПолноеИмяФайла);
Если Ложь
Или ирКэш.НомерВерсииПлатформыЛкс() >= 803008 И ирКэш.НомерВерсииPowerShellЛкс() >= 3
Тогда
Если Не ЗначениеЗаполнено(ИдентификаторПроцесса) Тогда
ИдентификаторПроцесса = ВыбратьПроцессКонфигуратора();
Если ИдентификаторПроцесса = Неопределено Тогда
Возврат;
КонецЕсли;
КонецЕсли;
ТекстСкрипта = ПолучитьМакет("СкриптОткрытьМодульВнешнейОбработки");
ФайлСкрипта = Новый Файл(ПолучитьИмяВременногоФайла("ps1"));
ТекстСкрипта.Записать(ФайлСкрипта.ПолноеИмя);
СтрокаЗапуска = ирОбщий.КомандаСистемыЗапускаСкриптаPowerShellЛкс(ФайлСкрипта.Имя + " -processID " + ИдентификаторПроцесса + " -file """ + ПолноеИмяФайла + """");
Если НомерСтрокиВМодуле > 0 Тогда
СтрокаЗапуска = СтрокаЗапуска + " -line " + Формат(НомерСтрокиВМодуле, "ЧГ=");
КонецЕсли;
Если ЗначениеЗаполнено(ВнутреннееИмя) Тогда
СтрокаЗапуска = СтрокаЗапуска + " -internalName """ + ВнутреннееИмя + """";
КонецЕсли;
//РезультатКоманды = ирОбщий.ВыполнитьКомандуОСЛкс(СтрокаЗапуска); // Так возникает 20с ожидание на инструкции $mainWindow = $rootElement.FindFirst(...)
ЗапуститьПриложение(СтрокаЗапуска, КаталогВременныхФайлов());
Иначе
ПолучитьФайлОткрывателя1С();
СтрокаЗапуска = """" + ФайлОткрывателя1С.ПолноеИмя + """ -com -ob1""" + ФайлВнешнейОбработки.ПолноеИмя + """";
Если НомерСтрокиВМодуле > 0 Тогда
СтрокаЗапуска = СтрокаЗапуска + " -num" + Формат(НомерСтрокиВМодуле, "ЧГ=");
КонецЕсли;
Если ЗначениеЗаполнено(ИдентификаторПроцесса) Тогда
СтрокаЗапуска = СтрокаЗапуска + " -pid" + Формат(ИдентификаторПроцесса, "ЧГ=");
КонецЕсли;
//Если Переоткрыть Тогда
СтрокаЗапуска = СтрокаЗапуска + " -reopen";
//КонецЕсли;
WshShell().Run(СтрокаЗапуска, 0, Ложь);
КонецЕсли;
КонецПроцедуры
Функция ВыбратьПроцессКонфигуратора(Знач ИдентификаторыОтладчиков = Неопределено) Экспорт
Если ИдентификаторыОтладчиков = Неопределено Тогда
ИдентификаторыОтладчиков = ИдентификаторыПроцессовОтладчиков();
#Если Сервер И Не Сервер Тогда
ИдентификаторыОтладчиков = Новый Массив;
#КонецЕсли
КонецЕсли;
ТекстСкрипта = ПолучитьМакет("СкриптОткрытыеПриложения1С");
ФайлСкрипта = Новый Файл(ПолучитьИмяВременногоФайла("ps1"));
ТекстСкрипта.Записать(ФайлСкрипта.ПолноеИмя);
КомандаСистемыЗапускаСкрипта = ирОбщий.КомандаСистемыЗапускаСкриптаPowerShellЛкс(ФайлСкрипта.Имя);
РезультатСкрипта = ирОбщий.ВыполнитьКомандуОСЛкс(КомандаСистемыЗапускаСкрипта);
ТаблицаКонфигураторов = ирОбщий.ТаблицаИзСтрокиСРазделителемЛкс(РезультатСкрипта,,, Истина);
НачальноеЗначениеВыбора = Неопределено;
СписокКонфигураторов = Новый СписокЗначений;
Для Каждого СтрокаКонфигуратора Из ТаблицаКонфигураторов Цикл
ПроцессОС = ирОбщий.ПолучитьПроцессОСЛкс(СтрокаКонфигуратора.Id);
Если Не ирОбщий.ЛиПроцессОСКонфигуратораЛкс(ПроцессОС) Тогда
Продолжить;
КонецЕсли;
ПредставлениеПроцесса = СтрокаКонфигуратора.MainWindowTitle;
ЛиОтладчик = ИдентификаторыОтладчиков.Найти(СтрокаКонфигуратора.Id) <> Неопределено;
Если ЛиОтладчик Тогда
ПредставлениеПроцесса = "<Отладчик>" + ПредставлениеПроцесса;
КонецЕсли;
НовыйЭлемент = СписокКонфигураторов.Добавить(СтрокаКонфигуратора.Id, ПредставлениеПроцесса);
Если ЛиОтладчик Тогда
НачальноеЗначениеВыбора = НовыйЭлемент;
КонецЕсли;
КонецЦикла;
Если СписокКонфигураторов.Количество() = 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(мСвязанныйКонфигуратор.ИД);
ТекстДок = Новый ТекстовыйДокумент;
ТекстДок.УстановитьТекст(ПередаваемыйТекст);
ТекстДок.Записать(мСвязанныйКонфигуратор.ИмяФайлаБуфера);
КонецПроцедуры
// <Описание процедуры>
//
// Параметры:
// <Параметр1> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>.
//
Процедура СохранитьНастройкиАлгоритмов() Экспорт
//ирОбщий.СохранитьЗначениеЛкс("ирПлатформа.ФиксироватьВнешниеИсключенияАлгоритмов", ФиксироватьВнешниеИсключенияАлгоритмов);
ирОбщий.СохранитьЗначениеЛкс("ФиксироватьВнешниеИсключенияАлгоритмов", ФиксироватьВнешниеИсключенияАлгоритмов);
//ирОбщий.СохранитьЗначениеЛкс("ирПлатформа.СинтаксическийКонтрольПередЗаписью", СинтаксическийКонтрольПередЗаписью);
ирОбщий.СохранитьЗначениеЛкс("СинтаксическийКонтрольПередЗаписью", СинтаксическийКонтрольПередЗаписью);
//ирОбщий.СохранитьЗначениеЛкс("ирПлатформа.ВыполнятьАлгоритмыЧерезВнешниеОбработки", ВыполнятьАлгоритмыЧерезВнешниеОбработки);
ирОбщий.СохранитьЗначениеЛкс("ВыполнятьАлгоритмыЧерезВнешниеОбработки", ВыполнятьАлгоритмыЧерезВнешниеОбработки);
ирОбщий.СохранитьЗначениеЛкс("ФайловыйКэшАлгоритмовДопускаетРедактирование", ФайловыйКэшАлгоритмовДопускаетРедактирование);
//ирОбщий.СохранитьЗначениеЛкс("ирПлатформа.ПоказыватьВнешниеИсключенияПриВыполненииАлгоритмов", ПоказыватьВнешниеИсключенияПриВыполненииАлгоритмов);
ирОбщий.СохранитьЗначениеЛкс("ПоказыватьВнешниеИсключенияПриВыполненииАлгоритмов", ПоказыватьВнешниеИсключенияПриВыполненииАлгоритмов);
КонецПроцедуры // СохранитьНастройкиАлгоритмов()
Функция ТаблицаРедактируемыхТиповИзОписанияТипов(ОписаниеТипов = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
ОписаниеТипов = Новый ОписаниеТипов;
#КонецЕсли
ПоляКлюча = "Имя, 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
Если Парсер <> Неопределено Тогда
Парсер.TrimReductions = Истина;
МакетГрамматики = ПолучитьМакет(ИмяГрамматики);
ФайлСкомпилированнойГрамматики = ПолучитьИмяВременногоФайла("cgt");
МакетГрамматики.Записать(ФайлСкомпилированнойГрамматики);
Если Не Парсер.LoadCompiledGrammar(ФайлСкомпилированнойГрамматики) Тогда
ирОбщий.СообщитьСУчетомМодальностиЛкс("Не удалось загрузить файл грамматики """ + ФайлСкомпилированнойГрамматики + """",
Истина, СтатусСообщения.Важное);
Парсер = Неопределено;
КонецЕсли;
УдалитьФайлы(ФайлСкомпилированнойГрамматики);
Иначе
ирОбщий.СообщитьЛкс(СообщениеПользователюПриНеудаче, СтатусСообщения.Внимание);
КонецЕсли;
Если Кэшировать Тогда
Парсеры.Вставить(ИмяГрамматики, Парсер);
КонецЕсли;
Возврат Парсер;
КонецФункции
// <Описание процедуры>
//
// Параметры:
// <Параметр1> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>.
//
Процедура ПроверитьСтруктуруФайловогоКэша() Экспорт
ПроверитьКаталогФайловогоКэша();
СтруктураПодкаталоговФайловогоКэша = Новый Структура;
СтруктураПодкаталоговФайловогоКэша.Вставить("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
ВызватьИсключение "Нельзя использовать кириллические буквы в именах файлов внешних компонент";
КонецЕсли;
ФайлКомпоненты = ПроверитьЗаписатьКомпонентуИзМакетаВФайл(ИмяМакетаКомпоненты);
Местоположение = ФайлКомпоненты.ПолноеИмя;
Если ЗначениеЗаполнено(ИмяМакетаДополнительнойБиблиотеки) Тогда
ФайлДополнительнойБиблиотеки = ПроверитьЗаписатьКомпонентуИзМакетаВФайл(ИмяМакетаДополнительнойБиблиотеки);
КонецЕсли;
Успех = ПодключитьВнешнююКомпоненту(Местоположение, ИмяКомпоненты, ТипКомпоненты);
ПодключитьВнешнююКомпоненту(ИмяОбъекта);
Попытка
Результат = Новый (ИмяОбъекта);
Исключение
КонецПопытки;
КонецПопытки;
Возврат Результат;
КонецФункции
Функция ПроверитьЗаписатьКомпонентуИзМакетаВФайл(Знач ИмяМакетаКомпоненты, КаталогУстановки = "", Расширение = "dll") Экспорт
Если Не ЗначениеЗаполнено(КаталогУстановки) Тогда
КаталогУстановки = ПапкаВнешнихКомпонент.ПолноеИмя;
КонецЕсли;
ДвоичныеДанныеМакета = ПолучитьДвоичныеДанныеКомпоненты(ИмяМакетаКомпоненты);
ФайлКомпоненты = Новый Файл(КаталогУстановки + ирОбщий.РазделительПутиКФайлуЛкс() + ИмяМакетаКомпоненты + "." + Расширение);
ВременныйФайл = Новый Файл(ПолучитьИмяВременногоФайла());
Попытка
ДвоичныеДанныеМакета.Записать(ВременныйФайл.ПолноеИмя);
Исключение
ирОбщий.СообщитьЛкс("Не удалось создать временный файл компоненты """ + ИмяМакетаКомпоненты + """: " + ОписаниеОшибки(), СтатусСообщения.Внимание);
Возврат Неопределено;
КонецПопытки;
Счетчик = 1;
ФайлПодходит = Ложь;
Пока ФайлКомпоненты.Существует() Цикл
#Если Клиент Тогда
СравнениеФайлов = Новый СравнениеФайлов;
СравнениеФайлов.СпособСравнения = СпособСравненияФайлов.Двоичное;
СравнениеФайлов.ПервыйФайл = ВременныйФайл.ПолноеИмя;
СравнениеФайлов.ВторойФайл = ФайлКомпоненты.ПолноеИмя;
Если СравнениеФайлов.Сравнить() Тогда
ФайлПодходит = Истина;
Прервать;
КонецЕсли;
#Иначе
// Внешняя компонента может собираться с одинаковым размером (сборщик ее дополняет пустотой до нужного размера)
//Если ВременныйФайл.Размер() = ФайлКомпоненты.Размер() Тогда // Опасно. Переделать на Хэш
// ФайлПодходит = Истина;
// Прервать;
//КонецЕсли;
#КонецЕсли
Попытка
УдалитьФайлы(ФайлКомпоненты.ПолноеИмя);
Исключение
ФайлКомпоненты = Новый Файл(КаталогУстановки + ирОбщий.РазделительПутиКФайлуЛкс() + ИмяМакетаКомпоненты + "_" + Формат(Счетчик, "ЧГ=") + "." + Расширение);
Счетчик = Счетчик + 1;
КонецПопытки;
КонецЦикла;
Если Не ФайлПодходит Тогда
Попытка
ПереместитьФайлКакАдминистратор(ВременныйФайл.ПолноеИмя, ФайлКомпоненты.ПолноеИмя);
Исключение
УдалитьФайлы(ВременныйФайл.ПолноеИмя);
ирОбщий.СообщитьЛкс("Файл """ + ФайлКомпоненты.ПолноеИмя + """ недоступен для изменения и не был перезаписан.", СтатусСообщения.Внимание);
Возврат Неопределено;
КонецПопытки;
КонецЕсли;
Возврат ФайлКомпоненты;
КонецФункции
// Способ через ZIP архив (32+64) появился только в 8.3
Функция ПолучитьДвоичныеДанныеКомпоненты(БазовоеИмяМакетаКомпоненты) Экспорт
Если Метаданные().Макеты.Найти(БазовоеИмяМакетаКомпоненты) = Неопределено Тогда
Если ирКэш.ЛиПлатформаWindowsЛкс() Тогда
БазовоеИмяМакетаКомпоненты = БазовоеИмяМакетаКомпоненты + "Win";
Иначе
БазовоеИмяМакетаКомпоненты = БазовоеИмяМакетаКомпоненты + "Lin";
КонецЕсли;
Если ирКэш.Это64битныйПроцессЛкс() Тогда
БазовоеИмяМакетаКомпоненты = БазовоеИмяМакетаКомпоненты + "64";
Иначе
БазовоеИмяМакетаКомпоненты = БазовоеИмяМакетаКомпоненты + "32";
КонецЕсли;
КонецЕсли;
ДвоичныеДанныеМакета = ПолучитьМакет(БазовоеИмяМакетаКомпоненты);
Возврат ДвоичныеДанныеМакета;
КонецФункции
// <Описание функции>
//
// Параметры:
// <Параметр1> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>.
//
// Возвращаемое значение:
// - <Тип.Вид> - <описание значения>
// <продолжение описания значения>;
// <Значение2> - <Тип.Вид> - <описание значения>
// <продолжение описания значения>.
//
Функция СоздатьОбъектВнешнихМетаданных(ПолноеИмяФайла, МенеджерВнешнихОбъектов = Неопределено, Конвертировать = Истина) Экспорт
Если МенеджерВнешнихОбъектов = Неопределено Тогда
МенеджерВнешнихОбъектов = ВнешниеОбработки;
КонецЕсли;
Попытка
ВнешнийОбъект = МенеджерВнешнихОбъектов.Создать(ПолноеИмяФайла, Ложь);
Исключение
#Если Клиент Тогда
ОписаниеОшибки = ОписаниеОшибки();
Если Истина
И Конвертировать
И Найти(НРег(ОписаниеОшибки), НРег("не может быть прочитан")) > 0
//И ирКэш.НомерВерсииПлатформыЛкс() <> 802015 // Антибаг 8.2.15 http://partners.v8.1c.ru/forum/thread.jsp?id=1003164#1003164
Тогда
СтрокаЗапуска = "DESIGNER /ConvertFiles""" + ПолноеИмяФайла + """";
ЗапуститьСистему(СтрокаЗапуска, Истина);
ВнешнийОбъект = МенеджерВнешнихОбъектов.Создать(ПолноеИмяФайла, Ложь);
Иначе
#КонецЕсли
ВызватьИсключение;
#Если Клиент Тогда
КонецЕсли;
#КонецЕсли
КонецПопытки;
Возврат ВнешнийОбъект;
КонецФункции
// <Описание функции>
//
// Параметры:
// <Параметр1> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>.
//
// Возвращаемое значение:
// - <Тип.Вид> - <описание значения>
// <продолжение описания значения>;
// <Значение2> - <Тип.Вид> - <описание значения>
// <продолжение описания значения>.
//
Функция СоздатьВнешнююОбработкуАлгоритма(АлгоритмОбъект, ПолноеИмя) Экспорт
Попытка
ВнешняяОбработка = СоздатьОбъектВнешнихМетаданных(ПолноеИмя);
Результат = ВнешняяОбработка;
Исключение
ИнформацияОбОшибке = ИнформацияОбОшибке();
ОписаниеОшибки = ирОбщий.ПодробноеПредставлениеОшибкиЛкс(ИнформацияОбОшибке);
Если Найти(НРег(ОписаниеОшибки), НРег("не может быть прочитана текущей версией")) > 0 Тогда
УдалитьФайлы(ПолноеИмя);
КонецЕсли;
СобытиеОшибки = "Ошибка создания внешнего объекта";
ОписаниеОшибки = "Загрузка сервиса """ + АлгоритмОбъект.Наименование + """";
Если ИнформацияОбОшибке.Причина <> Неопределено Тогда
ОписаниеОшибки = ОписаниеОшибки + "
|" + ПредставлениеИнформацииОбОшибке(ИнформацияОбОшибке.Причина);
КонецЕсли;
ОписаниеОшибки = СобытиеОшибки + ": " + ОписаниеОшибки;
ОписаниеОшибки = ОписаниеОшибки + ": " + ИнформацияОбОшибке.Описание
+ Символы.ПС + ИнформацияОбОшибке.ИсходнаяСтрока;
ирОбщий.СообщитьЛкс(ОписаниеОшибки, СтатусСообщения.Важное);
ЗаписьЖурналаРегистрации(СобытиеОшибки, УровеньЖурналаРегистрации.Ошибка, Метаданные.НайтиПоТипу(ТипЗнч(АлгоритмОбъект.Ссылка)),
АлгоритмОбъект.Ссылка, ОписаниеОшибки);
Результат = Неопределено;
КонецПопытки;
Возврат Результат;
КонецФункции // СоздатьВнешнююОбработкуАлгоритма()
// Проверяет актуальность кэша. Вызывается когда кэш в памяти уже точно не соотвествует объекту БД.
//
// Параметры:
// <Параметр1> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>.
//
// Возвращаемое значение:
// - <Тип.Вид> - <описание значения>
// <продолжение описания значения>;
// <Значение2> - <Тип.Вид> - <описание значения>
// <продолжение описания значения>.
//
Функция ПроверитьАктуальностьКэшаВнешнейОбработки(ЭлементКэша, ДатаИзмененияКэша, ФайлВнешнейОбработки, ДатаИзмененияОбъекта,
КэшВнешнейОбработкиАктуален, ФайлВнешнейОбработкиАктуален, ФайловыйКэшДопускаетРедактирование) Экспорт
Попытка
ДатаИзмененияФайла = ФайлВнешнейОбработки.ПолучитьВремяИзменения() + ирКэш.ПолучитьСмещениеВремениЛкс();
ФайлВнешнейОбработкиСуществует = Истина;
Исключение
ФайлВнешнейОбработкиСуществует = Ложь;
КонецПопытки;
Если ФайлВнешнейОбработкиСуществует Тогда
Если Истина
И ЭлементКэша <> Неопределено
И ЭлементКэша.ДатаИзменения >= ДатаИзмененияФайла
И ЭлементКэша.ДатаИзменения >= ДатаИзмененияОбъекта
Тогда
КэшВнешнейОбработкиАктуален = Истина;
ИначеЕсли Ложь
Или (Истина
И ЭлементКэша = Неопределено
И ДатаИзмененияФайла = ДатаИзмененияОбъекта)
Или (Истина
И ЭлементКэша <> Неопределено
И ДатаИзмененияФайла = ЭлементКэша.ДатаИзменения
И ДатаИзмененияФайла = ДатаИзмененияОбъекта)
Или (Истина
И ФайловыйКэшДопускаетРедактирование
И (Ложь
Или (Истина
И ЭлементКэша = Неопределено
И ДатаИзмененияФайла >= ДатаИзмененияОбъекта)
Или (Истина
И ЭлементКэша <> Неопределено
И ДатаИзмененияФайла >= ЭлементКэша.ДатаИзменения
И ДатаИзмененияФайла >= ДатаИзмененияОбъекта)))
Тогда
ФайлВнешнейОбработкиАктуален = Истина;
ДатаИзмененияКэша = ДатаИзмененияФайла;
КонецЕсли;
КонецЕсли;
КонецФункции // ПроверитьАктуальностьКэшаВнешнейОбработки()
// <Описание процедуры>
//
// Параметры:
// <Параметр1> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>.
//
Функция РазвернутьНовыйШаблонВнешнейОбработки(СМакетом = Ложь, ГлобальныйКлюч = Неопределено,
ФайлСИменем, ТекстПотокаСИменем, Знач ДляИДВерсииПлатформы = "") Экспорт
Если ПустаяСтрока(ДляИДВерсииПлатформы) Тогда
ДляИДВерсииПлатформы = ирКэш.НомерИзданияПлатформыЛкс();
КонецЕсли;
Если ДляИДВерсииПлатформы = "83" Тогда
ДляИДВерсииПлатформы = "82";
КонецЕсли;
Если ГлобальныйКлюч = Неопределено Тогда
ГлобальныйКлюч = "" + Новый УникальныйИдентификатор;
КонецЕсли;
лПутьКШаблонуВнешнейОбработки = ПутьККаталогуСлужебныхВременныхФайлов + ГлобальныйКлюч;
Файл = Новый Файл(ПолучитьИмяВременногоФайла());
//ПолучитьМакет("ВнешняяОбработка").Записать(Файл.ПолноеИмя);
Если СМакетом Тогда
ИмяМакета = "ШаблонВнешнейОбработкиСМакетом";
Иначе
ИмяМакета = "ШаблонВнешнейОбработкиСервиса";
КонецЕсли;
ИмяМакета = ИмяМакета + ДляИДВерсииПлатформы;
ПолучитьМакет(ИмяМакета).Записать(Файл.ПолноеИмя);
Чтение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;
КонецЕсли;
Возврат ИспользоватьБыстрыйГенератор;
КонецФункции
// <Описание функции>
//
// Параметры:
// <Параметр1> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>.
//
// Возвращаемое значение:
// - <Тип.Вид> - <описание значения>
// <продолжение описания значения>;
// <Значение2> - <Тип.Вид> - <описание значения>
// <продолжение описания значения>.
//
Функция СформироватьВнешнююОбработку(Знач ФайлОбработки, Знач ИмяОбработки, Знач ТекстМодуля, Знач ТекстМакета = Неопределено, Знач ДляИДВерсииПлатформы = "", ИспользоватьБыструюРаспаковку = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
ФайлОбработки = Новый файл;
#КонецЕсли
//Если ИспользоватьБыструюРаспаковку = Неопределено Тогда
// ИспользоватьБыструюРаспаковку = ЛиИспользоватьБыструюРаспаковкуВнешнейОбработки();
//КонецЕсли;
ИспользоватьБыструюРаспаковку = Истина; // используется шаблон с макетом, то там надо добавить файл versions.data.und - https://github.com/e8tools/v8unpack/issues/69
Если Не ИспользоватьБыструюРаспаковку Тогда
// Штатный способ платформы, но работает только на 8.3.8+
Если ТекстМакета <> Неопределено Тогда
ВызватьИсключение "Парамер ТекстМакета для 8.3.11+ не поддерживается";
КонецЕсли;
ШаблонВнешнейОбработки = ШаблоныВнешнейОбработки["8"];
Если ШаблонВнешнейОбработки = Неопределено Тогда
ИмяВременногоФайла = ПолучитьИмяВременногоФайла("epf");
ПолучитьМакет("ВнешняяОбработка").Записать(ИмяВременногоФайла);
ШаблонВнешнейОбработки = ПолучитьИмяВременногоФайла();
СоздатьКаталог(ШаблонВнешнейОбработки);
ТекстЛога = Неопределено;
Если Не ирОбщий.ВыполнитьКомандуКонфигуратораЛкс("/DumpExternalDataProcessorOrReportToFiles """ + ШаблонВнешнейОбработки + """ """ + ИмяВременногоФайла + """",, ТекстЛога, Истина,,,,,,, Ложь) Тогда
УдалитьФайлы(ШаблонВнешнейОбработки);
УдалитьФайлы(ИмяВременногоФайла);
ирОбщий.СообщитьЛкс(ТекстЛога);
Возврат Ложь;
КонецЕсли;
ШаблоныВнешнейОбработки["8"] = ШаблонВнешнейОбработки;
КонецЕсли;
Файлы = НайтиФайлы(ШаблонВнешнейОбработки, "ObjectModule.bsl", Истина);
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.УстановитьТекст(ТекстМодуля);
ТекстовыйДокумент.Записать(Файлы[0].ПолноеИмя);
ТекстЛога = Неопределено;
ИмяКорневогоФайла = ШаблонВнешнейОбработки + ирОбщий.РазделительПутиКФайлуЛкс() + "ИмяВнешнейОбработки.xml";
Если ЗначениеЗаполнено(ИмяОбработки) Тогда
ПотокСИменемОбработки = Новый ТекстовыйДокумент;
ПотокСИменемОбработки.Прочитать(ИмяКорневогоФайла);
ПотокСИменемОбработки.УстановитьТекст(СтрЗаменить(ПотокСИменемОбработки.ПолучитьТекст(), "ИмяВнешнейОбработки", ИмяОбработки));
ПотокСИменемОбработки.Записать(ИмяКорневогоФайла);
КонецЕсли;
Если Не ирОбщий.ВыполнитьКомандуКонфигуратораЛкс("/LoadExternalDataProcessorOrReportFromFiles """ + ИмяКорневогоФайла + """ """ + ФайлОбработки.ПолноеИмя + """", , ТекстЛога, Истина,,,,,,, Ложь) Тогда
УдалитьФайлы(ШаблонВнешнейОбработки);
УдалитьФайлы(ИмяВременногоФайла);
ирОбщий.СообщитьЛкс(ТекстЛога);
Возврат Ложь;
КонецЕсли;
Результат = Истина;
Иначе
Если ПустаяСтрока(ДляИДВерсииПлатформы) Тогда
ДляИДВерсииПлатформы = ирКэш.НомерИзданияПлатформыЛкс();
КонецЕсли;
Если ДляИДВерсииПлатформы = "83" Тогда
ДляИДВерсииПлатформы = "82";
КонецЕсли;
Если ТекстМакета <> Неопределено Тогда
ШаблонВнешнейОбработкиСМакетом = ШаблоныВнешнейОбработкиСМакетом[ДляИДВерсииПлатформы];
Если ШаблонВнешнейОбработкиСМакетом = Неопределено Тогда
ШаблонВнешнейОбработкиСМакетом = Новый Структура("Путь, ФайлСИменем, ФайлЗамок, ТекстПотокаСИменем");
ШаблонВнешнейОбработкиСМакетом.Путь = РазвернутьНовыйШаблонВнешнейОбработки(Истина,,
ШаблонВнешнейОбработкиСМакетом.ФайлСИменем, ШаблонВнешнейОбработкиСМакетом.ТекстПотокаСИменем, ДляИДВерсииПлатформы);
ФайлЗамокШаблонаСМакетом = Новый ЗаписьТекста;
ФайлЗамокШаблонаСМакетом.Открыть(ШаблонВнешнейОбработкиСМакетом.Путь + ".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");
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ЭлементКэша <> Неопределено Тогда
Результат = ЭлементКэша.ВнешняяОбработка;
Иначе
Результат = Неопределено;
КонецЕсли;
Возврат Результат;
КонецФункции // ПолучитьВнешнююОбработкуПоАлгоритму()
Функция ЕстьАдминистративныеПраваУУчетнойЗаписиОС() Экспорт
Если мЕстьАдминистративныеПраваУУчетнойЗаписиОС <> Неопределено Тогда
Возврат мЕстьАдминистративныеПраваУУчетнойЗаписиОС;
КонецЕсли;
Попытка
Network = Новый COMОбъект("WScript.Network");
Исключение
// Например Linux
ОписаниеОшибки = ОписаниеОшибки();
Возврат Ложь;
КонецПопытки;
//ПользовательОС = Network.UserDomain + "\" + Network.UserName;
ПользовательОС = Network.UserName;
КомандаСистемы = "Net user " + ПользовательОС;
РезультатКоманды = ТекстРезультатаКомандыСистемы(КомандаСистемы);
мЕстьАдминистративныеПраваУУчетнойЗаписиОС = Ложь
Или Найти(РезультатКоманды, "Администраторы") > 0
Или Найти(РезультатКоманды, "Administrators") > 0;
Возврат мЕстьАдминистративныеПраваУУчетнойЗаписиОС;
КонецФункции
Функция ПереместитьФайлКакАдминистратор(ИмяИсточника, ИмяПриемника) Экспорт
Успех = Истина;
Попытка
//ПереместитьФайл(ИмяИсточника, ИмяПриемника); // так не работает наследование прав от каталога-приемника!
КопироватьФайл(ИмяИсточника, ИмяПриемника);
Исключение
ОписаниеОшибки = ОписаниеОшибки();
КонецПопытки;
Если ОписаниеОшибки <> Неопределено Тогда
//КомандаСистемы = "cmd.exe /c move """ + ИмяИсточника + """ """ + ИмяПриемника + """"; // так не работает наследование прав от каталога-приемника!
КомандаСистемы = "cmd.exe /c copy """ + ИмяИсточника + """ """ + ИмяПриемника + """";
ОписаниеОшибки = ТекстРезультатаКомандыСистемы(КомандаСистемы,, Истина);
// При успехе возвращает:
// Скопировано файлов: 1.
Если Найти(ОписаниеОшибки, "1") = 0 Тогда
ВызватьИсключение "Ошибка доступа к файлу """ + ИмяПриемника + """: " + ОписаниеОшибки;
КонецЕсли;
КонецЕсли;
Если Успех Тогда
Попытка
УдалитьФайлы(ИмяИсточника);
Исключение
КомандаСистемы = "cmd.exe /c del """ + ИмяИсточника + """";
ОписаниеОшибки = ТекстРезультатаКомандыСистемы(КомандаСистемы,, Истина);
// При успехе возвращает пустую строку
Если Не ПустаяСтрока(ОписаниеОшибки) Тогда
ВызватьИсключение "Ошибка доступа к файлу """ + ИмяИсточника + """: " + ОписаниеОшибки;
КонецЕсли;
КонецПопытки;
КонецЕсли;
Возврат Успех;
КонецФункции
Функция ПолучитьПолноеИмяКомпьютераСетиПоЛюбомуИмени(ИмяКомпьютера) Экспорт
ФайлРезультата = Новый Файл(ПолучитьИмяВременногоФайла());
ирОбщий.ЗапуститьСкрытоеПриложениеИДождатьсяЗавершенияЛкс("nslookup " + ИмяКомпьютера, ФайлРезультата.Путь, ФайлРезультата.Имя);
Если Не ФайлРезультата.Существует() Тогда
ПолноеИмяКомпьютера = "";
Иначе
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.Прочитать(ФайлРезультата.ПолноеИмя);
УдалитьФайлы(ФайлРезультата.ПолноеИмя);
ТекстРезультата = ТекстовыйДокумент.ПолучитьТекст();
RegExp.IgnoreCase = Истина;
RegExp.Pattern = "(?:name|имя|╚ь ):\s*([-" + шБукваЦифра + "]+(\.([-" + шБукваЦифра + "]+))*)\s*";
Результат = RegExp.НайтиВхождения(ТекстРезультата);
Если Результат.Количество() > 0 Тогда
ПолноеИмяКомпьютера = Результат[0].SubMatches(0);
Иначе
ПолноеИмяКомпьютера = "";
КонецЕсли;
КонецЕсли;
//ASPDNS = ПолучитьCOMОбъектИзМакета("ASPDNS", "ASPDNS.DNSLookup");
//IP = ASPDNS.GetIPFromName(ИмяКомпьютера);
//ПолноеИмяКомпьютера = ASPDNS.GetNameFromIP(IP);
Возврат ПолноеИмяКомпьютера;
КонецФункции
Функция ПроверитьКаталогФайловогоКэша() Экспорт
//http://www.hostedredmine.com/issues/851201
//СтрокаСоединения = ирКэш.СтрокаСоединенияСервераЛкс();
СтрокаСоединения = СтрокаСоединенияИнформационнойБазы();
КаталогВерсииПлатформыВПрофиле = ирКэш.КаталогИзданияПлатформыВПрофилеЛкс();
КаталогФайловогоКэша = КаталогВерсииПлатформыВПрофиле + ирОбщий.РазделительПутиКФайлуЛкс() + ирОбщий.ИдентификаторИзПредставленияЛкс(СтрокаСоединения);
ПапкаФайловогоКэша = Новый Файл(КаталогФайловогоКэша);
Если Не ПапкаФайловогоКэша.Существует() Тогда
Попытка
СоздатьКаталог(ПапкаФайловогоКэша.ПолноеИмя);
ПробныйФайл = Новый ТекстовыйДокумент;
ПробныйФайл.Записать(ПапкаФайловогоКэша.ПолноеИмя + ирОбщий.РазделительПутиКФайлуЛкс() + "1.txt");
Исключение
ОписаниеОшибки = ОписаниеОшибки();
Сообщить("Файловые кэши отключены из-за ошибки: " + ОписаниеОшибки, СтатусСообщения.Важное); // При использовании ирОбщий.СообщитьЛкс() может происходить переполнение стека
ВыполнятьАлгоритмыЧерезВнешниеОбработки = Ложь;
Возврат Ложь;
КонецПопытки;
КонецЕсли;
Возврат Истина;
КонецФункции
Функция НастройкиКомпьютера() Экспорт
Если НастройкиКомпьютера = Неопределено Тогда
ФайлаНастроекКомпьютера = Новый Файл(ИмяФайлаНастроекКомпьютера());
Если ФайлаНастроекКомпьютера.Существует() Тогда
НастройкиКомпьютера = ирОбщий.ЗагрузитьЗначениеИзФайлаЛкс(ФайлаНастроекКомпьютера.ПолноеИмя);
Если НастройкиКомпьютера <> Неопределено Тогда
ЗначениеНастройки = НастройкиКомпьютера["ПапкаКэшаМодулей"];
ЗначениеНастройки = Новый Файл(ЗначениеНастройки);
Если ЗначениеНастройки.Существует() Тогда
ПапкаКэшаМодулей = ЗначениеНастройки;
КонецЕсли;
ЗначениеНастройки = НастройкиКомпьютера["ПапкаКэшаРолей"];
ЗначениеНастройки = Новый Файл(ЗначениеНастройки);
Если ЗначениеНастройки.Существует() Тогда
ПапкаКэшаРолей = ЗначениеНастройки;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если НастройкиКомпьютера = Неопределено Тогда
НастройкиКомпьютера = Новый Соответствие;
КонецЕсли;
Возврат НастройкиКомпьютера;
КонецФункции
Процедура СохранитьНастройкиКомпьтера() Экспорт
ИмяФайлаНастроекКомпьютера = ИмяФайлаНастроекКомпьютера();
ирОбщий.СохранитьЗначениеВФайлЛкс(НастройкиКомпьютера, ИмяФайлаНастроекКомпьютера);
КонецПроцедуры
Функция ИмяФайлаНастроекКомпьютера()
ПапкаФайловогоКэша = Новый Файл(КаталогФайловогоКэша);
ИмяФайлаНастроекКомпьютера = ПапкаФайловогоКэша.ПолноеИмя + ирОбщий.РазделительПутиКФайлуЛкс() + "ComputerSettings.xml";
Возврат ИмяФайлаНастроекКомпьютера;
КонецФункции
Функция ИмяНеопределеннойПеременнойИзИнформацииОбОшибке(ИнформацияОбОшибке, СообщитьНеобрабатываемуюОшибку = Ложь) Экспорт
Если ИнформацияОбОшибке <> Неопределено Тогда
RegExp.Global = Ложь;
//ОписаниеОшибки = ирОбщий.ПодробноеПредставлениеОшибкиЛкс(ИнформацияОбОшибке);
Пока ИнформацияОбОшибке.Причина <> Неопределено Цикл // Добавлено 26.07.2011 из-за доработки синтаксического контроля в COM сеансе
ИнформацияОбОшибке = ИнформацияОбОшибке.Причина;
КонецЦикла;
ОписаниеОшибки = ИнформацияОбОшибке.Описание;
RegExp.Pattern = "(?:Переменная не определена |Variable is not defined )\(([_0-9" + шБуква + "]+)\)";
Результат = RegExp.НайтиВхождения(ОписаниеОшибки);
Если Результат.Количество() > 0 Тогда
ИмяПеременнойРезультата = Результат[0].SubMatches(0);
Иначе
Если СообщитьНеобрабатываемуюОшибку Тогда
ирОбщий.СообщитьЛкс(ирОбщий.ПодробноеПредставлениеОшибкиЛкс(ИнформацияОбОшибке), СтатусСообщения.Важное);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат ИмяПеременнойРезультата;
КонецФункции
Функция ИмяНеопределенногоМетодаИзИнформацииОбОшибке(ИнформацияОбОшибке, СообщитьНеобрабатываемуюОшибку = Ложь) Экспорт
Если ИнформацияОбОшибке <> Неопределено Тогда
RegExp.Global = Ложь;
//ОписаниеОшибки = ирОбщий.ПодробноеПредставлениеОшибкиЛкс(ИнформацияОбОшибке);
Пока ИнформацияОбОшибке.Причина <> Неопределено Цикл // Добавлено 26.07.2011 из-за доработки синтаксического контроля в COM сеансе
ИнформацияОбОшибке = ИнформацияОбОшибке.Причина;
КонецЦикла;
ОписаниеОшибки = ИнформацияОбОшибке.Описание;
RegExp.Pattern = "(?:Процедура или функция с указанным именем не определена |TODO_xxxx9469326459823 )\(([_0-9" + шБуква + "]+)\)";
Результат = RegExp.НайтиВхождения(ОписаниеОшибки);
Если Результат.Количество() > 0 Тогда
ИмяМетодаРезультата = Результат[0].SubMatches(0);
Иначе
Если СообщитьНеобрабатываемуюОшибку Тогда
ирОбщий.СообщитьЛкс(ирОбщий.ПодробноеПредставлениеОшибкиЛкс(ИнформацияОбОшибке), СтатусСообщения.Важное);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат ИмяМетодаРезультата;
КонецФункции
#Если Клиент Или ВнешнееСоединение Тогда
// Выполняет алгоритм по ссылке.
//
// Параметры:
// <Параметр1> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>.
//
// Возвращаемое значение:
// - <Тип.Вид> - <описание значения>
// <продолжение описания значения>;
// <Значение2> - <Тип.Вид> - <описание значения>
// <продолжение описания значения>.
//
Функция ВыполнитьАлгоритм(СсылкаАлгоритма, СтруктураПараметров = Неопределено) Экспорт
Если СтруктураПараметров = Неопределено Тогда
СтруктураПараметров = Новый Структура;
КонецЕсли;
АлгоритмОбъект = Неопределено;
Если Не КешАлгоритмов.Свойство(СсылкаАлгоритма, АлгоритмОбъект) Тогда
АлгоритмОбъект = СсылкаАлгоритма.ПолучитьОбъект();
КешАлгоритмов.Вставить(СсылкаАлгоритма, АлгоритмОбъект);
КонецЕсли;
Результат = ВыполнитьМетодАлгоритма(АлгоритмОбъект, 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;
КонецЕсли;
ПолеТекстаПрограммы = мПоляТекстаПрограммы[ЯзыкПрограммы];
Если ПолеТекстаПрограммы = Неопределено Тогда
ПолеТекстаПрограммы = ирОбщий.НовыйАнализаторКодаЛкс();
#Если Сервер И Не Сервер Тогда
ПолеТекстаПрограммы = Обработки.ирКлсПолеТекстаПрограммы.Создать();
#КонецЕсли
ПолеТекстаПрограммы.ИнициироватьНеинтерактивно(ЯзыкПрограммы);
ПолеТекстаПрограммы.ЭтоМодуль = Истина;
мПоляТекстаПрограммы[ЯзыкПрограммы] = ПолеТекстаПрограммы;
КонецЕсли;
Возврат ПолеТекстаПрограммы;
КонецФункции
#КонецЕсли
Функция ПредставлениеПустогоЗначенияЛкс(ПустоеЗначение) Экспорт
Если ПустоеЗначение = Неопределено Тогда
Результат = "<Неопределено>";
Иначе
Результат = мКэшПустыхЗначений[ПустоеЗначение];
Если Результат = Неопределено Тогда
Если ПустоеЗначение = Null Тогда
Результат = "<Null>";
ИначеЕсли ТипЗнч(ПустоеЗначение) = Тип("Булево") И ПустоеЗначение = Ложь Тогда
//Результат = "<Булево: Нет>";
Результат = "" + ПустоеЗначение;
ИначеЕсли ПустоеЗначение = "" Тогда
Результат = "<Строка>";
ИначеЕсли ПустоеЗначение = 0 Тогда
//Результат = "<Пустое число>";
Результат = Формат(ПустоеЗначение, "ЧН=");
ИначеЕсли ПустоеЗначение = Дата("00010101") Тогда
Результат = "<Дата>";
ИначеЕсли ТипЗнч(ПустоеЗначение) = Тип("УникальныйИдентификатор") Тогда
Результат = "<Идентификатор>";
ИначеЕсли ТипЗнч(ПустоеЗначение) = Тип("Картинка") Тогда
Результат = "<Картинка>";
Иначе
ОбъектМД = ирОбщий.ПолучитьМетаданныеЛкс(ПустоеЗначение);
Если ОбъектМД <> Неопределено Тогда
Результат = "<" + ОбъектМД.ПолноеИмя() + ".Ссылка>";
КонецЕсли;
КонецЕсли;
мКэшПустыхЗначений[ПустоеЗначение] = Результат;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
// Возвращает текущее время в миллисекундах.
//
// Параметры:
// Нет.
//
// Возвращаемое значение:
// Число.
//
Функция ПолучитьТекущееВремяВМиллисекундах() Экспорт
Если ирКэш.НомерИзданияПлатформыЛкс() >= "83" Тогда
Результат = Вычислить("ТекущаяУниверсальнаяДатаВМиллисекундах()");
КонецЕсли;
Если Результат = Неопределено Тогда
Если JavaScript = Неопределено Тогда
Попытка
JavaScript = Новый COMОбъект("MSScriptControl.ScriptControl");
Исключение
ирОбщий.СообщитьЛкс("Ошибка создания MSScriptControl.ScriptControl: " + ОписаниеОшибки(), СтатусСообщения.Внимание);
Возврат 0;
КонецПопытки;
JavaScript.Language = "javascript";
КонецЕсли;
Результат = JavaScript.Eval("new Date().getTime()");
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПроверитьПолучитьОбъектСервиса(Знач АлгоритмОбъект) Экспорт
Если ТипЗнч(АлгоритмОбъект) = Тип("СтрокаТаблицыЗначений") Тогда
лОбъект = АлгоритмОбъект.ЭтотОбъект;
Если лОбъект = Неопределено Тогда
лОбъект = АлгоритмОбъект.Ссылка.ПолучитьОбъект();
ЗаполнитьЗначенияСвойств(лОбъект, АлгоритмОбъект, , "ЭтотОбъект, Ссылка, мПолнаяТаблицаПараметров"); ////%!%
АлгоритмОбъект.ЭтотОбъект = лОбъект;
КонецЕсли;
АлгоритмОбъект = лОбъект;
КонецЕсли;
Возврат АлгоритмОбъект;
КонецФункции // ПроверитьПолучитьОбъектСервиса()
Функция ПредставлениеИнформацииОбОшибке(Знач ИнформацияОбОшибке) Экспорт
// Антибаг платформы. В описании повторяется причина и описание между уровнями. В общем бардак.
ОписаниеОшибки = ИнформацияОбОшибке.Описание;
Если ИнформацияОбОшибке.Причина <> Неопределено Тогда
Пока Истина
И ИнформацияОбОшибке.Причина <> Неопределено
И ИнформацияОбОшибке.Описание = ОписаниеОшибки
Цикл
ИнформацияОбОшибке = ИнформацияОбОшибке.Причина;
КонецЦикла;
Если ИнформацияОбОшибке.Описание <> ОписаниеОшибки Тогда
ОписаниеОшибки = ОписаниеОшибки + Символы.ПС + ПредставлениеИнформацииОбОшибке(ИнформацияОбОшибке);
КонецЕсли;
Иначе
Фрагмент = ирОбщий.ПоследнийФрагментЛкс(ОписаниеОшибки, "по причине:" + Символы.ПС);
Позиция = Найти(ОписаниеОшибки, Фрагмент + Символы.ПС + "по причине:" + Символы.ПС + Фрагмент);
Если Позиция > 0 Тогда
ОписаниеОшибки = Лев(ОписаниеОшибки, Позиция) + Фрагмент;
КонецЕсли;
КонецЕсли;
Возврат ОписаниеОшибки;
КонецФункции // ПредставлениеИнформацииОбОшибке()
Функция ОбработатьВнешнееИсключениеАлгоритма(ДескрипторСервиса, ИнформацияОбОшибке, РежимВыполненияАлгоритма, Интерактивно = Истина) Экспорт
//СервисОбъект = ПроверитьПолучитьОбъектСервиса(ДескрипторСервиса);
// Такой прием применен для избежания обращения к БД внутри сломанной транзакции
Если ТипЗнч(ДескрипторСервиса) = Тип("СтрокаТаблицыЗначений") Тогда
лОбъект = ДескрипторСервиса.ЭтотОбъект;
Если лОбъект = Неопределено Тогда
//лОбъект = Справочники.Сервисы2iS.СоздатьЭлемент();
//ЗаполнитьЗначенияСвойств(лОбъект, ДескрипторСервиса, , "ЭтотОбъект, Ссылка, КэшПараметров");
лОбъект = Новый ("СправочникОбъект.Сервисы2iS");
ЗаполнитьЗначенияСвойств(лОбъект, ДескрипторСервиса, "мЗначенияПоУмолчанию, мВнешниеПараметры, мВнутренниеПараметры");
КонецЕсли;
СервисОбъект = лОбъект;
Иначе
СервисОбъект = ДескрипторСервиса;
КонецЕсли;
Если РежимВыполненияАлгоритма = 3 Тогда
Смещение = СервисОбъект.ПолучитьСтартовуюСтрокуАлгоритмаВРежиме2();
ИмяМодуляСервиса = "";
ИначеЕсли РежимВыполненияАлгоритма = 2 Тогда
Смещение = СервисОбъект.ПолучитьСтартовуюСтрокуАлгоритмаВТексте();
ИмяМодуляСервиса = "";
ИначеЕсли Ложь
Или РежимВыполненияАлгоритма = 1
Или РежимВыполненияАлгоритма = 0
Тогда
Смещение = СервисОбъект.ПолучитьСтартовуюСтрокуМетодаВМодуле();
ИмяМодуляСервиса = "ВнешняяОбработка." + ДескрипторСервиса.Наименование;
Если Ложь
Или ирКэш.НомерИзданияПлатформыЛкс() = "82"
Или ирКэш.НомерИзданияПлатформыЛкс() = "83"
Тогда
ИмяМодуляСервиса = ИмяМодуляСервиса + ".МодульОбъекта";
КонецЕсли;
КонецЕсли;
ПрефиксСервиса = "Сервис ";
Если ИмяМодуляСервиса = ИнформацияОбОшибке.ИмяМодуля Тогда
НомерСтрокиАлгоритма = ИнформацияОбОшибке.НомерСтроки;
НомерСтрокиАлгоритма = НомерСтрокиАлгоритма - Смещение;
ОписаниеОшибки = ПрефиксСервиса + """" + ДескрипторСервиса.Наименование + """[" + РежимВыполненияАлгоритма + "]{"
+ НомерСтрокиАлгоритма + "}:" + Символы.ПС + "==========================================================================" + Символы.ПС
+ ИнформацияОбОшибке.Описание + Символы.ПС + ИнформацияОбОшибке.ИсходнаяСтрока;
Иначе
ОписаниеОшибки = ПрефиксСервиса + """" + ДескрипторСервиса.Наименование + """[" + РежимВыполненияАлгоритма + "]";
МаркерСлужебногоИсключения = "ВызватьИсключение Ошибка;//#Служебное";
Если Найти(ИнформацияОбОшибке.ИсходнаяСтрока, МаркерСлужебногоИсключения) = 0 Тогда
ОписаниеОшибки = ОписаниеОшибки + "{" + ИнформацияОбОшибке.ИмяМодуля + "(" + ИнформацияОбОшибке.НомерСтроки + ")}: ";
КонецЕсли;
ОписаниеОшибки = ОписаниеОшибки + Символы.ПС + ИнформацияОбОшибке.Описание;
Если Найти(ИнформацияОбОшибке.ИсходнаяСтрока, МаркерСлужебногоИсключения) = 0 Тогда
ОписаниеОшибки = ОписаниеОшибки + Символы.ПС + ИнформацияОбОшибке.ИсходнаяСтрока;
КонецЕсли;
КонецЕсли;
Если ИнформацияОбОшибке.Причина <> Неопределено Тогда
ОписаниеОшибки = ОписаниеОшибки + "
|" + ПредставлениеИнформацииОбОшибке(ИнформацияОбОшибке.Причина);
КонецЕсли;
#Если Клиент Тогда
Если Интерактивно И ПоказыватьВнешниеИсключенияПриВыполненииАлгоритмов Тогда
Если Не ирКэш.ЛиПортативныйРежимЛкс() И ирКлиент.ЛиЕстьИнтерактивныйДоступКИнструментамЛкс() Тогда
Если Истина
И ОтложенноеОткрытиеИсточникаОшибки.Количество() > 0
И ОтложенноеОткрытиеИсточникаОшибки[0].АлгоритмОбъект = Неопределено // СтопСтрока
Тогда
// Не подключаем отложенное открытие, т.к. уже внутри него. Случается при ПолученииДанных
Иначе
СтрокаИсточникаОшибки = ОтложенноеОткрытиеИсточникаОшибки.Добавить();
СтрокаИсточникаОшибки.АлгоритмОбъект = ДескрипторСервиса.Ссылка;
СтрокаИсточникаОшибки.ИнформацияОбОшибке = ИнформацияОбОшибке;
СтрокаИсточникаОшибки.РежимВыполненияАлгоритма = РежимВыполненияАлгоритма;
СтрокаИсточникаОшибки.Смещение = Смещение;
ПодключитьОбработчикОжидания("ОтложенноеОткрытиеИсточникаОшибки", 0.1, Истина);
КонецЕсли;
//Возврат Символы.ПС + ОписаниеОшибки;
Иначе
ирОбщий.СообщитьЛкс(ОписаниеОшибки, СтатусСообщения.Важное);
КонецЕсли;
КонецЕсли;
#КонецЕсли
Возврат ОписаниеОшибки;
КонецФункции // ОбработатьВнешнееИсключениеАлгоритма()
// Выполняет алгоритм по объекту.
//
// Параметры:
// <Параметр1> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>.
//
Функция ВыполнитьМетодАлгоритма(ДескрипторСервиса, Режим, П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);
ВызватьИсключение Ошибка;//#Служебное
КонецПопытки;
Иначе
Результат = ВнешняяОбработкаАлгоритма.мМетод(ДескрипторСервиса, Режим, П0, П1, П2, П3, П4, П5, П6, П7, П8, П9);
КонецЕсли;
Иначе
//ирОбщий.СообщитьЛкс("Ошибка компиляции сервиса """ + ДескрипторСервиса.Наименование + """. Сервис не выполнен.", СтатусСообщения.Внимание);
ВызватьИсключение "Ошибка компиляции сервиса """ + ДескрипторСервиса.Наименование + """";
КонецЕсли;
Иначе
// Прямые вызовы
Если ФиксироватьВнешниеИсключенияАлгоритмов Тогда
Попытка
Результат = Вычислить("ВнешняяОбработкаСервисы._" + ДескрипторСервиса.Наименование
+ "(ДескрипторСервиса, Режим, П0, П1, П2, П3, П4, П5, П6, П7, П8, П9)");
Исключение
ИнформацияОбОшибке = ИнформацияОбОшибке();
Ошибка = ОбработатьВнешнееИсключениеАлгоритма(ДескрипторСервиса, ИнформацияОбОшибке, 0);
ВызватьИсключение Ошибка;//#Служебное
КонецПопытки;
Иначе
Результат = Вычислить("ВнешняяОбработкаСервисы._" + ДескрипторСервиса.Наименование
+ "(ДескрипторСервиса, Режим, П0, П1, П2, П3, П4, П5, П6, П7, П8, П9)");
КонецЕсли;
КонецЕсли;
Иначе
//#КонецЕсли
//#Если Не Клиент И Не ВнешнееСоединение Тогда
//ДескрипторСервиса.ирПлатформа = ЭтотОбъект;
//#КонецЕсли
СервисОбъект = ПроверитьПолучитьОбъектСервиса(ДескрипторСервиса);
#Если Сервер И Не Сервер Тогда
СервисОбъект = Обработки.ирИмитаторАлгоритмОбъект.Создать();
#КонецЕсли
ТекстАлгоритмаСПараметрами = СервисОбъект.ПолучитьТелоМетода();
Если ФиксироватьВнешниеИсключенияАлгоритмов Тогда
Попытка
Результат = ирОбщий.ВыполнитьАлгоритм(ТекстАлгоритмаСПараметрами, СервисОбъект, Режим, П0, П1, П2, П3, П4, П5, П6, П7, П8, П9);
Исключение
ИнформацияОбОшибке = ИнформацияОбОшибке();
Ошибка = ОбработатьВнешнееИсключениеАлгоритма(СервисОбъект, ИнформацияОбОшибке, 2);
ВызватьИсключение Ошибка;//#Служебное
КонецПопытки;
Иначе
Результат = ирОбщий.ВыполнитьАлгоритм(ТекстАлгоритмаСПараметрами, СервисОбъект, Режим, П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;
КонецФункции
Процедура ПрочитатьОбщиеНастройки()
ОбщиеНастройки = ирОбщий.ВосстановитьЗначениеЛкс("ОбщиеНастройки");
Если ОбщиеНастройки = Неопределено Тогда
// Старый формат настроек
ФайловыйКэшАлгоритмовДопускаетРедактирование = ирОбщий.ВосстановитьЗначениеЛкс("ФайловыйКэшАлгоритмовДопускаетРедактирование");
АвторегистрацияComКомпонент = ирОбщий.ВосстановитьЗначениеЛкс("АвторегистрацияComКомпонент");
ПерехватКлавиатурногоВводаВОбычномПриложении = ирОбщий.ВосстановитьЗначениеЛкс("ПерехватКлавиатурногоВводаВОбычномПриложении");
ВыделениеРезультатовПоиска = ирОбщий.ВосстановитьЗначениеЛкс("ВыделениеРезультатовПоиска");
НеИспользоватьУправляемыеФормыИнструментов = ирОбщий.ВосстановитьЗначениеЛкс("НеИспользоватьУправляемыеФормыИнструментов");
Иначе
ФайловыйКэшАлгоритмовДопускаетРедактирование = ОбщиеНастройки.ФайловыйКэшАлгоритмовДопускаетРедактирование;
АвторегистрацияComКомпонент = ОбщиеНастройки.АвторегистрацияComКомпонент;
ПерехватКлавиатурногоВводаВОбычномПриложении = ОбщиеНастройки.ПерехватКлавиатурногоВводаВОбычномПриложении;
ВыделениеРезультатовПоиска = ОбщиеНастройки.ВыделениеРезультатовПоиска;
НеИспользоватьУправляемыеФормыИнструментов = ОбщиеНастройки.НеИспользоватьУправляемыеФормыИнструментов;
КонецЕсли;
// Фиксированные. Больше не меняем.
ФиксироватьВнешниеИсключенияАлгоритмов = Истина;
ВыполнятьАлгоритмыЧерезВнешниеОбработки = Ложь;
ПоказыватьВнешниеИсключенияПриВыполненииАлгоритмов = Ложь;
Если ФайловыйКэшАлгоритмовДопускаетРедактирование = Неопределено Тогда
ФайловыйКэшАлгоритмовДопускаетРедактирование = Ложь;
КонецЕсли;
Если НеИспользоватьУправляемыеФормыИнструментов = Неопределено Тогда
НеИспользоватьУправляемыеФормыИнструментов = Ложь;
КонецЕсли;
// Антибаг http://partners.v8.1c.ru/forum/thread.jsp?id=861032#861032
Если АвторегистрацияComКомпонент = Неопределено Тогда
АвторегистрацияComКомпонент = Истина;
КонецЕсли;
#Если Клиент Тогда
Если ПерехватКлавиатурногоВводаВОбычномПриложении = Неопределено Тогда
ПерехватКлавиатурногоВводаВОбычномПриложении = Метаданные.ОсновнойРежимЗапуска = РежимЗапускаКлиентскогоПриложения.УправляемоеПриложение;
КонецЕсли;
//СинтаксическийКонтрольПередЗаписью = ирОбщий.ВосстановитьЗначениеЛкс("СинтаксическийКонтрольПередЗаписью");
//Если СинтаксическийКонтрольПередЗаписью = Неопределено Тогда
СинтаксическийКонтрольПередЗаписью = Истина;
//КонецЕсли;
Если ВыделениеРезультатовПоиска = Неопределено Тогда
ВыделениеРезультатовПоиска = "⧼⧽";
КонецЕсли;
#КонецЕсли
Если ОбщиеНастройки = Неопределено Тогда
СохранитьОбщиеНастройки();
КонецЕсли;
КонецПроцедуры
Процедура СохранитьОбщиеНастройки() Экспорт
ОбщиеНастройки = Новый Структура;
ОбщиеНастройки.Вставить("ФайловыйКэшАлгоритмовДопускаетРедактирование", ФайловыйКэшАлгоритмовДопускаетРедактирование);
ОбщиеНастройки.Вставить("АвторегистрацияComКомпонент", АвторегистрацияComКомпонент);
ОбщиеНастройки.Вставить("ПерехватКлавиатурногоВводаВОбычномПриложении", ПерехватКлавиатурногоВводаВОбычномПриложении);
ОбщиеНастройки.Вставить("ВыделениеРезультатовПоиска", ВыделениеРезультатовПоиска);
ОбщиеНастройки.Вставить("НеИспользоватьУправляемыеФормыИнструментов", НеИспользоватьУправляемыеФормыИнструментов);
ирОбщий.СохранитьЗначениеЛкс("ОбщиеНастройки", ОбщиеНастройки);
КонецПроцедуры
Функция НовоеСлужебноеПолеТекста(Знач СлужебнаяФорма = Неопределено, Знач Суффикс = "") Экспорт
Перем ПолеТекста;
Если СлужебнаяФорма = Неопределено Тогда
СлужебнаяФорма = мСлужебнаяФорма;
КонецЕсли;
ПолеТекста = СлужебнаяФорма.ЭлементыФормы.Добавить(Тип("ПолеТекстовогоДокумента"), "СлужебноеПолеТекста" + Суффикс, Ложь);
Возврат ПолеТекста;
КонецФункции
//ирПортативный Контейнер = Новый Структура();
//ирПортативный #Если Клиент Тогда
//ирПортативный Оповестить("ирПолучитьБазовуюФорму", Контейнер);
//ирПортативный #КонецЕсли
//ирПортативный Если Не Контейнер.Свойство("ирПортативный", ирПортативный) Тогда
//ирПортативный Файл = Новый Файл(ИспользуемоеИмяФайла);
//ирПортативный ПолноеИмяФайлаБазовогоМодуля = Лев(Файл.Путь, СтрДлина(Файл.Путь) - СтрДлина("Модули\")) + "ирПортативный.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| )*";
// Когда внутри шРазделитель был управляющий символ <начало строки>, то возникали зависания на больших литералах https://www.hostedredmine.com/issues/966307
//шСтрокаПрограммы = """(?:""""|[^""\n])*(?:" + шРазделитель + "*\|(?:""""|[^""\n])*)*(?:""|$)"; //
шСтрокаПрограммы = """(?:""""|[^""\n\r])*(?:(?:\n|\r|^)(?:\t| )*(?:" + шКомментарий + "|\|(?:""""|[^""\n\r])*)|\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+)?";
шИндекс = "(\[[^\]\[]+?(?:(?:\[[^\]]+?\][^\]\[]*?)*)*\])";
шСтрокаПростая = """[^""]*""";
шМеждуСкобок = "[^\(\);""]";
шСкобки = "(\(" + шМеждуСкобок + "*(?:(?:" + шСтрокаПростая + "|\((?:" + "[^\);""]" + "|" + шСтрокаПростая + ")*\))" + шМеждуСкобок + "*)*\))"; // МультиМетка82355611
шИмя = "[" + шБуква + "][" + шБуква + "\d]*";
шИмяСРешеткой = "[" + шБукваСРешеткой + "][" + шБукваСРешеткой + "\d]*";
шИмяВременнойТаблицы = шИмяСРешеткой + "(?:\." + шИмяСРешеткой + ")*";
шГиперСсылка = "(\b(?:[" + шБукваЦифра + "]+)://[" + шБукваЦифра + "-+&@#\\/%?=~_|!:,.;()]+)";
ВложенностьИндикации = 0;
ИмяКластераСерверов = НСтр(СтрокаСоединенияИнформационнойБазы(), "Srvr");
ЭтоФайловаяБаза = ПустаяСтрока(ИмяКластераСерверов);
ПрочитатьОбщиеНастройки();
Парсеры = Новый Структура;
ШаблоныВнешнейОбработки = Новый Соответствие;
ШаблоныВнешнейОбработкиСМакетом = Новый Соответствие;
ПроверитьСтруктуруФайловогоКэша();
ИмяФайлаПакера = "v8unpack.exe";
МассивОбычныхЭлементовУправления = Новый Массив;
РежимОтладки = Ложь;
АсинхронностьЗапрещена = Ложь;
#Если Клиент Тогда
ТаблицаСтатистикиВыбора = ирОбщий.ВосстановитьЗначениеЛкс("ирПлатформа.ТаблицаСтатистикиВыбора");
Если ТаблицаСтатистикиВыбора <> Неопределено Тогда
Если ТаблицаСтатистикиВыбора.Колонки.Найти("ЯзыкПрограммы") = Неопределено Тогда
ТаблицаСтатистикиВыбора = Неопределено;
КонецЕсли;
КонецЕсли;
Если ТаблицаСтатистикиВыбора = Неопределено Тогда
ТаблицаСтатистикиВыбора = Новый ТаблицаЗначений;
ТаблицаСтатистикиВыбора.Колонки.Добавить("ТипКонтекста");
ТаблицаСтатистикиВыбора.Колонки.Добавить("Слово");
ТаблицаСтатистикиВыбора.Колонки.Добавить("ЯзыкПрограммы");
ТаблицаСтатистикиВыбора.Колонки.Добавить("Рейтинг", Новый ОписаниеТипов("Число"));
КонецЕсли;
РежимОтладки = Найти(НРег(ПараметрЗапуска), НРег("РежимОтладкиИР")) > 0;
АсинхронностьЗапрещена = Найти(НРег(ПараметрЗапуска), НРег("ЗапретитьАсинхронностьИР")) > 0;
COMНавигатор = "НеИнициализирован";
ОтложенноеОткрытиеИсточникаОшибки = Новый ТаблицаЗначений;
ОтложенноеОткрытиеИсточникаОшибки.Колонки.Добавить("АлгоритмОбъект");
ОтложенноеОткрытиеИсточникаОшибки.Колонки.Добавить("ИнформацияОбОшибке");
ОтложенноеОткрытиеИсточникаОшибки.Колонки.Добавить("РежимВыполненияАлгоритма");
ОтложенноеОткрытиеИсточникаОшибки.Колонки.Добавить("Смещение", Новый ОписаниеТипов("Число"));
мСлужебнаяФорма = ПолучитьФорму("Служебная");
Если мСлужебнаяФорма <> Неопределено Тогда // Для портативного режима управляемого приложения
СлужебноеПолеТекста = НовоеСлужебноеПолеТекста();
СлужебноеПолеТекста2 = НовоеСлужебноеПолеТекста(, "2");
//СлужебноеПолеHtmlДокумента = СлужебнаяФорма.ЭлементыФормы.Добавить(Тип("ПолеHTMLДокумента"), "СлужебноеПолеHTMLДокумента", Ложь); // Тяжелая операция
КонецЕсли;
МассивОбычныхЭлементовУправления.Добавить("Диаграмма");
МассивОбычныхЭлементовУправления.Добавить("ДиаграммаГанта");
МассивОбычныхЭлементовУправления.Добавить("Дендрограмма");
МассивОбычныхЭлементовУправления.Добавить("Индикатор");
МассивОбычныхЭлементовУправления.Добавить("ПолеКалендаря");
МассивОбычныхЭлементовУправления.Добавить("Кнопка");
МассивОбычныхЭлементовУправления.Добавить("КолонкаТабличногоПоля");
МассивОбычныхЭлементовУправления.Добавить("КоманднаяПанель");
МассивОбычныхЭлементовУправления.Добавить("Надпись");
МассивОбычныхЭлементовУправления.Добавить("Панель");
МассивОбычныхЭлементовУправления.Добавить("Переключатель");
МассивОбычныхЭлементовУправления.Добавить("ПолеГрафическойСхемы");
МассивОбычныхЭлементовУправления.Добавить("ПолеГеографическойСхемы");
МассивОбычныхЭлементовУправления.Добавить("ПолеТабличногоДокумента");
МассивОбычныхЭлементовУправления.Добавить("ПолеHTMLДокумента");
МассивОбычныхЭлементовУправления.Добавить("ПолеТекстовогоДокумента");
МассивОбычныхЭлементовУправления.Добавить("ПолеВвода");
МассивОбычныхЭлементовУправления.Добавить("ПолеВыбора");
МассивОбычныхЭлементовУправления.Добавить("ПолеСписка");
МассивОбычныхЭлементовУправления.Добавить("ПолеКартинки");
МассивОбычныхЭлементовУправления.Добавить("ПолосаРегулирования");
МассивОбычныхЭлементовУправления.Добавить("Разделитель");
МассивОбычныхЭлементовУправления.Добавить("РамкаГруппы");
МассивОбычныхЭлементовУправления.Добавить("СводнаяДиаграмма");
МассивОбычныхЭлементовУправления.Добавить("СтраницаПанели");
МассивОбычныхЭлементовУправления.Добавить("ТабличноеПоле");
МассивОбычныхЭлементовУправления.Добавить("Флажок");
мМассивТиповЭлементовУправления = Новый Массив;
Для Каждого ИмяТипа Из МассивОбычныхЭлементовУправления Цикл
мМассивТиповЭлементовУправления.Добавить(Тип(ИмяТипа));
КонецЦикла;
#КонецЕсли
МассивУправляемыхЭлементовУправления = Новый Массив;
МассивУправляемыхЭлементовУправления.Добавить("ПолеФормы");
МассивУправляемыхЭлементовУправления.Добавить("КнопкаФормы");
МассивУправляемыхЭлементовУправления.Добавить("ТаблицаФормы");
МассивУправляемыхЭлементовУправления.Добавить("ГруппаФормы");
МассивУправляемыхЭлементовУправления.Добавить("ДекорацияФормы");
мМассивТиповСМетаданными = Новый Массив;
мМассивТиповСМетаданными.Добавить(Тип("ОбъектМетаданных"));
мМассивТиповСМетаданными.Добавить(Тип("КоллекцияОбъектовМетаданных"));
мМассивТиповСМетаданными.Добавить(Тип("КоллекцияДвижений"));
мМассивТиповСМетаданными.Добавить(Тип("ОписанияСтандартныхРеквизитов"));
мМассивТиповСМетаданными.Добавить(Тип("СписокПолей"));
мМассивТиповСМетаданными.Добавить(Тип("Структура"));
мМассивТиповСМетаданными.Добавить(Тип("СписокЗначений"));
мМассивТиповСМетаданными.Добавить(Тип("ФиксированнаяСтруктура"));
мМассивТиповСМетаданными.Добавить(Тип("ТаблицаЗначений"));
мМассивТиповСМетаданными.Добавить(Тип("ДеревоЗначений"));
мМассивТиповСМетаданными.Добавить(Тип("СтрокаТаблицыЗначений"));
мМассивТиповСМетаданными.Добавить(Тип("СтрокаДереваЗначений"));
мМассивТиповСМетаданными.Добавить(Тип("ВыборкаИзРезультатаЗапроса"));
мМассивТиповСМетаданными.Добавить(Тип("РезультатЗапроса"));
мМассивТиповСМетаданными.Добавить(Тип("Отбор"));
мМассивТиповСМетаданными.Добавить(Тип("НастройкаОформления"));
мМассивТиповСМетаданными.Добавить(Тип("COMОбъект"));
мМассивТиповСМетаданными.Добавить(Тип("ВнешнийОбъект"));
мМассивТиповСМетаданными.Добавить(Тип("ОбъектXDTO"));
мМассивТиповСМетаданными.Добавить(Тип("СвойствоXDTO"));
//мМассивТиповСМетаданными.Добавить(Тип("ОбщийМодуль"));
мМассивТиповСМетаданными.Добавить(Тип("ПостроительЗапроса"));
мМассивТиповСМетаданными.Добавить(Тип("ПостроительОтчета"));
мМассивТиповСМетаданными.Добавить(Тип("ПоляНастройки"));
мМассивТиповСМетаданными.Добавить(Тип("СхемаКомпоновкиДанных"));
мМассивТиповСМетаданными.Добавить(Тип("ТабличныйДокумент"));
мМассивТиповСМетаданными.Добавить(Тип("ТекстовыйДокумент"));
мМассивТиповСМетаданными.Добавить(Тип("НаборыДанныхСхемыКомпоновкиДанных"));
мМассивТиповСМетаданными.Добавить(Тип("ПараметрыСхемыКомпоновкиДанных"));
//мМассивТиповСМетаданными.Добавить(Тип("ДинамическийСписок")); // Будет давать ошибку сериализации
мМассивТиповСМетаданными.Добавить(Тип("ДанныеФормыДерево"));
мМассивТиповСМетаданными.Добавить(Тип("ДанныеФормыКоллекция"));
мМассивТиповСМетаданными.Добавить(Тип("ДанныеФормыКоллекцияЭлементовДерева"));
мМассивТиповСМетаданными.Добавить(Тип("ДанныеФормыСтруктура"));
мМассивТиповСМетаданными.Добавить(Тип("ДанныеФормыСтруктураСКоллекцией"));
мМассивТиповСМетаданными.Добавить(Тип("ДанныеФормыЭлементДерева"));
мМассивТиповСМетаданными.Добавить(Тип("ДанныеФормыЭлементКоллекции"));
мМассивТиповСМетаданными.Добавить(ирОбщий.ТипУправляемаяФормаЛкс());
мМассивТиповСМетаданными.Добавить(Тип("ПолеФормы"));
мМассивТиповСМетаданными.Добавить(Тип("ГруппаФормы"));
мМассивТиповСМетаданными.Добавить(Тип("ТаблицаФормы"));
мМассивТиповСМетаданными.Добавить(Тип("КомандыФормы"));
#Если Клиент Тогда
мМассивТиповСМетаданными.Добавить(Тип("Форма"));
мМассивТиповСМетаданными.Добавить(Тип("ТабличноеПоле"));
мМассивТиповСМетаданными.Добавить(Тип("Панель"));
мМассивТиповСМетаданными.Добавить(Тип("КнопкаКоманднойПанели"));
мМассивТиповСМетаданными.Добавить(Тип("КоманднаяПанель"));
мМассивТиповСМетаданными.Добавить(Тип("ПолеВвода"));
#КонецЕсли
// Мультиметка73327878378078
мТаблицаТипов = Новый ТаблицаЗначений;
мТаблицаТипов.Колонки.Добавить("ИмяОбщегоТипа", Новый ОписаниеТипов("Строка"));
мТаблицаТипов.Колонки.Добавить("Метаданные");
мТаблицаТипов.Колонки.Добавить("СтрокаОписания"); // СтрокаТаблицыЗначений
мТаблицаТипов.Колонки.Добавить("ТипЯзыка", Новый ОписаниеТипов("Строка"));
мТаблицаТипов.Колонки.Добавить("ВиртуальнаяТаблица");
мТаблицаТипов.Колонки.Добавить("Конструктор", Новый ОписаниеТипов("Булево"));
мТаблицаТипов.Колонки.Добавить("ДополнительныеТипы");
мТаблицаТипов.Колонки.Добавить("ДержательМетаданных");
мТаблицаТипов.Колонки.Добавить("Квалификаторы");
мТаблицаТипов.Колонки.Добавить("Детальность");
//#Если Клиент Или ВнешнееСоединение Тогда
СубПутьКФайлуПотокаМодуляВнешнейОбработки = "1ad4dbd4-e136-4202-8121-02c33ad2af45.0.data.und.unp\text.data";
СубПутьКФайлуПотокаМакетаВнешнейОбработки = "902f74d3-f929-4b0f-8719-4cbb655891aa.0.data.und";
СубПутьКФайлуПотокаЗаголовкаВнешнейОбработки = "4eb1cc18-835d-4f8c-a120-3f9d886d75d4.data.und";
СубПутьККонтрольномуФайлуВнешнейОбработки = "1ad4dbd4-e136-4202-8121-02c33ad2af45.0.data";
//КешВнешнихОбработокАлгоритмов = Новый Структура;
КешАлгоритмов = Новый Структура;
ТаблицаТиповМетаОбъектов = ирКэш.ТипыМетаОбъектов();
МакетыКомпонент = Новый Структура;
МаркерКоллекцииОбъектовМетаданных = "КоллекцияОбъектовМетаданных";
МаркерОбъектаМетаданных = "ОбъектМетаданных";
мМассивИсключенийИменКоллекций = Новый СписокЗначений;
мМассивИсключенийИменКоллекций.Добавить("Свойства");
мМассивИсключенийИменКоллекций.Добавить("Методы");
мМассивИсключенийИменКоллекций.Добавить("");
СоответствиеВидовСравнения = Новый ТаблицаЗначений;
СоответствиеВидовСравнения.Колонки.Добавить("Построитель");
СоответствиеВидовСравнения.Колонки.Добавить("Компоновка");
СоответствиеВидовСравнения.Колонки.Добавить("Имя");
СоответствиеВидовСравнения.Индексы.Добавить("Построитель");
СоответствиеВидовСравнения.Индексы.Добавить("Компоновка");
//Интервал
//ИнтервалВключаяГраницы
//ИнтервалВключаяНачало
//ИнтервалВключаяОкончание
СоответствиеВидовСравнения.Добавить().Имя = "Больше";
СоответствиеВидовСравнения.Добавить().Имя = "БольшеИлиРавно";
СоответствиеВидовСравнения.Добавить().Имя = "ВИерархии";
СоответствиеВидовСравнения.Добавить().Имя = "ВСписке";
СоответствиеВидовСравнения.Добавить().Имя = "ВСпискеПоИерархии";
СоответствиеВидовСравнения.Добавить().Имя = "Меньше";
СоответствиеВидовСравнения.Добавить().Имя = "МеньшеИлиРавно";
СоответствиеВидовСравнения.Добавить().Имя = "НеВИерархии";
СоответствиеВидовСравнения.Добавить().Имя = "НеВСписке";
СоответствиеВидовСравнения.Добавить().Имя = "НеВСпискеПоИерархии";
СоответствиеВидовСравнения.Добавить().Имя = "НеРавно";
СоответствиеВидовСравнения.Добавить().Имя = "НеСодержит";
СоответствиеВидовСравнения.Добавить().Имя = "Равно";
СоответствиеВидовСравнения.Добавить().Имя = "Содержит";
Для Каждого СтрокаСоответствия Из СоответствиеВидовСравнения Цикл
СтрокаСоответствия.Построитель = Вычислить("ВидСравнения." + СтрокаСоответствия.Имя);
СтрокаСоответствия.Компоновка = Вычислить("ВидСравненияКомпоновкиДанных." + СтрокаСоответствия.Имя);
КонецЦикла;
мТаблицаЗамеров = Новый ТаблицаЗначений;
мТаблицаЗамеров.Колонки.Добавить("_0");
мТаблицаЗамеров.Колонки.Добавить("Ключ");
мТаблицаЗамеров.Колонки.Добавить("ДатаНачала");
мТаблицаЗамеров.Колонки.Добавить("ОтладкаРазрешена", Новый ОписаниеТипов("Булево"));
мТаблицаЗамеров.Колонки.Добавить("КоличествоПроходов", Новый ОписаниеТипов("Число"));
мТаблицаИндикаторов = Новый ТаблицаЗначений;
мТаблицаИндикаторов.Колонки.Добавить("КоличествоПроходов", Новый ОписаниеТипов("Число"));
мТаблицаИндикаторов.Колонки.Добавить("ПредставлениеПроцесса", Новый ОписаниеТипов("Строка"));
мТаблицаИндикаторов.Колонки.Добавить("ЛиВыводитьВремя", Новый ОписаниеТипов("Булево"));
мТаблицаИндикаторов.Колонки.Добавить("РазрешитьПрерывание", Новый ОписаниеТипов("Булево"));
мТаблицаИндикаторов.Колонки.Добавить("ДатаНачалаПроцесса", Новый ОписаниеТипов("Дата"));
мТаблицаИндикаторов.Колонки.Добавить("МинимальныйПериодОбновления", Новый ОписаниеТипов("Число"));
мТаблицаИндикаторов.Колонки.Добавить("СледующееОбновление", Новый ОписаниеТипов("Дата"));
мТаблицаИндикаторов.Колонки.Добавить("Шаг", Новый ОписаниеТипов("Число"));
мТаблицаИндикаторов.Колонки.Добавить("ТекстСостояния", Новый ОписаниеТипов("Строка"));
мТаблицаИндикаторов.Колонки.Добавить("СледующийСчетчик", Новый ОписаниеТипов("Число"));
мТаблицаИндикаторов.Колонки.Добавить("Счетчик", Новый ОписаниеТипов("Число"));
мТаблицаИндикаторов.Колонки.Добавить("РежимОтладки", Новый ОписаниеТипов("Булево")); // Для ускорения
мТаблицаИндикаторов.Колонки.Добавить("СледующаяПроверкаПрерывания", Новый ОписаниеТипов("Дата"));
//#КонецЕсли
RegExp = ирОбщий.НовоеРегВыражениеЛкс();
RegExp.IgnoreCase = Истина;
RegExp.MultiLine = Ложь;
RegExp2 = ирОбщий.НовоеРегВыражениеЛкс();
RegExp2.IgnoreCase = Истина;
RegExp2.MultiLine = Ложь;
мИменаОсновныхКлассовБиблиотекCOM = Новый Соответствие;
мОбразцыCOMОбъектов = Новый Соответствие;
БуферыСравнения = Новый Соответствие;
МодальныеГруппы = Новый СписокЗначений;
ОтмененныеФоновыеЗадания = Новый Массив;
мДобавленныеОбщиеМодули = Новый Структура;
мОписаниеТипаМДТабличнаяЧасть = ОписаниеТипаМетаОбъектов("ТабличнаяЧасть");
мОписаниеТипаМДВнешнийИсточникДанных = ОписаниеТипаМетаОбъектов("ВнешнийИсточникДанных");