RDT1C/src/DataProcessors/ирПлатформа/Ext/ObjectModule.bsl
Администратор 586adbc006 .
2022-12-11 19:51:11 +03:00

8784 lines
619 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.

//ирПортативный Перем ирПортативный Экспорт;
//ирПортативный Перем ирОбщий Экспорт;
//ирПортативный Перем ирСервер Экспорт;
//ирПортативный Перем ирКэш Экспорт;
//ирПортативный Перем ирПривилегированный Экспорт;
Перем ЧистыйКонтекст;
Перем ФиксироватьВнешниеИсключенияАлгоритмов Экспорт;
Перем ВерсияПлатформы Экспорт;
Перем ЭтоФайловаяБаза Экспорт;
Перем мМетаданные Экспорт;
Перем Это2iS Экспорт;
Перем ЭтоИнтеграция Экспорт;
Перем СоответствиеВидовСравнения Экспорт;
Перем МаркерНачалаАлгоритма Экспорт;
Перем МаркерКонцаАлгоритма Экспорт;
Перем МакетыКомпонент Экспорт;
Перем мКэшПустыхЗначений Экспорт;
Перем ВложенностьИндикации Экспорт;
Перем КэшОбъектов Экспорт;
Перем ВремяОбъект Экспорт;
Перем СловарьПеревода Экспорт;
Перем АрхитектураПроцессора Экспорт;
Перем ВыполнятьАлгоритмыЧерезВнешниеОбработки Экспорт;
Перем ВнешняяОбработкаСервисы Экспорт;
Перем ФайловыйКэшАлгоритмовДопускаетРедактирование Экспорт;
Перем ФормаПустышка Экспорт;
//Перем ТекстПотокаСИменемВнешнейОбработки;
//Перем ТекстПотокаСИменемВнешнейОбработкиСМакетом;
//Перем ФайлСИменемВнешнейОбработки;
//Перем ФайлСИменемВнешнейОбработкиСМакетом;
////Перем КешВнешнихОбработокАлгоритмов;
Перем КешАлгоритмов;
Перем СубПутьКФайлуПотокаМодуляВнешнейОбработки;
Перем СубПутьКФайлуПотокаМакетаВнешнейОбработки;
Перем СубПутьКФайлуПотокаЗаголовкаВнешнейОбработки;
Перем СубПутьККонтрольномуФайлуВнешнейОбработки;
Перем ПутьККаталогуСлужебныхВременныхФайлов;
Перем мЕстьАдминистративныеПраваУУчетнойЗаписиОС;
Перем СообщениеОНеобходимостиОбновитьКэшМодулейВыводилось;
//Перем ФайлЗамокШаблона;
//Перем ФайлЗамокШаблонаСМакетом;
Перем ПапкаКешаВнешнихОбработокАлгоритмов Экспорт;
//Перем ПапкаКеёшаВнешнихОбработокАрхива Экспорт;
Перем ПапкаВнешнихКомпонент Экспорт;
Перем ПапкаКэшаМодулей Экспорт;
Перем ПапкаКэшаРолей Экспорт;
Перем КаталогФайловогоКэша Экспорт;
Перем СтруктураПодкаталоговФайловогоКэша Экспорт;
Перем ИмяФайлаПакера Экспорт;
Перем ШаблоныВнешнейОбработки;
Перем ШаблоныВнешнейОбработкиСМакетом;
Перем ФайлРегистратораКомпонентCU;
Перем ФайлРегистратораNetКомпонент;
Перем МассивСравненияТекстов Экспорт;
Перем мВопросОтключенияПроверкиМодальностиЗадавался Экспорт;
Перем мПроверкаСовместимостиКонфигурацииВыполнялась Экспорт;
Перем мПроверкаЗащитыОтОпасныхДействийВыполнялась Экспорт;
Перем мПроверкаСоединенияADOЭтойБДВыполнялась Экспорт;
Перем мПерехватКлавиатуры;
Перем АсинхронностьЗапрещена Экспорт;
Перем РежимОтладки Экспорт; // Отключает использование однострочных сверток кода. Снижает скорость, но облегчает отладку.
Перем НастройкиКомпьютера Экспорт;
Перем мДиалектыSQL Экспорт; // Используется в Обработка.ирКлсПолеТекстаПрограммы
Перем WScriptShell;
Перем WinAPI Экспорт;
Перем ИМЯ_КЛАССА_DynamicWrapperX Экспорт;
Перем RegExp Экспорт;
Перем RegExp2 Экспорт;
Перем шЛюбой Экспорт;
Перем шБуква Экспорт;
Перем шБукваЦифра Экспорт;
Перем шИмя Экспорт;
Перем шЧисло Экспорт;
Перем шИндекс Экспорт;
Перем шСкобки Экспорт;
Перем шGUID Экспорт;
Перем шКомментарий Экспорт;
Перем шРазделитель Экспорт;
Перем шПустоеНачалоСтроки Экспорт;
Перем шИмяВременнойТаблицы Экспорт;
Перем МаркерОбъектаМетаданных;
Перем МаркерКоллекцииОбъектовМетаданных;
//#Если Клиент Или ВнешнееСоединение Тогда
Перем ИдентификаторПроцессаОС Экспорт;
Перем VBScript Экспорт;
Перем JavaScript Экспорт;
Перем ДеревоТипов Экспорт;
Перем ТаблицаОбщихТипов Экспорт;
Перем ТаблицаИменЭлементовКоллекций Экспорт;
Перем ТаблицаРасширенийТипов Экспорт;
Перем ТаблицаШаблоновКонтекстов Экспорт;
Перем ТаблицаТиповМетаОбъектов Экспорт;
Перем ТаблицаПараметров Экспорт;
Перем СлужебноеПолеТекста Экспорт;
Перем СлужебноеПолеТекста2 Экспорт;
//Перем СлужебноеПолеHtmlДокумента Экспорт;
Перем МассивОбычныхЭлементовУправления Экспорт;
Перем МассивУправляемыхЭлементовУправления Экспорт;
Перем мМассивТиповЭлементовУправления Экспорт;
Перем ТаблицаСтатистикиВыбора Экспорт;
Перем мМассивТиповВключающихМетаданные Экспорт;
Перем мТаблицаСтруктурТипа; // Образец таблицы структур типа
Перем мТаблицаСоответствияВидов;
Перем мТаблицаЗамеров Экспорт;
Перем мТаблицаИндикаторов Экспорт;
Перем мИменаОсновныхКлассовБиблиотекCOM; // Кэш имен классов, например Exel - Application
Перем мОбразцыCOMОбъектов; // Для вычисления свойств
Перем мADOUtils; // GameWithFire.ADOUtils
Перем мКэшСловГлобальногоКонтекста;
Перем мКолонкиБД Экспорт;
Перем мСтруктураХраненияБДСРазмерами Экспорт;
Перем мТаблицаРедактируемыхТипов;
Перем мОписаниеТипаМДТабличнаяЧасть;
Перем мОписаниеТипаМДВнешнийИсточникДанных;
Перем мДеревоОбъектовМД;
Перем мТаблицаВсехТаблицБД;
Перем СлужебнаяФорма;
Перем COMНавигатор Экспорт;
Перем ТаблицаШаблоновТекста Экспорт;
Перем КартинкиТипов;
Перем МассивИсключенийИменКоллекций;
Перем ФайлЗапаковщика1С Экспорт;
Перем ФайлБиблиотекиЗапаковщика;
Перем ФайлОткрывателя1С Экспорт;
Перем ФайлРаспаковщикаZIP Экспорт;
Перем СинтаксПомощник;
Перем Парсеры Экспорт;
Перем БуферыСравнения Экспорт;
Перем ПараметрыОбработчикаОжидания Экспорт;
Перем БазовыйФайлРедактораJSON;
Перем БазовыйФайлРедактораКода;
Перем мМаркерИмениЗапросаПакета Экспорт;
Перем мМаркерИмениЧастиОбъединения Экспорт;
Перем ПоказыватьВнешниеИсключенияПриВыполненииАлгоритмов Экспорт;
Перем СинтаксическийКонтрольПередЗаписью Экспорт;
Перем ОтложенноеОткрытиеИсточникаОшибки Экспорт;
Перем АвторегистрацияComКомпонент Экспорт;
Перем ЛиКомпонентаFormsTextBoxДоступна;
Перем МодальныеГруппы Экспорт;
Перем МодулиМетаданных Экспорт;
Перем ОткрытыеФормы Экспорт;
Перем ПерехватКлавиатурногоВводаВОбычномПриложении Экспорт;
Перем ОтмененныеФоновыеЗадания Экспорт;
Перем ВнутреннийБуферОбмена Экспорт;
Перем ПроверочноеСоединениеАДО Экспорт;
Перем ИспользоватьЭмуляциюНажатияКлавиш Экспорт;
Перем ВыделениеРезультатовПоиска Экспорт;
// Инициализирует, если необходимо, большие таблицы платформы.
// К ним относятся таблицы методов и свойств.
//
// Параметры:
// Нет.
//
Процедура ИнициализацияОписанияМетодовИСвойств() Экспорт
Если ТаблицаКонтекстов.Количество() > 0 Тогда
Возврат;
КонецЕсли;
#Если Клиент Тогда
Состояние("Инициализация таблицы методов и свойств...");
#КонецЕсли
МассивТаблиц = ЗначениеИзСтрокиВнутр(ПолучитьМакет("ТаблицаМетодовИСвойств").ПолучитьТекст());
ТаблицаКонтекстов = МассивТаблиц.ТаблицаКонтекстов;
ТаблицаКонтекстов.Колонки.Добавить("Описание");
ТаблицаКонтекстов.Индексы.Добавить("ТипКонтекста");
ТаблицаКонтекстов.Индексы.Добавить("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка");
ТаблицаКонтекстов.Индексы.Добавить("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка, ТипСлова");
ТаблицаКонтекстов.Индексы.Добавить("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка, НСлово");
ТаблицаКонтекстов.Индексы.Добавить("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка, НСлово, ТипСлова");
ТаблицаШаблоновКонтекстов = МассивТаблиц.ТаблицаШаблоновКонтекстов;
ТаблицаШаблоновКонтекстов.Колонки.Добавить("Описание"); // Нужно для вирт. таблицы КритерийОтбора.<Имя критерия отбора>()
ТаблицаШаблоновКонтекстов.Индексы.Добавить("ТипКонтекста");
ТаблицаШаблоновКонтекстов.Индексы.Добавить("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка");
ТаблицаПараметров = МассивТаблиц.ТаблицаПараметров;
ТаблицаПараметров.Колонки.Добавить("Описание");
ТаблицаПараметров.Индексы.Добавить("ТипКонтекста, ЯзыкПрограммы, Слово, Номер");
#Если Клиент Тогда
Состояние("");
#КонецЕсли
КонецПроцедуры
// Инициализирует, если необходимо, малые таблицы платформы.
// К ним относятся таблицы типов и коллекций.
//
// Параметры:
// Нет.
//
Процедура ИнициализацияОписанияОбщихТипов() Экспорт
Если ТипЗнч(ТаблицаОбщихТипов) = Тип("ТаблицаЗначений") Тогда
Возврат;
КонецЕсли;
МассивТаблиц = ЗначениеИзСтрокиВнутр(ПолучитьМакет("ТаблицаИменЭлементовКоллекций").ПолучитьТекст());
ТаблицаИменЭлементовКоллекций = МассивТаблиц.ТаблицаИменЭлементовКоллекций;
#Если Сервер И Не Сервер Тогда
ТаблицаИменЭлементовКоллекций = НОвый ТаблицаЗначений;
#КонецЕсли
ТаблицаИменЭлементовКоллекций.Индексы.Добавить("ИмяКоллекции");
ТаблицаИменЭлементовКоллекций.Индексы.Добавить("ИмяЭлементаКоллекции");
ТаблицаИменЭлементовКоллекций.Индексы.Добавить("ИмяОбщегоТипа, ИмяЭлементаКоллекции");
ТаблицаРасширенийТипов = МассивТаблиц.ТаблицаРасширений;
#Если Сервер И Не Сервер Тогда
ТаблицаРасширенийТипов = НОвый ТаблицаЗначений;
#КонецЕсли
ТаблицаРасширенийТипов.Индексы.Добавить("Расширение");
МассивТаблиц = ЗначениеИзСтрокиВнутр(ПолучитьМакет("ТаблицаОбщихТипов").ПолучитьТекст());
ТаблицаОбщихТипов = МассивТаблиц.ТаблицаОбщихТипов;
#Если Сервер И Не Сервер Тогда
ТаблицаОбщихТипов = НОвый ТаблицаЗначений;
#КонецЕсли
ТаблицаОбщихТипов.Индексы.Добавить("Слово, ЯзыкПрограммы");
ТаблицаОбщихТипов.Индексы.Добавить("Слово, ТипТипа");
//ТаблицаОбщихТипов.Индексы.Добавить("Слово, ЯзыкПрограммы, ТипТипа");
ТаблицаОбщихТипов.Индексы.Добавить("НСлово, ЯзыкПрограммы, ЕстьКонструктор");
ТаблицаОбщихТипов.Индексы.Добавить("Представление, ТипТипа");
ТаблицаОбщихТипов.Индексы.Добавить("ИД");
КонецПроцедуры
// Добавляет дополнительные Свойства для типов контекстов платформы.
//
// Параметры:
// <Параметр1> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>.
//
Процедура ДобавитьСловоВОписаниеТипаКонтекста(ТипКонтекста, Слово, ТипСлова, ТипЗначения) Экспорт
ИнициализацияОписанияМетодовИСвойств();
НоваяСтрока = ТаблицаКонтекстов.Добавить();
НоваяСтрока.ТипКонтекста = ТипКонтекста;
НоваяСтрока.Слово = Слово;
НоваяСтрока.НСлово = НРег(Слово);
НоваяСтрока.ТипСлова = ТипСлова;
НоваяСтрока.ТипЗначения = ТипЗначения;
КонецПроцедуры // ДобавитьСловоВОписаниеТипаКонтекста()
// Добавляет в список значений коллекцию объектов метаданных.
//
// Параметры:
// пСписокМетаданных - СписокЗначений - куда добавляем объекты;
// пИмяМетаданных - Строка - имя коллекции объектов метаданных или имя корневого типа;
// *ЛиПолноеИмя - Булево, *Истина - добавлять полные имена, иначе краткие;
// *ЛиДобавлятьКартинки - Булево, *Истина - добавлять картинки;
// *ОтборПоПраву - Строка, *Неопределено - проверять перед добавлением право текущего пользователя.
//
Процедура ДобавитьВСписокКоллекциюМетаданных(пСписокМетаданных, пИмяМетаданных, ЛиПолноеИмя = Истина, ЛиДобавлятьКартинки = Истина, ОтборПоПраву = Неопределено) Экспорт
Картинка = Неопределено;
СтрокаКорневогоТипа = ОписаниеТипаМетаОбъектов(пИмяМетаданных, , 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");
// // Это новые слова
// Список.Добавить("ЗНАЧЕНИЯХАРАКТЕРИСТИК");
// Список.Добавить("ПОЛЕИМЕНИ");
// Список.Добавить("ПОЛЕКЛЮЧА");
// Список.Добавить("ПОЛЕЗНАЧЕНИЯ");
// Список.Добавить("ПОЛЕВИДА");
// Список.Добавить("ПОЛЕТИПАЗНАЧЕНИЯ");
// Список.Добавить("ПОЛЕОБЪЕКТА");
// Список.Добавить("ВИДЫХАРАКТЕРИСТИК");
//КонецЕсли;
КонецЕсли;
Возврат Список;
КонецФункции // ПолучитьСписокСловЯзыкаЗапросов()
// Получает список ключевых встроенного языка.
//
// Параметры:
// Нет.
//
// Возвращаемое значение:
// СписокЗначений - где значение содержит слово.
//
Функция ПолучитьСписокКлючевыхСловВстроенногоЯзыка() Экспорт
Список = Новый СписокЗначений;
Список.Добавить("Возврат");
Список.Добавить("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");
//// Инструкции препроцессора. Добавлено 28.01.2012
//// Здесь им не место, т.к. по этому списку проверяется валидность имен переменных
//Список.Добавить("Клиент");
//Список.Добавить("Сервер");
//Список.Добавить("ВнешнееСоединение");
//Список.Добавить("ТолстыйКлиентУправляемоеПриложение");
//Список.Добавить("ТолстыйКлиентОбычноеПриложение");
//Список.Добавить("ТонкийКлиент");
//Список.Добавить("ВебКлиент");
Список.Добавить("Истина");
Список.Добавить("True");
Список.Добавить("Ложь");
Список.Добавить("False");
Список.Добавить("Неопределено");
Список.Добавить("Undefined");
Список.Добавить("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)
Тогда
Продолжить;
КонецЕсли;
Результат.Добавить(КлючИЗначение.Значение);
КонецЦикла;
Возврат Результат;
КонецФункции
Функция РазбитьГрубоТекстПакетногоЗапросаНаЗапросы(Знач ТекстПакета, Знач ПозицияКурсора = Неопределено, выхПозиции = Неопределено) Экспорт
МассивТекстовЗапросов = Новый Массив;
Если Не ирКэш.ДоступныРегВыраженияЛкс() Тогда
Если ирКэш.НомерВерсииПлатформыЛкс() >= 803005 Тогда
Схема = Вычислить("Новый СхемаЗапроса");
#Если Сервер И Не Сервер Тогда
Схема = Новый СхемаЗапроса;
#КонецЕсли
Попытка
Схема.УстановитьТекстЗапроса(ТекстПакета);
Исключение
ОписаниеОшибки = ОписаниеОшибки(); // Для отладки
Возврат МассивТекстовЗапросов;
КонецПопытки;
Для Каждого ЗапросПакета Из Схема.ПакетЗапросов Цикл
МассивТекстовЗапросов.Добавить(ЗапросПакета.ПолучитьТекстЗапроса());
КонецЦикла;
КонецЕсли;
Возврат МассивТекстовЗапросов;
КонецЕсли;
шСтрокаЗапроса = """(?:(?:"""")|[^""\n])*(?:" + шРазделитель + "*(?:(?:"""")|[^""\n])*)*(?:""|$)";
RegExp.Global = Истина;
ШаблонЗапроса = "(?:" + шСтрокаЗапроса + ")|" + шКомментарий + "|;|$";
RegExp.Pattern = ШаблонЗапроса;
Результат = RegExp.НайтиВхождения(ТекстПакета);
НачалоЗапроса = 1;
ОстальнойТекст = ТекстПакета;
МассивТаблиц = Новый Массив;
ДлинаТекстаПакета = СтрДлина(ТекстПакета);
выхПозиции = Новый Массив;
выхПозиции.Добавить(0);
Для Каждого Match Из Результат Цикл
ПозицияВхождения = Match.FirstIndex;
Если Истина
И Match.Value <> ";"
И ПозицияВхождения <> ДлинаТекстаПакета
Тогда
Продолжить;
КонецЕсли;
ИмяВременнойТаблицы = "";
ДлинаТекстаЗапроса = ПозицияВхождения + Match.Length;
ТекстЗапроса = Сред(ТекстПакета, НачалоЗапроса, ДлинаТекстаЗапроса - НачалоЗапроса + 1);
Если ПустаяСтрока(ТекстЗапроса) Тогда
Продолжить;
КонецЕсли;
//Если ТекстЗапроса = ";" Тогда
// Продолжить;
//КонецЕсли;
ОстальнойТекст = Сред(ОстальнойТекст, ДлинаТекстаЗапроса + 1);
НачалоЗапроса = НачалоЗапроса + СтрДлина(ТекстЗапроса);
МассивТекстовЗапросов.Добавить(ТекстЗапроса);
выхПозиции.Добавить(ПозицияВхождения + 1);
Если ПозицияКурсора <> Неопределено И ПозицияКурсора < ПозицияВхождения Тогда
Прервать;
КонецЕсли;
КонецЦикла;
Возврат МассивТекстовЗапросов;
КонецФункции
Функция СтруктураРезультатаПакетногоЗапроса(ТекстПакета, ПрефиксКомментария = "//") Экспорт
Результат = Новый Структура;
Если Не ирКэш.ДоступныРегВыраженияЛкс() Тогда
Возврат Результат;
КонецЕсли;
МассивТекстовЗапросов = РазбитьГрубоТекстПакетногоЗапросаНаЗапросы(ТекстПакета);
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);
КонецЕсли;
Возврат Результат;
КонецФункции // ПолучитьТекстЗапросаДоУпорядочивания()
// Получает имя создаваемой временной таблицы из текста запроса.
// Это неточный метод, основанный на regexp.
//
// Параметры:
// ТекстЗапроса - Строка.
//
// Возвращаемое значение:
// Строка, Неопределено.
//
Функция ПолучитьМассивСоздаваемыхВременныхТаблицПакета(ТекстПакета, ТолькоТребующиеУничтоженияНаВходе = Ложь) Экспорт
СозданныеТаблицы = Новый Массив;
Если Не ирКэш.ДоступныРегВыраженияЛкс() Тогда
Если ирКэш.НомерВерсииПлатформыЛкс() >= 803005 Тогда
Схема = Вычислить("Новый СхемаЗапроса");
#Если Сервер И Не Сервер Тогда
Схема = Новый СхемаЗапроса;
#КонецЕсли
Попытка
Схема.УстановитьТекстЗапроса(ТекстПакета);
Исключение
ОписаниеОшибки = ОписаниеОшибки(); // Для отладки
Возврат СозданныеТаблицы;
КонецПопытки;
Для Каждого ЗапросПакета Из Схема.ПакетЗапросов Цикл
ИмяСоздаваемойТаблицы = Неопределено;
Если Истина
И ТипЗнч(ЗапросПакета) = Тип("ЗапросВыбораСхемыЗапроса")
И ЗначениеЗаполнено(ЗапросПакета.ТаблицаДляПомещения)
Тогда
ИмяСоздаваемойТаблицы = ЗапросПакета.ТаблицаДляПомещения;
КонецЕсли;
СозданныеТаблицы.Добавить(ИмяСоздаваемойТаблицы);
КонецЦикла;
КонецЕсли;
Возврат СозданныеТаблицы;
КонецЕсли;
МассивТекстовЗапросов = РазбитьГрубоТекстПакетногоЗапросаНаЗапросы(ТекстПакета);
RegExp2.Global = Истина;
// Ищем в очередном запросе предложение ПОМЕСТИТЬ
шСтрокаЗапроса = """(?:(?:"""")|[^""\n])*(?:" + шРазделитель + "*(?:(?:"""")|[^""\n])*)*(?:""|$)";
ШаблонПОМЕСТИТЬИЗ = "(?:" + шСтрокаЗапроса + ")|(?:" + шРазделитель + "(?:(ПОМЕСТИТЬ|INTO\s+TABLE|INTO)|(УНИЧТОЖИТЬ|DROP|DROP\s+TABLE))" + шРазделитель
+ "+(" + шИмяВременнойТаблицы + ")(" + шРазделитель + "|;)|(?:" + шРазделитель + "))";
RegExp2.Pattern = ШаблонПОМЕСТИТЬИЗ;
СозданныеТаблицыНрег = Новый Массив;
СначалаУничтоженныеТаблицы = Новый Массив;
Для Каждого ТекстЗапроса Из МассивТекстовЗапросов Цикл
Результат2 = RegExp2.НайтиВхождения(ТекстЗапроса);
ИмяСозданнойВременнойТаблицы = Неопределено;
Для Каждого Match2 Из Результат2 Цикл
Если Не ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(Match2.SubMatches(0)) Тогда
ИмяВременнойТаблицы = Match2.SubMatches(2);
Если Ложь
Или Не ТолькоТребующиеУничтоженияНаВходе
Или СначалаУничтоженныеТаблицы.Найти(НРег(ИмяВременнойТаблицы)) = Неопределено
Тогда
ИмяСозданнойВременнойТаблицы = ИмяВременнойТаблицы;
КонецЕсли;
Прервать;
ИначеЕсли Истина
И ТолькоТребующиеУничтоженияНаВходе
И Не ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(Match2.SubMatches(1))
Тогда
ИмяВременнойТаблицы = Нрег(Match2.SubMatches(2));
Если СозданныеТаблицыНрег.Найти(ИмяВременнойТаблицы) = Неопределено Тогда
СначалаУничтоженныеТаблицы.Добавить(ИмяВременнойТаблицы);
КонецЕсли;
Прервать;
КонецЕсли;
КонецЦикла;
СозданныеТаблицы.Добавить(ИмяСозданнойВременнойТаблицы);
Если ИмяСозданнойВременнойТаблицы <> Неопределено Тогда
СозданныеТаблицыНрег.Добавить(НРег(ИмяСозданнойВременнойТаблицы));
КонецЕсли;
КонецЦикла;
Возврат СозданныеТаблицы;
КонецФункции
////////////////////////////////////////////////////////////////////////////////
// РАБОТА С ТИПАМИ
// Получает чистую внутреннюю таблицу предопределенных слов.
//
// Параметры:
// Нет.
//
// Возвращаемое значение:
// ТаблицаЗначений - с колонками "Слово", "ТипСлова", "ТаблицаСтруктурТипов".
//
Функция НоваяТаблицаСвойствТипа() Экспорт
ВнутренняяТаблицаСлов = Новый ТаблицаЗначений;
ВнутренняяТаблицаСлов.Колонки.Добавить("Слово");
ВнутренняяТаблицаСлов.Колонки.Добавить("ТипСлова");
ВнутренняяТаблицаСлов.Колонки.Добавить("ТаблицаСтруктурТипов");
ВнутренняяТаблицаСлов.Колонки.Добавить("ТипЗначения");
ВнутренняяТаблицаСлов.Колонки.Добавить("Определение");
ВнутренняяТаблицаСлов.Колонки.Добавить("МожноУточнитьТип");
ВнутренняяТаблицаСлов.Индексы.Добавить("Слово, ТипСлова");
Возврат ВнутренняяТаблицаСлов;
КонецФункции
// Функция - Подобрать вариант синтаксиса метода
//
// Параметры:
// ТаблицаВариантов - - содержимое будет утеряно!
//
// Возвращаемое значение:
// строка - название варианта синтаксиса
//
Функция ПодобратьВариантСинтаксисаМетода(Знач ТаблицаВариантов, КоличествоФактПараметровМетода, ТекущийВариант = "", ТекущийВариантУстановленВручную = Ложь, выхНомер = 0) Экспорт
#Если Сервер И Не Сервер Тогда
ТаблицаВариантов = Новый ТаблицаЗначений;
#КонецЕсли
ТаблицаВариантов.Колонки.Добавить("Количество", Новый ОписаниеТипов("Число"));
ТаблицаВариантов.ЗаполнитьЗначения(1, "Количество");
ТаблицаВариантов.Свернуть("ВариантСинтаксиса", "Количество");
ТаблицаВариантов.Сортировать("Количество");
НовыйТекущийВариант = "";
Если ТаблицаВариантов.Количество() > 0 Тогда
Для Каждого СтрокаВарианта Из ТаблицаВариантов Цикл
Если ТекущийВариантУстановленВручную И СтрокаВарианта.ВариантСинтаксиса = ТекущийВариант Тогда
НовыйТекущийВариант = ТекущийВариант;
выхНомер = ТаблицаВариантов.Индекс(СтрокаВарианта);
Прервать;
КонецЕсли;
Если СтрокаВарианта.Количество >= КоличествоФактПараметровМетода Тогда
НовыйТекущийВариант = СтрокаВарианта.ВариантСинтаксиса;
выхНомер = ТаблицаВариантов.Индекс(СтрокаВарианта);
Если Не ТекущийВариантУстановленВручную Тогда
Прервать;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если СтрокаВарианта.Количество < КоличествоФактПараметровМетода Тогда
НовыйТекущийВариант = СтрокаВарианта.ВариантСинтаксиса;
выхНомер = ТаблицаВариантов.Индекс(СтрокаВарианта);
КонецЕсли;
КонецЕсли;
выхНомер = выхНомер + 1;
Возврат НовыйТекущийВариант;
КонецФункции
Функция СинтаксПомощник() Экспорт
Если СинтаксПомощник = Неопределено Тогда
СинтаксПомощник = ирОбщий.СоздатьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирСинтаксПомощник");
КонецЕсли;
Возврат СинтаксПомощник;
КонецФункции
Функция ДоступныеЗначенияТипа(Знач ИмяТипаИлиТипЗначения) Экспорт
ИнициализацияОписанияМетодовИСвойств();
Если ТипЗнч(ИмяТипаИлиТипЗначения) = Тип("Тип") Тогда
ИмяТипаИлиТипЗначения = СтруктураТипаИзКонкретногоТипа(ИмяТипаИлиТипЗначения).ИмяОбщегоТипа;
КонецЕсли;
//Пустышка = Вычислить("Метаданные.СвойстваОбъектов." + ИмяТипаЗначения);
СтрокиЗначений = ТаблицаКонтекстов.НайтиСтроки(Новый Структура("ТипКонтекста, ТипСлова", "ПеречислениеМетаданных: " + ИмяТипаИлиТипЗначения, "Свойство"));
Если СтрокиЗначений.Количество() = 0 Тогда
ИмяТипаПеречисления = ИмяТипаИлиТипЗначения;
Если Не ирОбщий.СтрНачинаетсяСЛкс(ИмяТипаИлиТипЗначения, "Перечисление") Тогда
ИмяТипаПеречисления = "Перечисление" + ИмяТипаПеречисления;
КонецЕсли;
СтрокиЗначений = ТаблицаКонтекстов.НайтиСтроки(Новый Структура("ТипКонтекста, ТипСлова", ИмяТипаПеречисления, "Свойство"));
КонецЕсли;
СтрокиЗначений = ТаблицаКонтекстов.Скопировать(СтрокиЗначений);
СписокЗначений = Новый СписокЗначений;
СписокЗначений.ЗагрузитьЗначения(СтрокиЗначений.ВыгрузитьКолонку("Слово"));
Возврат СписокЗначений;
КонецФункции
#Если Клиент Тогда
// Позволяет пользователю выбрать один из возможных вариантов описания слова.
//
// Параметры:
// СтруктураЦикла - Соответствие - где ключи - имена ветвей дерева, а значения - таблицы структур типов;
// *ВключатьПутьКОписаниюТипаЗначения - Булево, *Неопределено - признак добавления в список выбора тип значения слова.
//
// Возвращаемое значение:
// СтрокаТаблицыЗначений, Структура - описание слова.
//
Функция ВыбратьСтрокуОписанияИзМассиваСтруктурТипов(СтруктураЦикла, ВключатьПутьКОписаниюТипаЗначения = Ложь, ВладелецФормы = Неопределено, Слово = "",
НомерПараметраМетода = 0, БезусловнаяАктивизацияРезультатов = Истина, выхФормаВыбора = Неопределено, КоличествоФактПараметровМетода = 0) Экспорт
ДеревоВыбора = Новый ДеревоЗначений;
ДеревоВыбора.Колонки.Добавить("Ключ");
ДеревоВыбора.Колонки.Добавить("Представление");
ДеревоВыбора.Колонки.Добавить("ТипСлова");
СчетчикСтрокВторогоУровня = 0;
НачальнаяСтрокаВыбора = Неопределено;
Для Каждого ЭлементЦикла Из СтруктураЦикла Цикл
СтрокаЭлементаЦикла = ДеревоВыбора.Строки.Добавить();
СтрокаЭлементаЦикла.Представление = ЭлементЦикла.Ключ;
КонецЦикла;
ДеревоВыбора.Строки.Сортировать("Представление");
Для Каждого СтрокаЭлементаЦикла Из ДеревоВыбора.Строки Цикл
Для Каждого СтруктураТипаКонтекста Из СтруктураЦикла[СтрокаЭлементаЦикла.Представление] Цикл
//Если СтруктураТипаКонтекста.СтрокаОписания = Неопределено Тогда
// Продолжить;
//КонецЕсли;
Если СтруктураТипаКонтекста.ИмяОбщегоТипа = "Неизвестный контекст" Тогда
Продолжить;
КонецЕсли;
СтрокаОписания = СтруктураТипаКонтекста.СтрокаОписания;
// Ранее среди параметров были: ПутьКСлову = "", ТекущееСлово = "",
//// Добавим строку описания слова
//ЭтоИмяТипа = Ложь;
//Попытка
// Если СтрокаОписания.ТипЯзыка = "ИмяТипа" Тогда
// ЭтоИмяТипа = Истина;
// КонецЕсли;
//Исключение
//КонецПопытки;
//
//Если ЭтоИмяТипа Тогда
//
// Если Прав(ПутьКСлову, 1) = "(" Тогда
// ЧистыйПутьКСлову = Лев(ПутьКСлову, СтрДлина(ПутьКСлову) - 1);
// Иначе
// ЧистыйПутьКСлову = ТекущееСлово;
// КонецЕсли;
//
// БазовыйТип = ирОбщий.ПервыйФрагментЛкс(ЧистыйПутьКСлову);
// Если БазовыйТип = "" Тогда
// // Неизвестный контекст
// СтрокаОписания = Неопределено;
// Иначе
// СтрокаОписания = ТаблицаОбщихТипов.Найти(БазовыйТип, "БазовыйТип");
// КонецЕсли;
//КонецЕсли;
Если Истина
И СтрокаОписания <> Неопределено
И ТипЗнч(СтрокаОписания) <> Тип("COMОбъект")
И СтрокаЭлементаЦикла.Строки.Найти(СтрокаОписания, "Ключ") = Неопределено
И СтрокаОписания.Владелец().Колонки.Найти("ЛиЭкспорт") = Неопределено
И (Ложь
Или СтрокаОписания.Владелец().Колонки.Найти("ТипЯзыка") = Неопределено
Или СтрокаОписания.ТипЯзыка <> "ИмяТипа")
Тогда
ПредставлениеТипа = СтрокаОписания.Слово;
Если Истина
И СтрокаОписания.Владелец().Колонки.Найти("ТипКонтекста") <> Неопределено
И ЗначениеЗаполнено(СтрокаОписания.ТипКонтекста)
Тогда
ПредставлениеТипа = СтрокаОписания.ТипКонтекста + "." + ПредставлениеТипа;
КонецЕсли;
СтрокаДереваВыбора = СтрокаЭлементаЦикла.Строки.Добавить();
СтрокаДереваВыбора.Ключ = СтрокаОписания;
Попытка
СтрокаДереваВыбора.ТипСлова = СтрокаОписания.ТипСлова;
Исключение
СтрокаДереваВыбора.ТипСлова = "Тип";
КонецПопытки;
СтрокаДереваВыбора.Представление = ПредставлениеТипа;
КонецЕсли;
Если ВключатьПутьКОписаниюТипаЗначения Тогда
// Добавим строку описания типа значения
СтрокаОписанияТипаЗначения = ТаблицаОбщихТипов.Найти(НРег(СтруктураТипаКонтекста.ИмяОбщегоТипа), "НСлово");
Если СтрокаОписанияТипаЗначения <> Неопределено Тогда
Если СтрокаЭлементаЦикла.Строки.Найти(СтрокаОписанияТипаЗначения, "Ключ") = Неопределено Тогда
ПредставлениеТипа = СтрокаОписанияТипаЗначения.Слово;
СтрокаДереваВыбора = СтрокаЭлементаЦикла.Строки.Добавить();
СтрокаДереваВыбора.Ключ = СтрокаОписанияТипаЗначения;
СтрокаДереваВыбора.ТипСлова = "Тип";
СтрокаДереваВыбора.Представление = ПредставлениеТипа;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЦикла;
СчетчикСтрокВторогоУровня = СчетчикСтрокВторогоУровня + СтрокаЭлементаЦикла.Строки.Количество();
Если Истина
И НачальнаяСтрокаВыбора = Неопределено
И СтрокаЭлементаЦикла.Строки.Количество() > 0
Тогда
Если СтрокаДереваВыбора.ТипСлова = "Конструктор" Тогда
Отбор = Новый Структура;
Отбор.Вставить("ТипКонтекста", СтрокаОписания.ТипКонтекста);
Отбор.Вставить("Слово", "<Новый>");
Отбор.Вставить("ЯзыкПрограммы", 0);
ТаблицаВариантов = ТаблицаПараметров.Скопировать(Отбор);
НовыйТекущийВариант = ПодобратьВариантСинтаксисаМетода(ТаблицаВариантов, КоличествоФактПараметровМетода);
Для Каждого СтрокаВарианта Из СтрокаЭлементаЦикла.Строки Цикл
Если НовыйТекущийВариант = СтрокаВарианта.Ключ.Слово Тогда
НачальнаяСтрокаВыбора = СтрокаВарианта;
Прервать;
КонецЕсли;
КонецЦикла;
Иначе
НачальнаяСтрокаВыбора = СтрокаЭлементаЦикла.Строки[0];
КонецЕсли;
КонецЕсли;
СтрокаЭлементаЦикла.Строки.Сортировать("Представление");
КонецЦикла;
Если выхФормаВыбора = Неопределено Тогда
выхФормаВыбора = ирОбщий.ПолучитьФормуЛкс("Обработка.ирСинтаксПомощник.Форма");
КонецЕсли;
Если СчетчикСтрокВторогоУровня > 0 Или выхФормаВыбора.Открыта() Тогда
выхФормаВыбора.ДеревоТиповСлова = ДеревоВыбора;
выхФормаВыбора.ИскомоеСлово = Слово;
выхФормаВыбора.ПоискСУчетомТипаСлова = Истина;
выхФормаВыбора.НомерИскомогоПараметра = НомерПараметраМетода;
выхФормаВыбора.ВладелецФормы = ВладелецФормы;
Если НачальнаяСтрокаВыбора <> Неопределено Тогда
выхФормаВыбора.ВыбратьИскомуюСтроку(НачальнаяСтрокаВыбора, БезусловнаяАктивизацияРезультатов);
КонецЕсли;
выхФормаВыбора.ВладелецФормы = Неопределено; // Перенес в саму форму
КонецЕсли;
Если Ложь
Или СчетчикСтрокВторогоУровня = 1
Или (Истина
И СчетчикСтрокВторогоУровня = 2
И ДеревоВыбора.Строки[0].Строки.Количество() = 1
И НачальнаяСтрокаВыбора.Ключ = ДеревоВыбора.Строки[1].Строки[0].Ключ)
Тогда
ВыбранныйЭлементТипа = НачальнаяСтрокаВыбора;
ИначеЕсли СчетчикСтрокВторогоУровня > 1 Тогда
//ФормаВыбора = ПолучитьФорму("ФормаВыбораСправкиПоСлову");
//ФормаВыбора.ДеревоТиповСлова = ДеревоВыбора;
//ФормаВыбора.НачальноеЗначениеВыбора = НачальнаяСтрокаВыбора;
//ВыбранныйЭлементТипа = ФормаВыбора.ОткрытьМодально();
ВыбранныйЭлементТипа = НачальнаяСтрокаВыбора;
Иначе
ВыбранныйЭлементТипа = Неопределено;
КонецЕсли;
Если ВыбранныйЭлементТипа = Неопределено Тогда
СтрокаОписания = Неопределено;
Иначе
СтрокаОписания = ВыбранныйЭлементТипа.Ключ;
КонецЕсли;
Возврат СтрокаОписания;
КонецФункции
#КонецЕсли
// Формирует построитель запроса по структуре типа.
//
// Параметры:
// СтруктураТипа - Структура - описатель типа.
//
// Возвращаемое значение:
// ПостроительЗапроса.
//
Функция ПостроительЗапросаПоСтруктуреТипа(СтрокаОбщегоТипа, ВиртуальнаяТаблица = Неопределено)
МетаданныеРодителя = СтрокаОбщегоТипа.Метаданные;
ТипМетаданныхРодителя = ТипЗнч(МетаданныеРодителя);
Если ТипМетаданныхРодителя = Тип("ОбъектМетаданных") Тогда
ПолноеИмя = МетаданныеРодителя.ПолноеИмя();
Иначе
ПолноеИмя = ирОбщий.КорневойТипКонфигурацииЛкс(КэшОбъект(МетаданныеРодителя).ПолноеИмя);
КонецЕсли;
МассивФрагментов = ирОбщий.СтрРазделитьЛкс(ПолноеИмя);
КорневойТипРодителя = МассивФрагментов[0];
ПостроительЗапроса = Новый Структура("ДоступныеПоля", Новый Массив);
Если ОписаниеТипаМетаОбъектов(КорневойТипРодителя, , 0) <> Неопределено Тогда
Если Ложь
Или (Истина
И МассивФрагментов.Количество() = 2
И МассивФрагментов[0] <> "ВнешнийИсточникДанных")
Или (Истина
И МассивФрагментов.Количество() = 4
И МассивФрагментов[2] = "ТабличнаяЧасть")
Тогда
Если СтрокаОбщегоТипа.ИмяОбщегоТипа = "Константы.<Имя константы>" Тогда
ИмяТаблицы = "Константы." + МассивФрагментов[1];
Иначе
ИмяТаблицы = ирКэш.ИмяТаблицыИзМетаданныхЛкс(ПолноеИмя, Ложь, ВиртуальнаяТаблица = Неопределено);
КонецЕсли;
Если ТипМетаданныхРодителя = Тип("ОбъектМетаданных") Тогда
Если Ложь
Или ВиртуальнаяТаблица = Неопределено
Или Найти(ВиртуальнаяТаблица.Выражение, "(") = 0
Тогда
ТаблицаРезультата = ирКэш.ПоляТаблицыБДЛкс(ИмяТаблицы + ВиртуальнаяТаблица.Выражение);
#Если Сервер И Не Сервер Тогда
ТаблицаРезультата = Новый ТаблицаЗначений;
#КонецЕсли
ТаблицаРезультата = ТаблицаРезультата.Скопировать(, "Имя, ТипЗначения"); // Делаем копию, т.к. будем ее модифицировать
ТаблицаРезультата.Колонки.Добавить("НИмя");
Для Каждого ПолеТаблицы Из ТаблицаРезультата Цикл
ирОбщий.ОбновитьКопиюСвойстваВНижнемРегистреЛкс(ПолеТаблицы);
КонецЦикла;
ПостроительЗапроса = Новый Структура("ДоступныеПоля", ТаблицаРезультата);
Иначе
Если СтрокаОбщегоТипа.ИмяОбщегоТипа = "Константы.<Имя константы>" Тогда
ОпределениеТаблицы = "ВЫБРАТЬ " + ИмяТаблицы;
Иначе
УникальноеИмяТаблицы = "______________________";
ОпределениеТаблицы = "ВЫБРАТЬ * ИЗ " + ИмяТаблицы ;
Если ВиртуальнаяТаблица <> Неопределено Тогда
ОпределениеТаблицы = ОпределениеТаблицы + ВиртуальнаяТаблица.Выражение;
КонецЕсли;
ОпределениеТаблицы = ОпределениеТаблицы + " КАК " + УникальноеИмяТаблицы;
КонецЕсли;
Попытка
//ПостроительЗапроса.Текст = ОпределениеТаблицы;
ТаблицаРезультата = ирОбщий.ПустаяТаблицаЗначенийИзТекстаЗапросаЛкс(ОпределениеТаблицы);
Исключение
Успех = Ложь;
Если ВиртуальнаяТаблица <> Неопределено Тогда
ПозицияСкобки = Найти(ВиртуальнаяТаблица.Выражение, "(");
Если ПозицияСкобки > 0 Тогда
ОпределениеТаблицы = "ВЫБРАТЬ * ИЗ " + ИмяТаблицы ;
ОпределениеТаблицы = ОпределениеТаблицы + Лев(ВиртуальнаяТаблица.Выражение, ПозицияСкобки - 1);
ОпределениеТаблицы = ОпределениеТаблицы + " КАК " + УникальноеИмяТаблицы;
Попытка
//ПостроительЗапроса.Текст = ОпределениеТаблицы;
ТаблицаРезультата = ирОбщий.ПустаяТаблицаЗначенийИзТекстаЗапросаЛкс(ОпределениеТаблицы);
Успех = Истина;
Исключение
КонецПопытки;
КонецЕсли;
КонецЕсли;
Если Не Успех Тогда
ВызватьИсключение "ОшибкаВычисленияВиртуальнойТаблицы";
КонецЕсли;
КонецПопытки;
ТаблицаРезультата = ирОбщий.ТаблицаЗначенийВТаблицуПолейБДЛкс(ТаблицаРезультата);
ПостроительЗапроса = Новый Структура("ДоступныеПоля", ТаблицаРезультата);
КонецЕсли;
ирОбщий.ДополнитьТаблицуПолейТаблицыБДВиртуальнымиПолямиЛкс(ПостроительЗапроса.ДоступныеПоля, ирОбщий.ОписаниеТаблицыБДЛкс(ИмяТаблицы));
Иначе
ПостроительЗапроса = Новый ПостроительЗапроса;
ЗапросРеквизитов = Новый Запрос("ВЫБРАТЬ Имя, ТипыСтрокой ИЗ Справочник.СвойстваМетаданных ГДЕ Владелец = &СсылкаМД");
ЗапросРеквизитов.УстановитьПараметр("СсылкаМД", МетаданныеРодителя);
ТаблицаРеквизитов = ЗапросРеквизитов.Выполнить().Выгрузить();
Для Каждого СтрокаРеквизита Из ТаблицаРеквизитов Цикл
ДоступноеПоле = ПостроительЗапроса.ДоступныеПоля.Добавить(СтрокаРеквизита.Имя);
Для Каждого СтрокаТипа Из СтрокаРеквизита.Типы Цикл
МассивТипов = Новый Массив;
ОбъектМД = КэшОбъект(СтрокаТипа.Объект);
МассивТипов.Добавить(Тип(ОбъектМД.Наименование));
КонецЦикла;
ДоступноеПоле.ТипЗначения = Новый ОписаниеТипов(МассивТипов);
КонецЦикла;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат ПостроительЗапроса;
КонецФункции
// Получает массив общих типов, дополняя исходный тип расширениями.
//
// Параметры:
// СтруктураТипа - Структура.
//
// Возвращаемое значение:
// Массив - структур типа.
//
Функция ТаблицаОбщихТиповИзСтруктурыТипа(СтруктураТипа) Экспорт
МассивОбщихТипов = НоваяТаблицаДополнительныхТипов();
ЗаполнитьЗначенияСвойств(МассивОбщихТипов.Добавить(), СтруктураТипа);
Если Найти(СтруктураТипа.ИмяОбщегоТипа, "ТабличнаяЧасть.") > 0 Тогда
НоваяСтрока = МассивОбщихТипов.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа);
НоваяСтрока.ИмяОбщегоТипа = "Табличная часть";
ИначеЕсли Найти(СтруктураТипа.ИмяОбщегоТипа, "ТабличнаяЧастьСтрока.") > 0 Тогда
НоваяСтрока = МассивОбщихТипов.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа);
НоваяСтрока.ИмяОбщегоТипа = "Строка табличной части";
ИначеЕсли СтруктураТипа.ИмяОбщегоТипа = "ПолеТекстовогоДокумента" Тогда
НоваяСтрока = МассивОбщихТипов.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа);
НоваяСтрока.ИмяОбщегоТипа = "ТекстовыйДокумент";
ИначеЕсли СтруктураТипа.ИмяОбщегоТипа = "ПолеГрафическойСхемы" Тогда
НоваяСтрока = МассивОбщихТипов.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа);
НоваяСтрока.ИмяОбщегоТипа = "ГрафическаяСхема";
ИначеЕсли СтруктураТипа.ИмяОбщегоТипа = "ПолеТабличногоДокумента" Тогда
НоваяСтрока = МассивОбщихТипов.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа);
НоваяСтрока.ИмяОбщегоТипа = "ТабличныйДокумент";
//ИначеЕсли Найти(СтруктураТипа.ИмяОбщегоТипа, "Расширение формы") > 0 Тогда
// НоваяСтрока = МассивОбщихТипов.Добавить();
// ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа);
// НоваяСтрока.ИмяОбщегоТипа = "Форма";
ИначеЕсли СтруктураТипа.ИмяОбщегоТипа = "Локальный" Тогда
Если ТипЗнч(СтруктураТипа.Метаданные) <> Тип("COMОбъект") Тогда
НоваяСтрока = МассивОбщихТипов.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа);
НоваяСтрока.ИмяОбщегоТипа = "Глобальный";
// Этот раздел был в 8.2. Но в каком то релизе 8.3 убрали
//НоваяСтрока = МассивОбщихТипов.Добавить();
//ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа);
//НоваяСтрока.ИмяОбщегоТипа = "Общее";
КонецЕсли;
ИначеЕсли СтруктураТипа.ИмяОбщегоТипа = "Automation сервер" Тогда
НоваяСтрока = МассивОбщихТипов.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа);
НоваяСтрока.ИмяОбщегоТипа = "Глобальный";
ИначеЕсли СтруктураТипа.ИмяОбщегоТипа = "Внешнее соединение" Тогда
НоваяСтрока = МассивОбщихТипов.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа);
НоваяСтрока.ИмяОбщегоТипа = "Глобальный";
Иначе
ОбщийТипМетаданных = ирОбщий.СтрокаМеждуМаркерамиЛкс(СтруктураТипа.ИмяОбщегоТипа, , ": ", Ложь);
//Если ОбщийТипМетаданных <> "" Тогда
Если ЗначениеЗаполнено(ОбщийТипМетаданных) Тогда
НоваяСтрока = МассивОбщихТипов.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа);
НоваяСтрока.ИмяОбщегоТипа = ОбщийТипМетаданных;
КонецЕсли;
КонецЕсли;
// Расширения, образованные элементом управления и типом связанных с ним данных
СтрокаРасширения = ТаблицаРасширенийТипов.Найти(СтруктураТипа.ИмяОбщегоТипа, "Расширение");
Если СтрокаРасширения <> Неопределено Тогда
Если Истина
И СтрокаРасширения.ОсновнойТип = "Форма"
И СтруктураТипа.ДополнительныеТипы = Неопределено
Тогда
НоваяСтрока = МассивОбщихТипов.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа);
НоваяСтрока.ИмяОбщегоТипа = СтрокаРасширения.РасширяющийТип;
//НоваяСтрока.НеВключатьМетоды = Истина; // Закомментировал 30.09.2010
#Если Клиент Тогда
Если ТипЗнч(СтруктураТипа.Метаданные) = Тип("Форма") Тогда
ОсновнойРеквизитФормы = ПолучитьИмяОсновногоРеквизитаФормы(СтруктураТипа.Метаданные);
НоваяСтрока.Метаданные = ирОбщий.ПолучитьМетаданныеЛкс(СтруктураТипа.Метаданные[ОсновнойРеквизитФормы]);
КонецЕсли;
#КонецЕсли
КонецЕсли;
НоваяСтрока = МассивОбщихТипов.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа);
НоваяСтрока.ИмяОбщегоТипа = СтрокаРасширения.ОсновнойТип;
КонецЕсли;
// Общие расширения элементов управления
лИмяОбщегоТипа = МассивОбщихТипов[МассивОбщихТипов.Количество() - 1].ИмяОбщегоТипа;
Если МассивОбычныхЭлементовУправления.Найти(лИмяОбщегоТипа) <> Неопределено Тогда
НоваяСтрока = МассивОбщихТипов.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа);
НоваяСтрока.ИмяОбщегоТипа = "Расширение элементов управления, расположенных в форме";
НоваяСтрока = МассивОбщихТипов.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа);
// Эту синтаксическую ошибку исправили только в 13-м релизе.
//НоваяСтрока.ИмяОбщегоТипа = "Расширение элементов управления расположенных на панели";
НоваяСтрока.ИмяОбщегоТипа = "Расширение элементов управления, расположенных на панели";
//ИначеЕсли МассивУправляемыхЭлементовУправления.Найти(лИмяОбщегоТипа) <> Неопределено Тогда
// // http://www.hostedredmine.com/issues/882998
// НоваяСтрока = МассивОбщихТипов.Добавить();
// ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа);
// НоваяСтрока.ИмяОбщегоТипа = "Расширение элементов управления, расположенных в форме";
КонецЕсли;
Если СтруктураТипа.ДополнительныеТипы <> Неопределено Тогда
ирОбщий.ЗагрузитьВТаблицуЗначенийЛкс(СтруктураТипа.ДополнительныеТипы, МассивОбщихТипов);
КонецЕсли;
Возврат МассивОбщихТипов;
КонецФункции // ТаблицаОбщихТиповИзСтруктурыТипа()
// Получает внутреннюю таблицу предопределенных слов заданного родительского типа.
//
// Параметры:
// РодительскаяСтруктураТипа - Структура;
// *Слово - Строка, *Неопределено - для отбора;
// *ТипСлова - Строка, *Неопределено - для отбора;
// *ВиртуальнаяТаблица - Структура, *Неопределено - описание виртуальной таблицы;
// *ЯзыкПрограммы - *Число, 0;
//
// Возвращаемое значение:
// ТаблицаЗначений - с колонками "Слово", "ТипСлова", "ТаблицаСтруктурТипов".
//
Функция СвойстваТипаПредопределенные(Знач РодительскаяСтруктураТипа, Знач Слово = Неопределено, Знач ТипСлова = Неопределено, Знач ВиртуальнаяТаблица = Неопределено, Знач ЯзыкПрограммы = 0,
Знач Конфигурация = Неопределено, Знач ВычислятьТипы = Истина, Знач ЛиСерверныйКонтекст = Ложь, Знач ТаблицаСвойств = Неопределено) Экспорт
КлючПоискаКонструктора = Новый Структура;
Если РодительскаяСтруктураТипа.Конструктор Тогда
КлючПоискаКонструктора = Новый Структура("ЕстьКонструктор, ЯзыкПрограммы, НСлово", Истина, ЯзыкПрограммы);
КонецЕсли;
ИмяОбщегоТипа = РодительскаяСтруктураТипа.ИмяОбщегоТипа;
Если Найти(ИмяОбщегоТипа, " {V") > 0 Тогда
ЧистоеИмяТипа = ирОбщий.ПервыйФрагментЛкс(ИмяОбщегоТипа, " ");
Если Найти(ЧистоеИмяТипа, "IV8COMConnector") = 1 Тогда
РодительскаяСтруктураТипа.ИмяОбщегоТипа = "Менеджер COM-соединений";
ИначеЕсли Найти(ЧистоеИмяТипа, "IServerAgentConnection") = 1 Тогда
РодительскаяСтруктураТипа.ИмяОбщегоТипа = "Соединение с агентом сервера";
ИначеЕсли Найти(ИмяОбщегоТипа, "IWorkingProcessConnection") Тогда
РодительскаяСтруктураТипа.ИмяОбщегоТипа = "Соединение с рабочим процессом";
ИначеЕсли Найти(ИмяОбщегоТипа, "Application") Тогда
РодительскаяСтруктураТипа.ИмяОбщегоТипа = "Automation сервер";
КонецЕсли;
КонецЕсли;
МассивОбщихТипов = ТаблицаОбщихТиповИзСтруктурыТипа(РодительскаяСтруктураТипа);
#Если Сервер И Не Сервер Тогда
МассивОбщихТипов = Новый ТаблицаЗначений;
ТаблицаСвойств = Новый ТаблицаЗначений;
#КонецЕсли
НомерВерсииПлатформы = ирКэш.НомерВерсииПлатформыЛкс();
СтрокаОбщегоТипаГлобального = МассивОбщихТипов.Найти("Глобальный", "ИмяОбщегоТипа");
Если СтрокаОбщегоТипаГлобального <> Неопределено Тогда
// Глобальный контекст всегда идет строго первым
МассивОбщихТипов.Сдвинуть(СтрокаОбщегоТипаГлобального, -МассивОбщихТипов.Индекс(СтрокаОбщегоТипаГлобального));
КонецЕсли;
Для Каждого СтрокаОбщегоТипа Из МассивОбщихТипов Цикл
ИмяОбщегоТипа = СтрокаОбщегоТипа.ИмяОбщегоТипа;
ИспользоватьКэширование = Истина
И ИмяОбщегоТипа = "Глобальный"
И Слово = Неопределено;
Если ИспользоватьКэширование Тогда
КлючКэширования = "" + ЯзыкПрограммы + ";" + Конфигурация + ";" + ВычислятьТипы + ";" + ЛиСерверныйКонтекст;
Если мКэшСловГлобальногоКонтекста = Неопределено Тогда
мКэшСловГлобальногоКонтекста = Новый Соответствие;
КонецЕсли;
ТаблицаСловИзКэша = мКэшСловГлобальногоКонтекста[КлючКэширования];
#Если Сервер И Не Сервер Тогда
ТаблицаСловИзКэша = Новый ТаблицаЗначений;
#КонецЕсли
Если ТаблицаСловИзКэша <> Неопределено Тогда
Если ТипСлова <> Неопределено Тогда
ОтборСлов = Новый Структура("ТипСлова", ТипСлова);
Иначе
ОтборСлов = Неопределено;
КонецЕсли;
Если ТаблицаСвойств <> Неопределено Тогда
ВызватьИсключение "Для глобального контекста нельзя передавать таблицу-приемник";
КонецЕсли;
ТаблицаСвойств = ТаблицаСловИзКэша.Скопировать(ОтборСлов);
Продолжить;
КонецЕсли;
КонецЕсли;
Если ТаблицаСвойств = Неопределено Тогда
ТаблицаСвойств = НоваяТаблицаСвойствТипа();
КонецЕсли;
МетаданныеРодителя = СтрокаОбщегоТипа.Метаданные;
КорневойТипРодителя = Неопределено;
ПостроительЗапросаРодителя = Неопределено;
ТипМетаданныхРодителя = ТипЗнч(МетаданныеРодителя);
Если Истина
И (Ложь
Или ТипМетаданныхРодителя = Тип("ОбъектМетаданных")
Или (Истина
И Это2iS
И (Ложь
Или ТипМетаданныхРодителя = Тип("СправочникСсылка.ОбъектыМетаданных2iS")
Или ТипМетаданныхРодителя = Тип("СправочникСсылка.СвойстваМетаданных2iS")))
Или (Истина
И ЭтоИнтеграция
И (Ложь
Или ТипМетаданныхРодителя = Тип("СправочникСсылка.МетаданныеИис")
Или ТипМетаданныхРодителя = Тип("СправочникСсылка.СвойстваМетаданныхИис"))))
И РодительскаяСтруктураТипа.ТипЯзыка <> "ИмяТипа"
Тогда
Если ТипМетаданныхРодителя = Тип("ОбъектМетаданных") Тогда
КорневойТипРодителя = ирОбщий.КорневойТипКонфигурацииЛкс(МетаданныеРодителя);
Иначе
КорневойТипРодителя = ирОбщий.КорневойТипКонфигурацииЛкс(КэшОбъект(МетаданныеРодителя).ПолноеИмя);
КонецЕсли;
ПостроительЗапросаРодителя = ПостроительЗапросаПоСтруктуреТипа(СтрокаОбщегоТипа, РодительскаяСтруктураТипа.ВиртуальнаяТаблица);
КонецЕсли;
Если ИмяОбщегоТипа = "Локальный" Тогда
НайденныеСтроки = Новый Массив;
ИначеЕсли ТипСлова = "Конструктор" Тогда
НайденныеСтроки = Новый Массив;
Если ИмяОбщегоТипа = "Глобальный" Тогда
СтруктураКлюча = Новый Структура("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка, ТипСлова",
Слово, ЯзыкПрограммы, РодительскаяСтруктураТипа.ТипЯзыка, ТипСлова);
НайденныеСтроки = ТаблицаКонтекстов.НайтиСтроки(СтруктураКлюча);
КонецЕсли;
Иначе
// Состав полей совпадает с индексом
СтруктураКлюча = Новый Структура("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка",
ИмяОбщегоТипа, ЯзыкПрограммы, РодительскаяСтруктураТипа.ТипЯзыка);
Если Слово <> Неопределено Тогда
СтруктураКлюча.Вставить("НСлово", НРег(Слово));
Если Истина
И ЯзыкПрограммы = 0 // В языке запросов может быть неоднозначность между типами слов Таблица и Поле. Поэтому для них жертвуем попаданием в индекс
И ТипСлова = Неопределено
Тогда
//ирОбщий.СообщитьЛкс("Использован медленный поиск по таблице контекстов");
ТипСлова = "Свойство"; // Так будем всегда попадать в индекс
КонецЕсли;
КонецЕсли;
Если ТипСлова <> Неопределено Тогда
СтруктураКлюча.Вставить("ТипСлова", ТипСлова);
КонецЕсли;
ирОбщий.ДобавитьИндексВТаблицуЛкс(ТаблицаКонтекстов, СтруктураКлюча); // спасает в случае языка запросов, где ТипСлова не используется
НайденныеСтроки = ТаблицаКонтекстов.НайтиСтроки(СтруктураКлюча);
КонецЕсли;
ПредыдущаяСтрокаСлова = Неопределено; // Для регистра бухгалтерии
ВычислятьТипыЦикл = ВычислятьТипы Или НайденныеСтроки.Количество() < 100;
Для Каждого СтрокаСлова Из НайденныеСтроки Цикл
Если Истина
И ПредыдущаяСтрокаСлова <> Неопределено
И ПредыдущаяСтрокаСлова.НСлово = СтрокаСлова.НСлово
И ПредыдущаяСтрокаСлова.ТипСлова = СтрокаСлова.ТипСлова
Тогда
Продолжить;
КонецЕсли;
ПредыдущаяСтрокаСлова = СтрокаСлова;
Если СтрокаСлова.НомерВерсииПлатформы > НомерВерсииПлатформы Тогда
Продолжить;
КонецЕсли;
Если Истина
И СтрокаСлова.ТипСлова = "Метод"
И СтрокаОбщегоТипа.НеВключатьМетоды
Тогда
Продолжить;
КонецЕсли;
Если Истина
И ТипСлова = Неопределено
И (Ложь
Или СтрокаСлова.ТипСлова = "Событие"
Или СтрокаСлова.ТипСлова = "Параметр"
Или СтрокаСлова.ТипСлова = "Конструктор")
Тогда
Продолжить;
КонецЕсли;
Если РодительскаяСтруктураТипа.Конструктор Тогда
КлючПоискаКонструктора.НСлово = НРег(СтрокаСлова.Слово);
Если ТаблицаОбщихТипов.НайтиСтроки(КлючПоискаКонструктора).Количество() = 0 Тогда
Продолжить;
КонецЕсли;
КонецЕсли;
ТаблицаСтруктурТипов = Неопределено;
Если ВычислятьТипыЦикл Тогда
ТаблицаСтруктурТипов = НоваяТаблицаСтруктурТипа();
ЛиДобавляемСлово = Истина;
МассивТиповЗначения = ирОбщий.СтрРазделитьЛкс(СтрокаСлова.ТипЗначения, ", ");
Для Каждого ИмяОбщегоТипа Из МассивТиповЗначения Цикл
СтруктураТипа = НоваяСтруктураТипа();
СтруктураТипа.СтрокаОписания = СтрокаСлова;
ЗаполнитьЗначенияСвойств(СтруктураТипа, РодительскаяСтруктураТипа, , "ИмяОбщегоТипа, СтрокаОписания, Метаданные");
Если Истина
//И ТипЗнч(МетаданныеРодителя) <> Тип("COMОбъект")
//И ИмяОбщегоТипа <>
//И СтрокаСлова.ТипСлова = "Свойство"
Тогда
ЗаполнитьЗначенияСвойств(СтруктураТипа, СтрокаОбщегоТипа, "Метаданные");
КонецЕсли;
Если ИмяОбщегоТипа = "ОбъектМетаданныхКонфигурация" Тогда
//СтруктураТипа.Метаданные = Конфигурация;
Если Конфигурация <> Неопределено Тогда
СтруктураТипа.Метаданные = Конфигурация;
Иначе
СтруктураТипа.Метаданные = мМетаданные;
КонецЕсли;
ИначеЕсли ИмяОбщегоТипа = "Отбор" Тогда
Если Ложь
//Или Найти(НРег(СтрокаОбщегоТипа.ИмяОбщегоТипа), "объект.") > 0
Или Найти(НРег(СтрокаОбщегоТипа.ИмяОбщегоТипа), "наборзаписей.") > 0
Тогда
ИмяТаблицыБД = ирКэш.ИмяТаблицыИзМетаданныхЛкс(СтрокаОбщегоТипа.Метаданные.ПолноеИмя());
СтруктураОбъекта = ирОбщий.ОбъектБДПоКлючуЛкс(ИмяТаблицыБД);
СтруктураТипа.Метаданные = СтруктураОбъекта.Методы;
ИначеЕсли СтрокаОбщегоТипа.ИмяОбщегоТипа = "Расширение табличного поля табличной части" Тогда
СтруктураТипа.Метаданные = Метаданные.НайтиПоТипу(ТипЗнч(СтрокаОбщегоТипа.Метаданные.Значение));
Иначе
КонкретныйТип = ИмяТипаИзСтруктурыТипа(СтрокаОбщегоТипа);
Если Истина
И Найти(КонкретныйТип, "<") = 0
И ТипЗнч(СтруктураТипа.Метаданные) <> Тип(КонкретныйТип)
Тогда
Попытка
Образователь = Новый (КонкретныйТип);
СтруктураТипа.Метаданные = Образователь;
Исключение
// Срабатывает для табличных полей
КонецПопытки;
КонецЕсли;
КонецЕсли;
КонецЕсли;
СтруктураТипа.ИмяОбщегоТипа = ИмяОбщегоТипа;
Если ВиртуальнаяТаблица <> Неопределено Тогда
ЗаполнитьЗначенияСвойств(СтруктураТипа.ВиртуальнаяТаблица, ВиртуальнаяТаблица);
КонецЕсли;
Если РодительскаяСтруктураТипа.ТипЯзыка = "ИмяТипа" Тогда
СтруктураТипа.ИмяОбщегоТипа = СтрокаСлова.Слово;
Если СтрокаСлова.ТипКонтекста <> "" Тогда
СтруктураТипа.ИмяОбщегоТипа = СтрокаСлова.ТипКонтекста + "." + СтруктураТипа.ИмяОбщегоТипа;
КонецЕсли;
КонецЕсли;
Если Истина
И СтруктураТипа.ИмяОбщегоТипа = "Строка табличной части"
И Найти(РодительскаяСтруктураТипа.ИмяОбщегоТипа, "ТабличнаяЧасть.") > 0
Тогда
СтруктураТипа.ИмяОбщегоТипа = СтрЗаменить(РодительскаяСтруктураТипа.ИмяОбщегоТипа, "ТабличнаяЧасть.", "ТабличнаяЧастьСтрока.");
КонецЕсли;
МаркерРасширений = "Расширение ";
Если Истина
И Лев(РодительскаяСтруктураТипа.ИмяОбщегоТипа, СтрДлина(МаркерРасширений)) = МаркерРасширений
И СтрокаСлова.Слово = "Значение"
Тогда
Если РодительскаяСтруктураТипа.Метаданные <> Неопределено Тогда
СтруктураТипа = СтруктураТипаИзЗначения(РодительскаяСтруктураТипа.Метаданные.Значение);
Иначе
СтрокаРасширения = ТаблицаРасширенийТипов.Найти(РодительскаяСтруктураТипа.ИмяОбщегоТипа, "Расширение");
//Если СтрокаРасширения <> Неопределено Тогда
СтруктураТипа.ИмяОбщегоТипа = СтрокаРасширения.РасширяющийТип;
//КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Истина
И МетаданныеРодителя <> Неопределено
И СтрокаСлова.ТипСлова = "Свойство"
Тогда
Если Ложь
Или ТипЗнч(МетаданныеРодителя) = Тип("ПостроительЗапроса")
Или (Истина // Нельзя допускать неявного выполнения запроса при обращении к свойству "Результат" построителя
И СтруктураТипа.ИмяОбщегоТипа = "РезультатЗапроса"
И ТипЗнч(МетаданныеРодителя) = Тип("ПостроительЗапроса"))
Или (Истина // Здесь свойство есть у объекта метаданных, но имеет другой смысл
И СтрокаСлова.Слово = "ВидыСубконто"
И СтруктураТипа.ИмяОбщегоТипа = "ПланСчетовВидыСубконто.<Имя плана счетов>")
Тогда
ЗначениеСвойства = МетаданныеРодителя;
Иначе
Если Истина
#Если Клиент Тогда
И ТипЗнч(МетаданныеРодителя) = Тип("ТабличноеПоле")
#Иначе
И Ложь
#КонецЕсли
И СтрокаСлова.Слово = "ТекущийРодитель"
Тогда
// Антибаг платформы 8.2.16. Вывести в чистом виде не удалось. Падает при вычислении свойства ТекущийРодитель в форме списка РС.ООП_ВаучерыТез
ЗначениеСвойства = Неопределено;
Иначе
Попытка
ЗначениеСвойства = МетаданныеРодителя[СтрокаСлова.Слово];
Исключение
ЗначениеСвойства = Неопределено;
КонецПопытки;
КонецЕсли;
КонецЕсли;
Если ЗначениеСвойства <> Неопределено Тогда
Если мМассивТиповВключающихМетаданные.Найти(ТипЗнч(ЗначениеСвойства)) <> Неопределено Тогда
СтруктураТипа.Метаданные = ЗначениеСвойства;
КонецЕсли;
КонецЕсли;
КонецЕсли;
// Для методов метаданных нужна специфическая обработка для усечения типов
Если Истина
И СтрокаСлова.ТипСлова = "Метод"
И Лев(ИмяОбщегоТипа, СтрДлина(МаркерОбъектаМетаданных)) = МаркерОбъектаМетаданных
И СтрокаСлова.Слово = "Родитель"
Тогда
Родитель = Неопределено;
Если ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") Тогда
Родитель = МетаданныеРодителя.Родитель();
КонецЕсли;
Если Родитель <> Неопределено Тогда
МассивФрагментов = ирОбщий.СтрРазделитьЛкс(Родитель.ПолноеИмя());
СтруктураТипа.ИмяОбщегоТипа = МаркерОбъектаМетаданных + ": " + МассивФрагментов[МассивФрагментов.ВГраница() - 1];
Иначе
СтруктураТипа.ИмяОбщегоТипа = "Неопределено";
КонецЕсли;
СтруктураТипа.Метаданные = Родитель;
ДобавитьВТаблицуСтруктурТипов(ТаблицаСтруктурТипов, СтруктураТипа);
Прервать;
ИначеЕсли Истина
И СтрокаСлова.ТипСлова = "Метод"
И Лев(ИмяОбщегоТипа, СтрДлина(МаркерКоллекцииОбъектовМетаданных)) = МаркерКоллекцииОбъектовМетаданных
И (Ложь
Или СтрокаСлова.Слово = "Найти"
Или СтрокаСлова.Слово = "Получить")
Тогда
СтруктураКлюча = Новый Структура("БазовыйТип, ЯзыкПрограммы", ИмяОбщегоТипа, ЯзыкПрограммы);
НайденныеСтроки = ТаблицаОбщихТипов.НайтиСтроки(СтруктураКлюча);
СтруктураТипа.ИмяОбщегоТипа = НайденныеСтроки[0].ТипЭлементаКоллекции;
ДобавитьВТаблицуСтруктурТипов(ТаблицаСтруктурТипов, СтруктураТипа);
Прервать;
КонецЕсли;
Если КорневойТипРодителя <> Неопределено Тогда
ДоступноеПолеСлова = ПостроительЗапросаРодителя.ДоступныеПоля.Найти(НРег(СтрокаСлова.Слово));
// Частные случаи
Если Ложь
Или СтрокаСлова.ТипСлова = "Поле"
Или СтрокаСлова.Слово = "Активность"
Или СтрокаСлова.Слово = "Владелец"
Или СтрокаСлова.Слово = "ВидДвижения"
Или СтрокаСлова.Слово = "Период"
Или СтрокаСлова.Слово = "Регистратор"
Или СтрокаСлова.Слово = "МоментВремени"
Или СтрокаСлова.Слово = "НомерСтроки"
//Или СтрокаСлова.Слово = "СубконтоДт" // Закомментировано 14.04.2012
//Или СтрокаСлова.Слово = "СубконтоКт" // Закомментировано 14.04.2012
Или СтрокаСлова.Слово = "СчетДт"
Или СтрокаСлова.Слово = "СчетКт"
Тогда
Если ДоступноеПолеСлова = Неопределено Тогда
ЛиДобавляемСлово = Ложь;
Иначе
ОписаниеТиповСлова = ДоступноеПолеСлова.ТипЗначения;
Для Каждого ТипЗначенияСлова Из ОписаниеТиповСлова.Типы() Цикл
ШаблонСтруктурыТипа = Новый Структура("СтрокаОписания, ТипЯзыка, Квалификаторы");
ШаблонСтруктурыТипа.СтрокаОписания = СтрокаСлова;
ШаблонСтруктурыТипа.Квалификаторы = ОписаниеТиповСлова;
ЗаполнитьЗначенияСвойств(ШаблонСтруктурыТипа, РодительскаяСтруктураТипа, "ТипЯзыка");
СтруктураТипа = СтруктураТипаИзКонкретногоТипа(ТипЗначенияСлова, ЯзыкПрограммы, ШаблонСтруктурыТипа);
ДобавитьВТаблицуСтруктурТипов(ТаблицаСтруктурТипов, СтруктураТипа);
КонецЦикла;
КонецЕсли;
Прервать;
ИначеЕсли Ложь
Или (Истина
И ИмяОбщегоТипа = "КонстантаМенеджер.<Имя константы>"
И СтрокаСлова.Слово = "Получить")
Или (Истина
И ИмяОбщегоТипа = "КонстантаМенеджерЗначения.<Имя константы>"
И СтрокаСлова.Слово = "Значение")
Тогда
ОписаниеТиповСлова = МетаданныеРодителя.Тип;
Для Каждого ТипЗначенияСлова Из ОписаниеТиповСлова.Типы() Цикл
ШаблонСтруктурыТипа = Новый Структура("СтрокаОписания, ТипЯзыка, Квалификаторы");
ШаблонСтруктурыТипа.СтрокаОписания = СтрокаСлова;
ШаблонСтруктурыТипа.Квалификаторы = ОписаниеТиповСлова;
ЗаполнитьЗначенияСвойств(ШаблонСтруктурыТипа, РодительскаяСтруктураТипа, "ТипЯзыка");
СтруктураТипа = СтруктураТипаИзКонкретногоТипа(ТипЗначенияСлова, ЯзыкПрограммы, ШаблонСтруктурыТипа);
ДобавитьВТаблицуСтруктурТипов(ТаблицаСтруктурТипов, СтруктураТипа);
КонецЦикла;
ИначеЕсли Истина
И СтрокаСлова.ТипСлова = "Метод"
И (Ложь
Или СтрокаСлова.Слово = "Выгрузить"
Или СтрокаСлова.Слово = "ВыгрузитьКолонки")
И ТипЗнч(СтрокаОбщегоТипа.Метаданные) = Тип("ОбъектМетаданных")
Тогда
КонкретныйТип = ИмяТипаИзСтруктурыТипа(СтрокаОбщегоТипа);
Образователь = Неопределено;
Если НРег(КонкретныйТип) = Нрег("Табличная часть") Тогда
МассивФрагментов = ирОбщий.СтрРазделитьЛкс(СтрокаОбщегоТипа.Метаданные.ПолноеИмя());
Если Ложь
Или МассивФрагментов[0] = "Обработка"
Или МассивФрагментов[0] = "Отчет"
Тогда
Образователь = Новый (МассивФрагментов[0] + "Объект." + МассивФрагментов[1]);
Образователь = Образователь[МассивФрагментов[3]];
Иначе
СтруктураОбъекта = ирОбщий.ОбъектБДПоКлючуЛкс(МассивФрагментов[0] + "." + МассивФрагментов[1]);
Образователь = СтруктураОбъекта.Данные[МассивФрагментов[3]];
КонецЕсли;
ИначеЕсли НРег(СтрокаОбщегоТипа.ИмяОбщегоТипа) = Нрег("ПланСчетовВидыСубконто.<Имя плана счетов>") Тогда
МассивФрагментов = ирОбщий.СтрРазделитьЛкс(СтрокаОбщегоТипа.Метаданные.ПолноеИмя());
СтруктураОбъекта = ирОбщий.ОбъектБДПоКлючуЛкс(МассивФрагментов[0] + "." + МассивФрагментов[1]);
Образователь = СтруктураОбъекта.Данные.ВидыСубконто;
ИначеЕсли Ложь
Или НРег(СтрокаОбщегоТипа.ИмяОбщегоТипа) = Нрег("ВытесняющиеВидыРасчета.<Имя плана видов расчета>")
Или НРег(СтрокаОбщегоТипа.ИмяОбщегоТипа) = Нрег("БазовыеВидыРасчета.<Имя плана видов расчета>")
Или НРег(СтрокаОбщегоТипа.ИмяОбщегоТипа) = Нрег("ВедущиеВидыРасчета.<Имя плана видов расчета>")
Тогда
МассивФрагментов = ирОбщий.СтрРазделитьЛкс(СтрокаОбщегоТипа.Метаданные.ПолноеИмя());
СтруктураОбъекта = ирОбщий.ОбъектБДПоКлючуЛкс(МассивФрагментов[0] + "." + МассивФрагментов[1]);
ИмяТЧ = ирОбщий.ПервыйФрагментЛкс(СтрокаОбщегоТипа.ИмяОбщегоТипа);
Попытка
Образователь = СтруктураОбъекта.Данные[ИмяТЧ];
Исключение
КонецПопытки;
ИначеЕсли Найти(КонкретныйТип, "<") = 0 Тогда
СтруктураОбъекта = ирОбщий.ОбъектБДПоКлючуЛкс(ирКэш.ИмяТаблицыИзМетаданныхЛкс(СтрокаОбщегоТипа.Метаданные.ПолноеИмя()));
Образователь = СтруктураОбъекта.Данные;
КонецЕсли;
Если Образователь <> Неопределено Тогда
Если ТипЗнч(Образователь) = Тип("ТаблицаЗначений") Тогда
Образователь = Образователь;
Иначе
Образователь = Образователь.ВыгрузитьКолонки();
КонецЕсли;
СтруктураТипа.Метаданные = Образователь;
КонецЕсли;
ИначеЕсли Истина
И (Ложь
Или СтрокаСлова.Слово = "СрезПервых"
Или СтрокаСлова.Слово = "СрезПоследних")
И КорневойТипРодителя = "РегистрСведений"
И МетаданныеРодителя.ПериодичностьРегистраСведений = мМетаданные.СвойстваОбъектов.ПериодичностьРегистраСведений.Непериодический
Тогда
ЛиДобавляемСлово = Ложь;
Прервать;
ИначеЕсли Истина
И (Ложь
Или СтрокаСлова.Слово = "Остатки"
Или СтрокаСлова.Слово = "ОстаткиИОбороты")
И КорневойТипРодителя = "РегистрНакопления"
И МетаданныеРодителя.ВидРегистра = мМетаданные.СвойстваОбъектов.ВидРегистраНакопления.Обороты
Тогда
ЛиДобавляемСлово = Ложь;
Прервать;
ИначеЕсли Истина
И (Ложь
Или СтрокаСлова.Слово = "ОборотыДтКт")
И КорневойТипРодителя = "РегистрБухгалтерии"
И Не МетаданныеРодителя.Корреспонденция
Тогда
ЛиДобавляемСлово = Ложь;
Прервать;
Иначе
ДобавитьВТаблицуСтруктурТипов(ТаблицаСтруктурТипов, СтруктураТипа);
КонецЕсли;
ИначеЕсли Истина
И СтрокаСлова.ТипСлова = "Метод"
И СтрокаСлова.Слово = "Выгрузить"
И ТипЗнч(СтрокаОбщегоТипа.Метаданные) = Тип("ПостроительЗапроса")
Тогда
ТаблицаЗначений = Новый ТаблицаЗначений;
Для Каждого ВыбранноеПоле Из СтрокаОбщегоТипа.Метаданные.ВыбранныеПоля Цикл
ТаблицаЗначений.Колонки.Добавить(ВыбранноеПоле.Имя, СтрокаОбщегоТипа.Метаданные.ДоступныеПоля[ВыбранноеПоле.Имя].ТипЗначения);
КонецЦикла;
СтруктураТипа.Метаданные = ТаблицаЗначений;
ДобавитьВТаблицуСтруктурТипов(ТаблицаСтруктурТипов, СтруктураТипа, Ложь);
Иначе
Если Истина
И ИмяОбщегоТипа = "Форма"
И СтрокаСлова.Слово = "ЭтаФорма"
Тогда
ДобавитьВТаблицуСтруктурТипов(ТаблицаСтруктурТипов, РодительскаяСтруктураТипа, Истина);
Иначе
ДобавитьВТаблицуСтруктурТипов(ТаблицаСтруктурТипов, СтруктураТипа, Ложь);
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если Не ЛиДобавляемСлово Тогда
Продолжить;
КонецЕсли;
Если ТаблицаСтруктурТипов.Количество() = 0 Тогда
ДобавитьВТаблицуСтруктурТипов(ТаблицаСтруктурТипов, СтруктураТипа);
КонецЕсли;
КонецЕсли;
ДобавитьВТаблицуСлов(ТаблицаСвойств, СтрокаСлова.Слово, СтрокаСлова.ТипСлова, ТаблицаСтруктурТипов, СтрокаСлова.ТипЗначения, "Предопределенный");
КонецЦикла;
Если ИспользоватьКэширование Тогда
мКэшСловГлобальногоКонтекста[КлючКэширования] = ТаблицаСвойств.Скопировать();
КонецЕсли;
КонецЦикла;
Возврат ТаблицаСвойств;
КонецФункции
// Получает внутреннюю таблицу метаданных слов заданного родительского типа.
//
// Параметры:
// РодительскаяСтруктураТипа - Структура;
// *Слово - Строка, *Неопределено - для отбора;
// *ТипСлова - Строка, *Неопределено - для отбора;
// *ВиртуальнаяТаблица - Структура, *Неопределено - описание виртуальной таблицы;
// *ЯзыкПрограммы - *Число, 0;
// *ТекущийИндекс - Строка - выражение в квадратных скобках.
//
// Возвращаемое значение:
// ТаблицаЗначений - с колонками "Слово", "ТипСлова", "ТаблицаСтруктурТипов".
//
Функция СвойстваТипаМетаданные(Знач РодительскаяСтруктураТипа, Знач Слово = Неопределено, Знач ТипСлова = Неопределено, Знач ВиртуальнаяТаблица = Неопределено, Знач ЯзыкПрограммы = 0,
Знач ТекущийИндекс = Неопределено, Знач ВнешниеФункцииКомпоновкиДанных = Истина, Знач ВычислятьТипы = Истина, Знач ЛиСерверныйКонтекст = Ложь, Знач МодульМетаданных = Неопределено,
Знач ТаблицаСвойств = Неопределено, Знач ВычислятьТипыМетодовМодулей = Ложь) Экспорт
Если ТаблицаСвойств = Неопределено Тогда
ТаблицаСвойств = НоваяТаблицаСвойствТипа();
КонецЕсли;
ЭтоМетаданныеТабличнойЧастиВнешнейОбработки = ирОбщий.ПервыйФрагментЛкс(ирОбщий.ПредставлениеЗначенияЛкс(РодительскаяСтруктураТипа.Метаданные)) = "ВнешняяОбработкаТабличнаяЧасть";
Если Не ЭтоМетаданныеТабличнойЧастиВнешнейОбработки Тогда
КонкретныйТип = ИмяТипаИзСтруктурыТипа(РодительскаяСтруктураТипа);
Если Найти(КонкретныйТип, "<") > 0 Тогда
// Такой конкретный тип не разрешен
Возврат ТаблицаСвойств;
КонецЕсли;
КонецЕсли;
Если ЗначениеЗаполнено(Слово) Тогда
ВычислятьТипыМетодовМодулей = Истина;
КонецЕсли;
ТаблицаОбщихТиповСтруктурыТипа = ТаблицаОбщихТиповИзСтруктурыТипа(РодительскаяСтруктураТипа);
Если Истина
И Слово <> Неопределено
И ТекущийИндекс <> Неопределено
Тогда
RegExp.Global = Ложь;
RegExp.Pattern = "^""(" + шИмя + ")""$";
РезультатСтроковойКонстанты = RegExp.НайтиВхождения(Слово);
Если РезультатСтроковойКонстанты.Количество() > 0 Тогда
Слово = РезультатСтроковойКонстанты[0].SubMatches(0);
КонецЕсли;
RegExp.Pattern = "^(" + шИмя + ")$";
ЛиСловоИдентификатор = RegExp.Проверить(Слово);
Если Не ЛиСловоИдентификатор Тогда
// Это элемент универсальной коллекции
СтруктураКлюча = Новый Структура("Слово, ЯзыкПрограммы", РодительскаяСтруктураТипа.ИмяОбщегоТипа, ЯзыкПрограммы);
НайденныеСтроки = ТаблицаОбщихТипов.НайтиСтроки(СтруктураКлюча);
Если НайденныеСтроки.Количество() > 0 Тогда
ТипыЭлементовКоллекции = ирОбщий.СтрРазделитьЛкс(НайденныеСтроки[0].ТипЭлементаКоллекции, ",", Истина, Ложь);
Для Каждого ТипЭлементаКоллекции Из ТипыЭлементовКоллекции Цикл
СтруктураКлюча = Новый Структура("БазовыйТип, ЯзыкПрограммы", ТипЭлементаКоллекции, ЯзыкПрограммы);
НайденныеСтроки = ТаблицаОбщихТипов.НайтиСтроки(СтруктураКлюча);
Если НайденныеСтроки.Количество() > 0 Тогда
СтрокаТипа = НайденныеСтроки[0];
СтруктураТипа = НоваяСтруктураТипа();
СтруктураТипа.СтрокаОписания = СтрокаТипа;
СтруктураТипа.ИмяОбщегоТипа = СтрокаТипа.Слово;
СтруктураТипа.Метаданные = РодительскаяСтруктураТипа.Метаданные;
ТаблицаСтруктурТипов = НоваяТаблицаСтруктурТипа();
ДобавитьВТаблицуСтруктурТипов(ТаблицаСтруктурТипов, СтруктураТипа);
ДобавитьВТаблицуСлов(ТаблицаСвойств, СтрокаТипа.Слово, "Свойство", ТаблицаСтруктурТипов,, "Метаданные");
КонецЕсли;
КонецЦикла;
КонецЕсли;
Возврат ТаблицаСвойств;
КонецЕсли;
КонецЕсли;
НомерВерсииПлатформы = ирКэш.НомерВерсииПлатформыЛкс();
Для Каждого СтрокаОбщегоТипа Из ТаблицаОбщихТиповСтруктурыТипа Цикл
ИмяОбщегоТипа = СтрокаОбщегоТипа.ИмяОбщегоТипа;
Если ирОбщий.СтрокиРавныЛкс(ИмяОбщегоТипа, "ISWbemObject {WbemScripting.SwbemLocator}") Тогда
Если ТипЗнч(СтрокаОбщегоТипа.Метаданные) = Тип("COMОбъект") Тогда
СтруктураЦикла = Новый Структура();
Попытка
СтруктураЦикла.Вставить("Свойство", СтрокаОбщегоТипа.Метаданные.Properties_);
СтруктураЦикла.Вставить("Метод", СтрокаОбщегоТипа.Метаданные.Methods_);
Исключение
КонецПопытки;
Для Каждого КлючИЗначение Из СтруктураЦикла Цикл
КоллекцияСвойств = КлючИЗначение.Значение;
лТипСлова = КлючИЗначение.Ключ;
Если Истина
И ТипСлова <> Неопределено
И Не ирОбщий.СтрокиРавныЛкс(лТипСлова, ТипСлова)
Тогда
Продолжить;
КонецЕсли;
Для Каждого Свойство Из КоллекцияСвойств Цикл
ИмяСвойства = Свойство.Name;
Если Истина
И Слово <> Неопределено
И Не ирОбщий.СтрокиРавныЛкс(ИмяСвойства, Слово)
Тогда
Продолжить;
КонецЕсли;
ТаблицаСтруктурТипов = НоваяТаблицаСтруктурТипа();
СтруктураТипа = ТаблицаСтруктурТипов.Добавить();
СтруктураТипа.СтрокаОписания = Свойство;
СтруктураТипа.ИмяОбщегоТипа = ирОбщий.ИмяТипаИзКвалификаторовWMIЛкс(Свойство);
СтруктураТипа.Метаданные = РодительскаяСтруктураТипа.Метаданные;
ДобавитьВТаблицуСлов(ТаблицаСвойств, ИмяСвойства, лТипСлова, ТаблицаСтруктурТипов,, "Метаданные");
КонецЦикла;
КонецЦикла;
КонецЕсли;
КонецЕсли;
МетаданныеРодителя = СтрокаОбщегоТипа.Метаданные;
КорневойТипРодителя = Неопределено;
ПостроительЗапросаРодителя = Неопределено;
Если РодительскаяСтруктураТипа.ТипЯзыка <> "ИмяТипа" Тогда
ТипМетаданныхРодителя = ТипЗнч(МетаданныеРодителя);
Если Ложь
Или ТипМетаданныхРодителя = Тип("ОбъектМетаданных")
Или (Истина
И Это2iS
И (Ложь
Или ТипМетаданныхРодителя = Тип("СправочникСсылка.ОбъектыМетаданных2iS")
Или ТипМетаданныхРодителя = Тип("СправочникСсылка.СвойстваМетаданных2iS")))
Или (Истина
И ЭтоИнтеграция
И (Ложь
Или ТипМетаданныхРодителя = Тип("СправочникСсылка.МетаданныеИис")
Или ТипМетаданныхРодителя = Тип("СправочникСсылка.СвойстваМетаданныхИис")))
Тогда
Если ТипМетаданныхРодителя = Тип("ОбъектМетаданных") Тогда
КорневойТипРодителя = ирОбщий.КорневойТипКонфигурацииЛкс(МетаданныеРодителя);
Иначе
КорневойТипРодителя = ирОбщий.КорневойТипКонфигурацииЛкс(КэшОбъект(МетаданныеРодителя).ПолноеИмя);
КонецЕсли;
ПостроительЗапросаРодителя = ПостроительЗапросаПоСтруктуреТипа(СтрокаОбщегоТипа, РодительскаяСтруктураТипа.ВиртуальнаяТаблица);
КонецЕсли;
КонецЕсли;
Если Истина
И ЯзыкПрограммы = 2
И ИмяОбщегоТипа = "Глобальный"
И ВнешниеФункцииКомпоновкиДанных
Тогда
СтруктураКлюча = Новый Структура("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка, НСлово", ИмяОбщегоТипа, 0, РодительскаяСтруктураТипа.ТипЯзыка, НРег("<Имя общего модуля>"));
Иначе
СтруктураКлюча = Новый Структура("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка", ИмяОбщегоТипа, ЯзыкПрограммы, РодительскаяСтруктураТипа.ТипЯзыка);
КонецЕсли;
Если ТипСлова <> Неопределено Тогда
СтруктураКлюча.Вставить("ТипСлова", ТипСлова);
КонецЕсли;
НайденныеСтроки = ТаблицаШаблоновКонтекстов.НайтиСтроки(СтруктураКлюча);
ПредыдущаяСтрокаВида = Неопределено; // Для регистра бухгалтерии
Для Каждого СтрокаВида Из НайденныеСтроки Цикл
Если Истина
И ПредыдущаяСтрокаВида <> Неопределено
И ПредыдущаяСтрокаВида.НСлово = СтрокаВида.НСлово
И ПредыдущаяСтрокаВида.ТипСлова = СтрокаВида.ТипСлова
Тогда
Продолжить;
КонецЕсли;
ПредыдущаяСтрокаВида = СтрокаВида;
Если СтрокаВида.НомерВерсииПлатформы > НомерВерсииПлатформы Тогда
Продолжить;
КонецЕсли;
СхемаКоллекции = Новый Соответствие;
МетаданныеЭлементов = Новый Соответствие;
КоллекцияЗначений = Неопределено;
ИмяЭлементаКоллекции = ирОбщий.СтрокаМеждуМаркерамиЛкс(СтрокаВида.Слово, "<", ">", Ложь, Истина);
КлючПоиска = Новый Структура("ИмяОбщегоТипа, ИмяЭлементаКоллекции", ИмяОбщегоТипа, ИмяЭлементаКоллекции);
СтрокаОписанияВида = Неопределено;
НайденныеСтрокиКоллекций = ТаблицаИменЭлементовКоллекций.НайтиСтроки(КлючПоиска);
Если НайденныеСтрокиКоллекций.Количество() > 0 Тогда
СтрокаОписанияВида = НайденныеСтрокиКоллекций[0];
КонецЕсли;
Если СтрокаОписанияВида = Неопределено Тогда
КлючПоиска.Удалить("ИмяОбщегоТипа");
НайденныеСтрокиКоллекций = ТаблицаИменЭлементовКоллекций.НайтиСтроки(КлючПоиска);
Если НайденныеСтрокиКоллекций.Количество() > 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.Получить(Свойство.Имя);
КонецЕсли;
КоллекцияЗначений.Вставить(Свойство.Имя, ЗначениеСвойства);
КонецЕсли;
#Если Клиент Тогда
ИначеЕсли Истина
И СтрокаОписанияВида.ИмяКоллекции = "Реквизиты"
И ТипЗнч(МетаданныеРодителя) = Тип("Форма")
Тогда
МассивИмен = ПолучитьМассивИменРеквизитовФормы(МетаданныеРодителя);
КоллекцияЗначений = Новый Структура;
Для Каждого ИмяРеквизита Из МассивИмен Цикл
КоллекцияЗначений.Вставить(ИмяРеквизита, МетаданныеРодителя[ИмяРеквизита]);
КонецЦикла;
ИначеЕсли Ложь
Или (Истина
И СтрокаОписанияВида.ИмяКоллекции = "ЭлементыФормы"
И ТипЗнч(МетаданныеРодителя) = Тип("Форма"))
Или (Истина
И СтрокаОписанияВида.ИмяКоллекции = "Элементы"
И ТипЗнч(МетаданныеРодителя) = Тип("УправляемаяФорма"))
Или (Истина
И СтрокаОписанияВида.ИмяКоллекции = "Страницы"
И ТипЗнч(МетаданныеРодителя) = Тип("Панель"))
Или (Истина
И СтрокаОписанияВида.ИмяКоллекции = "Кнопки"
И (Ложь
Или ТипЗнч(МетаданныеРодителя) = Тип("КнопкаКоманднойПанели")
Или ТипЗнч(МетаданныеРодителя) = Тип("КнопкиКоманднойПанели")))
Тогда
КоллекцияЗначений = МетаданныеРодителя[СтрокаОписанияВида.ИмяКоллекции];
ИначеЕсли Истина
И СтрокаОписанияВида.ИмяКоллекции = "ПодчиненныеЭлементы"
И (Ложь
Или ТипЗнч(МетаданныеРодителя) = Тип("УправляемаяФорма")
Или ТипЗнч(МетаданныеРодителя) = Тип("ТаблицаФормы")
Или ТипЗнч(МетаданныеРодителя) = Тип("ГруппаФормы"))
Тогда
КоллекцияЗначений = МетаданныеРодителя[СтрокаОписанияВида.ИмяКоллекции];
#КонецЕсли
ИначеЕсли ТипЗнч(МетаданныеРодителя) = Тип("НаборыДанныхСхемыКомпоновкиДанных") Тогда
КоллекцияЗначений = МетаданныеРодителя;
//ИначеЕсли СтрокаОписанияВида.ИмяКоллекции = "Оформление" Тогда
// Для Каждого МетаОбщийМодуль Из МетаданныеРодителя[СтрокаОписанияВида.ИмяКоллекции] Цикл
// Если МетаОбщийМодуль.Глобальный Тогда
// Продолжить;
// КонецЕсли;
// СхемаКоллекции.Вставить(МетаОбщийМодуль.Имя);
// КонецЦикла;
ИначеЕсли Истина
И СтрокаОписанияВида.ИмяКоллекции = "ОбщиеМодули"
И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданныхКонфигурация") //
Тогда
СхемаКоллекции = ирКэш.ДоступныеОбщиеМодулиЛкс(ЛиСерверныйКонтекст);
ИначеЕсли Истина
И СтрокаОписанияВида.ИмяКоллекции = "ВидыСубконто"
И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") //
Тогда
Для Счетчик = 1 По МетаданныеРодителя.ПланСчетов.МаксКоличествоСубконто Цикл
СхемаКоллекции.Вставить(Строка(Счетчик), МетаданныеРодителя.ПланСчетов.ВидыСубконто);
КонецЦикла;
ИначеЕсли СтрокаОписанияВида.ИмяКоллекции = "Движения" Тогда
Если ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") Тогда
Для Каждого МетаРегистр Из МетаданныеРодителя[СтрокаОписанияВида.ИмяКоллекции] Цикл
МассивФрагментов = ирОбщий.СтрРазделитьЛкс(МетаРегистр.ПолноеИмя());
СхемаКоллекции.Вставить(МетаРегистр.Имя, Новый ОписаниеТипов(МассивФрагментов[0] + "НаборЗаписей." + МассивФрагментов[1]));
КонецЦикла;
ИначеЕсли ТипЗнч(МетаданныеРодителя) = Тип("КоллекцияДвижений") Тогда
Для Каждого НаборЗаписейРегистра Из МетаданныеРодителя Цикл
СхемаКоллекции.Вставить(НаборЗаписейРегистра.Метаданные().Имя, НаборЗаписейРегистра);
КонецЦикла;
ИначеЕсли Истина
И Слово <> Неопределено
И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданныхКонфигурация") //
Тогда
МетаданныеРегистра = Метаданные.РегистрыСведений.Найти(Слово);
Если МетаданныеРегистра = Неопределено Тогда
МетаданныеРегистра = Метаданные.РегистрыНакопления.Найти(Слово);
КонецЕсли;
Если МетаданныеРегистра = Неопределено Тогда
МетаданныеРегистра = Метаданные.РегистрыБухгалтерии.Найти(Слово);
КонецЕсли;
Если МетаданныеРегистра = Неопределено Тогда
МетаданныеРегистра = Метаданные.РегистрыРасчета.Найти(Слово);
КонецЕсли;
Если МетаданныеРегистра <> Неопределено Тогда
МассивФрагментов = ирОбщий.СтрРазделитьЛкс(МетаданныеРегистра.ПолноеИмя());
СхемаКоллекции.Вставить(МассивФрагментов[1], Новый ОписаниеТипов(МассивФрагментов[0] + "НаборЗаписей." + МассивФрагментов[1]));
КонецЕсли;
КонецЕсли;
ИначеЕсли Истина
И СтрокаОписанияВида.ИмяКоллекции = "ТочкиМаршрута"
И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных")
Тогда
КоллекцияЗначений = ирОбщий.ПолучитьМенеджерЛкс(МетаданныеРодителя)[СтрокаОписанияВида.ИмяКоллекции];
ИначеЕсли Истина
И СтрокаОписанияВида.ИмяКоллекции = "<Имя коллекции метаданных>"
И (Ложь
Или ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных")
Или ТипЗнч(МетаданныеРодителя) = Тип("КоллекцияОбъектовМетаданных")
Или ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданныхКонфигурация"))
Тогда
КоллекцияЗначений = МетаданныеРодителя;
Если ТипЗнч(МетаданныеРодителя) = Тип("КоллекцияОбъектовМетаданных") Тогда
//
Иначе
ИмяКоллекцииОбъектовМетаданных = ирОбщий.СтрокаМеждуМаркерамиЛкс(ИмяОбщегоТипа, МаркерКоллекцииОбъектовМетаданных + ": ", , Ложь);
Если ЗначениеЗаполнено(ИмяКоллекцииОбъектовМетаданных) Тогда
СтрокаКорневогоТипа = ОписаниеТипаМетаОбъектов(, ИмяКоллекцииОбъектовМетаданных);
Если СтрокаКорневогоТипа <> Неопределено Тогда
//КоллекцияЗначений = МетаданныеРодителя[ИмяКоллекцииОбъектовМетаданных];
Попытка
КоллекцияЗначений = МетаданныеРодителя[РодительскаяСтруктураТипа.СтрокаОписания.Слово];
Исключение
ИнформацияОбОшибке = ИнформацияОбОшибке(); // Для отладки
КонецПопытки;
КонецЕсли;
КонецЕсли;
КонецЕсли;
ИначеЕсли Истина
//И СтрокаОписанияВида.ИмяКоллекции = "<Имя коллекции метаданных>"
И Это2iS
И (Ложь
Или ТипЗнч(МетаданныеРодителя) = Тип("СправочникСсылка.КонфигурацииМетаданных2iS")
Или ТипЗнч(МетаданныеРодителя) = Тип("СправочникСсылка.ОбъектыМетаданных2iS"))
Тогда
Если СтрокаОписанияВида.ИмяКоллекции = "<Имя коллекции метаданных>" Тогда
ИмяКоллекцииОбъектовМетаданных = ирОбщий.СтрокаМеждуМаркерамиЛкс(ИмяОбщегоТипа, МаркерКоллекцииОбъектовМетаданных + ": ", , Ложь);
Иначе
ИмяКоллекцииОбъектовМетаданных = СтрокаОписанияВида.ИмяКоллекции;
КонецЕсли;
Если ЗначениеЗаполнено(ИмяКоллекцииОбъектовМетаданных) Тогда
СтрокаКорневогоТипа = ОписаниеТипаМетаОбъектов(, ИмяКоллекцииОбъектовМетаданных);
Запрос = Новый Запрос;
Если СтрокаКорневогоТипа <> Неопределено Тогда
//лИмяКоллекции = РодительскаяСтруктураТипа.СтрокаОписания.Слово;
Если ИмяКоллекцииОбъектовМетаданных = "Реквизиты" Тогда
ТекстЗапроса = "ВЫБРАТЬ Наименование КАК Имя, Типы Как Значение ИЗ Справочник.СвойстваМетаданных2iS
|ГДЕ Владелец = &Владелец И Вид <> ЗНАЧЕНИЕ(Перечисление.ВидыСвойств.Свойство)";
Запрос.Текст = ТекстЗапроса;
Запрос.УстановитьПараметр("Владелец", МетаданныеРодителя);
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
СхемаКоллекции[Выборка.Имя] = Выборка.Значение.Выгрузить().ВыгрузитьКолонку("Тип");
КонецЦикла;
Иначе
ТекстЗапроса = "ВЫБРАТЬ Имя, Ссылка КАК Значение ИЗ Справочник.ОбъектыМетаданных2iS
|ГДЕ Владелец = &Владелец И Родитель.Наименование = &ИмяРодителя";
Запрос.УстановитьПараметр("ИмяРодителя", ИмяКоллекцииОбъектовМетаданных);
Запрос.Текст = ТекстЗапроса;
Запрос.УстановитьПараметр("Владелец", МетаданныеРодителя);
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
СхемаКоллекции[Выборка.Имя] = Выборка.Значение;
КонецЦикла;
КонецЕсли;
КонецЕсли;
Иначе
//КоллекцияЗначений = МетаданныеРодителя;
КонецЕсли;
ИначеЕсли Истина
//И СтрокаОписанияВида.ИмяКоллекции = "<Имя коллекции метаданных>"
И ЭтоИнтеграция
И (Ложь
Или ТипЗнч(МетаданныеРодителя) = Тип("СправочникСсылка.КонфигурацииМетаданныхИис")
Или ТипЗнч(МетаданныеРодителя) = Тип("СправочникСсылка.МетаданныеИис"))
Тогда
Если СтрокаОписанияВида.ИмяКоллекции = "<Имя коллекции метаданных>" Тогда
ИмяКоллекцииОбъектовМетаданных = ирОбщий.СтрокаМеждуМаркерамиЛкс(ИмяОбщегоТипа, МаркерКоллекцииОбъектовМетаданных + ": ", , Ложь);
Иначе
ИмяКоллекцииОбъектовМетаданных = СтрокаОписанияВида.ИмяКоллекции;
КонецЕсли;
Если ЗначениеЗаполнено(ИмяКоллекцииОбъектовМетаданных) Тогда
СтрокаКорневогоТипа = ОписаниеТипаМетаОбъектов(, ИмяКоллекцииОбъектовМетаданных);
Запрос = Новый Запрос;
Если СтрокаКорневогоТипа <> Неопределено Тогда
//лИмяКоллекции = РодительскаяСтруктураТипа.СтрокаОписания.Слово;
Если ИмяКоллекцииОбъектовМетаданных = "Реквизиты" Тогда
ТекстЗапроса = "ВЫБРАТЬ Наименование КАК Имя, Типы Как Значение ИЗ Справочник.СвойстваМетаданныхИис
|ГДЕ КонфигурацияМетаданных = &Владелец И Вид <> ЗНАЧЕНИЕ(Перечисление.ВидыСвойствМетаданныхИис.Свойство)";
Запрос.Текст = ТекстЗапроса;
Запрос.УстановитьПараметр("Владелец", МетаданныеРодителя);
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
СхемаКоллекции[Выборка.Имя] = Выборка.Значение.Выгрузить().ВыгрузитьКолонку("Тип");
КонецЦикла;
Иначе
ТекстЗапроса = "ВЫБРАТЬ Имя, Ссылка КАК Значение ИЗ Справочник.МетаданныеИис
|ГДЕ КонфигурацияМетаданных = &Владелец И ТипМетаданных.ИмяМножественное = &ИмяРодителя";
Запрос.УстановитьПараметр("ИмяРодителя", ИмяКоллекцииОбъектовМетаданных);
Запрос.Текст = ТекстЗапроса;
Запрос.УстановитьПараметр("Владелец", МетаданныеРодителя);
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
СхемаКоллекции[Выборка.Имя] = Выборка.Значение;
КонецЦикла;
КонецЕсли;
КонецЕсли;
Иначе
//КоллекцияЗначений = МетаданныеРодителя;
КонецЕсли;
ИначеЕсли Истина
И СтрокаОписанияВида.ИмяКоллекции = "Реквизиты"
И ТипЗнч(МетаданныеРодителя) = Тип("УправляемаяФорма")
Тогда
//
Иначе
Если МассивИсключенийИменКоллекций.НайтиПоЗначению(СтрокаОписанияВида.ИмяКоллекции) <> Неопределено Тогда
Продолжить;
КонецЕсли;
СхемаКоллекции = МетаданныеРодителя;
Если ТипЗнч(МетаданныеРодителя) <> Тип("КоллекцияОбъектовМетаданных") Тогда
ЦелевойТип = Неопределено;
Если Найти(СтрокаОбщегоТипа.ИмяОбщегоТипа, "<") = 0 Тогда
Попытка
ЦелевойТип = Тип(СтрокаОбщегоТипа.ИмяОбщегоТипа);
Исключение
КонецПопытки;
КонецЕсли;
Попытка
Если ТипЗнч(МетаданныеРодителя) = ЦелевойТип Тогда
СхемаКоллекции = МетаданныеРодителя;
Иначе
СхемаКоллекции = МетаданныеРодителя[СтрокаОписанияВида.ИмяКоллекции];
КонецЕсли;
Исключение
Продолжить;
КонецПопытки;
КонецЕсли;
КонецЕсли;
Если КоллекцияЗначений = Неопределено Тогда
КоллекцияЗначений = СхемаКоллекции;
Если Слово <> Неопределено Тогда
ЭлементСхемы = Неопределено;
Если Ложь
Или ТипЗнч(КоллекцияЗначений) = Тип("ФиксированнаяСтруктура")
Или ТипЗнч(КоллекцияЗначений) = Тип("ФиксированноеСоответствие")
Или ТипЗнч(КоллекцияЗначений) = Тип("Структура")
Или ТипЗнч(КоллекцияЗначений) = Тип("Соответствие")
Тогда
//Для Каждого ЭлементКоллекции Из КоллекцияЗначений Цикл
// Если ЭлементКоллекции.Ключ = ИмяТекущегоСлова Тогда
// ЭлементСхемы = ЭлементКоллекции.Значение;
// Прервать;
// КонецЕсли;
//КонецЦикла;
Попытка
ЭлементСхемы = КоллекцияЗначений[ИмяТекущегоСлова];
Исключение
КонецПопытки;
Иначе
ЭлементСхемы = Null;
Если ТипЗнч(КоллекцияЗначений) <> Тип("Массив") Тогда
Попытка
ЭлементСхемы = КоллекцияЗначений.Найти(ИмяТекущегоСлова);
Исключение
КонецПопытки;
КонецЕсли;
Если ЭлементСхемы = Null Тогда
ЭлементСхемы = Неопределено;
Для Каждого ЭлементКоллекции Из КоллекцияЗначений Цикл
Если ЭлементКоллекции.Имя = ИмяТекущегоСлова Тогда
ЭлементСхемы = ЭлементКоллекции;
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЕсли;
КоллекцияЗначений = Новый Соответствие;
Если ЭлементСхемы <> Неопределено Тогда
КоллекцияЗначений.Вставить(ИмяТекущегоСлова, ЭлементСхемы);
КонецЕсли;
КонецЕсли;
Иначе
Если Слово <> Неопределено Тогда
Попытка
ЭлементСхемы = КоллекцияЗначений[ИмяТекущегоСлова];
Исключение
КонецПопытки;
КоллекцияЗначений = Новый Соответствие;
Если ЭлементСхемы <> Неопределено Тогда
КоллекцияЗначений.Вставить(ИмяТекущегоСлова, ЭлементСхемы);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если КоллекцияЗначений = Неопределено Тогда
КоллекцияЗначений = Новый Массив();
КонецЕсли;
ЭтоСубконто = Найти(СтрокаВида.Слово, "Субконто") = 1;
ПредыдущаяТаблицаСтруктурТипов = Неопределено;
ВычислятьТипыЦикл = ВычислятьТипы Или КоллекцияЗначений.Количество() < 100;
Для Каждого ЭлементКоллекции Из КоллекцияЗначений Цикл
Если ЭлементКоллекции = Неопределено Тогда
// ПараметрыМакетаТабличногоДокумента
Продолжить;
КонецЕсли;
Если ТипЗнч(ЭлементКоллекции) = Тип("КлючИЗначение") Тогда
ИмяСвойства = ЭлементКоллекции.Ключ;
ЗначениеСвойства = ЭлементКоллекции.Значение;
Иначе
ИмяСвойства = ЭлементКоллекции.Имя;
ЗначениеСвойства = ЭлементКоллекции;
КонецЕсли;
КонечноеСлово = СтрЗаменить(СтрокаВида.Слово, ИмяЭлементаКоллекции, ИмяСвойства);
ТаблицаСтруктурТипов = Неопределено;
Если ВычислятьТипыЦикл Тогда
Если ЭтоСубконто И ПредыдущаяТаблицаСтруктурТипов <> Неопределено Тогда
ТаблицаСтруктурТипов = ПредыдущаяТаблицаСтруктурТипов;
Иначе
ТаблицаСтруктурТипов = НоваяТаблицаСтруктурТипа();
ПредыдущаяТаблицаСтруктурТипов = ТаблицаСтруктурТипов;
МассивТипов = Новый Массив;
Квалификаторы = Неопределено;
ОписаниеТиповЗначения = Неопределено;
Если СхемаКоллекции.Количество() > 0 Тогда
Если Ложь
Или СтрокаВида.ТипЗначения = "Произвольный"
Или СтрокаВида.ТипЗначения = "Набор записей регистра"
Или Найти(СтрокаВида.ТипЗначения, "<") > 0
Тогда
Если ТипЗнч(ЗначениеСвойства) = Тип("ОписаниеТипов") Тогда
ОписаниеТиповЗначения = ЗначениеСвойства;
КонецЕсли;
Если Истина
И ЯзыкПрограммы = 1
И РодительскаяСтруктураТипа.ТипЯзыка <> "ЗначениеВЗапросе"
И КорневойТипРодителя <> Неопределено
И КорневойТипРодителя <> "ВнешнийИсточникДанных"
Тогда
ДоступноеПолеСлова = ПостроительЗапросаРодителя.ДоступныеПоля.Найти(НРег(КонечноеСлово));
Если ДоступноеПолеСлова = Неопределено Тогда
Продолжить;
КонецЕсли;
Если ДоступноеПолеСлова.ТипЗначения <> Новый ОписаниеТипов("ТаблицаЗначений") Тогда
ОписаниеТиповЗначения = ДоступноеПолеСлова.ТипЗначения;
КонецЕсли;
КонецЕсли;
Если Истина
И ОписаниеТиповЗначения = Неопределено
И СтрокаОписанияВида.ИмяКоллекции <> "КритерииОтбора"
И СтрокаОписанияВида.ИмяКоллекции <> "ПланыВидовХарактеристик"
И ИмяОбщегоТипа <> "Константа"
Тогда
Попытка
ОписаниеТиповЗначения = ЗначениеСвойства.Тип;
Исключение
КонецПопытки;
Если ТипЗнч(ОписаниеТиповЗначения) <> Тип("ОписаниеТипов") Тогда
ОписаниеТиповЗначения = Неопределено;
КонецЕсли;
КонецЕсли;
Если ТипЗнч(ОписаниеТиповЗначения) = Тип("ОписаниеТипов") Тогда
МассивТипов = ОписаниеТиповЗначения.Типы();
Квалификаторы = ОписаниеТиповЗначения;
ИначеЕсли ТипЗнч(ЗначениеСвойства) = Тип("Массив") Тогда
МассивТипов = ЗначениеСвойства;
КонецЕсли;
КонецЕсли;
Иначе
МассивТипов = ирОбщий.ЗначенияВМассивЛкс(ТипЗнч(ЗначениеСвойства));
КонецЕсли;
Если Истина
//И ОписаниеТиповЗначения <> Неопределено
И МассивТипов.Количество() > 0
И СтрокаОписанияВида.ИмяКоллекции <> "<Имя коллекции метаданных>"
И (Ложь
Или СтрокаОписанияВида.ИмяКоллекции <> "Константы"
Или ЯзыкПрограммы = 1)
Тогда
ШаблонСтруктурыТипа = Новый Структура("СтрокаОписания, ТипЯзыка, Метаданные, ДержательМетаданных, Квалификаторы");
ШаблонСтруктурыТипа.СтрокаОписания = СтрокаВида;
ШаблонСтруктурыТипа.ТипЯзыка = РодительскаяСтруктураТипа.ТипЯзыка;
ШаблонСтруктурыТипа.ДержательМетаданных = РодительскаяСтруктураТипа.ДержательМетаданных;
ШаблонСтруктурыТипа.Квалификаторы = Квалификаторы;
//ШаблонСтруктурыТипа.Метаданные = МетаданныеРодителя;
Для Каждого Тип Из МассивТипов Цикл
//Если Истина
// И Тип = ТипЗнч(ЗначениеСвойства)
// И (Ложь
// Или мМассивТиповВключающихМетаданные.Найти(Тип) <> Неопределено
// Или мМассивТиповЭлементовУправления.Найти(Тип) <> Неопределено)
//Тогда
// ШаблонСтруктурыТипа.Метаданные = ЗначениеСвойства;
// СтруктураТипаСвойства = СтруктураТипаИзЗначения(ЗначениеСвойства, ЯзыкПрограммы, ШаблонСтруктурыТипа);
//Иначе
// ШаблонСтруктурыТипа.Метаданные = МетаданныеРодителя;
// СтруктураТипаСвойства = СтруктураТипаИзКонкретногоТипа(Тип, ЯзыкПрограммы, ШаблонСтруктурыТипа);
//КонецЕсли;
Если Истина
И Тип = ТипЗнч(ЗначениеСвойства)
//И (Ложь
// Или мМассивТиповВключающихМетаданные.Найти(Тип) <> Неопределено
// Или мМассивТиповЭлементовУправления.Найти(Тип) <> Неопределено)
Тогда
МетаданныеЭлемента = МетаданныеЭлементов[ИмяСвойства];
Если МетаданныеЭлемента = Неопределено Тогда
МетаданныеЭлемента = ЗначениеСвойства;
КонецЕсли;
ШаблонСтруктурыТипа.Метаданные = МетаданныеЭлемента;
СтруктураТипаСвойства = СтруктураТипаИзЗначения(ЗначениеСвойства, ЯзыкПрограммы, ШаблонСтруктурыТипа);
ИначеЕсли Истина
И Это2iS
И ТипЗнч(Тип) = Тип("СправочникСсылка.ОбъектыМетаданных2iS")
Тогда
СтруктураТипаСвойства = НоваяСтруктураТипа();
СтруктураТипаСвойства.Метаданные = Тип;
ТипОбъект = КэшОбъект(Тип);
ОбъектСистемы = ТипОбъект.ОбъектСистемы;
Расширение = Вычислить("Ядро2iS.ПолучитьРасширениеСсылкиОбъектаСистемы(ОбъектСистемы)");
Если ЗначениеЗаполнено(Расширение) Тогда
СтруктураТипаСвойства.ИмяОбщегоТипа = Расширение.ИмяОбщегоТипа;
Иначе
СтруктураТипаСвойства.ИмяОбщегоТипа = ТипОбъект.Наименование;
КонецЕсли;
ИначеЕсли Истина
И ЭтоИнтеграция
И ТипЗнч(Тип) = Тип("СправочникСсылка.МетаданныеИис")
Тогда
СтруктураТипаСвойства = НоваяСтруктураТипа();
СтруктураТипаСвойства.Метаданные = Тип;
ТипОбъект = КэшОбъект(Тип);
//ОбъектСистемы = ТипОбъект.ОбъектСистемы;
//Расширение = Вычислить("Ядро2iS.ПолучитьРасширениеСсылкиОбъектаСистемы(ОбъектСистемы)");
//Если ЗначениеЗаполнено(Расширение) Тогда
// СтруктураТипаСвойства.ИмяОбщегоТипа = Расширение.ИмяОбщегоТипа;
//Иначе
СтруктураТипаСвойства.ИмяОбщегоТипа = ТипОбъект.Наименование;
//КонецЕсли;
Иначе
ШаблонСтруктурыТипа.Метаданные = МетаданныеРодителя;
СтруктураТипаСвойства = СтруктураТипаИзКонкретногоТипа(Тип, ЯзыкПрограммы, ШаблонСтруктурыТипа);
КонецЕсли;
ДобавитьВТаблицуСтруктурТипов(ТаблицаСтруктурТипов, СтруктураТипаСвойства);
КонецЦикла;
Иначе
СтруктураТипаСвойства = НоваяСтруктураТипа();
ЗаполнитьЗначенияСвойств(СтруктураТипаСвойства, РодительскаяСтруктураТипа, "ТипЯзыка");
Если РодительскаяСтруктураТипа.ТипЯзыка = "ИмяТипа" Тогда
СтруктураТипаСвойства.ИмяОбщегоТипа = СтрокаВида.Слово;
Если СтрокаВида.ТипКонтекста <> "" Тогда
СтруктураТипаСвойства.ИмяОбщегоТипа = СтрокаВида.ТипКонтекста + "." + СтруктураТипаСвойства.ИмяОбщегоТипа;
КонецЕсли;
Иначе
СтруктураТипаСвойства.ИмяОбщегоТипа = СтрокаВида.ТипЗначения;
СтруктураТипаСвойства.СтрокаОписания = СтрокаВида;
КонецЕсли;
СтруктураТипаСвойства.Метаданные = ЗначениеСвойства;
ДобавитьВТаблицуСтруктурТипов(ТаблицаСтруктурТипов, СтруктураТипаСвойства);
КонецЕсли;
КонецЕсли;
Иначе
//
КонецЕсли;
ДобавитьВТаблицуСлов(ТаблицаСвойств, КонечноеСлово, СтрокаВида.ТипСлова, ТаблицаСтруктурТипов,, "Метаданные");
КонецЦикла;
КонецЦикла;
КонецЦикла;
Если Ложь
Или ЯзыкПрограммы = 0
Или ЯзыкПрограммы = 2
Тогда
Если Истина
И МодульМетаданных = Неопределено
И СтрокаОбщегоТипа.ИмяОбщегоТипа = "Глобальный"
Тогда
Если ТипСлова = "Метод" Тогда
СтруктураТипа = НоваяСтруктураТипа();
СтруктураТипа.ИмяОбщегоТипа = "ОбщийМодуль";
Для Каждого МетаОбщийМодуль Из Метаданные.ОбщиеМодули Цикл
#Если Сервер И Не Сервер Тогда
МетаОбщийМодуль = Метаданные.ОбщиеМодули.ирОбщий;
#КонецЕсли
Если Ложь
Или Не МетаОбщийМодуль.Глобальный
Или (Истина
И ЛиСерверныйКонтекст
И Не МетаОбщийМодуль.Сервер)
Или (Истина
И Не ЛиСерверныйКонтекст
И Не МетаОбщийМодуль.ВызовСервера
И (Ложь
#Если ТолстыйКлиентОбычноеПриложение Тогда
Или Не МетаОбщийМодуль.КлиентОбычноеПриложение
#Иначе
Или Не МетаОбщийМодуль.КлиентУправляемоеПриложение
#КонецЕсли
)
)
Тогда
Продолжить;
КонецЕсли;
СтруктураТипа.Метаданные = МетаОбщийМодуль;
МодульМетаданных = ПодготовитьМодульМетаданных(СтруктураТипа);
ДобавитьВТаблицуСловЭлементыМодуляМетаданных(СтрокаОбщегоТипа, Слово, ТипСлова, ТаблицаСвойств, МодульМетаданных, ВычислятьТипыМетодовМодулей, ВычислятьТипы);
КонецЦикла;
КонецЕсли;
Если Не ЛиСерверныйКонтекст Тогда
СтруктураТипа = СтруктураТипаИзЗначения(Метаданные);
#Если ТолстыйКлиентОбычноеПриложение Тогда
МодульМетаданных = ПодготовитьМодульМетаданных(СтруктураТипа, "МодульОбычногоПриложения");
#Иначе
МодульМетаданных = ПодготовитьМодульМетаданных(СтруктураТипа, "МодульУправляемогоПриложения");
#КонецЕсли
КонецЕсли;
КонецЕсли;
ДобавитьВТаблицуСловЭлементыМодуляМетаданных(СтрокаОбщегоТипа, Слово, ТипСлова, ТаблицаСвойств, МодульМетаданных, ВычислятьТипыМетодовМодулей, ВычислятьТипы);
#Если Клиент Тогда
Если Истина
И (Ложь
Или ТипЗнч(МетаданныеРодителя) = Тип("COMОбъект")
Или ТипЗнч(МетаданныеРодителя) = Тип("ВнешнийОбъект"))
И ЛиИмяТипаComОбъекта(ИмяОбщегоТипа)
Тогда
ИмяБиблиотеки = "";
ИнфоТипа = ПолучитьИнфоТипаCOMОбъекта(МетаданныеРодителя, ИмяОбщегоТипа, ИмяБиблиотеки);
Если ИнфоТипа <> Неопределено Тогда
Если Найти(ИмяОбщегоТипа, " {") > 0 Тогда
ИнфоТипа = ИнфоТипа.Parent.TypeInfos.NamedItem(ирОбщий.ПервыйФрагментЛкс(ИмяОбщегоТипа, " {"));
КонецЕсли;
//Если ИмяCOMКласса = "" Тогда
// Если Описатель.Parent.Name = "V" + ирКэш.НомерИзданияПлатформыЛкс() Тогда
// ИмяОбщегоТипа = "COM-соединитель";
// КонецЕсли;
//КонецЕсли;
Если НРег(ИнфоТипа.TypeKindString) = "coclass" Тогда
МассивИнфоТипа = ИнфоТипа.Interfaces;
Иначе
МассивИнфоТипа = Новый Массив;
МассивИнфоТипа.Добавить(ИнфоТипа);
Для Каждого ИнтерфейсОбъекта Из ИнфоТипа.ImpliedInterfaces Цикл
МассивИнфоТипа.Добавить(ИнтерфейсОбъекта);
КонецЦикла;
КонецЕсли;
Для Каждого ИнфоТипа Из МассивИнфоТипа Цикл
Для Каждого Член Из ИнфоТипа.Members Цикл
Если Член.AttributeMask = 1 Тогда
// Это члены IDispatch
Продолжить;
КонецЕсли;
ИмяЧлена = Член.Name;
Если Член.InvokeKind = 1 Или Член.Parameters.Count > 0 Тогда
лТипСлова = "Метод";
Иначе
лТипСлова = "Свойство";
КонецЕсли;
Если Слово <> Неопределено Тогда
Если Не ирОбщий.СтрокиРавныЛкс(Слово, ИмяЧлена) Тогда
Продолжить;
КонецЕсли;
Если Не ирОбщий.СтрокиРавныЛкс(ТипСлова, лТипСлова) Тогда
Продолжить;
КонецЕсли;
КонецЕсли;
СтруктураТипа = НоваяСтруктураТипа();
СтруктураТипа.ИмяОбщегоТипа = ПолучитьТипЗначенияЧленаИнтерфейса(Член.ReturnType, ИмяБиблиотеки, ИнфоТипа.Parent);
СтруктураТипа.СтрокаОписания = Член;
СтруктураТипа.Метаданные = МетаданныеРодителя;
ТаблицаСтруктурТипов = НоваяТаблицаСтруктурТипа();
ДобавитьВТаблицуСтруктурТипов(ТаблицаСтруктурТипов, СтруктураТипа);
ДобавитьВТаблицуСлов(ТаблицаСвойств, ИмяЧлена, лТипСлова, ТаблицаСтруктурТипов,, "Метаданные");
КонецЦикла;
КонецЦикла;
КонецЕсли;
КонецЕсли;
#КонецЕсли
КонецЕсли;
Если Истина
// Для того, чтобы постоянно не присваивался тип <ОбщийМодуль>
И ИмяОбщегоТипа <> "Глобальный"
И НайденныеСтроки.Количество() > 0
Тогда
Если Истина
И Слово <> Неопределено
И ТаблицаСвойств.Количество() = 0
И НайденныеСтроки.Количество() = 1
Тогда
// Шаблон только один. Берем его даже если имя элемента коллекции не подошло.
СтрокаВида = НайденныеСтроки[0];
СтруктураТипа = НоваяСтруктураТипа();
СтруктураТипа.ИмяОбщегоТипа = СтрокаВида.ТипЗначения;
СтруктураТипа.СтрокаОписания = СтрокаВида;
СтруктураТипа.Метаданные = МетаданныеРодителя;
ТаблицаСтруктурТипов = НоваяТаблицаСтруктурТипа();
ДобавитьВТаблицуСтруктурТипов(ТаблицаСтруктурТипов, СтруктураТипа);
ДобавитьВТаблицуСлов(ТаблицаСвойств, СтрокаВида.Слово, СтрокаВида.ТипСлова, ТаблицаСтруктурТипов,, "Метаданные");
КонецЕсли;
КонецЕсли;
Возврат ТаблицаСвойств;
КонецФункции
Функция ЛиИмяТипаComОбъекта(ИмяОбщегоТипа) Экспорт
Результат = Ложь
Или ирОбщий.СтрокиРавныЛкс(ИмяОбщегоТипа, "COMОбъект")
Или Найти(ИмяОбщегоТипа, " {") > 0;
Возврат Результат;
КонецФункции
Функция ДобавитьВТаблицуСловЭлементыМодуляМетаданных(Знач СтруктураТипа, Знач Слово = Неопределено, Знач ТипСлова = Неопределено, Знач ВнутренняяТаблицаСлов = Неопределено,
Знач МодульМетаданных = Неопределено, Знач ВычислятьТипыМетодовМодулей = Ложь, Знач ВычислятьТипы = Истина) Экспорт
Если ВнутренняяТаблицаСлов = Неопределено Тогда
ВнутренняяТаблицаСлов = НоваяТаблицаСвойствТипа();
КонецЕсли;
МетаданныеРодителя = СтруктураТипа.Метаданные;
Если ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") Тогда
Если МодульМетаданных = Неопределено Тогда
МодульМетаданных = ПодготовитьМодульМетаданных(СтруктураТипа);
КонецЕсли;
ОтборЭлементовМодуля = Новый Структура;
ОтборЭлементовМодуля.Вставить("ЛиЭкспорт", Истина);
Если ЗначениеЗаполнено(Слово) Тогда
ОтборЭлементовМодуля.Вставить("НИмя", НРег(Слово));
КонецЕсли;
Иначе
ОтборЭлементовМодуля = Новый Структура;
Если ЗначениеЗаполнено(Слово) Тогда
ОтборЭлементовМодуля.Вставить("НИмя", НРег(Слово));
КонецЕсли;
КонецЕсли;
Если МодульМетаданных <> Неопределено Тогда
Если Ложь
Или ТипСлова = Неопределено
Или ТипСлова = "Свойство"
Тогда
ПеременныеМодуля = МодульМетаданных.Переменные;
#Если Сервер И Не Сервер Тогда
ПеременныеМодуля = Новый ТаблицаЗначений;
#КонецЕсли
Если ОтборЭлементовМодуля.Количество() > 0 Тогда
ПодходящиеПеременные = ПеременныеМодуля.НайтиСтроки(ОтборЭлементовМодуля);
Иначе
ПодходящиеПеременные = ПеременныеМодуля;
КонецЕсли;
Для Каждого ПеременнаяМодуля Из ПодходящиеПеременные Цикл
ДобавитьВТаблицуСлов(ВнутренняяТаблицаСлов, ПеременнаяМодуля.Имя, "Свойство",,, "Метаданные");
КонецЦикла;
КонецЕсли;
Если Ложь
Или ТипСлова = Неопределено
Или ТипСлова = "Метод"
Тогда
МетодыМодуля = МодульМетаданных.Методы;
#Если Сервер И Не Сервер Тогда
МетодыМодуля = Новый ТаблицаЗначений;
#КонецЕсли
Если ОтборЭлементовМодуля.Количество() > 0 Тогда
ПодходящиеМетоды = МетодыМодуля.НайтиСтроки(ОтборЭлементовМодуля);
Иначе
ПодходящиеМетоды = МетодыМодуля;
КонецЕсли;
ИскательВозврата = Неопределено;
ВычислятьТипы = Ложь
Или ЗначениеЗаполнено(Слово)
Или ВычислятьТипы;
Если ЗначениеЗаполнено(Слово) Тогда
ВычислятьТипыМетодовМодулей = Истина;
КонецЕсли;
Если ВычислятьТипыМетодовМодулей Тогда
Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(ПодходящиеМетоды.Количество(), "Вычисление типов функций");
Иначе
Индикатор = Неопределено;
КонецЕсли;
Для Каждого МетодМодуля Из ПодходящиеМетоды Цикл
Если Индикатор <> Неопределено Тогда
ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
КонецЕсли;
Если ВычислятьТипы Тогда
Если ВычислятьТипыМетодовМодулей Тогда
ПодготовитьТипРезультатаМетода(МетодМодуля, МодульМетаданных, ИскательВозврата);
КонецЕсли;
Если МетодМодуля.ТаблицаСтруктурТипов <> Неопределено Тогда
ТаблицаСтруктурТипов = МетодМодуля.ТаблицаСтруктурТипов.Скопировать();
#Если Сервер И Не Сервер Тогда
ТаблицаСтруктурТипов = Новый ТаблицаЗначений;
#КонецЕсли
Иначе
ТаблицаСтруктурТипов = НоваяТаблицаСтруктурТипа();
СтруктураТипа = ТаблицаСтруктурТипов.Добавить();
Если МетодМодуля.Тип = "Функция" Тогда
СтруктураТипа.ИмяОбщегоТипа = "??";
КонецЕсли;
КонецЕсли;
ТаблицаСтруктурТипов.ЗаполнитьЗначения(МетодМодуля, "СтрокаОписания");
КонецЕсли;
ДобавитьВТаблицуСлов(ВнутренняяТаблицаСлов, МетодМодуля.Имя, "Метод", ТаблицаСтруктурТипов, МетодМодуля.ТипЗначения, "Метаданные");
КонецЦикла;
Если Индикатор <> Неопределено Тогда
ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат ВнутренняяТаблицаСлов;
КонецФункции
Функция ПодготовитьМодульМетаданных(Знач СтруктураТипа, Знач ТипМодуля = "") Экспорт
ИмяОбщегоТипа = СтруктураТипа.ИмяОбщегоТипа;
МетаданныеРодителя = СтруктураТипа.Метаданные;
ТипыМетаОбъектов = ирКэш.ТипыМетаОбъектов();
Если Не ЗначениеЗаполнено(ТипМодуля) Тогда
Если ИмяОбщегоТипа = "ОбщаяКоманда" Тогда
ТипМодуля = "МодульКоманды";
ИначеЕсли Ложь
Или ИмяОбщегоТипа = "WebСервис"
Или ИмяОбщегоТипа = "HttpСервис"
Или ИмяОбщегоТипа = "ОбщийМодуль"
Или ИмяОбщегоТипа = "ОбщаяКоманда"
Или ИмяОбщегоТипа = "ОбщаяФорма"
Тогда
ТипМодуля = "Модуль";
Если ИмяОбщегоТипа = "ОбщийМодуль" Тогда
СтрокаСозданияРодителя = МетаданныеРодителя.Имя;
КонецЕсли;
ИначеЕсли ИмяОбщегоТипа = "ОбъектМетаданныхКонфигурация" Тогда
Если Не ЗначениеЗаполнено(ТипМодуля) Тогда
#Если ТолстыйКлиентОбычноеПриложение Тогда
ТипМодуля = "МодульОбычногоПриложения";
#Иначе
ТипМодуля = "МодульУправляемогоПриложения";
#КонецЕсли
КонецЕсли;
Иначе
КорневойТипОбъекта = ирОбщий.ПервыйФрагментЛкс(ИмяОбщегоТипа, "Объект.", Ложь);
Если ЗначениеЗаполнено(КорневойТипОбъекта) Тогда
ТипМодуля = "МодульОбъекта";
СтрокаТипаМетаОбъекта = ТипыМетаОбъектов.Найти(КорневойТипОбъекта, "Единственное");
Если СтрокаТипаМетаОбъекта <> Неопределено Тогда
Множественное = СтрокаТипаМетаОбъекта.Множественное;
Если СтрокаТипаМетаОбъекта.Категория = 1 Тогда
СтрокаСозданияРодителя = Множественное + "." + МетаданныеРодителя.Имя + ".Создать()";
Иначе
СтрокаСозданияРодителя = Множественное + "." + МетаданныеРодителя.Имя + ".ПустаяСсылка().ПолучитьОбъект()";
КонецЕсли;
КонецЕсли;
ИначеЕсли ЗначениеЗаполнено(ирОбщий.ПервыйФрагментЛкс(ИмяОбщегоТипа, "НаборЗаписей.", Ложь)) Тогда
ТипМодуля = "МодульНабораЗаписей";
КорневойТип = ирОбщий.ПервыйФрагментЛкс(ИмяОбщегоТипа, "НаборЗаписей");
СтрокаТипаМетаОбъекта = ТипыМетаОбъектов.Найти(КорневойТип, "Единственное");
Если СтрокаТипаМетаОбъекта <> Неопределено Тогда
Множественное = СтрокаТипаМетаОбъекта.Множественное;
СтрокаСозданияРодителя = Множественное + "." + МетаданныеРодителя.Имя + ".СоздатьНаборЗаписей()";
КонецЕсли;
ИначеЕсли ЗначениеЗаполнено(ирОбщий.ПервыйФрагментЛкс(ИмяОбщегоТипа, "МенеджерЗначения.", Ложь)) Тогда
ТипМодуля = "МодульМенеджераЗначения";
СтрокаСозданияРодителя = "Константы." + МетаданныеРодителя.Имя + ".СоздатьМенеджерЗначения()";
ИначеЕсли ЗначениеЗаполнено(ирОбщий.ПервыйФрагментЛкс(ИмяОбщегоТипа, "Менеджер.", Ложь)) Тогда
ТипМодуля = "МодульМенеджера";
КорневойТип = ирОбщий.ПервыйФрагментЛкс(ИмяОбщегоТипа, "Менеджер");
СтрокаТипаМетаОбъекта = ТипыМетаОбъектов.Найти(КорневойТип, "Единственное");
Если СтрокаТипаМетаОбъекта <> Неопределено Тогда
Множественное = СтрокаТипаМетаОбъекта.Множественное;
СтрокаСозданияРодителя = Множественное + "." + МетаданныеРодителя.Имя;
КонецЕсли;
Иначе
// Еще можно добавить поддержку глобального контекста
ТипМодуля = Неопределено;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ТипМодуля <> Неопределено Тогда
Если МодулиМетаданных = Неопределено Тогда
МодулиМетаданных = Новый Соответствие;
КонецЕсли;
Если ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданныхКонфигурация") Тогда
ИмяФайлаМодуляБезРасширения = "Конфигурация" + "." + ТипМодуля;
Иначе
ИмяФайлаМодуляБезРасширения = МетаданныеРодителя.ПолноеИмя() + "." + ТипМодуля;
КонецЕсли;
МодульМетаданных = МодулиМетаданных[ИмяФайлаМодуляБезРасширения];
Если МодульМетаданных = Неопределено Тогда
//ПроверитьСтруктуруФайловогоКэша();
#Если Сервер И Не Сервер Тогда
ПапкаКэшаМодулей = Новый Файл;
#КонецЕсли
ФайлОписанияМодуля = Новый Файл(ПапкаКэшаМодулей.ПолноеИмя + ирОбщий.РазделительПутиКФайлуЛкс() + ИмяФайлаМодуляБезРасширения + ".ixd");
ФайлОписанияМодуляСуществует = ФайлОписанияМодуля.Существует();
ФайлМодуля = Новый Файл(ПапкаКэшаМодулей.ПолноеИмя + ирОбщий.РазделительПутиКФайлуЛкс() + ИмяФайлаМодуляБезРасширения + ".txt");
Если ФайлОписанияМодуляСуществует Тогда
МодульМетаданных = ирОбщий.ЗагрузитьЗначениеИзФайлаЛкс(ФайлОписанияМодуля.ПолноеИмя);
Если Ложь
Или ТипЗнч(МодульМетаданных) <> Тип("Структура")
Или МодульМетаданных.Методы.Колонки.Найти("ТипЗначения") = Неопределено
Тогда
// Старый формат кэша
ФайлОписанияМодуляСуществует = Ложь;
МодульМетаданных = Неопределено;
КонецЕсли;
КонецЕсли;
Если Ложь
Или Не ФайлОписанияМодуляСуществует
Или (Истина
И ФайлМодуля.Существует()
И ФайлМодуля.ПолучитьВремяИзменения() > ФайлОписанияМодуля.ПолучитьВремяИзменения())
Тогда
ТекстовыйДокумент = Новый ТекстовыйДокумент;
Если Не ФайлМодуля.Существует() Тогда
Если МодулиМетаданных.Количество() = 0 И СообщениеОНеобходимостиОбновитьКэшМодулейВыводилось <> Истина Тогда
ФайлыМодулей = НайтиФайлы(ПапкаКэшаМодулей.ПолноеИмя, "*Модул*");
Если ФайлыМодулей.Количество() = 0 Тогда
Форма = ирОбщий.ПолучитьФормуЛкс("Обработка.ирКлсПолеТекстаПрограммы.Форма.ФормаНастройки");
ирОбщий.Форма_ОткрытьБезЗахватаФокусаЛкс(Форма);
ирОбщий.СообщитьЛкс("Для получения экспортных методов и переменных модулей нужно обновить кэш модулей через открывшуюся форму настроек контекстной подсказки.");
КонецЕсли;
СообщениеОНеобходимостиОбновитьКэшМодулейВыводилось = Истина;
КонецЕсли;
Иначе
ТекстовыйДокумент.Прочитать(ФайлМодуля.ПолноеИмя);
//ирОбщий.СообщитьЛкс(ФайлМодуля.ПолноеИмя); // Отладка
МодульМетаданных = МодульМетаданных(ТекстовыйДокумент.ПолучитьТекст());
ирОбщий.СохранитьЗначениеВФайлЛкс(МодульМетаданных, ФайлОписанияМодуля.ПолноеИмя);
//УдалитьФайлы(ФайлМодуля.ПолноеИмя);
КонецЕсли;
КонецЕсли;
Если МодульМетаданных <> Неопределено Тогда
#Если Сервер И Не Сервер Тогда
МетодыМодуля = Новый ТаблицаЗначений;
#КонецЕсли
МодульМетаданных.Методы.Колонки.Имя.Заголовок = СтрокаСозданияРодителя; // Некрасиво, но компактно
КонецЕсли;
МодулиМетаданных[ИмяФайлаМодуляБезРасширения] = МодульМетаданных;
КонецЕсли;
КонецЕсли;
Возврат МодульМетаданных;
КонецФункции
Функция НайтиИмяМетодаСтрокиМодуля(ИмяМодуля, НомерСтроки, СодержаниеСтроки, ТекстыМодулей = Неопределено, СтароеИмяФайлаМодуляБезРасширения = "", Знач ЧислоСтрокДляПоискаИмениМетода = 1000) Экспорт
РегВыражение = ирКэш.ВычислительРегВыраженийЛкс();
#Если Сервер И Не Сервер Тогда
РегВыражение = Обработки.ирОболочкаРегВыражение.Создать();
#КонецЕсли
РегВыражение.Global = Истина;
РегВыражение.Pattern = "(?:" + шПустоеНачалоСтроки + "(?:Процедура|Функция)" + шРазделитель + "+(" + шИмя + ")" + шРазделитель + "*\()"
+ "|(?:" + шПустоеНачалоСтроки + "(?:КонецПроцедуры|КонецФункции)" + шРазделитель + "+?(?=\n))";
ОписаниеМодуля = ирОбщий.ОписаниеМодуляПоИмениЛкс(ИмяМодуля);
Если ТекстыМодулей = Неопределено Тогда
ТекстыМодулей = Новый Соответствие;
КонецЕсли;
КэшМодуля = ТекстыМодулей[ОписаниеМодуля.ИмяФайлаМодуля];
Если СтароеИмяФайлаМодуляБезРасширения <> ОписаниеМодуля.ИмяФайлаМодуля Тогда
ФайлМодуля = Новый Файл(ПапкаКэшаМодулей.ПолноеИмя + ирОбщий.РазделительПутиКФайлуЛкс() + ОписаниеМодуля.ИмяФайлаМодуля + ".txt");
Если КэшМодуля = Неопределено Тогда
ТекстМодуля = Новый ТекстовыйДокумент;
Попытка
ТекстМодуля.Прочитать(ФайлМодуля.ПолноеИмя);
Исключение
Пустышка = 0; // Для отладки
КонецПопытки;
Методы = Новый ТаблицаЗначений;
Методы.Колонки.Добавить("Метод");
Методы.Индексы.Добавить("Метод");
Методы.Колонки.Добавить("НачальнаяСтрока");
Методы.Колонки.Добавить("КонечнаяСтрока", Новый ОписаниеТипов("Число"));
КэшМодуля = Новый Структура("Текст, Методы", ТекстМодуля, Методы);
ТекстыМодулей[ОписаниеМодуля.ИмяФайлаМодуля] = КэшМодуля;
Методы = Неопределено;
КонецЕсли;
СлужебноеПолеТекста.УстановитьТекст(ТекстМодуля.ПолучитьТекст());
СтароеИмяФайлаМодуляБезРасширения = ОписаниеМодуля.ИмяФайлаМодуля;
КонецЕсли;
Если Истина
И КэшМодуля.Текст <> Неопределено
И СокрЛП(КэшМодуля.Текст.ПолучитьСтроку(НомерСтроки)) = СодержаниеСтроки
Тогда
НужноеОписаниеМетода = Неопределено;
Если ирКэш.РежимОтладкиЛкс() Тогда
// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
Для Каждого ОписаниеМетода Из КэшМодуля.Методы Цикл
Если Истина
И ОписаниеМетода.НачальнаяСтрока <= НомерСтроки
И ОписаниеМетода.КонечнаяСтрока >= НомерСтроки
Тогда
НужноеОписаниеМетода = ОписаниеМетода;
Прервать;
КонецЕсли;
КонецЦикла;
Иначе
// Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru)
Для Каждого ОписаниеМетода Из КэшМодуля.Методы Цикл   Если Истина   И ОписаниеМетода.НачальнаяСтрока <= НомерСтроки   И ОписаниеМетода.КонечнаяСтрока >= НомерСтроки   Тогда   НужноеОписаниеМетода = ОписаниеМетода;   Прервать;   КонецЕсли;   КонецЦикла;  
КонецЕсли;
Если НужноеОписаниеМетода = Неопределено Тогда
НачальнаяСтрокаДиапазона = Макс(1, НомерСтроки - ЧислоСтрокДляПоискаИмениМетода);
СлужебноеПолеТекста.УстановитьГраницыВыделения(НомерСтроки, 1, НачальнаяСтрокаДиапазона, 1);
Вхождения = РегВыражение.НайтиВхождения(СлужебноеПолеТекста.ВыделенныйТекст, Истина);
#Если Сервер И Не Сервер Тогда
Вхождения = Обработки.ирПлатформа.Создать().ВхожденияРегВыражения;
#КонецЕсли
Если Вхождения.Количество() > 0 Тогда
Вхождение = Вхождения[Вхождения.Количество() - 1];
ИмяМетода = Вхождение.SubMatches(0);
Если ИмяМетода = Неопределено Тогда
ИмяМетода = "<ИнициацияМодуля>";
КонецЕсли;
НужноеОписаниеМетода = КэшМодуля.Методы.Найти(ИмяМетода, "Метод");
Если НужноеОписаниеМетода = Неопределено Тогда
НужноеОписаниеМетода = КэшМодуля.Методы.Вставить(0);
НужноеОписаниеМетода.Метод = ИмяМетода;
НужноеОписаниеМетода.НачальнаяСтрока = НачальнаяСтрокаДиапазона + СтрЧислоСтрок(Лев(СлужебноеПолеТекста.ВыделенныйТекст, Вхождение.FirstIndex + Вхождение.Length));
Если ИмяМетода = "<ИнициацияМодуля>" Тогда
НужноеОписаниеМетода.КонечнаяСтрока = 100000000;
КонецЕсли;
КонецЕсли;
Иначе
Пустышка = 0; // Для отладки
КонецЕсли;
Иначе
ИмяМетода = НужноеОписаниеМетода.Метод;
КонецЕсли;
Если Истина
И НужноеОписаниеМетода <> Неопределено
И НомерСтроки > НужноеОписаниеМетода.КонечнаяСтрока
Тогда
НужноеОписаниеМетода.КонечнаяСтрока = НомерСтроки;
КонецЕсли;
Иначе
Пустышка = 0; // Для отладки
КонецЕсли;
Возврат ИмяМетода;
КонецФункции
Функция ОписаниеМетодаМодуля(ПолноеИмяМетода) Экспорт
СтруктураТипа = НоваяСтруктураТипа();
СтруктураТипа.ИмяОбщегоТипа = "ОбщийМодуль";
СтруктураТипа.Метаданные = Метаданные.ОбщиеМодули[ирОбщий.ПервыйФрагментЛкс(ПолноеИмяМетода)];
МодульМетаданных = ПодготовитьМодульМетаданных(СтруктураТипа);
Если МодульМетаданных = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
МетодыМодуля = МодульМетаданных.Методы;
#Если Сервер И Не Сервер Тогда
МетодыМодуля = Новый ТаблицаЗначений;
#КонецЕсли
ОписаниеМетода = МетодыМодуля.Найти(ирОбщий.ПоследнийФрагментЛкс(ПолноеИмяМетода), "Имя");
Возврат ОписаниеМетода;
КонецФункции
Функция ПолучитьРазделыМодуля1С(Знач ТекстМодуля = "") Экспорт
Шаблоны = ПолучитьШаблоныДляАнализаВстроенногоЯзыка();
RegExp.IgnoreCase = Истина;
RegExp.MultiLine = Ложь;
RegExp.Global = Истина;
RegExp.Pattern = Шаблоны.СтруктураМодуля;
// Если после последнего слова КонецПроцедуры или КонецФункции сразу расположен конец, то этот блок попадает в раздел ОсновнаяПрограмма
// Чтобы этого избежать нужно добавлять в конце текста пробел!
РезультатПоиска = RegExp.НайтиВхождения(ТекстМодуля + Символы.ПС);
Если РезультатПоиска.Количество() = 0 Тогда
ирОбщий.СообщитьЛкс("Неверный текст модуля", СтатусСообщения.Внимание);
Возврат Неопределено;
КонецЕсли;
Вхождение = РезультатПоиска[0];
Результат = Новый Структура;
Результат.Вставить("Переменные", Вхождение.SubMatches(0));
Результат.Вставить("Методы", Вхождение.SubMatches(7));
Результат.Вставить("Программа", Вхождение.SubMatches(14));
Возврат Результат;
КонецФункции
Функция ПолучитьШаблоныДляАнализаВстроенногоЯзыка() Экспорт
Перем шИмя, шПустоеНачалоСтроки, шКомментарийБезКонца, шРазделитель, шСтруктураКомментаПарам, шСтруктураКомментаВозвр, шВозврат, шСтруктураКомментаОписаниеПараметров, шКомментМетода, шОписаниеПеременной, шСтрокаПеременныхБезКомментов, шСтрокаПеременных, шСтрокаПрограммы, шПараметрыМетода, шДирективаПрепроцессора, шБлокКомментов, шМетодЧистый, шМетод1, шМетодСПредКомментом, шСтруктураМодуля, шЭлементОбластиМетодов;
// {ОписаниеРегулярногоВыражения.Начало} конструктор из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru)
// {Шаблон.Начало}
// + <шИмя> = [_ЁА-ЯA-Z][_ЁА-ЯA-Z\d]*
// + <шПустоеНачалоСтроки> = (?:\n|^)(?:\t| )*
// + <шКомментарийБезКонца> = //[^\n]*(?=(?:\n|$))
// + <шРазделитель> = (?:<шКомментарийБезКонца>|\s|^|$)
// + <шСтруктураКомментаПарам> = Параметры(?:\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]*(?=\n|$)
// + <шБлокКомментов> = <шКомментарийБезКонца>(?:<шПустоеНачалоСтроки><шКомментарийБезКонца>)*(?=(?:\n|$))
// + <шМетодЧистый> = ((Процедура|Функция)<шРазделитель>*(<шИмя>)<шРазделитель>*\(([^\)]*)\)(<шРазделитель>*Экспорт)?)((?:<шСтрокаПрограммы>|<шБлокКомментов>|\.Конец(?:Процедуры|Функции)|(?:\r|\n|.)(?!Конец(?:Процедуры|Функции)))*)[^а-яё_a-z0-9\."]Конец(?:Процедуры|Функции)(?=(?:<шКомментарийБезКонца>|[^а-яё_a-z0-9\."]|$))
// + <шМетод1> = <шПустоеНачалоСтроки><шМетодЧистый>
// + <шМетодСПредКомментом> = (?:(<шБлокКомментов>\n)|\n|^)[\t ]*<шМетодЧистый>
// + <шСтруктураМодуля> = ^((?:<шДирективаПрепроцессора>|<шСтрокаПеременныхБезКомментов>|<шРазделитель>)*<шСтрокаПеременныхБезКомментов>)?((?:<шДирективаПрепроцессора>|<шМетод1>|<шРазделитель>)*)((?:\r|\n|.)*)$
// + <шЭлементОбластиМетодов> = <шМетодСПредКомментом>|(<шБлокКомментов>)|(<шДирективаПрепроцессора>)
// {Шаблон.Конец}
шИмя = ЭтотОбъект.шИмя;
шПустоеНачалоСтроки = ЭтотОбъект.шПустоеНачалоСтроки;
шКомментарийБезКонца = "//[^\n]*(?=(?:\n|$))";
шРазделитель = "(?:" + шКомментарийБезКонца + "|\s|^|$)";
шСтруктураКомментаПарам = "Параметры(?:\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]*)?";
шСтрокаПрограммы = """(?:(?:"""")|[^""\n])*(?:" + шРазделитель + "*\|(?:(?:"""")|[^""\n])*)*(?:""|$)";
шПараметрыМетода = "" + шРазделитель + "*(Знач\s)?" + шРазделитель + "*(" + шИмя + ")" + шРазделитель + "*=?((?:" + шРазделитель + "*|(" + шСтрокаПрограммы + ")|(?:[^,\n]*))+)(?:,|$)";
шДирективаПрепроцессора = "" + шПустоеНачалоСтроки + "[#&][^\n]*(?=\n|$)";
шБлокКомментов = "" + шКомментарийБезКонца + "(?:" + шПустоеНачалоСтроки + "" + шКомментарийБезКонца + ")*(?=(?:\n|$))";
шМетодЧистый = "((Процедура|Функция)" + шРазделитель + "+(" + шИмя + ")" + шРазделитель + "*\(([^\)]*)\)(" + шРазделитель + "*Экспорт)?)((?:" + шСтрокаПрограммы + "|" + шБлокКомментов + "|\.Конец(?:Процедуры|Функции)|(?:\r|\n|.)(?!Конец(?:Процедуры|Функции)))*)[^а-яё_a-z0-9\.""]Конец(?:Процедуры|Функции)(?=(?:" + шКомментарийБезКонца + "|[^а-яё_a-z0-9\.""]|$))";
шМетод1 = "" + шПустоеНачалоСтроки + "" + шМетодЧистый + "";
шМетодСПредКомментом = "(?:(" + шБлокКомментов + "\n)|\n|^)[\t ]*" + шМетодЧистый + "";
// Если после последнего слова КонецПроцедуры или КонецФункции сразу расположен конец, то этот блок попадает в раздел ОсновнаяПрограмма
// Чтобы этого избежать нужно добавлять в конце текста пробел!
шСтруктураМодуля = "^((?:" + шДирективаПрепроцессора + "|" + шСтрокаПеременныхБезКомментов + "|" + шРазделитель + ")*" + шСтрокаПеременныхБезКомментов + ")?((?:" + шДирективаПрепроцессора + "|" + шМетод1 + "|" + шРазделитель + ")*)((?:\r|\n|.)*)$";
шЭлементОбластиМетодов = "" + шМетодСПредКомментом + "|(" + шБлокКомментов + ")|(" + шДирективаПрепроцессора + ")";
// {ОписаниеРегулярногоВыражения.Конец}
Результат = Новый Структура;
Результат.Вставить("СтрокаПрограммы", шСтрокаПрограммы);
Результат.Вставить("ДирективаПрепроцессора", шДирективаПрепроцессора);
Результат.Вставить("БлокКомментариев", шБлокКомментов);
Результат.Вставить("ОписаниеФункцииПроцедуры", шМетодСПредКомментом);
Результат.Вставить("ЭлементОбластиМетодов", шЭлементОбластиМетодов);
Результат.Вставить("ОписаниеПеременной", шОписаниеПеременной);
Результат.Вставить("ОписаниеСтрокиПеременных", шСтрокаПеременных);
Результат.Вставить("ОписаниеСтрокиПеременныхБезКомментов", шСтрокаПеременныхБезКомментов);
Результат.Вставить("КомментарийОписаниеМетода", шКомментМетода);
Результат.Вставить("ПараметрыМетода", шПараметрыМетода);
Результат.Вставить("СтруктураКомментарияВозвр", шСтруктураКомментаВозвр);
Результат.Вставить("СтруктураКомментарияПарам", шСтруктураКомментаПарам);
Результат.Вставить("СтруктураКомментарияОписаниеПараметров", шСтруктураКомментаОписаниеПараметров);
//Результат.Вставить("ВхождениеМетодов", шВхождениеМетодов);
Результат.Вставить("СтруктураМодуля", шСтруктураМодуля);
Результат.Вставить("Возврат", шВозврат);
Возврат Результат;
КонецФункции
Функция МодульМетаданных(ТекстМодуля, ПодробныйРазборТолькоЭкспортных = Истина) Экспорт
Результат = ПолучитьРазделыМодуля1С(ТекстМодуля);
Шаблоны = ПолучитьШаблоныДляАнализаВстроенногоЯзыка();
RegExp.IgnoreCase = Истина;
Переменные = Новый ТаблицаЗначений;
Переменные.Колонки.Добавить("Имя", Новый ОписаниеТипов("Строка"));
Переменные.Колонки.Добавить("НИмя", Новый ОписаниеТипов("Строка"));
Переменные.Колонки.Добавить("ЛиЭкспорт", Новый ОписаниеТипов("Булево"));
Переменные.Колонки.Добавить("Описание");
RegExp.Multiline = Ложь;
RegExp.Pattern = Шаблоны.ОписаниеСтрокиПеременных + "|(" + Шаблоны.БлокКомментариев + ")|(" + Шаблоны.ДирективаПрепроцессора + ")";
Вхождения = RegExp.НайтиВхождения(Результат.Переменные);
Для Каждого Вхождение Из Вхождения Цикл
Если Вхождение.SubMatches(0) <> Неопределено Тогда
RegExp2.Pattern = Шаблоны.ОписаниеПеременной + "|\s*(?:;|,)";
Результат2 = RegExp2.НайтиВхождения(Вхождение.SubMatches(0));
Для Каждого Вхождение2 Из Результат2 Цикл
Если Вхождение2.SubMatches(0) <> Неопределено Тогда
СтрокаПеременной = Переменные.Добавить();
СтрокаПеременной.Имя = Вхождение2.SubMatches(0);
СтрокаПеременной.НИмя = Нрег(СтрокаПеременной.Имя);
СтрокаПеременной.ЛиЭкспорт = ?(Вхождение2.SubMatches(1) = Неопределено, Ложь, Истина);
СтрокаПеременной.Описание = ОчиститьТекстМодуляОтПрефиксаКомментария(Вхождение.SubMatches(3));
КонецЕсли;
КонецЦикла;
//ИначеЕсли Вхождение.SubMatches(4) <> Неопределено Тогда
// СтрокаПеременной.Тип = "Комментарий";
//ИначеЕсли Вхождение.SubMatches(5) <> Неопределено Тогда
// СтрокаПеременной.Тип = "Директива";
КонецЕсли;
КонецЦикла;
Результат.Переменные = Переменные;
RegExp.MultiLine = Истина;
RegExp.Global = Истина;
RegExp.Pattern = "^(?://[^\n]*\n|\s|^|$)*(КонецПроцедуры|КонецФункции)";
Вхождения = RegExp.НайтиВхождения(Результат.Методы);
Если Вхождения.Количество() > 0 Тогда
НачалоТекстаПрограммы = Вхождения[Вхождения.Количество() - 1].FirstIndex + Вхождения[Вхождения.Количество() - 1].Length;
ТекстМетоды = Лев(Результат.Методы, НачалоТекстаПрограммы + 1);
Результат.Программа = Сред(Результат.Методы, НачалоТекстаПрограммы + 2) + Результат.Программа;
КонецЕсли;
RegExp.Pattern = Шаблоны.ЭлементОбластиМетодов;
RegExp.MultiLine = Ложь;
RegExp2.Global = Истина;
RegExp2.Pattern = Шаблоны.ПараметрыМетода;
Вхождения = RegExp.НайтиВхождения(" " + ТекстМетоды);
#Если Сервер И Не Сервер Тогда
Вхождения = Обработки.ирПлатформа.Создать().ВхожденияРегВыражения;
#КонецЕсли
КомпонентаПодсказки = Неопределено;
ИскательВозврата = Неопределено;
Методы = Новый ТаблицаЗначений;
Методы.Колонки.Добавить("Имя", Новый ОписаниеТипов("Строка"));
Методы.Колонки.Добавить("Тип", Новый ОписаниеТипов("Строка"));
//Методы.Колонки.Добавить("Индекс", Новый ОписаниеТипов("Число"));
Методы.Колонки.Добавить("НИмя", Новый ОписаниеТипов("Строка"));
Методы.Колонки.Добавить("Тело", Новый ОписаниеТипов("Строка"));
Методы.Колонки.Добавить("Параметры");
Методы.Колонки.Добавить("Описание");
Методы.Колонки.Добавить("ТипЗначения");
Методы.Колонки.Добавить("ОписаниеРезультата");
Методы.Колонки.Добавить("ТаблицаСтруктурТипов");
Методы.Колонки.Добавить("ЛиЭкспорт", Новый ОписаниеТипов("Булево"));
шРазделительВнутриСтроки = "[\-\]"; // Здесь 2 разных символа
шОписаниеПараметра = "\n\s{1,8}(" + шИмя + ")\*?\s*(?:" + шРазделительВнутриСтроки + "\s*([^\-\\n]*)\s*)?" + шРазделительВнутриСтроки + "\s*(.*(\n\s{5,}[^\s].*)*)[\.;]?";
Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(Вхождения.Количество(), "Поиск методов модуля");
Для Каждого Вхождение Из Вхождения Цикл
ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
Если Вхождение.SubMatches(1) <> Неопределено Тогда
СтрокаПараметров = "";
СтрокаМетода = Методы.Добавить();
ТекстМодуля = Вхождение.SubMatches(0);
СтрокаМетода.Описание = ОчиститьТекстМодуляОтПрефиксаКомментария(ТекстМодуля);
//СтрокаМетода.Индекс = Вхождение.FirstIndex + Смещение;
СтрокаМетода.Тип = ТРег(Вхождение.SubMatches(2));
СтрокаМетода.Имя = Вхождение.SubMatches(3);
СтрокаМетода.НИмя = Нрег(СтрокаМетода.Имя);
СтрокаПараметров = Вхождение.SubMatches(4);
ЛиЭкспорт = ?(Вхождение.SubMatches(5) = Неопределено, Ложь, Истина);
СтрокаМетода.ЛиЭкспорт = ЛиЭкспорт;
СтрокаМетода.Тело = Вхождение.SubMatches(6);
Если Истина
И Не ПустаяСтрока(СтрокаПараметров)
И (Ложь
Или Не ПодробныйРазборТолькоЭкспортных
Или ЛиЭкспорт)
Тогда
РезультатПараметров = RegExp2.НайтиВхождения(СтрокаПараметров);
Если РезультатПараметров.Количество() > 0 Тогда
ТаблицаПараметровМетода = Новый ТаблицаЗначений;
ТаблицаПараметровМетода.Колонки.Добавить("Имя");
ТаблицаПараметровМетода.Колонки.Добавить("НИмя");
ТаблицаПараметровМетода.Колонки.Добавить("ТипЗначения");
ТаблицаПараметровМетода.Колонки.Добавить("Описание");
ТаблицаПараметровМетода.Колонки.Добавить("Значение");
ТаблицаПараметровМетода.Колонки.Добавить("Знач");
СтрокаМетода.Параметры = ТаблицаПараметровМетода;
Для Каждого ВхождениеПараметра Из РезультатПараметров Цикл
СтрокаПраметра = ТаблицаПараметровМетода.Добавить();
СтрокаПраметра.Имя = ВхождениеПараметра.SubMatches(1);
СтрокаПраметра.НИмя = НРег(СтрокаПраметра.Имя);
СтрокаПраметра.Знач = ?(ВхождениеПараметра.SubMatches(0) = Неопределено, Ложь, Истина);
СтрокаПраметра.Значение = ВхождениеПараметра.SubMatches(2);
КонецЦикла;
Если ирОбщий.СтрокиРавныЛкс(СтрокаМетода.Тип, "функция") Тогда
СтрокаМетода.ТипЗначения = "??";
КонецЕсли;
Если ЗначениеЗаполнено(СтрокаМетода.Описание) Тогда
ВхожденияОписаний = ирОбщий.НайтиРегулярноеВыражениеЛкс(СтрокаМетода.Описание, шОписаниеПараметра, "Имя, ТипЗначения, Описание",,, Ложь, Ложь);
#Если Сервер И Не Сервер Тогда
ВхожденияОписаний = Обработки.ирПлатформа.Создать().ВхожденияРегВыражения;
#КонецЕсли
Для каждого ВхождениеОписания Из ВхожденияОписаний Цикл
СтрокаПараметра = ТаблицаПараметровМетода.Найти(НРег(ВхождениеОписания.Имя));
Если СтрокаПараметра <> Неопределено Тогда
СтрокаПараметра.Описание = ВхождениеОписания.Описание;
СтрокаПараметра.ТипЗначения = ВхождениеОписания.ТипЗначения;
КонецЕсли;
КонецЦикла;
Если ирОбщий.СтрокиРавныЛкс(СтрокаМетода.Тип, "функция") Тогда
ШаблонРезультата = "(?:Возвращаемое\s+значение|Результат)[:-]\s*([^-]+)\s*-\s*(.*)\s*";
ВхожденияОписаний = ирОбщий.НайтиРегулярноеВыражениеЛкс(СтрокаМетода.Описание, ШаблонРезультата, "ТипЗначения, Описание", Ложь,, Ложь, Ложь);
Если ВхожденияОписаний.Количество() > 0 Тогда
ВхождениеОписания = ВхожденияОписаний[ВхожденияОписаний.Количество() - 1];
СтрокаМетода.ТипЗначения = СтрокаМетода.ТипЗначения + ", " + ВхождениеОписания.ТипЗначения;
СтрокаМетода.ОписаниеРезультата = СокрЛП(ВхождениеОписания.Описание);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
//ИначеЕсли Вхождение.SubMatches(7) <> Неопределено Тогда
// //СтрокаБлока.Тип = "Комментарий";
//ИначеЕсли Вхождение.SubMatches(8) <> Неопределено Тогда
// //СтрокаБлока.Тип = "Директива";
КонецЕсли;
КонецЦикла;
ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
Методы.Индексы.Добавить("ЛиЭкспорт");
Методы.Индексы.Добавить("ЛиЭкспорт, НИмя");
Методы.Индексы.Добавить("НИмя");
Результат.Методы = Методы;
Возврат Результат;
КонецФункции
Функция ОчиститьТекстМодуляОтПрефиксаКомментария(Знач ТекстМодуля)
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.УстановитьТекст(ТекстМодуля);
Для Счетчик = 1 По ТекстовыйДокумент.КоличествоСтрок() Цикл
ТекущаяСтрока = ТекстовыйДокумент.ПолучитьСтроку(Счетчик);
ТекстовыйДокумент.ЗаменитьСтроку(Счетчик, Сред(ТекущаяСтрока, Найти(ТекущаяСтрока, "//") + 2));
КонецЦикла;
Описание = СокрЛП(ТекстовыйДокумент.ПолучитьТекст());
Возврат Описание;
КонецФункции
Функция ПодготовитьТипРезультатаМетода(СтрокаМетода, МодульМетаданных, кэшИскательВозврата = Неопределено, кэшКомпонентаПодсказки = Неопределено) Экспорт
Если СтрокаМетода.Тип = "Функция" И СтрокаМетода.ТаблицаСтруктурТипов = Неопределено Тогда
Если кэшИскательВозврата = Неопределено Тогда
Шаблоны = ПолучитьШаблоныДляАнализаВстроенногоЯзыка();
кэшИскательВозврата = ирКэш.ВычислительРегВыраженийЛкс();
кэшИскательВозврата.Pattern = Шаблоны.Возврат;
кэшИскательВозврата.Global = Истина;
КонецЕсли;
Если кэшКомпонентаПодсказки = Неопределено Тогда
кэшКомпонентаПодсказки = ирОбщий.СоздатьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКлсПолеТекстаПрограммы");
#Если Сервер И Не Сервер Тогда
кэшКомпонентаПодсказки = Обработки.ирКлсПолеТекстаПрограммы.Создать();
#КонецЕсли
кэшКомпонентаПодсказки.мПлатформа = ЭтотОбъект;
кэшКомпонентаПодсказки.мМодульМетаданных = МодульМетаданных;
кэшКомпонентаПодсказки.ИнициализироватьНеинтерактивно();
КонецЕсли;
ТелоБезКомментариев = кэшКомпонентаПодсказки.ЗалитьКомментарииИСтроковыеЛитералы(СтрокаМетода.Тело);
ВхожденияВозврата = кэшИскательВозврата.НайтиВхождения(ТелоБезКомментариев);
ИмяОбщегоТипа = "Произвольный";
СтрокаМетода.ТаблицаСтруктурТипов = НоваяТаблицаСтруктурТипа(); // Защита от циклической рекурсии
//СтрокаМетода.ТипЗначения = ПримитивныйТипЗначения;
НачальноеКоличество = ВхожденияВозврата.Количество();
Для Счетчик = 1 По НачальноеКоличество Цикл
ВхождениеВозврата = ВхожденияВозврата[НачальноеКоличество - Счетчик];
Выражение = ВхождениеВозврата.SubMatches(0);
Если Выражение = Неопределено Тогда
Продолжить;
КонецЕсли;
Если Ложь
Или Выражение = "Ложь"
Или Выражение = "Истина"
Или Выражение = "False"
Или Выражение = "True"
Тогда
ИмяОбщегоТипа = "Булево";
Продолжить;
КонецЕсли;
ТекстДляПоискаОпределения = Лев(ТелоБезКомментариев, ВхождениеВозврата.FirstIndex - 1);
// кэшКомпонентаПодсказки.МассивЗащитыОтРекурсии.Очистить(); // Возможно нужно делать
ТаблицаСтруктурТиповЛ = кэшКомпонентаПодсказки.ОпределитьТипЗначенияКонтекста(Выражение, ТекстДляПоискаОпределения, ТекстДляПоискаОпределения); // Здесь могут возникать дубли
ирОбщий.ЗагрузитьВТаблицуЗначенийЛкс(ТаблицаСтруктурТиповЛ, СтрокаМетода.ТаблицаСтруктурТипов);
Прервать;
КонецЦикла;
Если СтрокаМетода.ТаблицаСтруктурТипов.Количество() = 0 Тогда
СтруктураТипа = НоваяСтруктураТипа();
СтруктураТипа.ИмяОбщегоТипа = ИмяОбщегоТипа;
ЗаполнитьЗначенияСвойств(СтрокаМетода.ТаблицаСтруктурТипов.Добавить(), СтруктураТипа);
КонецЕсли;
СтрокаМетода.ТипЗначения = СтрЗаменить(СтрокаМетода.ТипЗначения, "??", ПредставлениеМассиваСтруктурТипов(СтрокаМетода.ТаблицаСтруктурТипов));
КонецЕсли;
// Еще можно анализировать возвращемые типы значений параметров
//СтрокаМетода.Тело = ""; // Не освобождаем память, т.к. теперь мы ищем по телам методов в форме "Общие методы"
КонецФункции
// Получает представление массива типов.
//
// Параметры:
// ТаблицаСтруктурТиповКонтекста - Массив.
//
// Возвращаемое значение:
// Строка - представление массива типов.
//
Функция ПредставлениеМассиваСтруктурТипов(ТаблицаСтруктурТиповКонтекста, БезДублей = Ложь, МаксКоличествоТипов = 10) Экспорт
#Если Сервер И Не Сервер Тогда
ТаблицаСтруктурТиповКонтекста = Новый ТаблицаЗначений;
#КонецЕсли
ПредставлениеТипаКонтекста = "";
Если ТаблицаСтруктурТиповКонтекста <> Неопределено Тогда
Если ТаблицаСтруктурТиповКонтекста.Количество() = 0 Тогда
ИначеЕсли ТаблицаСтруктурТиповКонтекста.Количество() = 1 Тогда
ПредставлениеТипаКонтекста = ИмяТипаИзСтруктурыТипа(ТаблицаСтруктурТиповКонтекста[0]);
Иначе
СписокОбрезан = Неопределено;
СписокИменТипов = ТаблицаСтруктурТиповДляПользователя(ТаблицаСтруктурТиповКонтекста, БезДублей, МаксКоличествоТипов, СписокОбрезан);
Если СписокОбрезан Тогда
СписокИменТипов.Добавить().Имя = "...";
КонецЕсли;
ПредставлениеТипаКонтекста = ирОбщий.СтрСоединитьЛкс(СписокИменТипов.ВыгрузитьКолонку("Имя"), ", ");
КонецЕсли;
КонецЕсли;
Возврат ПредставлениеТипаКонтекста;
КонецФункции
Функция ТаблицаСтруктурТиповДляПользователя(Знач ТаблицаСтруктурТиповКонтекста, Знач БезДублей = Истина, Знач МаксКоличествоТипов = 0, выхСписокОбрезан = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
ТаблицаСтруктурТиповКонтекста = Новый ТаблицаЗначений;
#КонецЕсли
Счетчик = 0;
выхСписокОбрезан = Ложь;
СписокИменТипов = Новый ТаблицаЗначений;
СписокИменТипов.Колонки.Добавить("Имя");
СписокИменТипов.Колонки.Добавить("СтруктураТипа");
Для Каждого СтруктураТипаКонтекста Из ТаблицаСтруктурТиповКонтекста Цикл
Счетчик = Счетчик + 1;
Если МаксКоличествоТипов > 0 И Счетчик > МаксКоличествоТипов Тогда
выхСписокОбрезан = Истина;
Прервать;
КонецЕсли;
СтрокаИменТипов = СписокИменТипов.Добавить();
СтрокаИменТипов.Имя = ИмяТипаИзСтруктурыТипа(СтруктураТипаКонтекста);
СтрокаИменТипов.СтруктураТипа = СтруктураТипаКонтекста;
КонецЦикла;
Если БезДублей Тогда
СписокИменТипов.Свернуть("Имя");
КонецЕсли;
СписокИменТипов.Сортировать("Имя");
Возврат СписокИменТипов;
КонецФункции
// Функция - Отбор параметров метода
//
// Параметры:
// СтрокаОписания - СтрокаТаблицыЗначений - строка таблицы ТаблицаКонтекстов
//
// Возвращаемое значение:
// -
//
Функция ОтборПараметровМетода(Знач СтрокаОписания) Экспорт
ОтборПараметров = Новый Структура;
ОтборПараметров.Вставить("ТипКонтекста", СтрокаОписания.ТипКонтекста);
Если СтрокаОписания.ТипСлова = "Конструктор" Тогда
ОтборПараметров.Вставить("Слово", "<Новый>");
Иначе
ОтборПараметров.Вставить("Слово", СтрокаОписания.Слово);
КонецЕсли;
ОтборПараметров.Вставить("ЯзыкПрограммы", СтрокаОписания.ЯзыкПрограммы);
Возврат ОтборПараметров;
КонецФункции
// Функция - Таблица параметров метода
//
// Параметры:
// СтрокаОписания - СтрокаТаблицыЗначений - строка таблицы ТаблицаКонтекстов
// ОтборПараметров - -
//
// Возвращаемое значение:
// -
//
Функция ТаблицаПараметровМетода(Знач СтрокаОписания, Знач ОтборПараметров = Неопределено) Экспорт
Если ОтборПараметров = Неопределено Тогда
ОтборПараметров = ОтборПараметровМетода(СтрокаОписания);
КонецЕсли;
СинтаксПомощник = СинтаксПомощник();
#Если Сервер И Не Сервер Тогда
СинтаксПомощник = Обработки.ирСинтаксПомощник.Создать();
#КонецЕсли
ПутьКЭлементуАрхива = СтрокаОписания.ПутьКОписанию;
НовыйАдрес = СинтаксПомощник.РаспаковатьФайлАрхиваСинтаксПомощника(ПутьКЭлементуАрхива);
КоличествоПараметров = 100;
Если НовыйАдрес <> Неопределено Тогда
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.Прочитать(ирОбщий.ПервыйФрагментЛкс(НовыйАдрес, "#"));
ТекстДокумента = ТекстовыйДокумент.ПолучитьТекст();
КоличествоПараметров = СинтаксПомощник.ЗагрузитьОписаниеМетода(СтрокаОписания.ТипКонтекста, СтрокаОписания.Слово, ТекстДокумента, СтрокаОписания.ТипСлова, СтрокаОписания.ЯзыкПрограммы,,, СтрокаОписания);
КонецЕсли;
СтрокиПараметров = ТаблицаПараметров.Скопировать(ОтборПараметров);
Пока КоличествоПараметров < СтрокиПараметров.Количество() Цикл
// Удаляем дубли параметров виртуальных таблиц регистра бухгалтерии 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Объектов[КлючКэша];
Если Результат <> Неопределено Тогда
ИнфоИнтерфейса = ПолучитьИнфоТипаCOMОбъекта(Результат,,ПолноеИмяОсновногоКлассаCOM);
Если ИнфоИнтерфейса = Неопределено Тогда
// Объект испорчен
Результат = Неопределено;
КонецЕсли;
КонецЕсли;
Если Результат = Неопределено Тогда
Попытка
Результат = Новый COMОбъект(ПолноеИмяОсновногоКлассаCOM);
Исключение
Возврат Неопределено;
КонецПопытки;
мОбразцыCOMОбъектов[КлючКэша] = Результат;
КонецЕсли;
Возврат Результат;
КонецФункции
// Получает новый экземпляр ком-объекта парсера.
//
// Параметры:
// Нет.
//
// Возвращаемое значение:
// Com-объект, Неопределено.
//
Функция ПолучитьCOMНавигатор() Экспорт
Если COMНавигатор = "НеИнициализирован" Тогда
COMНавигатор = ПолучитьCOMОбъектИзМакета("TLBINF32", "TLI.TLIApplication");
КонецЕсли;
Возврат COMНавигатор;
КонецФункции // ПолучитьCOMНавигатор()
Функция ПолучитьТипыЭлементовКоллекции(СтруктураТипаКоллекции, ЯзыкПрограммы = 0) Экспорт
ТипыЭлементовКоллекции = Новый Массив();
Если ЛиИмяТипаComОбъекта(СтруктураТипаКоллекции.ИмяОбщегоТипа) Тогда
ИмяОбщегоТипа = СтруктураТипаКоллекции.ИмяОбщегоТипа;
ТаблицаСтруктурТипаЭлемента = НоваяТаблицаСтруктурТипа();
ИмяБиблиотеки = "";
МетаданныеОбъекта = СтруктураТипаКоллекции.Метаданные;
ИнфоТипа = ПолучитьИнфоТипаCOMОбъекта(МетаданныеОбъекта, ИмяОбщегоТипа, ИмяБиблиотеки);
Если ИнфоТипа = Неопределено Тогда
Возврат ТаблицаСтруктурТипаЭлемента;
КонецЕсли;
Если НРег(ИнфоТипа.TypeKindString) = "coclass" Тогда
МассивИнфоТипа = ИнфоТипа.Interfaces;
Иначе
МассивИнфоТипа = Новый Массив;
МассивИнфоТипа.Добавить(ИнфоТипа);
КонецЕсли;
Для Каждого ИнфоТипа Из МассивИнфоТипа Цикл
Для Каждого Член Из ИнфоТипа.Members Цикл
Если Истина
//И Член.InvokeKind = 1 // метод // почему то иногда у него стоит 2 (например ADODB.Fields)
И ирОбщий.СтрокиРавныЛкс(Член.Name, "Item")
Тогда
ИнфоТипаЭлемента = Член.ReturnType.TypeInfo;
ИмяОбщегоТипаЭлемента = ПолучитьТипЗначенияЧленаИнтерфейса(Член.ReturnType, ИмяБиблиотеки, ИнфоТипа.Parent);
ТипыЭлементовКоллекции.Добавить(ИмяОбщегоТипаЭлемента);
Прервать;
КонецЕсли;
КонецЦикла;
КонецЦикла;
Иначе
СтруктураКлюча = Новый Структура("Слово, ЯзыкПрограммы", СтруктураТипаКоллекции.ИмяОбщегоТипа, ЯзыкПрограммы);
НайденныеСтроки = ТаблицаОбщихТипов.НайтиСтроки(СтруктураКлюча);
Если НайденныеСтроки.Количество() > 0 Тогда
Если НайденныеСтроки[0].ТипЭлементаКоллекции <> "" Тогда
ТипыЭлементовКоллекции = ирОбщий.СтрРазделитьЛкс(НайденныеСтроки[0].ТипЭлементаКоллекции, ",", Истина);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат ТипыЭлементовКоллекции;
КонецФункции
// Добавляет и заполяет строку в таблицу слов при условии отсутствия там строк по ключу (Слово, ТипСлова)
//
// Параметры:
// ТаблицаСлов - ТаблицаЗначений - НоваяТаблицаСвойствТипа();
// Слово - Строка;
// ТипСлова - Строка;
// ТаблицаСтруктурТипов - ТаблицаЗначений.
//
Функция ДобавитьВТаблицуСлов(ТаблицаСлов, Слово, ТипСлова, ТаблицаСтруктурТипов = Неопределено, ТипЗначения = "??", Определение = "") Экспорт
#Если Сервер И Не Сервер Тогда
ТаблицаСлов = Новый ТаблицаЗначений
#КонецЕсли
КлючПоиска = Новый Структура("Слово, ТипСлова", Слово, ТипСлова);
НайденныеСтроки = ТаблицаСлов.НайтиСтроки(КлючПоиска);
Если НайденныеСтроки.Количество() > 0 Тогда
Возврат НайденныеСтроки[0];
КонецЕсли;
СтрокаСлова = ТаблицаСлов.Добавить();
ЗаполнитьЗначенияСвойств(СтрокаСлова, КлючПоиска);
СтрокаСлова.ТипЗначения = ТипЗначения;
СтрокаСлова.Определение = Определение;
Если ТаблицаСтруктурТипов <> Неопределено Тогда
СтрокаСлова.ТаблицаСтруктурТипов = ТаблицаСтруктурТипов;
Попытка
ТипЗначенияВложенный = ТаблицаСтруктурТипов[0].СтрокаОписания.ТипЗначения;
Исключение
ТипЗначенияВложенный = "??";
КонецПопытки;
СтрокаСлова.МожноУточнитьТип = Ложь
Или (Истина
И ТипЗначенияВложенный <> "??"
И Лев(ТипЗначения, 2) = "??")
Или Найти(ТипЗначения, "<") > 0;
КонецЕсли;
Возврат СтрокаСлова;
КонецФункции
// Получает таблицу слов указанной структуры типа.
//
// Параметры:
// СтруктураТипа - Структура - описание типа.
//
// Возвращаемое значение:
// ТаблицаЗначений - с колонками "Слово", "ТипСлова", "ТаблицаСтруктурТипов", "Определение".
//
Функция ПолучитьТаблицуСловСтруктурыТипа(СтруктураТипа, ЯзыкПрограммы = 0, Конфигурация = Неопределено, ВнешниеФункцииКомпоновкиДанных = Истина, Знач ВычислятьТипы = Истина,
Знач РазрешитьСозданиеОбъектаИзТипа = Истина, ТипСлова = Неопределено, ЛиСерверныйКонтекст = Ложь, Знач Слово = Неопределено, Знач МодульМетаданных = Неопределено,
Знач ВычислятьТипыМетодовМодулей = Ложь) Экспорт
ИнициализацияОписанияМетодовИСвойств();
ТаблицаСвойств = СвойстваТипаПредопределенные(СтруктураТипа, Слово, ТипСлова,, ЯзыкПрограммы, Конфигурация, ВычислятьТипы, ЛиСерверныйКонтекст);
СвойстваТипаМетаданные(СтруктураТипа, Слово, ТипСлова,, ЯзыкПрограммы,, ВнешниеФункцииКомпоновкиДанных, ВычислятьТипы, ЛиСерверныйКонтекст,
МодульМетаданных, ТаблицаСвойств, ВычислятьТипыМетодовМодулей);
Возврат ТаблицаСвойств;
КонецФункции
// Получает новую структуру типа.
//
// Параметры:
// Нет.
//
// Возвращаемое значение:
// Структура - "ИмяОбщегоТипа", "Метаданные", "СтрокаОписания", "ТипЯзыка", "ВиртуальнаяТаблица".
//
Функция НоваяТаблицаДополнительныхТипов() Экспорт
ТаблицаСтруктурТипа = Новый ТаблицаЗначений;
ТаблицаСтруктурТипа.Колонки.Добавить("ИмяОбщегоТипа", Новый ОписаниеТипов("Строка"));
ТаблицаСтруктурТипа.Колонки.Добавить("Метаданные");
//ТаблицаСтруктурТипа.Колонки.Добавить("ВключатьСвойства", Новый ОписаниеТипов("Булево"));
ТаблицаСтруктурТипа.Колонки.Добавить("НеВключатьМетоды", Новый ОписаниеТипов("Булево"));
Возврат ТаблицаСтруктурТипа;
КонецФункции // НоваяТаблицаДополнительныхТипов()
// Получает допустимые типы (строку) из таблицы структур типа.
//
// Параметры:
// ТаблицаСтруктурТипов - ТаблицаЗначений.
//
// Возвращаемое значение:
// Строка.
//
Функция ДопустимыеТипыИзТаблицыСтруктурТипа(ТаблицаСтруктурТипов) Экспорт
СтрокаСериализованныхТипов = "";
Для Каждого СтруктураТипа Из ТаблицаСтруктурТипов Цикл
СтрокаСериализованныхТипов = СтрокаСериализованныхТипов + ";" + СтруктураТипаВСтрокуВнутр(СтруктураТипа);
КонецЦикла;
СтрокаСериализованныхТипов = Сред(СтрокаСериализованныхТипов, 2);
Возврат СтрокаСериализованныхТипов;
КонецФункции
Функция ДопустимыеТипыИзОписанияТипов(ОписаниеТипов) Экспорт
ТаблицаСтруктурТипов = ТаблицаСтруктурТиповИзОписанияТипов(ОписаниеТипов);
ДопустимыеТипы = ДопустимыеТипыИзТаблицыСтруктурТипа(ТаблицаСтруктурТипов);
Возврат ДопустимыеТипы;
КонецФункции
// Получает представление допустимых типов.
//
// Параметры:
// ДопустимыеТипы - Строка.
//
// Возвращаемое значение:
// СтрокаПредставления - Строка.
//
Функция ПредставлениеДопустимыхТипов(ДопустимыеТипы) Экспорт
ТаблицаСтруктурТипов = ПолучитьТаблицуСтруктурТиповИзДопустимыхТипов(ДопустимыеТипы);
СтрокаПредставления = "";
Для Каждого СтруктураТипа Из ТаблицаСтруктурТипов Цикл
СтрокаПредставления = СтрокаПредставления + ", " + ИмяТипаИзСтруктурыТипа(СтруктураТипа);
ТипМетаданных = ТипЗнч(СтруктураТипа.Метаданные);
Если ТипМетаданных = Тип("КвалификаторыДаты") Тогда
Квалификаторы = СтруктураТипа.Метаданные;
Если Квалификаторы.ЧастиДаты = ЧастиДаты.Время Тогда
ПредставлениеСоставаДаты = "В";
ИначеЕсли Квалификаторы.ЧастиДаты = ЧастиДаты.Дата Тогда
ПредставлениеСоставаДаты = "Д";
ИначеЕсли Квалификаторы.ЧастиДаты = ЧастиДаты.ДатаВремя Тогда
ПредставлениеСоставаДаты = "ДВ";
КонецЕсли;
СтрокаПредставления = СтрокаПредставления + "(" + ПредставлениеСоставаДаты + ")";
ИначеЕсли ТипМетаданных = Тип("КвалификаторыСтроки") Тогда
Квалификаторы = СтруктураТипа.Метаданные;
СтрокаПредставления = СтрокаПредставления + "("
+ Квалификаторы.Длина + ","
+ ?(Квалификаторы.ДопустимаяДлина = ДопустимаяДлина.Фиксированная, "Ф", "П") + ")";
ИначеЕсли ТипМетаданных = Тип("КвалификаторыЧисла") Тогда
Квалификаторы = СтруктураТипа.Метаданные;
СтрокаПредставления = СтрокаПредставления + "("
+ ?(Квалификаторы.ДопустимыйЗнак = ДопустимыйЗнак.Неотрицательный, "Н", "")
+ Квалификаторы.Разрядность + ","
+ Квалификаторы.РазрядностьДробнойЧасти + ")";
КонецЕсли;
КонецЦикла;
СтрокаПредставления = Сред(СтрокаПредставления, 3);
Возврат СтрокаПредставления;
КонецФункции // ПредставлениеДопустимыхТипов()
// Получает структуру типа из значения.
//
// Параметры:
// Значение - Произвольный;
// *ЯзыкПрограммы - Число, *0;
// *ШаблонСтруктурыТипа - Структура, *Неопределено - содержит значения по умолчанию для новой структуры типа.
//
// Возвращаемое значение:
// Структура - структура типа.
//
Функция СтруктураТипаИзЗначения(Значение, ЯзыкПрограммы = 0, ШаблонСтруктурыТипа = Неопределено) Экспорт
Если Истина
И ШаблонСтруктурыТипа = Неопределено
//И (Ложь
// #Если Клиент Тогда
// Или ТипЗнч(Значение) = Тип("Форма")
// Или ТипЗнч(Значение) = Тип("ПолеВвода")
// //Или ТипЗнч(Значение) = Тип("КолонкаТабличногоПоля")
// Или ТипЗнч(Значение) = Тип("ТабличноеПоле")
// #КонецЕсли
// Или ТипЗнч(Значение) = Тип("Структура")
// Или ТипЗнч(Значение) = Тип("ТаблицаЗначений")
// Или ТипЗнч(Значение) = Тип("ДеревоЗначений")
// Или ТипЗнч(Значение) = Тип("ОбъектМетаданных"))
И мМассивТиповВключающихМетаданные.Найти(ТипЗнч(Значение)) <> Неопределено
Тогда
ШаблонСтруктурыТипа = Новый Структура("Метаданные", Значение);
КонецЕсли;
СтруктураТипа = СтруктураТипаИзКонкретногоТипа(ТипЗнч(Значение), ЯзыкПрограммы, ШаблонСтруктурыТипа);
Если СтруктураТипа.ИмяОбщегоТипа = "COMОбъект" Тогда
СтруктураТипа.ИмяОбщегоТипа = ПолноеИмяТипаCOMОбъекта(Значение);
//ИначеЕсли СтруктураТипа.ИмяОбщегоТипа = "ПеречислимоеСвойствоОбъектовМетаданных" Тогда
// // Не работает. Оказывается одно ПеречислимоеСвойствоОбъектовМетаданных может иметь много экземпляров
// СтрокиСвойствПеречислений = ТаблицаКонтекстов.НайтиСтроки(Новый Структура("ТипКонтекста", "ПеречислимыеСвойстваОбъектовМетаданных"));
// Для Каждого СтрокиСвойстваПеречисления Из СтрокиСвойствПеречислений Цикл
// Если Метаданные.СвойстваОбъектов[СтрокиСвойстваПеречисления.Слово] = Значение Тогда
// СтруктураТипа.ИмяОбщегоТипа = "ПеречислениеМетаданных: " + СтрокиСвойстваПеречисления.Слово;
// Прервать;
// КонецЕсли;
// КонецЦикла;
КонецЕсли;
ИмяОбщегоТипа = СтруктураТипа.ИмяОбщегоТипа;
//Если Ложь
// Или (Истина
// И ИмяОбщегоТипа = "СтрокаТаблицыЗначений"
// И ТипЗнч(СтруктураТипа.Метаданные) <> Тип("ТаблицаЗначений"))
// Или (Истина
// И ИмяОбщегоТипа = "СтрокаДереваЗначений"
// И ТипЗнч(СтруктураТипа.Метаданные) <> Тип("ДеревоЗначений"))
// Или (Истина
// И ИмяОбщегоТипа = "ВыборкаИзРезультатаЗапроса"
// И ТипЗнч(СтруктураТипа.Метаданные) <> Тип("РезультатЗапроса"))
//Тогда
// Попытка
// СтруктураТипа.Метаданные = Значение.Владелец();
// Исключение
// // Строка была удалена из коллекции
// КонецПопытки;
//КонецЕсли;
Если Ложь
Или ИмяОбщегоТипа = "ВнешняяОбработкаОбъект.<Имя внешней обработки>"
Или ИмяОбщегоТипа = "ВнешнийОтчетОбъект.<Имя внешнего отчета>"
Тогда
МетаданныеЗначения = Значение.Метаданные();
ЛиНеУчитыватьПодтип = (ЯзыкПрограммы <> 0) И СтруктураТипа.ТипЯзыка <> "ЗначениеВЗапросе";
ИмяОбщегоТипа = ПолучитьИмяОбщегоТипаПоТипуЗначенияСМетаданными(ТипЗнч(Значение), МетаданныеЗначения, ЛиНеУчитыватьПодтип);
СтруктураТипа.Метаданные = МетаданныеЗначения;
КлючПоиска = Новый Структура("Слово", ИмяОбщегоТипа);
НайденныеСтроки = ТаблицаОбщихТипов.НайтиСтроки(КлючПоиска);
Если НайденныеСтроки.Количество() > 0 Тогда
СтруктураТипа.ИмяОбщегоТипа = НайденныеСтроки[0].Слово;
Если СтруктураТипа.СтрокаОписания = Неопределено Тогда
СтруктураТипа.СтрокаОписания = НайденныеСтроки[0];
КонецЕсли;
КонецЕсли;
КонецЕсли;
#Если Клиент Тогда
МаркерРасширений = "Расширение ";
Если Ложь
Или ИмяОбщегоТипа = "Форма"
Или ИмяОбщегоТипа = "ПолеВвода"
//Или ИмяОбщегоТипа = "КолонкаТабличногоПоля"
Или ИмяОбщегоТипа = "ТабличноеПоле"
Или ИмяОбщегоТипа = "УправляемаяФорма"
Или ИмяОбщегоТипа = "ФормаКлиентскогоПриложения"
Или ИмяОбщегоТипа = "ДекорацияФормы"
Или ИмяОбщегоТипа = "ПолеФормы"
Или ИмяОбщегоТипа = "ГруппаФормы"
Или ИмяОбщегоТипа = "ТаблицаФормы"
Тогда
РасширяющийТип = Неопределено;
Если Ложь
Или ИмяОбщегоТипа = "УправляемаяФорма"
Или ИмяОбщегоТипа = "ФормаКлиентскогоПриложения"
Тогда
ИмяОбщегоТипа = "ФормаКлиентскогоПриложения";
КлючОсновногоОбъекта = ирОбщий.КлючОсновногоОбъектаУправляемойФормыЛкс(Значение);
Если КлючОсновногоОбъекта <> Неопределено Тогда
СтруктураРасширяющегоТипа = СтруктураТипаИзЗначения(КлючОсновногоОбъекта);
Если Найти(СтруктураРасширяющегоТипа.ИмяОбщегоТипа, "Ссылка.") > 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(Поток, СтруктураТипа.Метаданные);
ОписательТипа.Метаданные = Новый ХранилищеЗначения(Поток.Закрыть());
Иначе
//ОписательТипа.Метаданные = СтруктураТипа.Метаданные;
КонецЕсли;
Результат = ЗначениеВСтрокуВнутр(ОписательТипа);
Возврат Результат;
КонецФункции // СтруктураТипаВСтрокуВнутр()
// <Описание функции>
//
// Параметры:
// <Параметр1> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>.
//
// Возвращаемое значение:
// - <Тип.Вид> - <описание значения>
// <продолжение описания значения>;
// <Значение2> - <Тип.Вид> - <описание значения>
// <продолжение описания значения>.
//
Функция ПолучитьИмяОбщегоТипаПоТипуЗначенияСМетаданными(Знач КонкрентыйТип, МетаданныеТипа, ЛиНеУчитыватьПодтип)
КонкрентыйТип = НРег(КонкрентыйТип);
Если Ложь
Или Найти(КонкрентыйТип, "(точка маршрута)") > 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] = "Форма";
ИначеЕсли МассивФрагментов[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 Тогда
СтруктураТипа.ИмяОбщегоТипа = Строка(КонкрентыйТип);
Иначе
//ирОбщий.СообщитьЛкс("Невозможно восстановить имя типа """ + КонкрентыйТип + """", СтатусСообщения.Важное);
КонецЕсли;
КонецЕсли;
Возврат СтруктураТипа;
КонецФункции
// Получает таблицу структур типов из описания типов.
//
// Параметры:
// ОписаниеТипов - ОписаниеТипов;
// *ТаблицаСтруктурТипов - ТаблицаЗначений, *Неопределено - существующая таблица.
//
// Возвращаемое значение:
// ТаблицаЗначений - структур типов.
//
Функция ТаблицаСтруктурТиповИзОписанияТипов(ОписаниеТипов, ТаблицаСтруктурТипов = Неопределено) Экспорт
Если ТаблицаСтруктурТипов = Неопределено Тогда
ТаблицаСтруктурТипов = НоваяТаблицаСтруктурТипа();
КонецЕсли;
Для Каждого Тип Из ОписаниеТипов.Типы() Цикл
СтруктураТипа = СтруктураТипаИзКонкретногоТипа(Тип);
СтруктураТипа.Квалификаторы = ОписаниеТипов;
ЗаполнитьЗначенияСвойств(ТаблицаСтруктурТипов.Добавить(), СтруктураТипа);
КонецЦикла;
Возврат ТаблицаСтруктурТипов;
КонецФункции
Функция ТаблицаСтруктурТиповИзЗначения(Значение, ТаблицаСтруктурТипов = Неопределено, ЯзыкПрограммы = 0) Экспорт
Если ТаблицаСтруктурТипов = Неопределено Тогда
ТаблицаСтруктурТипов = НоваяТаблицаСтруктурТипа();
КонецЕсли;
СтруктураТипа = СтруктураТипаИзЗначения(Значение, ЯзыкПрограммы);
ЗаполнитьЗначенияСвойств(ТаблицаСтруктурТипов.Добавить(), СтруктураТипа);
Возврат ТаблицаСтруктурТипов;
КонецФункции
// Получает объект по ссылке, кэшируя результат в соответствии.
//
// Параметры:
// Ссылка - Ссылка;
// ПринудительноОбновить - Булево, *Ложь.
//
// Возвращаемое значение:
// Объект.
//
Функция КэшОбъект(Ссылка, ПринудительноОбновить = Ложь) Экспорт
ТипСсылки = ТипЗнч(Ссылка);
Кэш = КэшОбъектов[ТипСсылки];
Если Кэш = Неопределено Тогда
Кэш = Новый Соответствие;
КэшОбъектов[ТипСсылки] = Кэш;
КонецЕсли;
Если Не ПринудительноОбновить Тогда
Результат = Кэш[Ссылка];
КонецЕсли;
Если Результат = Неопределено Тогда
Результат = Ссылка.ПолучитьОбъект();
Кэш[Ссылка] = Результат;
КонецЕсли;
Возврат Результат;
КонецФункции // КэшОбъект()
// Получает строку конкретного типа.
//
// Параметры:
// СтруктураТипа - Структура - описание типа.
//
// Возвращаемое значение:
// Строка - конкрентого типа.
//
Функция ИмяТипаИзСтруктурыТипа(СтруктураТипа) Экспорт
КонкретныйТип = СтруктураТипа.ИмяОбщегоТипа;
МаркерРасширенияФормы = "Расширение формы";
Если Лев(КонкретныйТип, СтрДлина(МаркерРасширенияФормы)) = МаркерРасширенияФормы Тогда
КонкретныйТип = "Форма";
КонецЕсли;
//Если Лев(КонкретныйТип, СтрДлина(МаркерКоллекцииМетаданных)) = МаркерКоллекцииМетаданных Тогда
// КонкретныйТип = МаркерКоллекцииМетаданных;
//КонецЕсли;
ОбъектМД = СтруктураТипа.Метаданные;
Если Истина
И ТипЗнч(ОбъектМД) = Тип("КоллекцияОбъектовМетаданных")
И ОбъектМД.Количество() > 0
Тогда
ОбъектМД = ОбъектМД[0].Родитель();
КонецЕсли;
ТипМетаданных = ТипЗнч(ОбъектМД);
Если ТипМетаданных = Тип("ОбъектМетаданных") Тогда
ПолноеИмя = ОбъектМД.ПолноеИмя();
МассивФрагментов = ирОбщий.СтрРазделитьЛкс(ПолноеИмя);
Если МассивФрагментов[0] = "ТабличнаяЧасть" Тогда
// Баг платформы. У внешних метаданных полное имя не включает сам внешний метаобъект
МассивФрагментов.Вставить(0, "Имя");
МассивФрагментов.Вставить(0, "");
КонецЕсли;
Для Счетчик = 0 По МассивФрагментов.Количество() / 2 - 1 Цикл
ИмяЭлементаКоллекции = ирОбщий.СтрокаМеждуМаркерамиЛкс(КонкретныйТип, "<", ">", Ложь, Истина);
КонкретныйТип = СтрЗаменить(КонкретныйТип, ИмяЭлементаКоллекции, МассивФрагментов[Счетчик * 2 + 1]);
КонецЦикла;
ИначеЕсли Истина
И Это2iS
И (Ложь
Или ТипМетаданных = Тип("СправочникСсылка.ОбъектыМетаданных2iS")
Или ТипМетаданных = Тип("СправочникСсылка.СвойстваМетаданных2iS"))
Тогда
ОбъектМД = КэшОбъект(ОбъектМД);
ПолноеИмя = ОбъектМД.ПолноеИмя;
МассивФрагментов = ирОбщий.СтрРазделитьЛкс(ПолноеИмя);
Если МассивФрагментов[0] = "ТабличнаяЧасть" Тогда
// Баг платформы. У внешних метаданных полное имя не включает сам внешний метаобъект
МассивФрагментов.Вставить(0, "Имя");
МассивФрагментов.Вставить(0, "");
КонецЕсли;
Для Счетчик = 0 По МассивФрагментов.Количество() / 2 - 1 Цикл
ИмяЭлементаКоллекции = ирОбщий.СтрокаМеждуМаркерамиЛкс(КонкретныйТип, "<", ">", Ложь, Истина);
КонкретныйТип = СтрЗаменить(КонкретныйТип, ИмяЭлементаКоллекции, МассивФрагментов[Счетчик * 2 + 1]);
КонецЦикла;
//ИначеЕсли ТипЗнч(СтруктураТипа.Метаданные) = Тип("Соответствие") Тогда
// Для Каждого ЭлементВида Из СтруктураТипа.Метаданные Цикл
// КонкретныйТип = СтрЗаменить(КонкретныйТип, ЭлементВида.Ключ, ЭлементВида.Значение);
// КонецЦикла;
ИначеЕсли Ложь
Или КонкретныйТип = "Неизвестный контекст"
Или КонкретныйТип = "Произвольный"
Тогда
КонкретныйТип = "?";
КонецЕсли;
Попытка
Квалификаторы = СтруктураТипа.Квалификаторы;
Исключение
Квалификаторы = Неопределено;
КонецПопытки;
Если Истина
И Квалификаторы <> Неопределено
И (Ложь
Или КонкретныйТип = "Строка"
Или КонкретныйТип = "Число"
Или КонкретныйТип = "Дата")
Тогда
ирОбщий.ДобавитьКвалификаторыВПредставлениеТипаЛкс(КонкретныйТип, Тип(КонкретныйТип), СтруктураТипа.Квалификаторы);
КонецЕсли;
Возврат КонкретныйТип;
КонецФункции
// Получает новую структуру типа.
//
// Параметры:
// Нет.
//
// Возвращаемое значение:
// Структура - "ИмяОбщегоТипа", "Метаданные", "СтрокаОписания", "ТипЯзыка", "ВиртуальнаяТаблица".
//
Функция НоваяСтруктураТипа() Экспорт
// Метка=7веан7878378078
Возврат Новый Структура("ИмяОбщегоТипа, Метаданные, СтрокаОписания, ТипЯзыка, Конструктор, ВиртуальнаяТаблица, ДополнительныеТипы, ДержательМетаданных, Квалификаторы",
"Неизвестный контекст", Неопределено, Неопределено, "", Ложь, Новый Структура("Выражение, НомерСтроки", "", 0));
КонецФункции
// Десериализатор структуры типа из неполной сериализации.
//
// Параметры:
// СтрокаСтруктурыТипа - Строка.
//
// Возвращаемое значение:
// СтруктураТипа - Структура.
//
Функция СтруктураТипаИзСтрокиВнутр(СтрокаСтруктурыТипа) Экспорт
СтруктураТипа = НоваяСтруктураТипа();
Если ПустаяСтрока(СтрокаСтруктурыТипа) Тогда
Возврат СтруктураТипа;
КонецЕсли;
Успех = Ложь;
Попытка
ОписательТипа = ЗначениеИзСтрокиВнутр(СтрокаСтруктурыТипа);
Успех = Истина;
Исключение
ОписательТипа = НоваяСтруктураТипа();
ОписательТипа.ИмяОбщегоТипа = "<Ошибка преобразования>";
КонецПопытки;
Если Успех Тогда
СтруктураТипа.ИмяОбщегоТипа = ОписательТипа.ИмяОбщегоТипа;
Если ТипЗнч(ОписательТипа.Метаданные) = Тип("Строка") Тогда
СтруктураТипа.Метаданные = ирКэш.ОбъектМДПоПолномуИмениЛкс(ОписательТипа.Метаданные);
ИначеЕсли ТипЗнч(ОписательТипа.Метаданные) = Тип("ХранилищеЗначения") Тогда
Поток = Новый ЧтениеXML;
Поток.УстановитьСтроку(ОписательТипа.Метаданные.Получить());
// Тут тормоз
СтруктураТипа.Метаданные = СериализаторXDTO.ПрочитатьXML(Поток);
Иначе
СтруктураТипа.Метаданные = ОписательТипа.Метаданные;
КонецЕсли;
КонецЕсли;
Возврат СтруктураТипа;
КонецФункции // СтруктураТипаВСтрокуВнутр()
// Получает новую структуру типа.
//
// Параметры:
// Нет.
//
// Возвращаемое значение:
// Структура - "ИмяОбщегоТипа", "Метаданные", "СтрокаОписания", "ТипЯзыка", "ВиртуальнаяТаблица".
//
Функция НоваяТаблицаСтруктурТипа() Экспорт
Возврат мТаблицаСтруктурТипа.СкопироватьКолонки();
КонецФункции
// Добавляет структуру типа в таблицу структур типов.
//
// Параметры:
// ТаблицаСтруктурТипов - ТаблицаЗначений;
// СтруктураТипа - Структура.
//
Процедура ДобавитьВТаблицуСтруктурТипов(ТаблицаСтруктурТипов, СтруктураТипа, ПередаватьДополнительныеТипы = Ложь) Экспорт
ИсключаемыеСвойства = Неопределено;
Если Не ПередаватьДополнительныеТипы Тогда
ИсключаемыеСвойства = "ДополнительныеТипы";
КонецЕсли;
ЗаполнитьЗначенияСвойств(ТаблицаСтруктурТипов.Добавить(), СтруктураТипа, , ИсключаемыеСвойства);
КонецПроцедуры // ДобавитьВТаблицуСтруктурТипов()
// Получает массив структур типов из строки допустимых типов.
//
// Параметры:
// ДопустимыеТипы - Строка;
// *ШаблонСтруктурыТипа - Структура, *Неопределено - содержит значения по умолчанию для новой структуры типа.
//
// Возвращаемое значение:
// Структура - структура типа.
//
Функция ПолучитьТаблицуСтруктурТиповИзДопустимыхТипов(ДопустимыеТипы, ШаблонСтруктурыТипа = Неопределено) Экспорт
ТаблицаСтруктурТипов = НоваяТаблицаСтруктурТипа();
Если ПустаяСтрока(ДопустимыеТипы) Тогда
Возврат ТаблицаСтруктурТипов;
КонецЕсли;
МассивСериализованныхТипов = ирОбщий.СтрРазделитьЛкс(ДопустимыеТипы, ";");
Для Каждого СериализованныйТип Из МассивСериализованныхТипов Цикл
СтруктураТипа = СтруктураТипаИзСтрокиВнутр(СериализованныйТип);
Если ШаблонСтруктурыТипа <> Неопределено Тогда
ЗаполнитьЗначенияСвойств(СтруктураТипа, ШаблонСтруктурыТипа);
КонецЕсли;
ДобавитьВТаблицуСтруктурТипов(ТаблицаСтруктурТипов, СтруктураТипа);
КонецЦикла;
Возврат ТаблицаСтруктурТипов;
КонецФункции // ПолучитьТаблицуСтруктурТиповИзДопустимыхТипов()
// Получает описание типов из допустимых типов.
//
// Параметры:
// ДопустимыеТипы - Строка;
// ТипЗначенияЭУ - ОписаниеТипов - все возможные типы из элемента управления.
//
// Возвращаемое значение:
// ОписаниеТипов.
//
Функция ПолучитьОписаниеТиповИзДопустимыхТипов(ДопустимыеТипы, ТипЗначенияЭУ = Неопределено) Экспорт
ТаблицаСтруктурТипов = ПолучитьТаблицуСтруктурТиповИзДопустимыхТипов(ДопустимыеТипы);
ОписаниеТипов = ОписаниеТиповИзТаблицыСтруктурТипов(ТаблицаСтруктурТипов, ТипЗначенияЭУ);
Возврат ОписаниеТипов;
КонецФункции
// Получает описание типов из таблицы структур типов.
//
// Параметры:
// ДопустимыеТипы - Строка;
// ТипЗначенияЭУ - ОписаниеТипов - все возможные типы из элемента управления.
//
// Возвращаемое значение:
// ОписаниеТипов.
//
Функция ОписаниеТиповИзТаблицыСтруктурТипов(ТаблицаСтруктурТипов, ТипЗначенияЭУ = Неопределено) Экспорт
Если ТаблицаСтруктурТипов = Неопределено Тогда
Возврат Новый ОписаниеТипов;
КонецЕсли;
МассивТипов = Новый Массив;
Для Каждого СтруктураТипа Из ТаблицаСтруктурТипов Цикл
СтрокаКонкретногоТипа = ИмяТипаИзСтруктурыТипа(СтруктураТипа);
Попытка
ТекущийТип = Тип(СтрокаКонкретногоТипа);
Исключение
Продолжить;
КонецПопытки;
ТипМетаданных = ТипЗнч(СтруктураТипа.Метаданные);
Если ТипМетаданных = Тип("КвалификаторыСтроки") Тогда
КвалификаторыСтроки = СтруктураТипа.Метаданные;
ИначеЕсли ТипМетаданных = Тип("КвалификаторыЧисла") Тогда
КвалификаторыЧисла = СтруктураТипа.Метаданные;
ИначеЕсли ТипМетаданных = Тип("КвалификаторыДаты") Тогда
КвалификаторыДаты = СтруктураТипа.Метаданные;
КонецЕсли;
Если ТипЗначенияЭУ <> Неопределено Тогда
Если Не ТипЗначенияЭУ.СодержитТип(ТекущийТип) Тогда
Продолжить;
КонецЕсли;
КонецЕсли;
МассивТипов.Добавить(ТекущийТип);
КонецЦикла;
ОписаниеТипов = Новый ОписаниеТипов(МассивТипов, КвалификаторыЧисла, КвалификаторыСтроки, КвалификаторыСтроки);
Возврат ОписаниеТипов;
КонецФункции // ПолучитьОписаниеТиповИзДопустимыхТипов()
// Получает строку типа метаобъектов по единственному или множественному числу.
//
// Параметры:
// *Единственное - Строка, *Неопределено - единственное число типа;
// *Множественное - Строка, *Неопределено - множественное число типа.
// *Категория - Число, *Неопределено.
//
// Возвращаемое значение:
// СтрокаТаблицыЗначений - найденная строка типа;
// Неопределено - корневой тип не найден.
//
Функция ОписаниеТипаМетаОбъектов(Знач Единственное = Неопределено, Знач Множественное = Неопределено, Категория = Неопределено) Экспорт
СтруктураПоиска = Новый Структура;
Если Категория <> Неопределено Тогда
СтруктураПоиска.Вставить("Категория", Категория);
КонецЕсли;
Если Единственное <> Неопределено Тогда
СтруктураПоиска.Вставить("НЕдинственное", НРег(Единственное));
КонецЕсли;
Если Множественное <> Неопределено Тогда
СтруктураПоиска.Вставить("НМножественное", НРег(Множественное));
КонецЕсли;
НайденныеСтроки = ТаблицаТиповМетаОбъектов.НайтиСтроки(СтруктураПоиска);
Если НайденныеСтроки.Количество() = 0 Тогда
Результат = Неопределено;
Иначе
Результат = НайденныеСтроки[0];
КонецЕсли;
Возврат Результат;
КонецФункции
Процедура ПроверитьЗагрузитьКэшМДСеанса()
ПереданныйКэш = ирКэш.ПараметрыСеансаЛкс().ПереданныйКэш;
КэшМДСеанса = Неопределено;
Если ЗначениеЗаполнено(ПереданныйКэш) Тогда
КэшМДСеанса = ПолучитьИзВременногоХранилища(ПереданныйКэш);
КонецЕсли;
Если КэшМДСеанса = Неопределено Тогда
СостояниеРасчета = ирКэш.СостояниеПодготовкиКэшМДСеансаЛкс();
Если СостояниеРасчета <> Неопределено Тогда
ФоновоеЗадание = ФоновыеЗадания.НайтиПоУникальномуИдентификатору(СостояниеРасчета.ИдентификаторЗадания);
КонецЕсли;
Если ФоновоеЗадание <> Неопределено Тогда
Если ФоновоеЗадание.Состояние = СостояниеФоновогоЗадания.Активно Тогда
ирОбщий.ОжидатьЗавершенияФоновойОперацииЛкс(ФоновоеЗадание);
КонецЕсли;
Если ФоновоеЗадание.Состояние = СостояниеФоновогоЗадания.Завершено Тогда
КэшМДСеанса = ирОбщий.ПрочитатьРезультатФоновогоЗаданияЛкс(СостояниеРасчета.АдресРезультата, СостояниеРасчета.ФормаРезультата);
Если КэшМДСеанса = Null Тогда
КэшМДСеанса = Неопределено;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если КэшМДСеанса <> Неопределено Тогда
#Если Сервер И Не Сервер Тогда
КэшМДСеанса = Новый Структура;
#КонецЕсли
мТаблицаВсехТаблицБД = КэшМДСеанса.ТаблицаВсехТаблицБД;
Если КэшМДСеанса.Свойство("ДеревоОбъектовМД") Тогда
мДеревоОбъектовМД = КэшМДСеанса.ДеревоОбъектовМД;
КонецЕсли;
Возврат;
КонецЕсли;
КонецПроцедуры
Функция ДеревоОбъектовМД() Экспорт
ПроверитьЗагрузитьКэшМДСеанса();
Если мДеревоОбъектовМД <> Неопределено Тогда
#Если Сервер И Не Сервер Тогда
мДеревоОбъектовМД = Новый ДеревоЗначений;
#КонецЕсли
#Если Клиент Тогда
Если мДеревоОбъектовМД.Колонки.Найти("КоличествоСтрок") = Неопределено Тогда
мДеревоОбъектовМД.Колонки.Добавить("КоличествоСтрок", Новый ОписаниеТипов("Строка, Число"));
КонецЕсли;
#КонецЕсли
Возврат мДеревоОбъектовМД;
КонецЕсли;
ДеревоОбъектовМД = Новый ДеревоЗначений;
ДеревоОбъектовМД.Колонки.Добавить("Имя", Новый ОписаниеТипов("Строка"));
ДеревоОбъектовМД.Колонки.Добавить("Представление", Новый ОписаниеТипов("Строка"));
ДеревоОбъектовМД.Колонки.Добавить("ПолноеИмяОбъекта", Новый ОписаниеТипов("Строка"));
ДеревоОбъектовМД.Колонки.Добавить("ИндексКартинки", Новый ОписаниеТипов("Число"));
ДеревоОбъектовМД.Колонки.Добавить("ЕстьДоступ", Новый ОписаниеТипов("Булево"));
ДеревоОбъектовМД.Колонки.Добавить("ПравоПросмотр", Новый ОписаниеТипов("Булево"));
ДеревоОбъектовМД.Колонки.Добавить("ТипТаблицы", Новый ОписаниеТипов("Строка"));
мТаблицаВсехТаблицБД = ирОбщий.СоздатьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКлсПолеТекстаПрограммы");
#Если Сервер И Не Сервер Тогда
мТаблицаВсехТаблицБД = Обработки.ирКлсПолеТекстаПрограммы.Создать();
#КонецЕсли
мТаблицаВсехТаблицБД = мТаблицаВсехТаблицБД.ДоступныеТаблицы.ВыгрузитьКолонки();
мТаблицаВсехТаблицБД.Колонки.Удалить("ПородившийЗапрос"); // Для экономии памяти
мТаблицаВсехТаблицБД.Колонки.Добавить("ТипСсылки");
//ТаблицаВсехТаблицБД.Колонки.Добавить("СтруктураКлюча");
КоллекцияКорневыхТипов = Новый Массив;
СтрокиМетаОбъектов = ТаблицаТиповМетаОбъектов.НайтиСтроки(Новый Структура("Категория", 0));
Для Каждого СтрокаТаблицыМетаОбъектов Из СтрокиМетаОбъектов Цикл
КоллекцияКорневыхТипов.Добавить(СтрокаТаблицыМетаОбъектов.Единственное);
КонецЦикла;
Если ирКэш.ДоступныВнешниеИсточникДанныхЛкс() Тогда
Для Каждого МетаВнешнийИсточникДанных Из Метаданные.ВнешниеИсточникиДанных Цикл
КоллекцияКорневыхТипов.Добавить(МетаВнешнийИсточникДанных.ПолноеИмя());
КонецЦикла;
КонецЕсли;
КоллекцияКорневыхТипов.Добавить("Отчет");
КоллекцияКорневыхТипов.Добавить("Обработка");
КоллекцияКорневыхТипов.Добавить("Роль");
КоллекцияКорневыхТипов.Добавить("Подсистема");
КоллекцияКорневыхТипов.Добавить("РегламентноеЗадание");
КоллекцияКорневыхТипов.Добавить("HTTPСервис");
КоллекцияКорневыхТипов.Добавить("WebСервис");
ИмяДвиженияССубконто = ирОбщий.ПеревестиСтроку("ДвиженияССубконто");
ИмяГраницы = ирОбщий.ПеревестиСтроку("Границы");
ИмяЗадачиПоИсполнителю = ирОбщий.ПеревестиСтроку("ЗадачиПоИсполнителю");
ИмяКонстанта = ирОбщий.ПеревестиСтроку("Константа");
ИмяОбороты = ирОбщий.ПеревестиСтроку("Обороты");
ИмяОборотыДтКт = ирОбщий.ПеревестиСтроку("ОборотыДтКт");
ИмяОстатки = ирОбщий.ПеревестиСтроку("Остатки");
ИмяОстаткиИОбороты = ирОбщий.ПеревестиСтроку("ОстаткиИОбороты");
ИмяСрезПервых = ирОбщий.ПеревестиСтроку("СрезПервых");
ИмяСрезПоследних = ирОбщий.ПеревестиСтроку("СрезПоследних");
ИмяСубконто = ирОбщий.ПеревестиСтроку("Субконто");
ИмяТабличнаяЧасть = ирОбщий.ПеревестиСтроку("ТабличнаяЧасть");
ИмяТочки = ирОбщий.ПеревестиСтроку("Точки");
ИндексКартинкиТЧ = мОписаниеТипаМДТабличнаяЧасть.ИндексКартинкиЕдинственное;
Если Метаданные.Константы.Количество() > 0 Тогда
ирОбщий.ДобавитьДоступнуюТаблицуБДЛкс(мТаблицаВсехТаблицБД, ирОбщий.ПеревестиСтроку("Константы"),, "Константы");
КонецЕсли;
ИндикаторТиповМД = ирОбщий.ПолучитьИндикаторПроцессаЛкс(КоллекцияКорневыхТипов.Количество(), "Анализ конфигурации");
Для Каждого КорневойТип Из КоллекцияКорневыхТипов Цикл
ирОбщий.ОбработатьИндикаторЛкс(ИндикаторТиповМД);
ОписаниеКорневогоТипа = ОписаниеТипаМетаОбъектов(КорневойТип);
Если ОписаниеКорневогоТипа = Неопределено Тогда
Если Найти(КорневойТип, ".") = 0 Тогда
// В текущей версии платформы нет поддержки такого типа метаданных
Продолжить;
КонецЕсли;
// Внешний источник данных
ОписаниеКорневогоТипа = мОписаниеТипаМДВнешнийИсточникДанных;
ОбъектМДКорневогоТипа = ирКэш.ОбъектМДПоПолномуИмениЛкс(КорневойТип);
МножественноеКорневогоТипа = КорневойТип;
ПредставлениеКатегории = ирОбщий.ПредставлениеИзИдентификатораЛкс(ОписаниеКорневогоТипа.Множественное) + "." + ОбъектМДКорневогоТипа.Представление();
ЕстьДоступ = ПравоДоступа("Использование", ОбъектМДКорневогоТипа);
СхемаТаблиц = ОбъектМДКорневогоТипа.Имя;
ТипТаблицы = "Внешняя";
КоллекцияМетаОбъектов = ОбъектМДКорневогоТипа.Таблицы;
ЕстьТаблицаБД = Истина;
Иначе
МножественноеКорневогоТипа = ОписаниеКорневогоТипа.Множественное;
ПредставлениеКатегории = ирОбщий.ПредставлениеИзИдентификатораЛкс(МножественноеКорневогоТипа);
ЕстьДоступ = Истина;
СхемаТаблиц = "";
//Если КорневойТип = "КритерийОтбора" Тогда
// ТипТаблицы = "ВиртуальнаяТаблица";
//Иначе
ТипТаблицы = КорневойТип;
//КонецЕсли;
Если КорневойТип = "Перерасчет" Тогда
КоллекцияМетаОбъектов = Новый Массив;
Для Каждого МетаРегистрРасчета Из Метаданные.РегистрыРасчета Цикл
Для Каждого Перерасчет Из МетаРегистрРасчета.Перерасчеты Цикл
КоллекцияМетаОбъектов.Добавить(Перерасчет);
КонецЦикла;
КонецЦикла;
Иначе
КоллекцияМетаОбъектов = Метаданные[МножественноеКорневогоТипа];
КонецЕсли;
ЕстьТаблицаБД = Истина
И (Ложь
Или КорневойТип <> "Константа"
Или ирКэш.ДоступныТаблицыКонстантЛкс())
И (Ложь
Или КорневойТип = "Константа"
Или КорневойТип = "КритерийОтбора"
Или КорневойТип = "ЖурналДокументов"
Или ирОбщий.ЛиКорневойТипПеречисленияЛкс(КорневойТип)
Или ирОбщий.ЛиКорневойТипСсылочногоОбъектаБДЛкс(КорневойТип)
Или ирОбщий.ЛиКорневойТипРегистраБДЛкс(КорневойТип)
Или ирОбщий.ЛиКорневойТипПоследовательностиЛкс(КорневойТип));
КонецЕсли;
Если КоллекцияМетаОбъектов.Количество() = 0 Тогда
Продолжить;
КонецЕсли;
СтрокаТипаМетаданных = ДеревоОбъектовМД.Строки.Добавить();
СтрокаТипаМетаданных.Представление = ПредставлениеКатегории;
СтрокаТипаМетаданных.Имя = МножественноеКорневогоТипа;
СтрокаТипаМетаданных.ПолноеИмяОбъекта = МножественноеКорневогоТипа;
СтрокаТипаМетаданных.ИндексКартинки = ОписаниеКорневогоТипа.ИндексКартинкиМножественное;
СтрокаТипаМетаданных.ЕстьДоступ = ЕстьДоступ;
ЛиКорневойТипОбъектаСТабличнымиЧастями = ирОбщий.ЛиКорневойТипСсылочногоОбъектаБДЛкс(КорневойТип);
ИндикаторОбъектовМД = ирОбщий.ПолучитьИндикаторПроцессаЛкс(КоллекцияМетаОбъектов.Количество(), "Анализ " + КорневойТип);
Для Каждого ОбъектМД Из КоллекцияМетаОбъектов Цикл
#Если Сервер И Не Сервер Тогда
ОбъектМД = Метаданные.Справочники.ирАлгоритмы;
#КонецЕсли
ирОбщий.ОбработатьИндикаторЛкс(ИндикаторОбъектовМД);
ПолноеИмяМД = ОбъектМД.ПолноеИмя();
ПредставлениеМД = ОбъектМД.Представление();
ПолноеИмяТаблицыБД = ирКэш.ИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД,, Ложь);
ФрагментыИмениТаблицы = ирОбщий.СтрРазделитьЛкс(ПолноеИмяТаблицыБД);
ИмяОбъектаМД = ОбъектМД.Имя;
Если КорневойТип = "Перерасчет" Тогда
МетаРегистрРасчета = ОбъектМД.Родитель();
ИмяОбъектаМД = МетаРегистрРасчета.Имя + "." + ИмяОбъектаМД;
ПредставлениеМД = МетаРегистрРасчета.Представление() + "." + ПредставлениеМД;
КонецЕсли;
СтрокаОбъектаМД = ДобавитьСтрокуДереваМД(СтрокаТипаМетаданных, ПолноеИмяТаблицыБД, ИмяОбъектаМД, ПредставлениеМД, ТипТаблицы, ОписаниеКорневогоТипа.ИндексКартинкиЕдинственное,
ЕстьТаблицаБД, мТаблицаВсехТаблицБД, ПолноеИмяМД, ОбъектМД.Имя, ПредставлениеМД, СхемаТаблиц, ОбъектМД,, ФрагментыИмениТаблицы);
Попытка
СтрокаОбъектаМД.ПравоПросмотр = ПравоДоступа("Просмотр", ОбъектМД);
Исключение
СтрокаОбъектаМД.ПравоПросмотр = Истина;
КонецПопытки;
Если ЛиКорневойТипОбъектаСТабличнымиЧастями Тогда
СтруктураТЧ = ирОбщий.ТабличныеЧастиОбъектаЛкс(ОбъектМД, ФрагментыИмениТаблицы);
Для Каждого КлючИЗначение Из СтруктураТЧ Цикл
СтрокаТЧВДереве = ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + КлючИЗначение.Ключ, КлючИЗначение.Ключ, КлючИЗначение.Значение, "ТабличнаяЧасть", ИндексКартинкиТЧ,
ЕстьТаблицаБД, мТаблицаВсехТаблицБД, ПолноеИмяМД + "." + ИмяТабличнаяЧасть + "." + КлючИЗначение.Ключ,, ПредставлениеМД + "." + КлючИЗначение.Значение,, ОбъектМД);
МетаТЧ = ОбъектМД.ТабличныеЧасти.Найти(КлючИЗначение.Ключ);
Если МетаТЧ <> Неопределено Тогда
СтрокаТЧВДереве.ПравоПросмотр = ПравоДоступа("Просмотр", МетаТЧ);
КонецЕсли;
КонецЦикла;
Если КорневойТип = "БизнесПроцесс" Тогда
ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяТочки, "Точки", "Точки", "Точки", ИндексКартинкиТЧ,
ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Точки",, ОбъектМД);
КонецЕсли;
Если КорневойТип = "Задача" Тогда
Если ОбъектМД.Адресация <> Неопределено Тогда
ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяЗадачиПоИсполнителю, "ЗадачиПоИсполнителю", "Задачи по исполнителю", "ВиртуальнаяТаблица", ИндексКартинкиТЧ,
ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Задачи по исполнителю",, ОбъектМД, 1);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если КорневойТип = "РегистрСведений" Тогда
Если ОбъектМД.ПериодичностьРегистраСведений <> Метаданные.СвойстваОбъектов.ПериодичностьРегистраСведений.Непериодический Тогда
ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяСрезПоследних, "СрезПоследних", ПредставлениеМД + ": срез последних", "ВиртуальнаяТаблица", ИндексКартинкиТЧ,
ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Срез последних",, ОбъектМД, 1);
ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяСрезПервых, "СрезПервых", ПредставлениеМД + ": срез первых", "ВиртуальнаяТаблица", ИндексКартинкиТЧ,
ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Срез первых",, ОбъектМД, 1);
КонецЕсли;
ИначеЕсли КорневойТип = "РегистрНакопления" Тогда
ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяОбороты, "Обороты", ПредставлениеМД + ": Обороты", "ВиртуальнаяТаблица", ИндексКартинкиТЧ,
ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Обороты",, ОбъектМД, 3);
Если ОбъектМД.ВидРегистра = Метаданные.СвойстваОбъектов.ВидРегистраНакопления.Остатки Тогда
ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяОстатки, "Остатки", ПредставлениеМД + ": Остатки", "ВиртуальнаяТаблица", ИндексКартинкиТЧ,
ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Остатки",, ОбъектМД, 1);
ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяОстаткиИОбороты, "ОстаткиИОбороты", ПредставлениеМД + ": Остатки и обороты", "ВиртуальнаяТаблица", ИндексКартинкиТЧ,
ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Остатки и обороты",, ОбъектМД, 4);
КонецЕсли;
ИначеЕсли КорневойТип = "РегистрБухгалтерии" Тогда
ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяОбороты, "Обороты", ПредставлениеМД + ": Обороты", "ВиртуальнаяТаблица", ИндексКартинкиТЧ,
ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Обороты",, ОбъектМД, 5);
ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяОстатки, "Остатки", ПредставлениеМД + ": Остатки", "ВиртуальнаяТаблица", ИндексКартинкиТЧ,
ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Остатки",, ОбъектМД, 3);
ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяОстаткиИОбороты, "ОстаткиИОбороты", ПредставлениеМД + ": Остатки и обороты", "ВиртуальнаяТаблица", ИндексКартинкиТЧ,
ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Остатки и обороты",, ОбъектМД, 6);
ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяДвиженияССубконто, "ДвиженияССубконто", ПредставлениеМД + ": Движения с субконто", "ДвиженияССубконто", ИндексКартинкиТЧ,
ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Движения с субконто",, ОбъектМД, 2);
Если ОбъектМД.ПланСчетов.МаксКоличествоСубконто > 0 Тогда
ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяСубконто, "Субконто", ПредставлениеМД + ": Субконто", "Субконто", ИндексКартинкиТЧ,
ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Субконто",, ОбъектМД);
КонецЕсли;
Если ОбъектМД.Корреспонденция Тогда
ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяОборотыДтКт, "ОборотыДтКт", ПредставлениеМД + ": Обороты Дт Кт", "ВиртуальнаяТаблица", ИндексКартинкиТЧ,
ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Обороты Дт Кт",, ОбъектМД, 7);
КонецЕсли;
ИначеЕсли КорневойТип = "Последовательность" Тогда
ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяГраницы, "Границы", ПредставлениеМД + ": Границы", "ВиртуальнаяТаблица", ИндексКартинкиТЧ,
ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Границы",, ОбъектМД);
КонецЕсли;
Если ирОбщий.ЕстьТаблицаИзмененийОбъектаМетаданных(ОбъектМД) Тогда
ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ирКэш.ИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД, Истина, Ложь), "Изменения", "Изменения", "Изменения", ИндексКартинкиТЧ,
ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Изменения",, ОбъектМД);
КонецЕсли;
КонецЦикла;
ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
Если СтрокаТипаМетаданных.Строки.Количество() = 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";
КонецЕсли;
Возврат БазовыйФайлРедактораКода;
КонецФункции
#Если Клиент Тогда
Функция ЗаполнитьСписокИнструментов() Экспорт
Если СписокИнструментов.Количество() = 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];
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
#Если Клиент Тогда
Функция ПолучитьДокументDOMФормы(Форма) Экспорт
Перем ДокументDOM;
Попытка
Форма.мСвойстваФормы.Свойство("ДокументDOM", ДокументDOM);
ЕстьХранилище = Истина;
Исключение
ЕстьХранилище = Ложь;
КонецПопытки;
Если ДокументDOM = Неопределено Тогда
СтрокаФормы = ЗначениеВСтрокуВнутр(Форма);
XMLСтрокаФормы = ирОбщий.СтрокаВнутрВХМЛТелоЛкс(СтрокаФормы);
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.УстановитьСтроку(XMLСтрокаФормы);
ПостроительDOM = Новый ПостроительDOM;
ДокументDOM = ПостроительDOM.Прочитать(ЧтениеXML);
Если ЕстьХранилище Тогда
Форма.мСвойстваФормы.Вставить("ДокументDOM", ДокументDOM);
КонецЕсли;
КонецЕсли;
Возврат ДокументDOM;
КонецФункции // ЛксПолучитьДокументDOMФормы()
Функция ПолучитьXPathИмениРеквизитаВОписанииРеквизита()
ИДВерсииПлатформы = ирКэш.НомерИзданияПлатформыЛкс();
Если ИДВерсииПлатформы = "81" Тогда
Результат = "/data[3]";
ИначеЕсли Ложь
Или ИДВерсииПлатформы = "82"
Или ИДВерсииПлатформы = "83"
Тогда
Результат = "/data[4]";
КонецЕсли;
Возврат Результат;
КонецФункции // ПолучитьXPathИмениРеквизитаВОписанииРеквизита()
Функция ПолучитьИмяОсновногоРеквизитаФормы(Форма) Экспорт
ДокументDOM = ПолучитьДокументDOMФормы(Форма);
РазыменовательПИ = Новый РазыменовательПространствИменDOM(ДокументDOM);
ИмяЭлемента = "/elem[1]/elem[1]/elem[2]/elem[1]/data[1]/text()";
РезультатXPath = ДокументDOM.ВычислитьВыражениеXPath(ИмяЭлемента, ДокументDOM, РазыменовательПИ, ТипРезультатаDOMXPath.Строка);
КлючОсновногоРеквизита = РезультатXPath.СтроковоеЗначение;
ИмяЭлемента = "/elem[1]/elem[1]/elem[2]/elem[2]/elem/elem[1]/data[1]/text()";
РезультатXPath = ДокументDOM.ВычислитьВыражениеXPath(ИмяЭлемента, ДокументDOM, РазыменовательПИ,
ТипРезультатаDOMXPath.УпорядоченныйИтераторУзлов);
Счетчик = 1;
Пока 1 = 1 Цикл
Узел = РезультатXPath.ПолучитьСледующий();
Если Узел = Неопределено Тогда
Прервать;
КонецЕсли;
Если Узел.ТекстовоеСодержимое = КлючОсновногоРеквизита Тогда
Прервать;
КонецЕсли;
Счетчик = Счетчик + 1;
КонецЦикла;
Если Узел = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
СтрокаXPath = "/elem[1]/elem[1]/elem[2]/elem[2]/elem[" + Счетчик + "]" + ПолучитьXPathИмениРеквизитаВОписанииРеквизита() + "/text()";
РезультатXPath = ДокументDOM.ВычислитьВыражениеXPath(СтрокаXPath, ДокументDOM, РазыменовательПИ, ТипРезультатаDOMXPath.Строка);
Длина = СтрДлина(РезультатXPath.СтроковоеЗначение);
Возврат Сред(РезультатXPath.СтроковоеЗначение, 2, Длина - 2);
КонецФункции // ЛксПолучитьИмяОсновногоРеквизитаФормы()
Функция ПолучитьМассивИменРеквизитовФормы(Форма) Экспорт
Массив = Новый Массив;
ДокументDOM = ПолучитьДокументDOMФормы(Форма);
РазыменовательПИ = Новый РазыменовательПространствИменDOM(ДокументDOM);
СтрокаXPath = "/elem[1]/elem[1]/elem[2]/elem[2]/elem" + ПолучитьXPathИмениРеквизитаВОписанииРеквизита() + "/text()";
РезультатXPath = ДокументDOM.ВычислитьВыражениеXPath(СтрокаXPath, ДокументDOM,
РазыменовательПИ, ТипРезультатаDOMXPath.НеупорядоченныйИтераторУзлов);
Пока 1 = 1 Цикл
Узел = РезультатXPath.ПолучитьСледующий();
Если Узел = Неопределено Тогда
Прервать;
КонецЕсли;
Текст = Узел.ТекстовоеСодержимое;
Длина = СтрДлина(Текст);
Текст = Сред(Текст, 2, Длина - 2);
Массив.Добавить(Текст);
КонецЦикла;
Возврат Массив;
КонецФункции // ЛксПолучитьМассивИменРеквизитовФормы()
// <Описание функции>
//
// Параметры:
// <Параметр1> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>;
// <Параметр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, Ложь);
КонецЕсли;
КонецПроцедуры
Функция ПодключитьПерехватКлавиатуры(НовоеЗначение = Неопределено) Экспорт
Если мПерехватКлавиатуры = Неопределено Тогда
Попытка
мПерехватКлавиатуры = Вычислить("ирПерехватКлавиатуры");
Исключение
КонецПопытки;
КонецЕсли;
Если мПерехватКлавиатуры = Неопределено Тогда
Если Не ирОбщий.ЛиПерехватКлавиатурногоВводаЛкс() Тогда
мПерехватКлавиатуры = Новый Структура("ЗахватПервым,СобытиеПриНажатии,ЗахватРазрешен");
ПерехватКлавиатурногоВводаВОбычномПриложении = Ложь;
Иначе
мПерехватКлавиатуры = ПолучитьОбъектВнешнейКомпонентыИзМакета("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> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>;
// <Параметр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Доступна;
КонецФункции
#КонецЕсли
////////////////////////////////////////////////////////////////////////////////////////////////////
// <Описание функции>
//
// Параметры:
// <Параметр1> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>.
//
// Возвращаемое значение:
// - <Тип.Вид> - <описание значения>
// <продолжение описания значения>;
// <Значение2> - <Тип.Вид> - <описание значения>
// <продолжение описания значения>.
//
Функция ИдентификаторПроцессаОС() Экспорт
Если Не ЗначениеЗаполнено(ИдентификаторПроцессаОС) Тогда
Если Не ирКэш.ЛиПлатформаWindowsЛкс() Тогда
Результат = ирОбщий.ВыполнитьКомандуОСЛкс("echo $PPID");
Попытка
ИдентификаторПроцессаОС = Число(Результат);
Исключение
ИдентификаторПроцессаОС = 0;
Сообщить(ОписаниеОшибки(), СтатусСообщения.Внимание);
КонецПопытки;
Иначе
Если ПолучитьWinAPI() <> Неопределено Тогда
ИдентификаторПроцессаОС = WinAPI.GetCurrentProcessId();
Иначе
//// Первый вариант иногда не оставлял процесс работать (он сразу завершался) и приводил ниже к ошибкам "Произошла исключительная ситуация (SWbemServicesEx): Not found"
//oShell = Новый COMОбъект("WScript.Shell");
//ДочернийПроцесс = oShell.Exec("rundll32.exe kernel32,Sleep");
//ИдентификаторПроцессаОС = ПолучитьCOMОбъект("winmgmts:{impersonationLevel=impersonate}!\\.\root\CIMV2:Win32_Process.Handle='" + XMLСтрока(ДочернийПроцесс.ProcessID) + "'").ParentProcessID;
//ДочернийПроцесс.Terminate(); // Может выполняться долго!
Попытка
ВК = ирОбщий.ВКОбщаяЛкс();
Исключение
// Например - Не найден файл внешней компоненты
ИдентификаторПроцессаОС = 0;
Сообщить(ОписаниеОшибки(), СтатусСообщения.Внимание);
КонецПопытки;
Если ВК <> Неопределено Тогда
ИдентификаторПроцессаОС = ВК.PID();
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат ИдентификаторПроцессаОС;
КонецФункции
// Получает новый экземпляр ком-объекта парсера.
//
// Параметры:
// Нет.
//
// Возвращаемое значение:
// 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Компоненты + "-компонента " + КлассКомпоненты, СтатусСообщения.Информация);
Возврат Компонента;
Иначе
ирОбщий.СообщитьЛкс(РезультатКоманды);
КонецЕсли;
КонецЕсли;
Иначе
Если Не Административная Тогда
// HKCU через сторонний регистратор. Иногда это срабатывает
Если ФайлРегистратораКомпонентCU = Неопределено Тогда
ФайлРегистратораКомпонентCU = ПроверитьЗаписатьКомпонентуИзМакетаВФайл("RegsvrPowerExeWin", , "exe");
ПроверитьЗаписатьКомпонентуИзМакетаВФайл("TLBINF32");
КонецЕсли;
ФайлКомпоненты = Новый Файл(ПолноеИмяDll);
КоманднаяСтрока = """" + ФайлРегистратораКомпонентCU.ПолноеИмя + """ " + ФайлКомпоненты.Имя + " /s"; // RegsvrPowerExeWin не понимает длинные пути
ирОбщий.ЗапуститьСкрытоеПриложениеИДождатьсяЗавершенияЛкс(КоманднаяСтрока, ФайлКомпоненты.Путь);
Компонента = ПолучитьПроверитьCOMОбъект(КлассКомпоненты, ИмяТипаВК);
Если Компонента <> Неопределено Тогда
ирОбщий.СообщитьЛкс("В HKCU " + ПрефикДействия + "регистрирована 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." + ИмяТипаВК);
Исключение
КонецПопытки;
Возврат Компонента;
Иначе
Если КлассКомпоненты = "DynamicWrapperX" Тогда
КлассКомпоненты = ИМЯ_КЛАССА_DynamicWrapperX;
КонецЕсли;
Попытка
Компонента = Новый COMОбъект(КлассКомпоненты);
Если КлассКомпоненты = ИМЯ_КЛАССА_DynamicWrapperX Тогда
// Проверка на нужную версию компоненты DynamicWrapperX
Попытка
Если ирКэш.Это64битныйПроцессЛкс() Тогда
Если Компонента.Version() <> "2.1.1.1" Тогда // Официальная версия, с ней информатор вылетает
ВызватьИсключение "Неверная версия компоненты";
КонецЕсли;
Иначе
Если Компонента.Version() <> "2.1.4.1" Тогда // Версия от Chessman
ВызватьИсключение "Неверная версия компоненты";
КонецЕсли;
КонецЕсли;
Возврат Компонента;
Исключение
Компонента = Неопределено;
КонецПопытки;
ИначеЕсли КлассКомпоненты = "GoldParserForNet.Parser" Тогда
Попытка
Если Компонента.Version = "5.08" Тогда
Возврат Компонента;
КонецЕсли;
Исключение
Компонента = Неопределено;
КонецПопытки;
Иначе
Возврат Компонента;
КонецЕсли;
Исключение
ОписаниеОшибки = ОписаниеОшибки(); // Для отладки
КонецПопытки;
Если Компонента = Неопределено Тогда
Если КлассКомпоненты = "DynamicWrapperX"
//И ирКэш.Это64битныйПроцессЛкс()
Тогда
ИМЯ_КЛАССА_DynamicWrapperX = "DynamicWrapperX.2"; // версия 2
Компонента = ПолучитьПроверитьCOMОбъект(КлассКомпоненты);
Возврат Компонента;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Неопределено;
КонецФункции
// Возвращает нужный 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";
КонецЕсли;
КонецЕсли;
Возврат Истина;
КонецФункции
// <Описание функции>
//
// Параметры:
// <Параметр1> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>.
//
// Возвращаемое значение:
// - <Тип.Вид> - <описание значения>
// <продолжение описания значения>;
// <Значение2> - <Тип.Вид> - <описание значения>
// <продолжение описания значения>.
//
Функция ПолучитьФайлВнешнейОбработкиАлгоритма(АлгоритмОбъект) Экспорт
Если Ложь
Или СтрДлина(ПапкаКешаВнешнихОбработокАлгоритмов.ПолноеИмя) + СтрДлина(АлгоритмОбъект.Наименование) > 250
Тогда
// Ограничение WinAPI на путь к файлу
КлючСервиса = "" + АлгоритмОбъект.Ссылка.УникальныйИдентификатор();
Иначе
КлючСервиса = АлгоритмОбъект.Наименование;
КонецЕсли;
ИмяФайла = КлючСервиса + ".epf";
ФайлВнешнейОбработки = Новый Файл(ПапкаКешаВнешнихОбработокАлгоритмов.ПолноеИмя + ирОбщий.РазделительПутиКФайлуЛкс() + ИмяФайла);
Возврат ФайлВнешнейОбработки;
КонецФункции // ПолучитьФайлВнешнейОбработкиАлгоритма()
// <Описание функции>
//
// Параметры:
// <Параметр1> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>.
//
// Возвращаемое значение:
// - <Тип.Вид> - <описание значения>
// <продолжение описания значения>;
// <Значение2> - <Тип.Вид> - <описание значения>
// <продолжение описания значения>.
//
Функция ПолучитьОбновитьФайлВнешнейОбработкиАлгоритма(ДескрипторСервиса, ЭлементКэша = Неопределено, ДатаИзмененияКэша = Неопределено) Экспорт
ВнешняяОбработка = Неопределено;
ФайлВнешнейОбработкиАктуален = Ложь;
КэшВнешнейОбработкиАктуален = Ложь;
ФайлВнешнейОбработки = ПолучитьФайлВнешнейОбработкиАлгоритма(ДескрипторСервиса);
ДатаИзмененияОбъекта = ДескрипторСервиса.ДатаИзмененияКонтекста;
//// Условие добавлено для мягкого перехода на новый кэш параметров сервисов 21.10.2010. Потом нужно убрать
//Если ЗначениеЗаполнено(ДескрипторСервиса.ДатаИзмененияКэша) Тогда
ПроверитьАктуальностьКэшаВнешнейОбработки(ЭлементКэша, ДатаИзмененияКэша, ФайлВнешнейОбработки, ДатаИзмененияОбъекта,
КэшВнешнейОбработкиАктуален, ФайлВнешнейОбработкиАктуален, ФайловыйКэшАлгоритмовДопускаетРедактирование);
//КонецЕсли;
Если Истина
И Не КэшВнешнейОбработкиАктуален
И Не ФайлВнешнейОбработкиАктуален
Тогда
СервисОбъект = ПроверитьПолучитьОбъектСервиса(ДескрипторСервиса);
СервисОбъект.СобратьКонтекст();
СформироватьВнешнююОбработку(ФайлВнешнейОбработки, СервисОбъект.Наименование,
СервисОбъект.ПолучитьТекстМодуляОбработки()
//, СервисОбъект.ПолучитьТекстМакетаПараметров()
);
Попытка
ФайлВнешнейОбработки.УстановитьВремяИзменения(СервисОбъект.ДатаИзмененияКонтекста);
Исключение
Если Не ФайлВнешнейОбработки.Существует() Тогда
ирОбщий.ПроверитьКодЯзыкаОСЛкс();
ВызватьИсключение "Файл внешней обработки сервиса """ + СервисОбъект.Наименование + """ не сформирован";
Иначе
ВызватьИсключение;
КонецЕсли;
КонецПопытки;
КонецЕсли;
Если КэшВнешнейОбработкиАктуален Тогда
Возврат Неопределено;
Иначе
Возврат ФайлВнешнейОбработки;
КонецЕсли;
КонецФункции
// <Описание функции>
//
// Параметры:
// <Параметр1> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>.
//
// Возвращаемое значение:
// - <Тип.Вид> - <описание значения>
// <продолжение описания значения>;
// <Значение2> - <Тип.Вид> - <описание значения>
// <продолжение описания значения>.
//
Функция ПолучитьВнешнююОбработкуПоАлгоритму(ДескрипторСервиса) Экспорт
// %%%% Здесь можно было бы структуру попробовать вместо ТЗ
//ЭлементКэша = 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 """ + ИмяИсточника + """";
ОписаниеОшибки = ТекстРезультатаКомандыСистемы(КомандаСистемы,, Истина);
// При успехе возвращает пустую строку
Если Не ПустаяСтрока(ОписаниеОшибки) Тогда
ВызватьИсключение "Ошибка доступа к файлу """ + ИмяИсточника + """: " + ОписаниеОшибки;
КонецЕсли;
КонецПопытки;
КонецЕсли;
Возврат Успех;
КонецФункции
// <Описание функции>
//
// Параметры:
// <Параметр1> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>.
//
// Возвращаемое значение:
// - <Тип.Вид> - <описание значения>
// <продолжение описания значения>;
// <Значение2> - <Тип.Вид> - <описание значения>
// <продолжение описания значения>.
//
Функция ПолучитьПолноеИмяКомпьютераСетиПоЛюбомуИмени(ИмяКомпьютера) Экспорт
ФайлРезультата = Новый Файл(ПолучитьИмяВременногоФайла());
ирОбщий.ЗапуститьСкрытоеПриложениеИДождатьсяЗавершенияЛкс("nslookup " + ИмяКомпьютера, ФайлРезультата.Путь, ФайлРезультата.Имя);
Если Не ФайлРезультата.Существует() Тогда
ПолноеИмяКомпьютера = "";
Иначе
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.Прочитать(ФайлРезультата.ПолноеИмя);
УдалитьФайлы(ФайлРезультата.ПолноеИмя);
ТекстРезультата = ТекстовыйДокумент.ПолучитьТекст();
RegExp.IgnoreCase = Истина;
RegExp.Pattern = "(?:name|имя|╚ь ):\s*([-" + шБукваЦифра + "]+(\.([-" + шБукваЦифра + "]+))*)\s*";
Результат = RegExp.НайтиВхождения(ТекстРезультата);
Если Результат.Количество() > 0 Тогда
ПолноеИмяКомпьютера = Результат[0].SubMatches(0);
Иначе
ПолноеИмяКомпьютера = "";
КонецЕсли;
КонецЕсли;
//ASPDNS = ПолучитьCOMОбъектИзМакета("ASPDNS", "ASPDNS.DNSLookup");
//IP = ASPDNS.GetIPFromName(ИмяКомпьютера);
//ПолноеИмяКомпьютера = ASPDNS.GetNameFromIP(IP);
Возврат ПолноеИмяКомпьютера;
КонецФункции
// <Описание процедуры>
//
// Параметры:
// <Параметр1> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>.
//
Функция ПроверитьКаталогФайловогоКэша() Экспорт
//http://www.hostedredmine.com/issues/851201
//СтрокаСоединения = ирКэш.СтрокаСоединенияСервераЛкс();
СтрокаСоединения = СтрокаСоединенияИнформационнойБазы();
КаталогВерсииПлатформыВПрофиле = ирКэш.КаталогИзданияПлатформыВПрофилеЛкс();
КаталогФайловогоКэша = КаталогВерсииПлатформыВПрофиле + ирОбщий.РазделительПутиКФайлуЛкс() + ирОбщий.ИдентификаторИзПредставленияЛкс(СтрокаСоединения);
ПапкаФайловогоКэша = Новый Файл(КаталогФайловогоКэша);
Если Не ПапкаФайловогоКэша.Существует() Тогда
Попытка
СоздатьКаталог(ПапкаФайловогоКэша.ПолноеИмя);
ПробныйФайл = Новый ТекстовыйДокумент;
ПробныйФайл.Записать(ПапкаФайловогоКэша.ПолноеИмя + ирОбщий.РазделительПутиКФайлуЛкс() + "1.txt");
Исключение
ОписаниеОшибки = ОписаниеОшибки();
Сообщить("Файловые кэши отключены из-за ошибки: " + ОписаниеОшибки, СтатусСообщения.Важное); // При использовании ирОбщий.СообщитьЛкс() может происходить переполнение стека
ВыполнятьАлгоритмыЧерезВнешниеОбработки = Ложь;
Возврат Ложь;
КонецПопытки;
КонецЕсли;
Возврат Истина;
КонецФункции
Функция НастройкиКомпьютера() Экспорт
Если НастройкиКомпьютера = Неопределено Тогда
ФайлаНастроекКомпьютера = Новый Файл(ИмяФайлаНастроекКомпьютера());
Если ФайлаНастроекКомпьютера.Существует() Тогда
НастройкиКомпьютера = ирОбщий.ЗагрузитьЗначениеИзФайлаЛкс(ФайлаНастроекКомпьютера.ПолноеИмя);
Если НастройкиКомпьютера <> Неопределено Тогда
ЗначениеНастройки = НастройкиКомпьютера["ПапкаКэшаМодулей"];
ЗначениеНастройки = Новый Файл(ЗначениеНастройки);
Если ЗначениеНастройки.Существует() Тогда
ПапкаКэшаМодулей = ЗначениеНастройки;
КонецЕсли;
ЗначениеНастройки = НастройкиКомпьютера["ПапкаКэшаРолей"];
ЗначениеНастройки = Новый Файл(ЗначениеНастройки);
Если ЗначениеНастройки.Существует() Тогда
ПапкаКэшаРолей = ЗначениеНастройки;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если НастройкиКомпьютера = Неопределено Тогда
НастройкиКомпьютера = Новый Соответствие;
КонецЕсли;
Возврат НастройкиКомпьютера;
КонецФункции
Процедура СохранитьНастройкиКомпьтера() Экспорт
ИмяФайлаНастроекКомпьютера = ИмяФайлаНастроекКомпьютера();
ирОбщий.СохранитьЗначениеВФайлЛкс(НастройкиКомпьютера, ИмяФайлаНастроекКомпьютера);
КонецПроцедуры
Функция ИмяФайлаНастроекКомпьютера()
ПапкаФайловогоКэша = Новый Файл(КаталогФайловогоКэша);
ИмяФайлаНастроекКомпьютера = ПапкаФайловогоКэша.ПолноеИмя + ирОбщий.РазделительПутиКФайлуЛкс() + "ComputerSettings.xml";
Возврат ИмяФайлаНастроекКомпьютера;
КонецФункции
// <Описание функции>
//
// Параметры:
// <Параметр1> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>.
//
// Возвращаемое значение:
// - <Тип.Вид> - <описание значения>
// <продолжение описания значения>;
// <Значение2> - <Тип.Вид> - <описание значения>
// <продолжение описания значения>.
//
Функция ИмяНеопределеннойПеременнойИзИнформацииОбОшибке(ИнформацияОбОшибке, СообщитьНеобрабатываемуюОшибку = Ложь) Экспорт
Если ИнформацияОбОшибке <> Неопределено Тогда
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, СтруктураПараметров);
Возврат Результат;
КонецФункции
// <Описание процедуры>
//
// Параметры:
// <Параметр1> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>.
//
Процедура ОчиститьКешАлгоритмов(ОчиститьКэшНаДиске = Ложь) Экспорт
КешАлгоритмов.Очистить();
//КешВнешнихОбработокАлгоритмов.Очистить();
Если ОчиститьКэшНаДиске Тогда
//Для Каждого ЭлементПодкаталога Из СтруктураПодкаталоговФайловогоКэша Цикл
// УдалитьФайлы(ЭлементПодкаталога.Значение.ПолноеИмя, "*.dat");
// УдалитьФайлы(ЭлементПодкаталога.Значение.ПолноеИмя, "*.epf");
//КонецЦикла;
ФайлПодкаталога = СтруктураПодкаталоговФайловогоКэша["a"];
УдалитьФайлы(ФайлПодкаталога.ПолноеИмя + ирОбщий.РазделительПутиКФайлуЛкс(), "*.*");
ПроверитьСтруктуруФайловогоКэша();
КонецЕсли;
КонецПроцедуры // ОчиститьКешАлгоритмов()
// <Описание процедуры>
//
// Параметры:
// <Параметр1> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>.
//
Процедура ОбновитьАлгоритмВКеше(АлгоритмОбъект) Экспорт
КешАлгоритмов.Вставить(АлгоритмОбъект.Ссылка, АлгоритмОбъект);
КонецПроцедуры // УдалитьАлгоритмИзКеша()
// <Описание функции>
//
// Параметры:
// <Параметр1> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>.
//
// Возвращаемое значение:
// - <Тип.Вид> - <описание значения>
// <продолжение описания значения>;
// <Значение2> - <Тип.Вид> - <описание значения>
// <продолжение описания значения>.
//
Функция ПолучитьФайлОткрывателя1С(БыстраяПроверка = Истина) Экспорт
Если Ложь
Или Не БыстраяПроверка
Или ФайлОткрывателя1С = Неопределено
Тогда
ФайлОткрывателя1С = Новый Файл(ПолучитьИмяВременногоФайла("exe"));
ПолучитьМакет("OpenIn1Cv8ExeWin").Записать(ФайлОткрывателя1С.ПолноеИмя);
КонецЕсли;
Возврат ФайлОткрывателя1С;
КонецФункции // ПолучитьФайлОткрывателя1С()
// <Описание функции>
//
// Параметры:
// <Параметр1> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>.
//
// Возвращаемое значение:
// - <Тип.Вид> - <описание значения>
// <продолжение описания значения>;
// <Значение2> - <Тип.Вид> - <описание значения>
// <продолжение описания значения>.
//
Функция ПолучитьФайлРаспаковщика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Имя;
КонецФункции
// <Описание функции>
//
// Параметры:
// <Параметр1> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>.
//
// Возвращаемое значение:
// - <Тип.Вид> - <описание значения>
// <продолжение описания значения>;
// <Значение2> - <Тип.Вид> - <описание значения>
// <продолжение описания значения>.
//
Процедура ЗаписатьМакетСУчетомМаскировки(ДанныеМакета, ПолноеИмя)
ДанныеМакета.Записать(ПолноеИмя);
КонецПроцедуры // ЗаписатьМакетСУчетомМаскировки()
// <Описание процедуры>
//
// Параметры:
// <Параметр1> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>.
//
Процедура УдалитьСлужебныеФайлы() Экспорт
СтруктураЦикла = Новый Массив;
СтруктураЦикла.Добавить(ШаблоныВнешнейОбработки);
СтруктураЦикла.Добавить(ШаблоныВнешнейОбработкиСМакетом);
Для Каждого ЭлементЦикла Из СтруктураЦикла Цикл
Для Каждого КлючИЗначение Из ЭлементЦикла Цикл
ШаблонВнешнейОбработки = КлючИЗначение.Значение;
Если ШаблонВнешнейОбработки.ФайлЗамок <> Неопределено Тогда
ШаблонВнешнейОбработки.ФайлЗамок.Закрыть();
Попытка
УдалитьФайлы(ШаблонВнешнейОбработки.Путь + ".lck");
УдалитьФайлы(ШаблонВнешнейОбработки.Путь);
Исключение
КонецПопытки;
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецПроцедуры // УдалитьСлужебныеФайлы()
Функция ПолучитьКартинкуТипа()
Если КартинкиТипов = Неопределено Тогда
КартинкиТипов = Новый ТаблицаЗначений;
КонецЕсли;
КонецФункции
#КонецЕсли
// <Описание функции>
//
// Параметры:
// <Параметр1> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>.
//
// Возвращаемое значение:
// - <Тип.Вид> - <описание значения>
// <продолжение описания значения>;
// <Значение2> - <Тип.Вид> - <описание значения>
// <продолжение описания значения>.
//
Функция ПредставлениеПустогоЗначенияЛкс(ПустоеЗначение) Экспорт
Если ПустоеЗначение = Неопределено Тогда
Результат = "<Неопределено>";
Иначе
Результат = мКэшПустыхЗначений[ПустоеЗначение];
Если Результат = Неопределено Тогда
Если ПустоеЗначение = Null Тогда
Результат = "<Null>";
ИначеЕсли ТипЗнч(ПустоеЗначение) = Тип("Булево") И ПустоеЗначение = Ложь Тогда
//Результат = "<Булево: Нет>";
Результат = "" + ПустоеЗначение;
ИначеЕсли ПустоеЗначение = "" Тогда
Результат = "<Строка>";
ИначеЕсли ПустоеЗначение = 0 Тогда
//Результат = "<Пустое число>";
Результат = Формат(ПустоеЗначение, "ЧН=");
ИначеЕсли ПустоеЗначение = Дата("00010101") Тогда
Результат = "<Дата>";
ИначеЕсли ТипЗнч(ПустоеЗначение) = Тип("УникальныйИдентификатор") Тогда
Результат = "<Идентификатор>";
ИначеЕсли ТипЗнч(ПустоеЗначение) = Тип("Картинка") Тогда
Результат = "<Картинка>";
Иначе
ОбъектМД = ирОбщий.ПолучитьМетаданныеЛкс(ПустоеЗначение);
Если ОбъектМД <> Неопределено Тогда
Результат = "<" + ОбъектМД.ПолноеИмя() + ".Ссылка>";
КонецЕсли;
КонецЕсли;
мКэшПустыхЗначений[ПустоеЗначение] = Результат;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
// Возвращает текущее время в миллисекундах.
//
// Параметры:
// Нет.
//
// Возвращаемое значение:
// Число.
//
Функция ПолучитьТекущееВремяВМиллисекундах() Экспорт
Если ПолучитьWinAPI() <> Неопределено Тогда
Результат = WinAPI.timeGetTime();
КонецЕсли;
Если Результат = Неопределено Тогда
Если ирКэш.НомерИзданияПлатформыЛкс() >= "83" Тогда
Результат = Вычислить("ТекущаяУниверсальнаяДатаВМиллисекундах()");
КонецЕсли;
КонецЕсли;
Если Результат = Неопределено Тогда
Если JavaScript = Неопределено Тогда
Попытка
JavaScript = Новый COMОбъект("MSScriptControl.ScriptControl");
Исключение
ирОбщий.СообщитьЛкс("Ошибка создания MSScriptControl.ScriptControl: " + ОписаниеОшибки(), СтатусСообщения.Внимание);
Возврат 0;
КонецПопытки;
JavaScript.Language = "javascript";
КонецЕсли;
Результат = JavaScript.Eval("new Date().getTime()");
КонецЕсли;
Возврат Результат;
КонецФункции
// <Описание функции>
//
// Параметры:
// <Параметр1> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>.
//
// Возвращаемое значение:
// - <Тип.Вид> - <описание значения>
// <продолжение описания значения>;
// <Значение2> - <Тип.Вид> - <описание значения>
// <продолжение описания значения>.
//
Функция ПроверитьПолучитьОбъектСервиса(Знач АлгоритмОбъект) Экспорт
Если ТипЗнч(АлгоритмОбъект) = Тип("СтрокаТаблицыЗначений") Тогда
лОбъект = АлгоритмОбъект.ЭтотОбъект;
Если лОбъект = Неопределено Тогда
лОбъект = АлгоритмОбъект.Ссылка.ПолучитьОбъект();
ЗаполнитьЗначенияСвойств(лОбъект, АлгоритмОбъект, , "ЭтотОбъект, Ссылка, мПолнаяТаблицаПараметров"); ////%!%
АлгоритмОбъект.ЭтотОбъект = лОбъект;
КонецЕсли;
АлгоритмОбъект = лОбъект;
КонецЕсли;
Возврат АлгоритмОбъект;
КонецФункции // ПроверитьПолучитьОбъектСервиса()
// <Описание функции>
//
// Параметры:
// <Параметр1> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>.
//
// Возвращаемое значение:
// - <Тип.Вид> - <описание значения>
// <продолжение описания значения>;
// <Значение2> - <Тип.Вид> - <описание значения>
// <продолжение описания значения>.
//
Функция ПредставлениеИнформацииОбОшибке(Знач ИнформацияОбОшибке) Экспорт
// Антибаг платформы. В описании повторяется причина и описание между уровнями. В общем бардак.
ОписаниеОшибки = ИнформацияОбОшибке.Описание;
Если ИнформацияОбОшибке.Причина <> Неопределено Тогда
Пока Истина
И ИнформацияОбОшибке.Причина <> Неопределено
И ИнформацияОбОшибке.Описание = ОписаниеОшибки
Цикл
ИнформацияОбОшибке = ИнформацияОбОшибке.Причина;
КонецЦикла;
Если ИнформацияОбОшибке.Описание <> ОписаниеОшибки Тогда
ОписаниеОшибки = ОписаниеОшибки + Символы.ПС + ПредставлениеИнформацииОбОшибке(ИнформацияОбОшибке);
КонецЕсли;
Иначе
Фрагмент = ирОбщий.ПоследнийФрагментЛкс(ОписаниеОшибки, "по причине:" + Символы.ПС);
Позиция = Найти(ОписаниеОшибки, Фрагмент + Символы.ПС + "по причине:" + Символы.ПС + Фрагмент);
Если Позиция > 0 Тогда
ОписаниеОшибки = Лев(ОписаниеОшибки, Позиция) + Фрагмент;
КонецЕсли;
КонецЕсли;
Возврат ОписаниеОшибки;
КонецФункции // ПредставлениеИнформацииОбОшибке()
// <Описание функции>
//
// Параметры:
// <Параметр1> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> - <Тип.Вид> - <описание параметра>
// <продолжение описания параметра>.
//
Функция ОбработатьВнешнееИсключениеАлгоритма(ДескрипторСервиса, ИнформацияОбОшибке, РежимВыполненияАлгоритма, Интерактивно = Истина) Экспорт
//СервисОбъект = ПроверитьПолучитьОбъектСервиса(ДескрипторСервиса);
// Такой прием применен для избежания обращения к БД внутри сломанной транзакции
Если ТипЗнч(ДескрипторСервиса) = Тип("СтрокаТаблицыЗначений") Тогда
лОбъект = ДескрипторСервиса.ЭтотОбъект;
Если лОбъект = Неопределено Тогда
//лОбъект = Справочники.Сервисы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);
КонецЕсли;
//#Если Клиент Тогда
КонецЕсли;
//#КонецЕсли
Возврат Результат;
КонецФункции // ВыполнитьМетодАлгоритма()
// Получает новый экземпляр ком-объекта DynamicWrapperX.
//
// Параметры:
// Нет.
//
// Возвращаемое значение:
// Com-объект, Неопределено.
//
Функция ПолучитьWinAPI() Экспорт
// Отключено из-за классификации HackTool со стороны Windows Defender
WinAPI = Неопределено;
Возврат WinAPI;
Если WinAPI = "НеИнициализирован" Тогда
#Если Клиент Или ВнешнееСоединение Тогда
WinAPI = ПолучитьCOMОбъектИзМакета("DynamicWrapperX", ИМЯ_КЛАССА_DynamicWrapperX);
#Иначе
// На сервере вызывало зависание. Пришлось отключить
WinAPI = Неопределено;
#КонецЕсли
Если WinAPI <> Неопределено Тогда
WinAPI.Register("KERNEL32.DLL", "Sleep", "i=h", "f=s");
//WinAPI.Register("KERNEL32.DLL", "GetTickCount64", "r=l", "f=s"); // обычный DynamicWrapper на x86 подключает, а этот - нет
WinAPI.Register("KERNEL32.DLL", "GetTickCount", "r=l", "f=s");
WinAPI.Register("KERNEL32.DLL", "GetProcessId", "i=l", "r=l", "f=s");
WinAPI.Register("KERNEL32.DLL", "GetCurrentProcessId", "r=l", "f=s");
WinAPI.Register("KERNEL32.DLL", "GetLastError", "f=s", "r=l");
WinAPI.Register("KERNEL32.DLL", "GetCurrentProcessId", "r=l", "f=s");
WinAPI.Register("KERNEL32.DLL", "GetCurrentThreadId", "f=s", "r=l");
WinAPI.Register("WINMM.DLL", "timeGetTime", "r=l", "f=s");
WinAPI.Register("WINMM.DLL", "timeBeginPeriod", "i=l", "r=l", "f=s");
WinAPI.Register("WINMM.DLL", "timeEndPeriod", "i=l", "r=l", "f=s");
WinAPI.Register("USER32.DLL", "GetForegroundWindow", "f=s", "r=l");
WinAPI.Register("USER32.DLL", "GetActiveWindow", "f=s", "r=l");
WinAPI.Register("USER32.DLL", "GetFocus", "f=s", "r=l");
WinAPI.Register("USER32.DLL", "SetFocus", "i=l", "f=s", "r=l");
WinAPI.Register("USER32.DLL", "EnableWindow", "i=l", "f=s", "r=l");
WinAPI.Register("USER32.DLL", "SendMessage", "i=llll", "f=s", "r=l");
WinAPI.Register("USER32.DLL", "PostMessage", "i=llll", "f=s", "r=l");
WinAPI.Register("USER32.DLL", "GetWindowThreadProcessId", "i=ll", "f=s", "r=l");
WinAPI.Register("USER32.DLL", "AttachThreadInput", "i=lll", "f=s", "r=l");
WinAPI.Register("USER32.DLL", "GetKeyState", "i=l", "f=s", "r=l");
WinAPI.Register("USER32.DLL", "GetAsyncKeyState", "i=l", "f=s", "r=l");
// Clipboard
WinAPI.Register("USER32.DLL", "OpenClipboard", "i=l", "f=s", "r=l");
WinAPI.Register("USER32.DLL", "GetClipboardData", "i=l", "f=s", "r=l");
WinAPI.Register("USER32.DLL", "SetClipboardData", "i=ll", "f=s", "r=l");
WinAPI.Register("USER32.DLL", "CloseClipboard", "f=s", "r=l");
WinAPI.Register("USER32.DLL", "EmptyClipboard", "f=s", "r=l");
WinAPI.Register("USER32.DLL", "IsClipboardFormatAvailable", "i=l", "f=s", "r=l");
WinAPI.Register("USER32.DLL", "RegisterClipboardFormat", "i=s", "f=s", "r=l");
WinAPI.Register("KERNEL32.DLL", "GlobalLock", "i=l", "f=s", "r=l");
WinAPI.Register("KERNEL32.DLL", "GlobalUnlock", "i=l", "f=s", "r=l");
WinAPI.Register("KERNEL32.DLL", "GlobalAlloc", "i=ll", "r=l");
WinAPI.Register("KERNEL32.DLL", "GlobalFree", "i=l", "r=l");
//Результат.Register("KERNEL32.DLL", "lstrlen", "i=l", "f=s", "r=l");
WinAPI.Register("KERNEL32.DLL", "lstrcpy", "i=ll", "f=s", "r=l");
WinAPI.Register("KERNEL32.DLL", "MultiByteToWideChar", "i=llllll", "f=s", "r=l");
WinAPI.Register("KERNEL32.DLL", "WideCharToMultiByte", "i=llllll", "f=s", "r=l");
Иначе
////#Если Клиент Тогда
////// Под пользователем ОС без админиских прав сразу после установки через regsvr32 /i компонента не создается почему то.
////// Нужно перезапускать приложение.
//Если Не ирКэш.Это64битныйПроцессЛкс() Тогда
// ирОбщий.СообщитьЛкс("Установлена новая компонента. Сеанс рекомендуется перезапустить", СтатусСообщения.Внимание);
//КонецЕсли;
//////ПрекратитьРаботуСистемы(Истина);
////#Иначе
//////ВызватьИсключение "Не удалось подключить компоненту расширения платформы";
////#КонецЕсли
КонецЕсли;
КонецЕсли;
Возврат WinAPI;
КонецФункции // ПолучитьWinAPI()
Функция ПолучитьИмяТипа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;
КонецФункции
//ирПортативный Контейнер = Новый Структура();
//ирПортативный #Если Клиент Тогда
//ирПортативный Оповестить("ирПолучитьБазовуюФорму", Контейнер);
//ирПортативный #КонецЕсли
//ирПортативный Если Не Контейнер.Свойство("ирПортативный", ирПортативный) Тогда
//ирПортативный Файл = Новый Файл(ИспользуемоеИмяФайла);
//ирПортативный ПолноеИмяФайлаБазовогоМодуля = Лев(Файл.Путь, СтрДлина(Файл.Путь) - СтрДлина("Модули\")) + "ирПортативный.epf";
//ирПортативный ирПортативный = ВнешниеОбработки.Создать(ПолноеИмяФайлаБазовогоМодуля, Ложь); // Это будет второй экземпляр объекта
//ирПортативный КонецЕсли;
//ирПортативный ирОбщий = ирПортативный.ПолучитьОбщийМодульЛкс("ирОбщий");
//ирПортативный ирКэш = ирПортативный.ПолучитьОбщийМодульЛкс("ирКэш");
//ирПортативный ирСервер = ирПортативный.ПолучитьОбщийМодульЛкс("ирСервер");
//ирПортативный ирПривилегированный = ирПортативный.ПолучитьОбщийМодульЛкс("ирПривилегированный");
ИМЯ_КЛАССА_DynamicWrapperX = "DynamicWrapperX";
ИнициализацияОписанияОбщихТипов();
мМетаданные = Метаданные;
КэшОбъектов = Новый Соответствие;
мКэшПустыхЗначений = Новый Соответствие;
СисИнфо = Новый СистемнаяИнформация;
Фрагменты = ирОбщий.СтрРазделитьЛкс(СисИнфо.ВерсияПриложения);
ВерсияПлатформы = Число(Фрагменты[0]) * 100 * 1000 + Число(Фрагменты[1]) * 1000 + Число(Фрагменты[2]);
Это2iS = Метаданные.ОбщиеМодули.Найти("Ядро2iS") <> Неопределено;
ЭтоИнтеграция = Метаданные.Справочники.Найти("иисМетаданные") <> Неопределено;
МаркерНачалаАлгоритма = "//НАЧАЛО.СЕРВИС" + Символы.ПС;
МаркерКонцаАлгоритма = "//КОНЕЦ_.СЕРВИС" + Символы.ПС;
мМаркерИмениЗапросаПакета = "{Запрос: ";
мМаркерИмениЧастиОбъединения = "{Выборка: ";
шЛюбой = "(?:.|\n|\r)";
шБуква = "_ЁА-ЯA-Z";
шБукваЦифра = "_ЁА-ЯA-Z0-9";
шБукваСРешеткой = "_ЁА-ЯA-Z#";
шКомментарий = "//[^\n]*[\n$]";
шРазделитель = "(?:" + шКомментарий + "|\s|^|$)"; // Возможно стоит добавить |\n|\r
шПустоеНачалоСтроки = "(?:\n|^)(?:\t| )*";
шGUID = "[A-F0-9]{8}(?:-[A-F0-9]{4}){3}-[A-F0-9]{12}";
шЧисло = "\d+(\.\d+)?";
шИндекс = "(\[[^\]\[]+?(?:(?:\[[^\]]+?\][^\]\[]*?)*)*\])";
//шСкобки = "(\([^\)\(]*?(?:(?:\([^\)]*?\)[^\)\(]*?)*)*\))";
шСкобки = "(\([^\(\)]*(?:\([^\(\)]*\)[^\(\)]*)*\))";
шИмя = "[" + шБуква + "][" + шБуква + "\d]*";
шИмяСРешеткой = "[" + шБукваСРешеткой + "][" + шБукваСРешеткой + "\d]*";
шИмяВременнойТаблицы = шИмяСРешеткой + "(?:\." + шИмяСРешеткой + ")*";
ВложенностьИндикации = 0;
ИмяКластераСерверов = НСтр(СтрокаСоединенияИнформационнойБазы(), "Srvr");
ЭтоФайловаяБаза = ПустаяСтрока(ИмяКластераСерверов);
//ФиксироватьВнешниеИсключенияАлгоритмов = ирОбщий.ВосстановитьЗначениеЛкс("ФиксироватьВнешниеИсключенияАлгоритмов");
//Если ФиксироватьВнешниеИсключенияАлгоритмов = Неопределено Тогда
ФиксироватьВнешниеИсключенияАлгоритмов = Истина;
//КонецЕсли;
ФайловыйКэшАлгоритмовДопускаетРедактирование = ирОбщий.ВосстановитьЗначениеЛкс("ФайловыйКэшАлгоритмовДопускаетРедактирование");
Если ФайловыйКэшАлгоритмовДопускаетРедактирование = Неопределено Тогда
ФайловыйКэшАлгоритмовДопускаетРедактирование = Ложь;
КонецЕсли;
//ВыполнятьАлгоритмыЧерезВнешниеОбработки = ирОбщий.ВосстановитьЗначениеЛкс("ВыполнятьАлгоритмыЧерезВнешниеОбработки");
//Если ВыполнятьАлгоритмыЧерезВнешниеОбработки = Неопределено Тогда
// // Антибаг http://partners.v8.1c.ru/forum/thread.jsp?id=861032#861032
ВыполнятьАлгоритмыЧерезВнешниеОбработки = Ложь;
//КонецЕсли;
//ПоказыватьВнешниеИсключенияПриВыполненииАлгоритмов = ирОбщий.ВосстановитьЗначениеЛкс("ирПлатформа.ПоказыватьВнешниеИсключенияПриВыполненииАлгоритмов");
//Если ПоказыватьВнешниеИсключенияПриВыполненииАлгоритмов = Неопределено Тогда
ПоказыватьВнешниеИсключенияПриВыполненииАлгоритмов = Ложь;
//КонецЕсли;
АвторегистрацияComКомпонент = ирОбщий.ВосстановитьЗначениеЛкс("АвторегистрацияComКомпонент");
Если АвторегистрацияComКомпонент = Неопределено Тогда
АвторегистрацияComКомпонент = Истина;
КонецЕсли;
#Если Клиент Тогда
ПерехватКлавиатурногоВводаВОбычномПриложении = ирОбщий.ВосстановитьЗначениеЛкс("ПерехватКлавиатурногоВводаВОбычномПриложении");
Если ПерехватКлавиатурногоВводаВОбычномПриложении = Неопределено Тогда
ПерехватКлавиатурногоВводаВОбычномПриложении = Метаданные.ОсновнойРежимЗапуска = РежимЗапускаКлиентскогоПриложения.УправляемоеПриложение;
КонецЕсли;
//СинтаксическийКонтрольПередЗаписью = ирОбщий.ВосстановитьЗначениеЛкс("СинтаксическийКонтрольПередЗаписью");
//Если СинтаксическийКонтрольПередЗаписью = Неопределено Тогда
СинтаксическийКонтрольПередЗаписью = Истина;
//КонецЕсли;
ВыделениеРезультатовПоиска = ирОбщий.ВосстановитьЗначениеЛкс("ВыделениеРезультатовПоиска");
Если ВыделениеРезультатовПоиска = Неопределено Тогда
ВыделениеРезультатовПоиска = "⧼⧽";
КонецЕсли;
#КонецЕсли
Парсеры = Новый Структура;
ШаблоныВнешнейОбработки = Новый Соответствие;
ШаблоныВнешнейОбработкиСМакетом = Новый Соответствие;
ПроверитьСтруктуруФайловогоКэша();
ИмяФайлаПакера = "v8unpack.exe";
WinAPI = "НеИнициализирован";
//ПолучитьWinAPI();
МассивОбычныхЭлементовУправления = Новый Массив;
РежимОтладки = Ложь;
АсинхронностьЗапрещена = Ложь;
#Если Клиент Тогда
РежимОтладки = Найти(НРег(ПараметрЗапуска), НРег("РежимОтладкиИР")) > 0;
АсинхронностьЗапрещена = Найти(НРег(ПараметрЗапуска), НРег("ЗапретитьАсинхронностьИР")) > 0;
COMНавигатор = "НеИнициализирован";
ТаблицаСтатистикиВыбора = ирОбщий.ВосстановитьЗначениеЛкс("ирПлатформа.ТаблицаСтатистикиВыбора");
Если ТаблицаСтатистикиВыбора <> Неопределено Тогда
Если ТаблицаСтатистикиВыбора.Колонки.Найти("ЯзыкПрограммы") = Неопределено Тогда
ТаблицаСтатистикиВыбора = Неопределено;
КонецЕсли;
КонецЕсли;
Если ТаблицаСтатистикиВыбора = Неопределено Тогда
ТаблицаСтатистикиВыбора = Новый ТаблицаЗначений;
ТаблицаСтатистикиВыбора.Колонки.Добавить("ТипКонтекста");
ТаблицаСтатистикиВыбора.Колонки.Добавить("Слово");
ТаблицаСтатистикиВыбора.Колонки.Добавить("ЯзыкПрограммы");
ТаблицаСтатистикиВыбора.Колонки.Добавить("Рейтинг", Новый ОписаниеТипов("Число"));
КонецЕсли;
ОтложенноеОткрытиеИсточникаОшибки = Новый ТаблицаЗначений;
ОтложенноеОткрытиеИсточникаОшибки.Колонки.Добавить("АлгоритмОбъект");
ОтложенноеОткрытиеИсточникаОшибки.Колонки.Добавить("ИнформацияОбОшибке");
ОтложенноеОткрытиеИсточникаОшибки.Колонки.Добавить("РежимВыполненияАлгоритма");
ОтложенноеОткрытиеИсточникаОшибки.Колонки.Добавить("Смещение", Новый ОписаниеТипов("Число"));
СлужебнаяФорма = ПолучитьФорму("Служебная");
Если СлужебнаяФорма <> Неопределено Тогда // Для портативного режима управляемого приложения
СлужебноеПолеТекста = СлужебнаяФорма.ЭлементыФормы.Добавить(Тип("ПолеТекстовогоДокумента"), "СлужебноеПолеТекста", Ложь);
СлужебноеПолеТекста2 = СлужебнаяФорма.ЭлементыФормы.Добавить(Тип("ПолеТекстовогоДокумента"), "СлужебноеПолеТекста2", Ложь);
//СлужебноеПолеHtmlДокумента = СлужебнаяФорма.ЭлементыФормы.Добавить(Тип("ПолеHTMLДокумента"), "СлужебноеПолеHTMLДокумента", Ложь); // Тяжелая операция
КонецЕсли;
МассивОбычныхЭлементовУправления.Добавить("Диаграмма");
МассивОбычныхЭлементовУправления.Добавить("ДиаграммаГанта");
МассивОбычныхЭлементовУправления.Добавить("Дендрограмма");
МассивОбычныхЭлементовУправления.Добавить("Индикатор");
МассивОбычныхЭлементовУправления.Добавить("ПолеКалендаря");
МассивОбычныхЭлементовУправления.Добавить("Кнопка");
МассивОбычныхЭлементовУправления.Добавить("КолонкаТабличногоПоля"); // Возможно что то сломается. Добавил для возможности автоопределения объекта системы
МассивОбычныхЭлементовУправления.Добавить("КоманднаяПанель");
МассивОбычныхЭлементовУправления.Добавить("Надпись");
МассивОбычныхЭлементовУправления.Добавить("Панель");
МассивОбычныхЭлементовУправления.Добавить("Переключатель");
МассивОбычныхЭлементовУправления.Добавить("ПолеГрафическойСхемы");
МассивОбычныхЭлементовУправления.Добавить("ПолеГеографическойСхемы");
МассивОбычныхЭлементовУправления.Добавить("ПолеТабличногоДокумента");
МассивОбычныхЭлементовУправления.Добавить("ПолеHTMLДокумента");
МассивОбычныхЭлементовУправления.Добавить("ПолеТекстовогоДокумента");
МассивОбычныхЭлементовУправления.Добавить("ПолеВвода");
МассивОбычныхЭлементовУправления.Добавить("ПолеВыбора");
МассивОбычныхЭлементовУправления.Добавить("ПолеСписка");
МассивОбычныхЭлементовУправления.Добавить("ПолеКартинки");
МассивОбычныхЭлементовУправления.Добавить("ПолосаРегулирования");
МассивОбычныхЭлементовУправления.Добавить("Разделитель");
МассивОбычныхЭлементовУправления.Добавить("РамкаГруппы");
МассивОбычныхЭлементовУправления.Добавить("СводнаяДиаграмма");
МассивОбычныхЭлементовУправления.Добавить("СтраницаПанели"); // Возможно что то сломается. Добавил для возможности автоопределения объекта системы
МассивОбычныхЭлементовУправления.Добавить("ТабличноеПоле");
МассивОбычныхЭлементовУправления.Добавить("Флажок");
мМассивТиповЭлементовУправления = Новый Массив;
Для Каждого ИмяТипа Из МассивОбычныхЭлементовУправления Цикл
мМассивТиповЭлементовУправления.Добавить(Тип(ИмяТипа));
КонецЦикла;
#КонецЕсли
МассивУправляемыхЭлементовУправления = Новый Массив;
МассивУправляемыхЭлементовУправления.Добавить("ПолеФормы");
МассивУправляемыхЭлементовУправления.Добавить("КнопкаФормы");
МассивУправляемыхЭлементовУправления.Добавить("ТаблицаФормы");
МассивУправляемыхЭлементовУправления.Добавить("ГруппаФормы");
МассивУправляемыхЭлементовУправления.Добавить("ДекорацияФормы");
мМассивТиповВключающихМетаданные = Новый Массив;
мМассивТиповВключающихМетаданные.Добавить(Тип("ОбъектМетаданных"));
мМассивТиповВключающихМетаданные.Добавить(Тип("КоллекцияОбъектовМетаданных")); // 31.10.2020
мМассивТиповВключающихМетаданные.Добавить(Тип("КоллекцияДвижений")); // 31.10.2020
мМассивТиповВключающихМетаданные.Добавить(Тип("ОписанияСтандартныхРеквизитов")); // 31.10.2020
мМассивТиповВключающихМетаданные.Добавить(Тип("СписокПолей")); // 31.10.2020
мМассивТиповВключающихМетаданные.Добавить(Тип("Структура"));
мМассивТиповВключающихМетаданные.Добавить(Тип("ФиксированнаяСтруктура"));
мМассивТиповВключающихМетаданные.Добавить(Тип("ТаблицаЗначений"));
мМассивТиповВключающихМетаданные.Добавить(Тип("ДеревоЗначений"));
мМассивТиповВключающихМетаданные.Добавить(Тип("СтрокаТаблицыЗначений"));
мМассивТиповВключающихМетаданные.Добавить(Тип("СтрокаДереваЗначений"));
мМассивТиповВключающихМетаданные.Добавить(Тип("ВыборкаИзРезультатаЗапроса"));
мМассивТиповВключающихМетаданные.Добавить(Тип("РезультатЗапроса"));
мМассивТиповВключающихМетаданные.Добавить(Тип("Отбор"));
мМассивТиповВключающихМетаданные.Добавить(Тип("НастройкаОформления"));
мМассивТиповВключающихМетаданные.Добавить(Тип("COMОбъект"));
мМассивТиповВключающихМетаданные.Добавить(Тип("ВнешнийОбъект"));
мМассивТиповВключающихМетаданные.Добавить(Тип("ОбъектXDTO"));
мМассивТиповВключающихМетаданные.Добавить(Тип("СвойствоXDTO"));
//мМассивТиповВключающихМетаданные.Добавить(Тип("ОбщийМодуль"));
мМассивТиповВключающихМетаданные.Добавить(Тип("ПостроительЗапроса"));
мМассивТиповВключающихМетаданные.Добавить(Тип("ПостроительОтчета"));
мМассивТиповВключающихМетаданные.Добавить(Тип("ПоляНастройки"));
мМассивТиповВключающихМетаданные.Добавить(Тип("СхемаКомпоновкиДанных"));
мМассивТиповВключающихМетаданные.Добавить(Тип("НаборыДанныхСхемыКомпоновкиДанных"));
мМассивТиповВключающихМетаданные.Добавить(Тип("ПараметрыСхемыКомпоновкиДанных"));
#Если Клиент Тогда
мМассивТиповВключающихМетаданные.Добавить(Тип("Форма"));
мМассивТиповВключающихМетаданные.Добавить(Тип("ТабличноеПоле"));
мМассивТиповВключающихМетаданные.Добавить(Тип("Панель"));
мМассивТиповВключающихМетаданные.Добавить(Тип("КнопкаКоманднойПанели"));
мМассивТиповВключающихМетаданные.Добавить(Тип("КоманднаяПанель"));
мМассивТиповВключающихМетаданные.Добавить(Тип("ПолеВвода"));
мМассивТиповВключающихМетаданные.Добавить(Тип("УправляемаяФорма"));
мМассивТиповВключающихМетаданные.Добавить(Тип("ГруппаФормы"));
мМассивТиповВключающихМетаданные.Добавить(Тип("ТаблицаФормы"));
#КонецЕсли
// Метка=7веан7878378078
мТаблицаСтруктурТипа = Новый ТаблицаЗначений;
мТаблицаСтруктурТипа.Колонки.Добавить("ИмяОбщегоТипа", Новый ОписаниеТипов("Строка"));
мТаблицаСтруктурТипа.Колонки.Добавить("Метаданные");
мТаблицаСтруктурТипа.Колонки.Добавить("СтрокаОписания");
мТаблицаСтруктурТипа.Колонки.Добавить("ТипЯзыка", Новый ОписаниеТипов("Строка"));
мТаблицаСтруктурТипа.Колонки.Добавить("ВиртуальнаяТаблица");
мТаблицаСтруктурТипа.Колонки.Добавить("Конструктор", Новый ОписаниеТипов("Булево"));
мТаблицаСтруктурТипа.Колонки.Добавить("ДополнительныеТипы");
мТаблицаСтруктурТипа.Колонки.Добавить("ДержательМетаданных");
мТаблицаСтруктурТипа.Колонки.Добавить("Квалификаторы");
//#Если Клиент Или ВнешнееСоединение Тогда
СубПутьКФайлуПотокаМодуляВнешнейОбработки = "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Объектов = Новый Соответствие;
БуферыСравнения = Новый Соответствие;
МодальныеГруппы = Новый СписокЗначений;
ОтмененныеФоновыеЗадания = Новый Массив;
мОписаниеТипаМДТабличнаяЧасть = ОписаниеТипаМетаОбъектов("ТабличнаяЧасть");
мОписаниеТипаМДВнешнийИсточникДанных = ОписаниеТипаМетаОбъектов("ВнешнийИсточникДанных");