//ирПортативный Перем ирПортативный Экспорт;
//ирПортативный Перем ирОбщий Экспорт;
//ирПортативный Перем ирСервер Экспорт;
//ирПортативный Перем ирКэш Экспорт;
//ирПортативный Перем ирПривилегированный Экспорт;

Перем ЧистыйКонтекст;
Перем ФиксироватьВнешниеИсключенияАлгоритмов Экспорт;
Перем ВерсияПлатформы Экспорт;
Перем ЭтоФайловаяБаза Экспорт;
Перем мМетаданные Экспорт;
Перем Это2iS Экспорт;
Перем ЭтоИнтеграция Экспорт;
Перем СоответствиеВидовСравнения Экспорт;
Перем МаркерНачалаАлгоритма Экспорт;
Перем МаркерКонцаАлгоритма Экспорт;
Перем МакетыКомпонент Экспорт;
Перем мКэшПустыхЗначений Экспорт;
Перем ВложенностьИндикации Экспорт;
Перем КэшОбъектов Экспорт;
Перем ВремяОбъект Экспорт;
Перем АрхитектураПроцессора Экспорт;
Перем ИсполнительСкрытыхКомандСистемы;
Перем СодержанияАрхивовСправки Экспорт;
Перем ИндексыАрхивовСправки Экспорт;
Перем ВыполнятьАлгоритмыЧерезВнешниеОбработки Экспорт;
Перем ВнешняяОбработкаСервисы Экспорт;
Перем ФайловыйКэшАлгоритмовДопускаетРедактирование Экспорт;
//Перем ТекстПотокаСИменемВнешнейОбработки;
//Перем ТекстПотокаСИменемВнешнейОбработкиСМакетом;
//Перем ФайлСИменемВнешнейОбработки;
//Перем ФайлСИменемВнешнейОбработкиСМакетом;
////Перем КешВнешнихОбработокАлгоритмов;
Перем КешАлгоритмов;
Перем СубПутьКФайлуПотокаМодуляВнешнейОбработки;
Перем СубПутьКФайлуПотокаМакетаВнешнейОбработки;
Перем СубПутьКФайлуПотокаЗаголовкаВнешнейОбработки;
Перем СубПутьККонтрольномуФайлуВнешнейОбработки;
Перем ПутьККаталогуСлужебныхВременныхФайлов;
Перем мЕстьАдминистративныеПраваУУчетнойЗаписиОС;
//Перем ФайлЗамокШаблона;
//Перем ФайлЗамокШаблонаСМакетом;
Перем ПапкаКешаВнешнихОбработокАлгоритмов Экспорт;
Перем ПапкаКешаВнешнихОбработокАрхива Экспорт;
Перем ПапкаВнешнихКомпонент Экспорт;
Перем КаталогФайловогоКэша Экспорт;
Перем СтруктураПодкаталоговФайловогоКэша Экспорт;
Перем ИмяФайлаПакера Экспорт;
Перем ШаблоныВнешнейОбработки;
Перем ШаблоныВнешнейОбработкиСМакетом;
Перем ФайлРегистратораКомпонентCU;
Перем ФайлРегистратораNetКомпонент;
Перем МассивСравненияТекстов Экспорт;
Перем ОбъектыМДПоПолномуИмени Экспорт;
Перем мВопросОтключенияПроверкиМодальностиЗадавался Экспорт;
Перем мПроверкаСовместимостиКонфигурацииВыполнялась Экспорт;
Перем мПроверкаЗащитыОтОпасныхДействийВыполнялась Экспорт;

Перем WshShell Экспорт;
Перем WinAPI Экспорт;
Перем RegExp Экспорт;
Перем RegExp2 Экспорт;
Перем VBRegExp;

Перем шБуква Экспорт;
Перем шИмя Экспорт;
Перем шЧисло Экспорт;
Перем шИндекс Экспорт;
Перем шСкобки Экспорт;
Перем шGUID Экспорт;
Перем шКомментарий Экспорт;
Перем шРазделитель Экспорт;
Перем шИмяВременнойТаблицы Экспорт;

Перем МаркерОбъектаМетаданных;
Перем МаркерКоллекцииОбъектовМетаданных;
Перем МаркерCOMОбъекта Экспорт;

//#Если Клиент Или ВнешнееСоединение Тогда
Перем ИдентификаторПроцессаОС Экспорт;
Перем VBScript Экспорт;
Перем JavaScript Экспорт;
Перем ДеревоТипов Экспорт;
Перем ТаблицаОбщихТипов Экспорт;
Перем ТаблицаИменЭлементовКоллекций Экспорт;
Перем ТаблицаКонтекстов Экспорт;
Перем ТаблицаРасширенийТипов Экспорт;
Перем ТаблицаШаблоновКонтекстов Экспорт;
Перем ТаблицаТиповМетаОбъектов Экспорт;
Перем ТаблицаПараметров Экспорт;
Перем СлужебноеПолеТекстовогоДокумента Экспорт;
Перем СлужебноеПолеHtmlДокумента Экспорт;
Перем МассивОбычныхЭлементовУправления Экспорт;
Перем МассивУправляемыхЭлементовУправления Экспорт;
Перем мМассивТиповЭлементовУправления Экспорт;
Перем ТаблицаСтатистикиВыбора Экспорт;
Перем мМассивТиповВключающихМетаданные Экспорт;
Перем мТаблицаСтруктурТипа; // Образец таблицы структур типа
Перем мТаблицаСоответствияВидов;
Перем мТаблицаЗамеров Экспорт;
Перем мТаблицаИндикаторов Экспорт;
Перем мИменаОсновныхКлассовБиблиотекCOM; // Кэш имен классов, например Exel - Application
Перем мОбразцыCOMОбъектов; // Для вычисления свойств
Перем мADOUtils; // GameWithFire.ADOUtils

Перем СлужебнаяФорма;
Перем COMНавигатор Экспорт;
Перем ТаблицаШаблоновТекста Экспорт;
Перем КартинкиТипов;
Перем мОшибкаИнформаторУжеВыводилась;

Перем МассивИсключенийИменКоллекций;

Перем ФайлЗапаковщика1С Экспорт;
Перем ФайлБиблиотекиЗапаковщика;
Перем ФайлОткрывателя1С Экспорт;
Перем ФайлРаспаковщикаZIP Экспорт;
Перем ФайлСтилейСинтаксПомощника Экспорт;
Перем АрхивСинтаксПомощника Экспорт;
Перем Парсеры Экспорт;
Перем БуферыСравнения Экспорт;
Перем ПараметрыОбработчикаОжидания Экспорт;
Перем мМаркерИмениЗапросаПакета Экспорт;
Перем мМаркерИмениЧастиОбъединения Экспорт;

Перем ПоказыватьВнешниеИсключенияПриВыполненииАлгоритмов Экспорт;
Перем СинтаксическийКонтрольПередЗаписью Экспорт;
Перем ОтложенноеОткрытиеИсточникаОшибки Экспорт;
Перем ЛиНизкоуровневоеПолучениеОписанийОбъектов Экспорт;
Перем АвторегистрацияComКомпонент Экспорт;
Перем НеИспользоватьИмитаторыОбъектовДанных Экспорт;
Перем ЛиКомпонентаFormsTextBoxДоступна;

///////////////////////////////////////////////////////////////////
// Информатор. Начало

Перем ИМЯ_КЛАССА_DynamicWrapperX;
Перем СТРОКА_ОПИСАНИЕ_МЕТОДА_БЕЗ_ПАРАМЕТРОВ Экспорт;
Перем СТРОКА_МЕТОДЫ Экспорт;
Перем СТРОКА_СВОЙСТВА Экспорт;
Перем СТРОКА_ГЛОБАЛЬНЫЙ_КОНТЕКСТ;

Перем	ФЛАГ_ЗАПОЛНЕНИЯ_ПРОВЕРИТЬ_СУЩЕСТВОВАНИЕ_СВОЙСТВ_И_МЕТОДОВ Экспорт;
Перем	ФЛАГ_ЗАПОЛНЕНИЯ_ПРОВЕРИТЬ_СУЩЕСТВОВАНИЕ_СВОЙСТВ;
Перем	ФЛАГ_ЗАПОЛНЕНИЯ_ПРОВЕРИТЬ_СУЩЕСТВОВАНИЕ_МЕТОДОВ;
Перем	ФЛАГ_ЗАПОЛНЕНИЯ_ПРОВЕРИТЬ_СУЩЕСТВОВАНИЕ_ЗНАЧЕНИЙ;
Перем	ФЛАГ_ЗАПОЛНЕНИЯ_ЗАПОЛНИТЬ_СВОЙСТВА;
Перем	ФЛАГ_ЗАПОЛНЕНИЯ_ЗАПОЛНИТЬ_МЕТОДЫ;

Перем	Wrap;
Перем	_SIZE;
Перем	_BUF;
Перем 	_pMEM;
Перем 	PAGE_EXECUTE_READWRITE;
Перем НомераМетодовИнтерфейса;

// Информатор. Конец
///////////////////////////////////////////////////////////////////


// Инициализирует, если необходимо, большие таблицы платформы.
// К ним относятся таблицы методов и свойств.
//
// Параметры:
//  Нет.
//
Процедура ИнициализацияОписанияМетодовИСвойств() Экспорт

	Если ТипЗнч(ТаблицаКонтекстов) = Тип("ТаблицаЗначений") Тогда
		Возврат;
	КонецЕсли;
	#Если Клиент Тогда	
		Состояние("Инициализация таблицы методов и свойств...");
	#КонецЕсли
	МассивТаблиц = ЗначениеИзСтрокиВнутр(ПолучитьМакет("ТаблицаМетодовИСвойств").ПолучитьТекст());
	ТаблицаКонтекстов = МассивТаблиц.ТаблицаКонтекстов;
	ТаблицаКонтекстов.Индексы.Добавить("ТипКонтекста");
	ТаблицаКонтекстов.Индексы.Добавить("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка");
	ТаблицаШаблоновКонтекстов = МассивТаблиц.ТаблицаШаблоновКонтекстов;
	ТаблицаШаблоновКонтекстов.Индексы.Добавить("ТипКонтекста");
	ТаблицаШаблоновКонтекстов.Индексы.Добавить("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка");
		
	#Если Клиент Тогда
		Состояние("");
	#КонецЕсли

КонецПроцедуры

// Инициализирует, если необходимо, малые таблицы платформы.
// К ним относятся таблицы типов и коллекций.
// 
// Параметры:
//  Нет.
//
Процедура ИнициализацияОписанияПараметровИТипов() Экспорт

	Если ТипЗнч(ТаблицаОбщихТипов) = Тип("ТаблицаЗначений") Тогда
		Возврат;
	КонецЕсли;
	МассивТаблиц = ЗначениеИзСтрокиВнутр(ПолучитьМакет("ТаблицаИменЭлементовКоллекций").ПолучитьТекст());
	ТаблицаИменЭлементовКоллекций = МассивТаблиц.ТаблицаИменЭлементовКоллекций;
	ТаблицаИменЭлементовКоллекций.Индексы.Добавить("ИмяКоллекции");
	ТаблицаИменЭлементовКоллекций.Индексы.Добавить("ИмяЭлементаКоллекции");
	ТаблицаИменЭлементовКоллекций.Индексы.Добавить("ИмяОбщегоТипа, ИмяЭлементаКоллекции");
	ТаблицаРасширенийТипов = МассивТаблиц.ТаблицаРасширений;
	ТаблицаРасширенийТипов.Индексы.Добавить("Расширение");
	МассивТаблиц = ЗначениеИзСтрокиВнутр(ПолучитьМакет("ТаблицаПараметровИТипов").ПолучитьТекст());
	ТаблицаОбщихТипов = МассивТаблиц.ТаблицаОбщихТипов;
	ТаблицаОбщихТипов.Индексы.Добавить("Слово, ЯзыкПрограммы");
	ТаблицаОбщихТипов.Индексы.Добавить("Слово, ТипТипа");
	//ТаблицаОбщихТипов.Индексы.Добавить("Слово, ЯзыкПрограммы, ТипТипа");
	ТаблицаОбщихТипов.Индексы.Добавить("Представление, ТипТипа");
	ТаблицаОбщихТипов.Индексы.Добавить("ИД, ТипТипа");
	ТаблицаПараметров = МассивТаблиц.ТаблицаПараметров;
	ТаблицаПараметров.Индексы.Добавить("ТипКонтекста, ЯзыкПрограммы, Слово, Номер");
	
КонецПроцедуры 

// Добавляет дополнительные Свойства для типов контекстов платформы.
//
// Параметры:
//  <Параметр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.Replace(ТекстЗапроса, "$2");
	выхВсеРазмаскировано = Найти(НовыйТекстЗапроса, """ВременнаяТаблица"" = """) = 0;
	Если Не выхВсеРазмаскировано Тогда
		ВызватьИсключение "Не удалось размаскировать временные таблицы в тексте запроса. Возможно на них был наложен несовместимый с маскировкой отбор компоновки.";
	КонецЕсли; 
	Возврат НовыйТекстЗапроса;

КонецФункции // РазмаскироватьВременныеТаблицы()

// Получает текст запроса, где каждая временная таблица заменена своим имитатором.
//
// Параметры:
//  ОбъектЗапроса – Запрос;
//  *ТекстЗапроса  – Строка, *Неопределено;
//  *МассивВременныхТаблиц - Массив, *Неопределено - все подменяемые таблицы заносятся сюда.
//
// Возвращаемое значение:
//  Строка - новый текст запроса.
//
Функция ЗамаскироватьВременныеТаблицы(ОбъектЗапроса, Знач ТекстЗапроса = Неопределено,
	МассивВременныхТаблиц = Неопределено) Экспорт 

	Если ТекстЗапроса = Неопределено Тогда
		ТекстЗапроса = ОбъектЗапроса.Текст;
	КонецЕсли;
	ВременныйЗапрос = Новый Запрос;
	ВременныйЗапрос.МенеджерВременныхТаблиц = ОбъектЗапроса.МенеджерВременныхТаблиц;
	ПроверочныйЗапрос = Новый ПостроительЗапроса;
	
	//// Исключительная ситуация должна быть обработана сверху
	//ПараметрыЗапроса = ВременныйЗапрос.НайтиПараметры();

	Если ТипЗнч(МассивВременныхТаблиц) <> Тип("Массив") Тогда
		МассивВременныхТаблиц = Новый Массив;
	КонецЕсли; 
	ТекстовыйДокумент = Новый ТекстовыйДокумент;
	ТекстовыйДокумент.УстановитьТекст(ТекстЗапроса);
	Пока Истина Цикл
		Попытка
			ПроверочныйЗапрос.Текст = ТекстЗапроса;
			//ПроверочныйЗапрос.НайтиПараметры();
			Прервать;
		Исключение
			ИнформацияОбОшибке = ИнформацияОбОшибке();
			//ИмяВременнойТаблицы = ирОбщий.ПолучитьСтрокуМеждуМаркерамиЛкс(ИнформацияОбОшибке.Причина.Описание, """", """");
			ИмяВременнойТаблицы = ирОбщий.ПолучитьСтрокуМеждуМаркерамиЛкс(ИнформацияОбОшибке.Причина.Описание, "Таблица не найдена """, """", Ложь);
			Если ЗначениеЗаполнено(ИмяВременнойТаблицы) Тогда
				ВременныйЗапрос.Текст = "ВЫБРАТЬ * ИЗ " + ИмяВременнойТаблицы;
				Попытка
					КолонкиВременнойТаблицы = ВременныйЗапрос.Выполнить().Колонки;
				Исключение
					Прервать;
				КонецПопытки;
			КонецЕсли; 
			// В 8.2.15 такой прием лишен смысла, т.к. движок запросов потом не сможет обработать обращения к дочерним полям
			//Если Не ЗначениеЗаполнено(ИмяВременнойТаблицы) Тогда
			//	ИмяВременнойТаблицы = ирОбщий.ПолучитьСтрокуМеждуМаркерамиЛкс(ИнформацияОбОшибке.Причина.Описание, "Неверные параметры """, """", Ложь);
			//	Если ЗначениеЗаполнено(ИмяВременнойТаблицы) Тогда
			//		Попытка
			//			КолонкиВременнойТаблицы = ОбъектЗапроса.Параметры[ИмяВременнойТаблицы].Колонки;
			//		Исключение
			//			Попытка
			//				КолонкиВременнойТаблицы = ВременныйЗапрос.Выполнить().Колонки;
			//			Исключение
			//				Прервать;
			//			КонецПопытки;
			//		КонецПопытки;
			//		ИмяВременнойТаблицы = "&" + ИмяВременнойТаблицы;
			//	КонецЕсли; 
			//КонецЕсли; 
			Если Не ЗначениеЗаполнено(ИмяВременнойТаблицы) Тогда
				Прервать;
			КонецЕсли;
			ИмитаторВременнойТаблицы = ирОбщий.ПолучитьЗапросИмитаторКоллекцииПолейЛкс(КолонкиВременнойТаблицы) 
				+ " ГДЕ ""ВременнаяТаблица"" = """ + ИмяВременнойТаблицы +  """";
			КоординатыОбращения = ирОбщий.ПолучитьСтрокуМеждуМаркерамиЛкс(ИнформацияОбОшибке.Причина.Описание, "{(", ")}");
			НомерСтроки = Число(ирОбщий.ПолучитьПервыйФрагментЛкс(КоординатыОбращения, ", "));    
			НомерКолонки = Число(ирОбщий.ПолучитьПоследнийФрагментЛкс(КоординатыОбращения, ","));
			СтрокаЗапроса = ТекстовыйДокумент.ПолучитьСтроку(НомерСтроки);
			ТекстПосле = Сред(СтрокаЗапроса, НомерКолонки + СтрДлина(ИмяВременнойТаблицы));
			СтрокаКАК = "КАК";
			Если Не ирОбщий.СтрокиРавныЛкс(Лев(СокрЛ(ТекстПосле), СтрДлина(СтрокаКАК)), СтрокаКАК) Тогда
				ТекстПосле = " КАК " + ИмяВременнойТаблицы + " " + ТекстПосле;
			КонецЕсли; 
			НоваяСтрока = Лев(СтрокаЗапроса, НомерКолонки - 1) + "(" + ИмитаторВременнойТаблицы + ")" + ТекстПосле;
			ТекстовыйДокумент.ЗаменитьСтроку(НомерСтроки, НоваяСтрока);
			ТекстЗапроса = ТекстовыйДокумент.ПолучитьТекст();
			МассивВременныхТаблиц.Добавить(ИмяВременнойТаблицы);
		КонецПопытки;
	КонецЦикла;
	Возврат ТекстЗапроса;

КонецФункции // ЗамаскироватьВременныеТаблицы()

// Результат - Массив
Функция НайтиВозможныеИменаВременныхТаблиц(ТекстЗапроса, ЛиДиалект1С = Истина) Экспорт
	
	Имена = Новый Соответствие;
	RegExp.Global = Истина;
	RegExp.pattern = "(?:ИЗ|СОЕДИНЕНИЕ|УНИЧТОЖИТЬ|,)\s+(" + шИмяВременнойТаблицы + ")(?:\s|$|[^\(\._\d" + шБуква + "])";
	РезультатПоиска = RegExp.Execute(ТекстЗапроса);
	Для Каждого Вхождение Из РезультатПоиска Цикл
		Имена.Вставить(Нрег(Вхождение.SubMatches(0)), Вхождение.SubMatches(0));
	КонецЦикла;
	Результат = Новый Массив();
	Для Каждого КлючИЗначение Из Имена Цикл
		Если Истина
			И ЛиДиалект1С
			И (Ложь
				Или ирОбщий.СтрокиРавныЛкс(КлючИЗначение.Значение, "Константы")
				Или Найти(КлючИЗначение.Значение, ".") > 0)
		Тогда
			Продолжить;
		КонецЕсли; 
		Результат.Добавить(КлючИЗначение.Значение);
	КонецЦикла;
	Возврат Результат;
	
КонецФункции

// <Описание функции>
//
// Параметры:
//  <Параметр1>  – <Тип.Вид> – <описание параметра>
//                 <продолжение описания параметра>;
//  <Параметр2>  – <Тип.Вид> – <описание параметра>
//                 <продолжение описания параметра>.
//
// Возвращаемое значение:
//               – <Тип.Вид> – <описание значения>
//                 <продолжение описания значения>;
//  <Значение2>  – <Тип.Вид> – <описание значения>
//                 <продолжение описания значения>.
//
Функция РазбитьГрубоТекстПакетногоЗапросаНаТекстыЗапросов(ТекстПакета) Экспорт 

	МассивТекстовЗапросов = Новый Массив;
	шСтрокаЗапроса    = """(?:(?:"""")|[^""\n$])*(?:" + шРазделитель + "*(?:(?:"""")|[^""\n$])*)*(?:""|$)";
	
	RegExp.Global = Истина;
	ШаблонЗапроса = "(?:" + шСтрокаЗапроса + ")|" + шКомментарий + "|;|$";
	RegExp.Pattern = ШаблонЗапроса;
	
	Результат = RegExp.Execute(ТекстПакета);
	НачалоЗапроса = 1;
	ОстальнойТекст = ТекстПакета;
	МассивТаблиц = Новый Массив;
	ДлинаТекстаПакета = СтрДлина(ТекстПакета);
	Для Каждого Match Из Результат Цикл
		Если Истина
			И Match.Value <> ";"
			И Match.FirstIndex <> ДлинаТекстаПакета
		Тогда
			Продолжить;
		КонецЕсли;
		ИмяВременнойТаблицы = "";
		ДлинаТекстаЗапроса = Match.FirstIndex + Match.Length;
		ТекстЗапроса = Сред(ТекстПакета, НачалоЗапроса, ДлинаТекстаЗапроса - НачалоЗапроса + 1);
		Если ПустаяСтрока(ТекстЗапроса) Тогда
			Продолжить;
		КонецЕсли;
		//Если ТекстЗапроса = ";" Тогда
		//	Продолжить;
		//КонецЕсли; 
		ОстальнойТекст = Сред(ОстальнойТекст, ДлинаТекстаЗапроса + 1);
		НачалоЗапроса = НачалоЗапроса + СтрДлина(ТекстЗапроса);
		МассивТекстовЗапросов.Добавить(ТекстЗапроса);
	КонецЦикла;
	
	Возврат МассивТекстовЗапросов;

КонецФункции // РазбитьГрубоТекстПакетногоЗапросаНаТекстыЗапросов()

Функция ПолучитьСтруктуруРезультатаПакетногоЗапроса(ТекстПакета, ПрефиксКомментария = "//") Экспорт 
	
	МассивТекстовЗапросов = РазбитьГрубоТекстПакетногоЗапросаНаТекстыЗапросов(ТекстПакета);
	RegExp.Global = Ложь;
	RegExp.Multiline = Истина;
	RegExp.Pattern = ПрефиксКомментария + мМаркерИмениЗапросаПакета + "(" + шИмя + ")(?: |\n|\r)";
	Индекс = -1;
	Результат = Новый Структура;
	Для Каждого ТекстЗапроса Из МассивТекстовЗапросов Цикл
		Индекс = Индекс + 1;
		Вхождения = RegExp.Execute(ТекстЗапроса);
		Если Вхождения.Count = 0 Тогда
			Продолжить;
		КонецЕсли; 
		ИмяЗапроса = Вхождения.Item(0).SubMatches(0);
		Если ирОбщий.ЛиИмяПеременнойЛкс(ИмяЗапроса) Тогда
			Результат.Вставить(ИмяЗапроса, Индекс);
		КонецЕсли; 
	КонецЦикла;
	Возврат Результат;
	
КонецФункции

// <Описание функции>
//
// Параметры:
//  <Параметр1>  – <Тип.Вид> – <описание параметра>
//                 <продолжение описания параметра>;
//  <Параметр2>  – <Тип.Вид> – <описание параметра>
//                 <продолжение описания параметра>.
//
// Возвращаемое значение:
//               – <Тип.Вид> – <описание значения>
//                 <продолжение описания значения>;
//  <Значение2>  – <Тип.Вид> – <описание значения>
//                 <продолжение описания значения>.
//
Функция ПреобразоватьЗапросВПодзапрос(Текст, ТекстВыбранныхПолей = "*", ПсевдонимВложенногоЗапроса = "ВложенныйЗапрос",
	ОбрезатьНачинаяСУпорядочивания = Ложь, ЭтоРусскийЯзык = Истина, Знач Смещение = "") Экспорт

	//ЭтоРусскийЯзык = ЭтоРусскийВариантТекстаЗапроса(ТекстЗапроса);
	RegExp.Pattern = "^(?:\s|(" + шКомментарий + "))*((?:ВЫБРАТЬ|SELECT)\s+((?:РАЗРЕШЕННЫЕ|ALLOWED)\s+)?)((?:(?:.|\r|\n)*\s((?:УПОРЯДОЧИТЬ|ORDER)\s+(?:ПО|BY)\s+" + шИмя 
		+ "(?:\s*,\s*" + шИмя + ")*(?:\s+(?:АВТОУПОРЯДОЧИВАНИЕ|AUTOORDER))?|(?:АВТОУПОРЯДОЧИВАНИЕ|AUTOORDER)))*)((?:.|\r|\n)*)$";
	РезультатПоиска = RegExp.Execute(Текст).Item(0);
	Если ЭтоРусскийЯзык Тогда
		Результат = "ВЫБРАТЬ";
	Иначе
		Результат = "SELECT";
	КонецЕсли; 
	Если Не ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(РезультатПоиска.SubMatches(2)) Тогда
		Если ЭтоРусскийЯзык Тогда
			Результат = Результат + " РАЗРЕШЕННЫЕ";
		Иначе
			Результат = Результат + " ALLOWED";
		КонецЕсли; 
	КонецЕсли; 
	Смещение = Смещение + Символы.Таб;
	Если ЭтоРусскийЯзык Тогда
		Результат = Результат + " " + ТекстВыбранныхПолей + " ИЗ (";
	Иначе
		Результат = Результат + " " + ТекстВыбранныхПолей + " FROM (";
	КонецЕсли; 
	НачальныйКомментарий = РезультатПоиска.SubMatches(0);
	Если ЗначениеЗаполнено(НачальныйКомментарий) Тогда
		Результат = Результат + Символы.ПС + Смещение + НачальныйКомментарий;
	Иначе
		Результат = Результат + Символы.ПС;
	КонецЕсли; 
	Если ЭтоРусскийЯзык Тогда
		Результат = Результат + Смещение + "ВЫБРАТЬ ";
	Иначе
		Результат = Результат + Смещение + "SELECT ";
	КонецЕсли; 
	ТекстДоПоследнегоУПОРЯДОЧИТЬ = РезультатПоиска.SubMatches(3);
	Если ЗначениеЗаполнено(ТекстДоПоследнегоУПОРЯДОЧИТЬ) Тогда
		ТекстДоПоследнегоУПОРЯДОЧИТЬ = ирОбщий.ПолучитьСтрокуБезКонцаЛкс(ТекстДоПоследнегоУПОРЯДОЧИТЬ, СтрДлина(РезультатПоиска.SubMatches(4)));
		ирОбщий.ДобавитьМногострочнуюСтрокуВТекстЛкс(Результат, ТекстДоПоследнегоУПОРЯДОЧИТЬ, Смещение);
	Иначе
		ирОбщий.ДобавитьМногострочнуюСтрокуВТекстЛкс(Результат, РезультатПоиска.SubMatches(5), Смещение);
	КонецЕсли; 
	Если ЭтоРусскийЯзык Тогда
		Результат = Результат + ") КАК ";
	Иначе
		Результат = Результат + ") AS ";
	КонецЕсли; 
	Результат = Результат + ПсевдонимВложенногоЗапроса;
	Если Истина
		//И ТекстДоПоследнегоУПОРЯДОЧИТЬ <> Неопределено 
		И Не ПустаяСтрока(ТекстДоПоследнегоУПОРЯДОЧИТЬ)
		И Не ОбрезатьНачинаяСУпорядочивания 
	Тогда
		Результат = Результат + Символы.ПС + РезультатПоиска.SubMatches(4) + РезультатПоиска.SubMatches(5);
	КонецЕсли; 
	Возврат Результат;

КонецФункции // ПолучитьТекстЗапросаДоУпорядочивания()
  
// <Описание функции>
//
// Параметры:
//  <Параметр1>  – <Тип.Вид> – <описание параметра>
//                 <продолжение описания параметра>;
//  <Параметр2>  – <Тип.Вид> – <описание параметра>
//                 <продолжение описания параметра>.
//
// Возвращаемое значение:
//               – <Тип.Вид> – <описание значения>
//                 <продолжение описания значения>;
//  <Значение2>  – <Тип.Вид> – <описание значения>
//                 <продолжение описания значения>.
//
Функция ПолучитьГрубоКоличествоСтрокВРезультатеЗапроса(ЗапросИлиПостроитель, ЛиЗамерВремени = Ложь, МодальныйРежим = Ложь, ИмяЗапроса = "") Экспорт

	Если ТипЗнч(ЗапросИлиПостроитель) = Тип("ПостроительЗапроса") Тогда
		Запрос = ЗапросИлиПостроитель.ПолучитьЗапрос();
	Иначе
		Запрос = ЗапросИлиПостроитель;
	КонецЕсли; 
	ОригинальныйТекстЗапроса = Запрос.Текст;
	
	// Исключаем тяжелые типы из финальной выборки
	МассивИменВременныхТаблиц = Новый Массив();
	ТекстПостроителя = ирКэш.Получить().ЗамаскироватьВременныеТаблицы(Запрос, , МассивИменВременныхТаблиц);
	ПостроительЗапроса = Новый ПостроительЗапроса;
	Попытка
		ПостроительЗапроса.Текст = ТекстПостроителя;
	Исключение
		ОписаниеОшибки = ОписаниеОшибки();
		Возврат ОписаниеОшибки;
	КонецПопытки; 
	ПостроительЗапроса.ДобавлениеПредставлений = ТипДобавленияПредставлений.НеДобавлять;
	ПостроительЗапроса.ЗаполнитьНастройки();
	УдаляемыеВыбранныеПоля = Новый Массив;
	Для Каждого ВыбранноеПоле Из ПостроительЗапроса.ВыбранныеПоля Цикл
		ДоступноеПоле = ПостроительЗапроса.ДоступныеПоля.Найти(ВыбранноеПоле.Имя);
		ТипЗначенияПоля = ДоступноеПоле.ТипЗначения;
		Если Ложь
			Или (Истина
				И ТипЗначенияПоля.СодержитТип(Тип("Строка"))
				И ТипЗначенияПоля.КвалификаторыСтроки.Длина = 0)
			Или ТипЗначенияПоля.СодержитТип(Тип("ХранилищеЗначения"))
		Тогда
			УдаляемыеВыбранныеПоля.Добавить(ВыбранноеПоле);
		КонецЕсли; 
	КонецЦикла;
	Для Каждого ВыбранноеПоле Из УдаляемыеВыбранныеПоля Цикл
		ПостроительЗапроса.ВыбранныеПоля.Удалить(ВыбранноеПоле);
	КонецЦикла;
	ПромежуточныйТекстЗапроса = ПостроительЗапроса.ПолучитьЗапрос().Текст;
	ПромежуточныйТекстЗапроса = ирКэш.Получить().РазмаскироватьВременныеТаблицы(ПромежуточныйТекстЗапроса, МассивИменВременныхТаблиц);
	
	МассивТекстовЗапросов = РазбитьГрубоТекстПакетногоЗапросаНаТекстыЗапросов(ПромежуточныйТекстЗапроса); // разбивка производится второй раз. можно оптимизировать
	ТекстПоследнегоЗапроса = МассивТекстовЗапросов[МассивТекстовЗапросов.ВГраница()];
	ТекстДоПоследнегоЗапроса = "";
	Для Индекс = 0 По МассивТекстовЗапросов.ВГраница() - 1 Цикл
		ТекстДоПоследнегоЗапроса = ТекстДоПоследнегоЗапроса + МассивТекстовЗапросов[Индекс];
	КонецЦикла;
	ТекстПоследнегоЗапроса = ПреобразоватьЗапросВПодзапрос(ТекстПоследнегоЗапроса, "КОЛИЧЕСТВО(1) КАК КоличествоСтрок",, Истина);
	Запрос.Текст = ТекстДоПоследнегоЗапроса + ТекстПоследнегоЗапроса;
	#Если Клиент Тогда
		НачалоПредварительногоВыполнения = ПолучитьТекущееВремяВМиллисекундах();
	#КонецЕсли 
	Попытка
		РезультатПредварительногоЗапроса = Запрос.Выполнить();
		ПредварительныйЗапросБылиОшибки = Ложь;
	Исключение
		ПредварительныйЗапросБылиОшибки = Истина;
		КоличествоСтрок = ОписаниеОшибки();
	КонецПопытки;
	#Если Клиент Тогда
		Если Истина
			И ЛиЗамерВремени 
			И Не ПредварительныйЗапросБылиОшибки
		Тогда
			ирОбщий.СообщитьСУчетомМодальностиЛкс("Время формирования предварительного результата """ + ИмяЗапроса + """ - " 
				+ Строка(ПолучитьТекущееВремяВМиллисекундах() - НачалоПредварительногоВыполнения) + " мс", МодальныйРежим);
			КонецЕсли;
	#КонецЕсли 
	Если Не ПредварительныйЗапросБылиОшибки Тогда
		КоличествоСтрок = РезультатПредварительногоЗапроса.Выгрузить()[0].КоличествоСтрок;
	КонецЕсли;
	Запрос.Текст = ОригинальныйТекстЗапроса;
	Возврат КоличествоСтрок;

КонецФункции

// <Описание функции>
//
// Параметры:
//  <Параметр1>  – <Тип.Вид> – <описание параметра>
//                 <продолжение описания параметра>;
//  <Параметр2>  – <Тип.Вид> – <описание параметра>
//                 <продолжение описания параметра>.
//
// Возвращаемое значение:
//               – <Тип.Вид> – <описание значения>
//                 <продолжение описания значения>;
//  <Значение2>  – <Тип.Вид> – <описание значения>
//                 <продолжение описания значения>.
//
Функция ПолучитьГрубоКоличествоСтрокВРезультатеКомпоновки(МакетКомпоновкиДанныхВКоллекциюЗначений, БылиОшибки = Ложь, ЛиЗамерВремени = Ложь,
	МодальныйРежим = Ложь) Экспорт

	КоличествоСтрокВсего = 0;
	Запрос = Новый Запрос;
	Для Каждого ЗначениеПараметра Из МакетКомпоновкиДанныхВКоллекциюЗначений.ЗначенияПараметров Цикл
		Запрос.Параметры.Вставить(ЗначениеПараметра.Имя, ЗначениеПараметра.Значение);
	КонецЦикла;
	Для Каждого НаборДанных Из МакетКомпоновкиДанныхВКоллекциюЗначений.НаборыДанных Цикл
		Если ТипЗнч(НаборДанных) <> Тип("НаборДанныхЗапросМакетаКомпоновкиДанных") Тогда
			Продолжить;
		КонецЕсли;
		Запрос.Текст = НаборДанных.Запрос;
		КоличествоСтрок = ПолучитьГрубоКоличествоСтрокВРезультатеЗапроса(Запрос, ЛиЗамерВремени, МодальныйРежим, НаборДанных.Имя);
		Если ТипЗнч(КоличествоСтрок) = Тип("Число") Тогда
			КоличествоСтрокВсего = КоличествоСтрокВсего + КоличествоСтрок;
		Иначе
			БылиОшибки = Истина;
		КонецЕсли;
	КонецЦикла;
	Возврат КоличествоСтрокВсего;

КонецФункции // ПолучитьГрубоКоличествоСтрокВРезультатеКомпоновки()

// Получает имя создаваемой временной таблицы из текста запроса.
// Это неточный метод, основанный на regexp.
//
// Параметры:
//  ТекстЗапроса – Строка.
//
// Возвращаемое значение:
//  Строка, Неопределено.
//
Функция ПолучитьМассивСоздаваемыхВременныхТаблицПакета(ТекстПакета, ТолькоТребующиеУничтоженияНаВходе = Ложь) Экспорт 

	МассивТекстовЗапросов = РазбитьГрубоТекстПакетногоЗапросаНаТекстыЗапросов(ТекстПакета);
	RegExp2.Global = Истина;
	// Ищем в очередном запросе предложение ПОМЕСТИТЬ
	шСтрокаЗапроса    = """(?:(?:"""")|[^""\n$])*(?:" + шРазделитель + "*(?:(?:"""")|[^""\n$])*)*(?:""|$)";
	ШаблонПОМЕСТИТЬИЗ = "(?:" + шСтрокаЗапроса + ")|(?:" + шРазделитель + "+" + "(?:(ПОМЕСТИТЬ|INTO\s+TABLE|INTO)|(УНИЧТОЖИТЬ|DROP|DROP\s+TABLE))" + шРазделитель 
		+ "+(" + шИмяВременнойТаблицы + ")(" + шРазделитель + "|;)|(?:" + шРазделитель + "))";
	RegExp2.Pattern = ШаблонПОМЕСТИТЬИЗ;
	СозданныеТаблицы = Новый Массив;
	СозданныеТаблицыНрег = Новый Массив;
	СначалаУничтоженныеТаблицы = Новый Массив;
	Для Каждого ТекстЗапроса Из МассивТекстовЗапросов Цикл
		Результат2 = RegExp2.Execute(ТекстЗапроса);
		ИмяСозданнойВременнойТаблицы = Неопределено;
		Для Каждого Match2 Из Результат2 Цикл
			Если Не ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(Match2.SubMatches(0)) Тогда
				ИмяВременнойТаблицы = Match2.SubMatches(2);
				Если Ложь
					Или Не ТолькоТребующиеУничтоженияНаВходе 
					Или СначалаУничтоженныеТаблицы.Найти(НРег(ИмяВременнойТаблицы)) = Неопределено
				Тогда
					ИмяСозданнойВременнойТаблицы = ИмяВременнойТаблицы;
				КонецЕсли; 
				Прервать;
			ИначеЕсли Истина
				И ТолькоТребующиеУничтоженияНаВходе
				И Не ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(Match2.SubMatches(1)) 
			Тогда
				ИмяВременнойТаблицы = Нрег(Match2.SubMatches(2));
				Если СозданныеТаблицыНрег.Найти(ИмяВременнойТаблицы) = Неопределено Тогда
					СначалаУничтоженныеТаблицы.Добавить(ИмяВременнойТаблицы);
				КонецЕсли; 
				Прервать;
			КонецЕсли;
		КонецЦикла;
		СозданныеТаблицы.Добавить(ИмяСозданнойВременнойТаблицы);
		Если ИмяСозданнойВременнойТаблицы <> Неопределено Тогда
			СозданныеТаблицыНрег.Добавить(НРег(ИмяСозданнойВременнойТаблицы));
		КонецЕсли; 
	КонецЦикла;
	Возврат СозданныеТаблицы;
	
КонецФункции // ПолучитьМассивСоздаваемыхВременныхТаблицПакета()

////////////////////////////////////////////////////////////////////////////////
// РАБОТА С ТИПАМИ

// Получает чистую внутреннюю таблицу предопределенных слов.
//
// Параметры:
//  Нет.
//
// Возвращаемое значение:
//  ТаблицаЗначений – с колонками "Слово", "ТипСлова", "ТаблицаСтруктурТипов".
//
Функция ПолучитьНовуюВнутреннююТаблицуСлов()

	ВнутренняяТаблицаСлов = Новый ТаблицаЗначений;
	ВнутренняяТаблицаСлов.Колонки.Добавить("Слово");
	ВнутренняяТаблицаСлов.Колонки.Добавить("ТипСлова");
	ВнутренняяТаблицаСлов.Колонки.Добавить("ТаблицаСтруктурТипов");
	ВнутренняяТаблицаСлов.Колонки.Добавить("ТипЗначения");
	Возврат ВнутренняяТаблицаСлов;

КонецФункции // ПолучитьНовуюВнутреннююТаблицуСлов()

// Получение объекта МД с внутренним кэшированием.
Функция ПолучитьОбъектМДПоПолномуИмени(ПолноеИмя) Экспорт
	
	ОбъектМД = ОбъектыМДПоПолномуИмени[ПолноеИмя];
	Если ОбъектМД = Неопределено Тогда
		ОбъектМД = мМетаданные.НайтиПоПолномуИмени(ПолноеИмя);
		ОбъектыМДПоПолномуИмени[ПолноеИмя] = ОбъектМД;
	КонецЕсли;
	Возврат ОбъектМД;
	
КонецФункции

#Если Клиент Тогда

// Позволяет пользователю выбрать один из возможных вариантов описания слова.
//
// Параметры:
//  СтруктураЦикла – Соответствие – где ключи - имена ветвей дерева, а значения - таблицы структур типов;
//  *ВключатьПутьКОписаниюТипаЗначения - Булево, *Неопределено - признак добавления в список выбора тип значения слова.
//
// Возвращаемое значение:
//  СтрокаТаблицыЗначений, Структура - описание слова.
//
Функция ВыбратьСтрокуОписанияИзМассиваСтруктурТипов(СтруктураЦикла, ВключатьПутьКОписаниюТипаЗначения = Ложь, ФормаВладелец = Неопределено, Слово = "",
	НомерПараметраМетода = 0, БезусловнаяАктивизацияРезультатов = Истина) Экспорт

	ДеревоВыбора = Новый ДеревоЗначений;
	ДеревоВыбора.Колонки.Добавить("Ключ");
	ДеревоВыбора.Колонки.Добавить("Представление");
	ДеревоВыбора.Колонки.Добавить("ТипСлова");
	СчетчикСтрокВторогоУровня = 0;
	НачальнаяСтрокаВыбора = Неопределено;
	Для Каждого ЭлементЦикла Из СтруктураЦикла Цикл
		СтрокаЭлементаЦикла = ДеревоВыбора.Строки.Добавить();
		СтрокаЭлементаЦикла.Представление = ЭлементЦикла.Ключ;
	КонецЦикла;
	ДеревоВыбора.Строки.Сортировать("Представление");
	Для Каждого СтрокаЭлементаЦикла Из ДеревоВыбора.Строки Цикл
		Для Каждого СтруктураТипаКонтекста Из СтруктураЦикла[СтрокаЭлементаЦикла.Представление] Цикл
			//Если СтруктураТипаКонтекста.СтрокаОписания = Неопределено Тогда 
			//	Продолжить;
			//КонецЕсли;
			Если СтруктураТипаКонтекста.ИмяОбщегоТипа = "Неизвестный контекст" Тогда
				Продолжить;
			КонецЕсли;
			СтрокаОписания = СтруктураТипаКонтекста.СтрокаОписания;
			
			// Ранее среди параметров были: ПутьКСлову = "", ТекущееСлово = "",
			//// Добавим строку описания слова
			//ЭтоИмяТипа = Ложь;
			//Попытка
			//	Если СтрокаОписания.ТипЯзыка = "ИмяТипа" Тогда
			//		ЭтоИмяТипа = Истина;
			//	КонецЕсли;
			//Исключение
			//КонецПопытки;
			//
			//Если ЭтоИмяТипа Тогда
			//	
			//	Если Прав(ПутьКСлову, 1) = "(" Тогда 
			//		ЧистыйПутьКСлову = Лев(ПутьКСлову, СтрДлина(ПутьКСлову) - 1);
			//	Иначе
			//		ЧистыйПутьКСлову = ТекущееСлово;
			//	КонецЕсли;
			//	
			//	БазовыйТип = ирОбщий.ПолучитьПервыйФрагментЛкс(ЧистыйПутьКСлову);
			//	Если БазовыйТип = "" Тогда
			//		// Неизвестный контекст
			//		СтрокаОписания = Неопределено;
			//	Иначе
			//		СтрокаОписания = ТаблицаОбщихТипов.Найти(БазовыйТип, "БазовыйТип");
			//	КонецЕсли;
			//КонецЕсли;
			
			Если Истина
				И СтрокаОписания <> Неопределено
				И СтрокаЭлементаЦикла.Строки.Найти(СтрокаОписания, "Ключ") = Неопределено
				И (Ложь
					Или СтрокаОписания.Владелец().Колонки.Найти("ТипЯзыка") = Неопределено
					Или СтрокаОписания.ТипЯзыка <> "ИмяТипа")
			Тогда
				ПредставлениеТипа = СтрокаОписания.Слово;
				Если Истина
					И СтрокаОписания.Владелец().Колонки.Найти("ТипКонтекста") <> Неопределено
					И ЗначениеЗаполнено(СтрокаОписания.ТипКонтекста)
				Тогда
					ПредставлениеТипа = СтрокаОписания.ТипКонтекста + "." + ПредставлениеТипа;
				КонецЕсли;
				СтрокаДереваВыбора = СтрокаЭлементаЦикла.Строки.Добавить();
				СтрокаДереваВыбора.Ключ = СтрокаОписания;
				Попытка
					СтрокаДереваВыбора.ТипСлова = СтрокаОписания.ТипСлова;
				Исключение
					СтрокаДереваВыбора.ТипСлова = "Тип";
				КонецПопытки;
				СтрокаДереваВыбора.Представление = ПредставлениеТипа;
			КонецЕсли;
			
			Если ВключатьПутьКОписаниюТипаЗначения Тогда
				// Добавим строку описания типа значения
				СтрокаОписанияТипаЗначения = ТаблицаОбщихТипов.Найти(НРег(СтруктураТипаКонтекста.ИмяОбщегоТипа), "НСлово");
				Если СтрокаОписанияТипаЗначения <> Неопределено Тогда
					Если СтрокаЭлементаЦикла.Строки.Найти(СтрокаОписанияТипаЗначения, "Ключ") = Неопределено Тогда
						ПредставлениеТипа = СтрокаОписанияТипаЗначения.Слово;
						СтрокаДереваВыбора = СтрокаЭлементаЦикла.Строки.Добавить();
						СтрокаДереваВыбора.Ключ = СтрокаОписанияТипаЗначения;
						СтрокаДереваВыбора.ТипСлова = "Тип";
						СтрокаДереваВыбора.Представление = ПредставлениеТипа;
					КонецЕсли;
				КонецЕсли;
			КонецЕсли;
			
		КонецЦикла;
		СчетчикСтрокВторогоУровня = СчетчикСтрокВторогоУровня + СтрокаЭлементаЦикла.Строки.Количество();
		Если Истина
			И НачальнаяСтрокаВыбора = Неопределено
			И СтрокаЭлементаЦикла.Строки.Количество() > 0
		Тогда
			НачальнаяСтрокаВыбора = СтрокаЭлементаЦикла.Строки[0];
		КонецЕсли;
		СтрокаЭлементаЦикла.Строки.Сортировать("Представление");
	КонецЦикла;
	Если СчетчикСтрокВторогоУровня > 0 Тогда
		ФормаВыбора = ирОбщий.ПолучитьФормуЛкс("Обработка.ирСинтаксПомощник.Форма");
		ФормаВыбора.ДеревоТиповСлова = ДеревоВыбора;
		ФормаВыбора.ИскомоеСлово = Слово;
		ФормаВыбора.ПоискСУчетомТипаСлова = Истина;
		ФормаВыбора.НомерИскомогоПараметра = НомерПараметраМетода;
		ФормаВыбора.ВладелецФормы = ФормаВладелец;
		ФормаВыбора.ВыбратьИскомуюСтроку(НачальнаяСтрокаВыбора, БезусловнаяАктивизацияРезультатов);
		ФормаВыбора.ВладелецФормы = Неопределено;
	КонецЕсли; 
	Если Ложь
		Или СчетчикСтрокВторогоУровня = 1
		Или (Истина
			И СчетчикСтрокВторогоУровня = 2
			И ДеревоВыбора.Строки[0].Строки.Количество() = 1
			И НачальнаяСтрокаВыбора.Ключ = ДеревоВыбора.Строки[1].Строки[0].Ключ)
	Тогда 
		ВыбранныйЭлементТипа = НачальнаяСтрокаВыбора;
	ИначеЕсли СчетчикСтрокВторогоУровня > 1 Тогда
		//ФормаВыбора = ПолучитьФорму("ФормаВыбораСправкиПоСлову");
		//ФормаВыбора.ДеревоТиповСлова = ДеревоВыбора;
		//ФормаВыбора.НачальноеЗначениеВыбора = НачальнаяСтрокаВыбора;
		//ВыбранныйЭлементТипа = ФормаВыбора.ОткрытьМодально();
		ВыбранныйЭлементТипа = НачальнаяСтрокаВыбора;
	Иначе
		ВыбранныйЭлементТипа = Неопределено;
	КонецЕсли;
	Если ВыбранныйЭлементТипа = Неопределено Тогда
		СтрокаОписания = Неопределено;
	Иначе
		СтрокаОписания = ВыбранныйЭлементТипа.Ключ;
	КонецЕсли;
	
	Возврат СтрокаОписания;

КонецФункции // ВыбратьСтрокуОписанияИзМассиваСтруктурТипов()

#КонецЕсли

// Формирует построитель запроса по структуре типа.
//
// Параметры:
//  СтруктураТипа – Структура - описатель типа.
//
// Возвращаемое значение:
//   ПостроительЗапроса.
//
Функция ПолучитьПостроительЗапросаПоСтруктуреТипа(СтрокаОбщегоТипа, ВиртуальнаяТаблица = Неопределено)

	МетаданныеРодителя = СтрокаОбщегоТипа.Метаданные;
	ТипМетаданныхРодителя = ТипЗнч(МетаданныеРодителя);
	Если ТипМетаданныхРодителя = Тип("ОбъектМетаданных") Тогда
		ПолноеИмя = МетаданныеРодителя.ПолноеИмя();
	Иначе
		ПолноеИмя = ирОбщий.ПолучитьКорневойТипКонфигурацииЛкс(КэшОбъект(МетаданныеРодителя).ПолноеИмя);
	КонецЕсли; 
	МассивФрагментов = ирОбщий.ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмя);
	КорневойТипРодителя = МассивФрагментов[0];
	ПостроительЗапроса = Новый ПостроительЗапроса;
	Если ПолучитьСтрокуТипаМетаОбъектов(КорневойТипРодителя, , 0) <> Неопределено Тогда
		Если Ложь
			Или (Истина
				И МассивФрагментов.Количество() = 2
				И МассивФрагментов[0] <> "ВнешнийИсточникДанных")
			Или (Истина
				И МассивФрагментов.Количество() = 4
				И МассивФрагментов[2] = "ТабличнаяЧасть")
		Тогда
			Если ТипМетаданныхРодителя = Тип("ОбъектМетаданных") Тогда
				//Если КорневойТипРодителя = "Константа" Тогда
				Если СтрокаОбщегоТипа.ИмяОбщегоТипа = "Константы.<Имя константы>" Тогда
					ОпределениеТаблицы = "ВЫБРАТЬ Константы." + МассивФрагментов[1];
				Иначе
					//ИмяТаблицы = КорневойТипРодителя + "." + МассивФрагментов[1];
					//Если МассивФрагментов.Количество() > 2 Тогда
					//	ИмяТаблицы = ИмяТаблицы + "." + МассивФрагментов[3];
					//КонецЕсли;
					ИмяТаблицы = ирОбщий.ПолучитьИмяТаблицыИзМетаданныхЛкс(ПолноеИмя, Ложь, ВиртуальнаяТаблица = Неопределено); // Добавлено 14.04.2012
					
					УникальноеИмяТаблицы = "______________________";
					ОпределениеТаблицы = "ВЫБРАТЬ * ИЗ " + ИмяТаблицы ;
					Если ВиртуальнаяТаблица <> Неопределено Тогда
						ОпределениеТаблицы = ОпределениеТаблицы + ВиртуальнаяТаблица.Выражение;
					КонецЕсли; 
					ОпределениеТаблицы = ОпределениеТаблицы + " КАК " + УникальноеИмяТаблицы;
				КонецЕсли;
				Попытка
					// Тормоз
					ПостроительЗапроса.Текст = ОпределениеТаблицы;
				Исключение
					Успех = Ложь;
					Если ВиртуальнаяТаблица <> Неопределено Тогда
						ПозицияСкобки = Найти(ВиртуальнаяТаблица.Выражение, "(");
						Если ПозицияСкобки > 0 Тогда
							ОпределениеТаблицы = "ВЫБРАТЬ * ИЗ " + ИмяТаблицы ;
							ОпределениеТаблицы = ОпределениеТаблицы + Лев(ВиртуальнаяТаблица.Выражение, ПозицияСкобки - 1);
							ОпределениеТаблицы = ОпределениеТаблицы + " КАК " + УникальноеИмяТаблицы;
							Попытка
								ПостроительЗапроса.Текст = ОпределениеТаблицы;
								Успех = Истина;
							Исключение
							КонецПопытки; 
						КонецЕсли; 
					КонецЕсли; 
					Если Не Успех Тогда
						ВызватьИсключение "ОшибкаВычисленияВиртуальнойТаблицы";
					КонецЕсли; 
				КонецПопытки;
				// Тормоз
				ПостроительЗапроса.ЗаполнитьНастройки();
			Иначе
				ЗапросРеквизитов = Новый Запрос("ВЫБРАТЬ Имя, ТипыСтрокой ИЗ Справочник.СвойстваМетаданных ГДЕ Владелец = &СсылкаМД");
				ЗапросРеквизитов.УстановитьПараметр("СсылкаМД", МетаданныеРодителя);
				ТаблицаРеквизитов = ЗапросРеквизитов.Выполнить().Выгрузить();
				Для Каждого СтрокаРеквизита Из ТаблицаРеквизитов Цикл
					ДоступноеПоле = ПостроительЗапроса.ДоступныеПоля.Добавить(СтрокаРеквизита.Имя);
					Для Каждого СтрокаТипа Из СтрокаРеквизита.Типы Цикл
						МассивТипов = Новый Массив;
						ОбъектМД = КэшОбъект(СтрокаТипа.Объект);
						МассивТипов.Добавить(Тип(ОбъектМД.Наименование));
					КонецЦикла; 
					ДоступноеПоле.ТипЗначения = Новый ОписаниеТипов(МассивТипов);
				КонецЦикла;
			КонецЕсли;
		КонецЕсли;
	КонецЕсли; 

	Возврат ПостроительЗапроса;

КонецФункции // ПолучитьПостроительЗапросаПоСтруктуреТипа()

// Получает массив общих типов, дополняя исходный тип расширениями.
//
// Параметры:
//  СтруктураТипа – Структура.
//
// Возвращаемое значение:
//  Массив - структур типа.
//
Функция ПолучитьТаблицуОбщихТиповСтруктурыТипа(СтруктураТипа) Экспорт 

	МассивОбщихТипов = ПолучитьНовуюТаблицуДополнительныхТипов();
	ЗаполнитьЗначенияСвойств(МассивОбщихТипов.Добавить(), СтруктураТипа);
	Если Найти(СтруктураТипа.ИмяОбщегоТипа, "ТабличнаяЧасть.") > 0 Тогда
		НоваяСтрока = МассивОбщихТипов.Добавить();
		ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа);
		НоваяСтрока.ИмяОбщегоТипа = "Табличная часть";
	ИначеЕсли Найти(СтруктураТипа.ИмяОбщегоТипа, "ТабличнаяЧастьСтрока.") > 0 Тогда
		НоваяСтрока = МассивОбщихТипов.Добавить();
		ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа);
		НоваяСтрока.ИмяОбщегоТипа = "Строка табличной части";
	ИначеЕсли СтруктураТипа.ИмяОбщегоТипа = "ПолеТекстовогоДокумента" Тогда
		НоваяСтрока = МассивОбщихТипов.Добавить();
		ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа);
		НоваяСтрока.ИмяОбщегоТипа = "ТекстовыйДокумент";
	ИначеЕсли СтруктураТипа.ИмяОбщегоТипа = "ПолеГрафическойСхемы" Тогда
		НоваяСтрока = МассивОбщихТипов.Добавить();
		ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа);
		НоваяСтрока.ИмяОбщегоТипа = "ГрафическаяСхема";
	ИначеЕсли СтруктураТипа.ИмяОбщегоТипа = "ПолеТабличногоДокумента" Тогда
		НоваяСтрока = МассивОбщихТипов.Добавить();
		ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа);
		НоваяСтрока.ИмяОбщегоТипа = "ТабличныйДокумент";
	//ИначеЕсли Найти(СтруктураТипа.ИмяОбщегоТипа, "Расширение формы") > 0 Тогда
	//	НоваяСтрока = МассивОбщихТипов.Добавить();
	//	ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа);
	//	НоваяСтрока.ИмяОбщегоТипа = "Форма";
	ИначеЕсли СтруктураТипа.ИмяОбщегоТипа = "Локальный контекст" Тогда
		Если ТипЗнч(СтруктураТипа.Метаданные) <> Тип("COMОбъект") Тогда // 31.07.2013
			НоваяСтрока = МассивОбщихТипов.Добавить();
			ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа);
			НоваяСтрока.ИмяОбщегоТипа = "Глобальный контекст";
			НоваяСтрока = МассивОбщихТипов.Добавить();
			ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа);
			НоваяСтрока.ИмяОбщегоТипа = "Общее";
		КонецЕсли; 
	ИначеЕсли СтруктураТипа.ИмяОбщегоТипа = "Automation сервер" Тогда
		НоваяСтрока = МассивОбщихТипов.Добавить();
		ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа);
		НоваяСтрока.ИмяОбщегоТипа = "Глобальный контекст";
	ИначеЕсли СтруктураТипа.ИмяОбщегоТипа = "COM-соединитель" Тогда
		НоваяСтрока = МассивОбщихТипов.Добавить();
		ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа);
		НоваяСтрока.ИмяОбщегоТипа = "Глобальный контекст";
	Иначе
		ОбщийТипМетаданных = ирОбщий.ПолучитьСтрокуМеждуМаркерамиЛкс(СтруктураТипа.ИмяОбщегоТипа, , ": ", Ложь);
		//Если ОбщийТипМетаданных <> "" Тогда
		Если ЗначениеЗаполнено(ОбщийТипМетаданных) Тогда
			НоваяСтрока = МассивОбщихТипов.Добавить();
			ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа);
			НоваяСтрока.ИмяОбщегоТипа = ОбщийТипМетаданных;
		КонецЕсли;
	КонецЕсли;
	
	// Расширения, образованные элементом управления и типом связанных с ним данных
	СтрокаРасширения = ТаблицаРасширенийТипов.Найти(СтруктураТипа.ИмяОбщегоТипа, "Расширение");
	Если СтрокаРасширения <> Неопределено Тогда
		Если Истина
			И СтрокаРасширения.ОсновнойТип = "Форма"
			И СтруктураТипа.ДополнительныеТипы = Неопределено
		Тогда
			НоваяСтрока = МассивОбщихТипов.Добавить();
			ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа);
			НоваяСтрока.ИмяОбщегоТипа = СтрокаРасширения.РасширяющийТип;
			//НоваяСтрока.НеВключатьМетоды = Истина; // Закомментировал 30.09.2010
			#Если Клиент Тогда
				Если ТипЗнч(СтруктураТипа.Метаданные) = Тип("Форма") Тогда
					ОсновнойРеквизитФормы = ПолучитьИмяОсновногоРеквизитаФормы(СтруктураТипа.Метаданные);
					НоваяСтрока.Метаданные = ирОбщий.ПолучитьМетаданныеЛкс(СтруктураТипа.Метаданные[ОсновнойРеквизитФормы]);
				КонецЕсли;
			#КонецЕсли 
		КонецЕсли;
		НоваяСтрока = МассивОбщихТипов.Добавить();
		ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа);
		НоваяСтрока.ИмяОбщегоТипа = СтрокаРасширения.ОсновнойТип;
	КонецЕсли;
	
	// Общие расширения элементов управления
	лИмяОбщегоТипа = МассивОбщихТипов[МассивОбщихТипов.Количество() - 1].ИмяОбщегоТипа;
	Если Ложь
		Или МассивОбычныхЭлементовУправления.Найти(лИмяОбщегоТипа) <> Неопределено
		Или МассивУправляемыхЭлементовУправления.Найти(лИмяОбщегоТипа) <> Неопределено
	Тогда
		НоваяСтрока = МассивОбщихТипов.Добавить();
		ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа);
		НоваяСтрока.ИмяОбщегоТипа = "Расширение элементов управления, расположенных в форме";
		НоваяСтрока = МассивОбщихТипов.Добавить();
		ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа);
		// Эту синтаксическую ошибку исправили только в 13-м релизе.
		//НоваяСтрока.ИмяОбщегоТипа = "Расширение элементов управления, расположенных на панели";
		НоваяСтрока.ИмяОбщегоТипа = "Расширение элементов управления расположенных на панели";
	КонецЕсли;

	Если СтруктураТипа.ДополнительныеТипы <> Неопределено Тогда
		ирОбщий.ЗагрузитьВТаблицуЗначенийЛкс(СтруктураТипа.ДополнительныеТипы, МассивОбщихТипов);
	КонецЕсли;
	Возврат МассивОбщихТипов;

КонецФункции // ПолучитьТаблицуОбщихТиповСтруктурыТипа()

// Получает внутреннюю таблицу метаданных слов заданного родительского типа.
//
// Параметры:
//  РодительскаяСтруктураТипа – Структура;
//  *Слово       – Строка, *Неопределено – для отбора;
//  *ТипСлова    – Строка, *Неопределено – для отбора;
//  *ВиртуальнаяТаблица - Структура, *Неопределено - описание виртуальной таблицы;
//  *ЯзыкПрограммы - *Число, 0;
//  *ТекущийИндекс - Строка - выражение в квадратных скобках.
//
// Возвращаемое значение:
//  ТаблицаЗначений – с колонками "Слово", "ТипСлова", "ТаблицаСтруктурТипов".
//
Функция ПолучитьВнутреннююТаблицуМетаданныхСлов(РодительскаяСтруктураТипа, Слово = Неопределено, ТипСлова = Неопределено,
	ВиртуальнаяТаблица = Неопределено, ЯзыкПрограммы = 0, ТекущийИндекс = Неопределено, ВнешниеФункцииКомпоновкиДанных = Истина, ВычислятьТипы = Истина) Экспорт 
	
	ВнутренняяТаблицаСлов = ПолучитьНовуюВнутреннююТаблицуСлов();
	ЭтоМетаданныеТабличнойЧастиВнешнейОбработки = ирОбщий.ПолучитьПервыйФрагментЛкс("" + РодительскаяСтруктураТипа.Метаданные) = "ВнешняяОбработкаТабличнаяЧасть";
	Если Не ЭтоМетаданныеТабличнойЧастиВнешнейОбработки Тогда
		КонкретныйТип = ПолучитьСтрокуКонкретногоТипа(РодительскаяСтруктураТипа);
		Если Найти(КонкретныйТип, "<") > 0 Тогда
			// Такой конкретный тип не разрешен
			Возврат ВнутренняяТаблицаСлов;
		КонецЕсли;
	КонецЕсли; 
	
	ТаблицуОбщихТиповСтруктурыТипа = ПолучитьТаблицуОбщихТиповСтруктурыТипа(РодительскаяСтруктураТипа);
	
	Если Истина
		И Слово <> Неопределено
		И ТекущийИндекс <> Неопределено
	Тогда
		RegExp.Global = Ложь;
		RegExp.Pattern = "^""(" + шИмя + ")""$";
		РезультатСтроковойКонстанты = RegExp.Execute(Слово);
		Если РезультатСтроковойКонстанты.Count > 0 Тогда
			Слово = РезультатСтроковойКонстанты.Item(0).SubMatches(0);
		КонецЕсли;
		RegExp.Pattern = "^(" + шИмя + ")$";
		ЛиСловоИдентификатор = RegExp.Test(Слово);
		Если Не ЛиСловоИдентификатор Тогда
			// Это элемент универсальной коллекции
			СтруктураКлюча = Новый Структура("Слово, ЯзыкПрограммы",
				РодительскаяСтруктураТипа.ИмяОбщегоТипа, ЯзыкПрограммы);
			НайденныеСтроки = ТаблицаОбщихТипов.НайтиСтроки(СтруктураКлюча);
			Если НайденныеСтроки.Количество() > 0 Тогда
				СтруктураКлюча = Новый Структура("БазовыйТип, ЯзыкПрограммы", НайденныеСтроки[0].ТипЭлементаКоллекции, ЯзыкПрограммы);
				НайденныеСтроки = ТаблицаОбщихТипов.НайтиСтроки(СтруктураКлюча);
				Если НайденныеСтроки.Количество() > 0 Тогда
					СтрокаТипа = НайденныеСтроки[0];
					СтруктураТипа = ПолучитьНовуюСтруктуруТипа();
					СтруктураТипа.СтрокаОписания = СтрокаТипа;
					СтруктураТипа.ИмяОбщегоТипа  = СтрокаТипа.Слово;
					СтруктураТипа.Метаданные = РодительскаяСтруктураТипа.Метаданные;
					ТаблицаСтруктурТипов = ПолучитьНовуюТаблицуСтруктурТипа();
					ДобавитьВТаблицуСтруктурТипов(ТаблицаСтруктурТипов, СтруктураТипа);
					ДобавитьВТаблицуСлов(ВнутренняяТаблицаСлов, СтрокаТипа.Слово, "Свойство", ТаблицаСтруктурТипов);
				КонецЕсли;
			КонецЕсли;
			Возврат ВнутренняяТаблицаСлов;
		КонецЕсли;
	КонецЕсли;
		
	Для Каждого СтрокаОбщегоТипа Из ТаблицуОбщихТиповСтруктурыТипа Цикл
        ИмяОбщегоТипа = СтрокаОбщегоТипа.ИмяОбщегоТипа;
		Если ирОбщий.СтрокиРавныЛкс(СтрокаОбщегоТипа.ИмяОбщегоТипа, "COMОбъект.{WbemScripting.SwbemLocator}.ISWbemObject") Тогда
			Если ТипЗнч(СтрокаОбщегоТипа.Метаданные) = Тип("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")
			Тогда
				//СхемаКоллекции = МетаданныеРодителя.ОбъектВладелец[МетаданныеРодителя.Имя].Свойства(); // Исправлено 31.07.2012
				СхемаКоллекции = МетаданныеРодителя.Тип.Свойства;
			#Если Клиент Тогда
			ИначеЕсли Истина
				И СтрокаОписанияВида.ИмяКоллекции = "Реквизиты" 
				И ТипЗнч(МетаданныеРодителя) = Тип("Форма")
			Тогда
				МассивИмен = ПолучитьМассивИменРеквизитовФормы(МетаданныеРодителя);
				КоллекцияЗначений = Новый Структура;
				Для Каждого ИмяРеквизита Из МассивИмен Цикл
					КоллекцияЗначений.Вставить(ИмяРеквизита, МетаданныеРодителя[ИмяРеквизита]);
				КонецЦикла;
			ИначеЕсли Ложь
				Или (Истина
					И СтрокаОписанияВида.ИмяКоллекции = "ЭлементыФормы" 
					И ТипЗнч(МетаданныеРодителя) = Тип("Форма"))
				Или (Истина
					И СтрокаОписанияВида.ИмяКоллекции = "ВсеЭлементыФормы" 
					И ТипЗнч(МетаданныеРодителя) = Тип("УправляемаяФорма"))
				Или (Истина
					И СтрокаОписанияВида.ИмяКоллекции = "Страницы" 
					И ТипЗнч(МетаданныеРодителя) = Тип("Панель"))
				Или (Истина
					И СтрокаОписанияВида.ИмяКоллекции = "Кнопки" 
					И (Ложь
						Или ТипЗнч(МетаданныеРодителя) = Тип("КнопкаКоманднойПанели")
						Или ТипЗнч(МетаданныеРодителя) = Тип("КнопкиКоманднойПанели")))
			Тогда
				КоллекцияЗначений = МетаданныеРодителя[СтрокаОписанияВида.ИмяКоллекции];
			#КонецЕсли 
			//ИначеЕсли СтрокаОписанияВида.ИмяКоллекции = "Оформление" Тогда
			//	Для Каждого МетаОбщийМодуль Из МетаданныеРодителя[СтрокаОписанияВида.ИмяКоллекции] Цикл
			//		Если МетаОбщийМодуль.Глобальный Тогда
			//			Продолжить;
			//		КонецЕсли;
			//		СхемаКоллекции.Вставить(МетаОбщийМодуль.Имя);
			//	КонецЦикла;
			ИначеЕсли Истина
				И СтрокаОписанияВида.ИмяКоллекции = "ОбщиеМодули"
				И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданныхКонфигурация") //
			Тогда
				КоллекцияЗначений = Новый Структура();
				Для Каждого МетаОбщийМодуль Из МетаданныеРодителя[СтрокаОписанияВида.ИмяКоллекции] Цикл
					Если МетаОбщийМодуль.Глобальный Тогда
						Продолжить;
					КонецЕсли;
					Если ирОбщий.СтрокиРавныЛкс(МетаОбщийМодуль.Имя, Слово) Тогда
						Попытка
							ОбщийМодуль = Вычислить(МетаОбщийМодуль.Имя);
						Исключение
							ОбщийМодуль = Неопределено;
						КонецПопытки; 
					Иначе
						// В больших или содержащих ошибки конфигурациях компиляция неглобальных общих модулей неудобна
						//Попытка
						//	ОбщийМодуль = Вычислить(МетаОбщийМодуль.Имя);
						//Исключение
						//	ОбщийМодуль = Неопределено;
						//КонецПопытки; 
						//КоллекцияЗначений.Вставить(МетаОбщийМодуль.Имя, ОбщийМодуль);
						//
						Попытка
							Выполнить("Если Ложь Тогда "  + МетаОбщийМодуль.Имя + ".Й() КонецЕсли");
							ОбщийМодуль = Неопределено;
						Исключение
							Продолжить;
						КонецПопытки;
					КонецЕсли; 
					КоллекцияЗначений.Вставить(МетаОбщийМодуль.Имя, ОбщийМодуль);
				КонецЦикла;
			ИначеЕсли Истина
				И СтрокаОписанияВида.ИмяКоллекции = "ВидыСубконто"
				И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных")  //
			Тогда
				Для Счетчик = 1 По МетаданныеРодителя.ПланСчетов.МаксКоличествоСубконто Цикл
					СхемаКоллекции.Вставить(Строка(Счетчик), МетаданныеРодителя.ПланСчетов.ВидыСубконто);
				КонецЦикла;
			ИначеЕсли СтрокаОписанияВида.ИмяКоллекции = "Движения" Тогда
				Если ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") Тогда
					Для Каждого Движение Из МетаданныеРодителя[СтрокаОписанияВида.ИмяКоллекции] Цикл
						МассивФрагментов = ирОбщий.ПолучитьМассивИзСтрокиСРазделителемЛкс(Движение.ПолноеИмя());
						СхемаКоллекции.Вставить(Движение.Имя, 
							Новый ОписаниеТипов(МассивФрагментов[0] + "НаборЗаписей." + МассивФрагментов[1]));
					КонецЦикла;
				ИначеЕсли Истина
					И Слово <> Неопределено
					И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданныхКонфигурация") //
				Тогда 
					МетаданныеРегистра = Метаданные.РегистрыСведений.Найти(Слово);
					Если МетаданныеРегистра = Неопределено Тогда
						МетаданныеРегистра = Метаданные.РегистрыНакопления.Найти(Слово);
					КонецЕсли;  
					Если МетаданныеРегистра = Неопределено Тогда
						МетаданныеРегистра = Метаданные.РегистрыБухгалтерии.Найти(Слово);
					КонецЕсли;  
					Если МетаданныеРегистра = Неопределено Тогда
						МетаданныеРегистра = Метаданные.РегистрыРасчета.Найти(Слово);
					КонецЕсли;  
					Если МетаданныеРегистра <> Неопределено Тогда
						МассивФрагментов = ирОбщий.ПолучитьМассивИзСтрокиСРазделителемЛкс(МетаданныеРегистра.ПолноеИмя());
						СхемаКоллекции.Вставить(МассивФрагментов[1], 
							Новый ОписаниеТипов(МассивФрагментов[0] + "НаборЗаписей." + МассивФрагментов[1]));
					КонецЕсли;  
				КонецЕсли;
			ИначеЕсли Истина
				И СтрокаОписанияВида.ИмяКоллекции = "ТочкиМаршрута"
				И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных")
			Тогда
				КоллекцияЗначений = ирОбщий.ПолучитьМенеджерЛкс(МетаданныеРодителя)[СтрокаОписанияВида.ИмяКоллекции];
			ИначеЕсли Истина
				И СтрокаОписанияВида.ИмяКоллекции = "<Имя коллекции метаданных>"
				И (Ложь
					Или ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных")
					Или ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданныхКонфигурация"))
			Тогда
				ИмяКоллекцииОбъектовМетаданных = ирОбщий.ПолучитьСтрокуМеждуМаркерамиЛкс(ИмяОбщегоТипа,
					МаркерКоллекцииОбъектовМетаданных + ": ", , Ложь);
				Если ЗначениеЗаполнено(ИмяКоллекцииОбъектовМетаданных) Тогда
					СтрокаКорневогоТипа = ПолучитьСтрокуТипаМетаОбъектов(, ИмяКоллекцииОбъектовМетаданных);
					Если СтрокаКорневогоТипа <> Неопределено Тогда
						//КоллекцияЗначений = МетаданныеРодителя[ИмяКоллекцииОбъектовМетаданных];
						Попытка
							КоллекцияЗначений = МетаданныеРодителя[РодительскаяСтруктураТипа.СтрокаОписания.Слово];
						Исключение
							ИнформацияОбОшибке = ИнформацияОбОшибке(); // Для отладки
						КонецПопытки;
					КонецЕсли;
				Иначе 
					КоллекцияЗначений = МетаданныеРодителя;
				КонецЕсли;
			ИначеЕсли Истина
				//И СтрокаОписанияВида.ИмяКоллекции = "<Имя коллекции метаданных>"
				И Это2iS
				И (Ложь
					Или ТипЗнч(МетаданныеРодителя) = Тип("СправочникСсылка.КонфигурацииМетаданных2iS")
					Или ТипЗнч(МетаданныеРодителя) = Тип("СправочникСсылка.ОбъектыМетаданных2iS"))
			Тогда
				Если СтрокаОписанияВида.ИмяКоллекции = "<Имя коллекции метаданных>" Тогда 
					ИмяКоллекцииОбъектовМетаданных = ирОбщий.ПолучитьСтрокуМеждуМаркерамиЛкс(ИмяОбщегоТипа,
						МаркерКоллекцииОбъектовМетаданных + ": ", , Ложь);
				Иначе
					ИмяКоллекцииОбъектовМетаданных = СтрокаОписанияВида.ИмяКоллекции;
				КонецЕсли;
				Если ЗначениеЗаполнено(ИмяКоллекцииОбъектовМетаданных) Тогда
					СтрокаКорневогоТипа = ПолучитьСтрокуТипаМетаОбъектов(, ИмяКоллекцииОбъектовМетаданных);
					Запрос = Новый Запрос;
					Если СтрокаКорневогоТипа <> Неопределено Тогда
						//лИмяКоллекции = РодительскаяСтруктураТипа.СтрокаОписания.Слово;
						Если ИмяКоллекцииОбъектовМетаданных = "Реквизиты" Тогда
							ТекстЗапроса = "ВЫБРАТЬ Наименование КАК Имя, Типы Как Значение ИЗ Справочник.СвойстваМетаданных2iS 
							|ГДЕ Владелец = &Владелец И Вид <> ЗНАЧЕНИЕ(Перечисление.ВидыСвойств.Свойство)";
							Запрос.Текст = ТекстЗапроса;
							Запрос.УстановитьПараметр("Владелец", МетаданныеРодителя);
							Выборка = Запрос.Выполнить().Выбрать();
							Пока Выборка.Следующий() Цикл
								СхемаКоллекции[Выборка.Имя] = Выборка.Значение.Выгрузить().ВыгрузитьКолонку("Тип");
							КонецЦикла;
						Иначе
							ТекстЗапроса = "ВЫБРАТЬ Имя, Ссылка КАК Значение ИЗ Справочник.ОбъектыМетаданных2iS 
							|ГДЕ Владелец = &Владелец И Родитель.Наименование = &ИмяРодителя";
							Запрос.УстановитьПараметр("ИмяРодителя", ИмяКоллекцииОбъектовМетаданных);
							Запрос.Текст = ТекстЗапроса;
							Запрос.УстановитьПараметр("Владелец", МетаданныеРодителя);
							Выборка = Запрос.Выполнить().Выбрать();
							Пока Выборка.Следующий() Цикл
								СхемаКоллекции[Выборка.Имя] = Выборка.Значение;
							КонецЦикла;
						КонецЕсли;
					КонецЕсли;
				Иначе
					//КоллекцияЗначений = МетаданныеРодителя;
				КонецЕсли;
			ИначеЕсли Истина
				//И СтрокаОписанияВида.ИмяКоллекции = "<Имя коллекции метаданных>"
				И ЭтоИнтеграция
				И (Ложь
					Или ТипЗнч(МетаданныеРодителя) = Тип("СправочникСсылка.КонфигурацииМетаданныхИис")
					Или ТипЗнч(МетаданныеРодителя) = Тип("СправочникСсылка.МетаданныеИис"))
			Тогда
				Если СтрокаОписанияВида.ИмяКоллекции = "<Имя коллекции метаданных>" Тогда 
					ИмяКоллекцииОбъектовМетаданных = ирОбщий.ПолучитьСтрокуМеждуМаркерамиЛкс(ИмяОбщегоТипа,
						МаркерКоллекцииОбъектовМетаданных + ": ", , Ложь);
				Иначе
					ИмяКоллекцииОбъектовМетаданных = СтрокаОписанияВида.ИмяКоллекции;
				КонецЕсли;
				Если ЗначениеЗаполнено(ИмяКоллекцииОбъектовМетаданных) Тогда
					СтрокаКорневогоТипа = ПолучитьСтрокуТипаМетаОбъектов(, ИмяКоллекцииОбъектовМетаданных);
					Запрос = Новый Запрос;
					Если СтрокаКорневогоТипа <> Неопределено Тогда
						//лИмяКоллекции = РодительскаяСтруктураТипа.СтрокаОписания.Слово;
						Если ИмяКоллекцииОбъектовМетаданных = "Реквизиты" Тогда
							ТекстЗапроса = "ВЫБРАТЬ Наименование КАК Имя, Типы Как Значение ИЗ Справочник.СвойстваМетаданныхИис 
							|ГДЕ КонфигурацияМетаданных = &Владелец И Вид <> ЗНАЧЕНИЕ(Перечисление.ВидыСвойствМетаданныхИис.Свойство)";
							Запрос.Текст = ТекстЗапроса;
							Запрос.УстановитьПараметр("Владелец", МетаданныеРодителя);
							Выборка = Запрос.Выполнить().Выбрать();
							Пока Выборка.Следующий() Цикл
								СхемаКоллекции[Выборка.Имя] = Выборка.Значение.Выгрузить().ВыгрузитьКолонку("Тип");
							КонецЦикла;
						Иначе
							ТекстЗапроса = "ВЫБРАТЬ Имя, Ссылка КАК Значение ИЗ Справочник.МетаданныеИис 
							|ГДЕ КонфигурацияМетаданных = &Владелец И ТипМетаданных.ИмяМножественное = &ИмяРодителя";
							Запрос.УстановитьПараметр("ИмяРодителя", ИмяКоллекцииОбъектовМетаданных);
							Запрос.Текст = ТекстЗапроса;
							Запрос.УстановитьПараметр("Владелец", МетаданныеРодителя);
							Выборка = Запрос.Выполнить().Выбрать();
							Пока Выборка.Следующий() Цикл
								СхемаКоллекции[Выборка.Имя] = Выборка.Значение;
							КонецЦикла;
						КонецЕсли;
					КонецЕсли;
				Иначе
					//КоллекцияЗначений = МетаданныеРодителя;
				КонецЕсли;
			Иначе
				Если МассивИсключенийИменКоллекций.НайтиПоЗначению(СтрокаОписанияВида.ИмяКоллекции) <> Неопределено Тогда 
					Продолжить;
				КонецЕсли;
				Попытка
					СхемаКоллекции = МетаданныеРодителя[СтрокаОписанияВида.ИмяКоллекции];
				Исключение
					Продолжить;
				КонецПопытки;
			КонецЕсли;
			
			Если КоллекцияЗначений = Неопределено Тогда
				КоллекцияЗначений = СхемаКоллекции;
				Если Слово <> Неопределено Тогда 
					ЭлементСхемы = Неопределено;
					Если Ложь
						Или ТипЗнч(КоллекцияЗначений) = Тип("Структура")
						Или ТипЗнч(КоллекцияЗначений) = Тип("Соответствие")
					Тогда
						Для Каждого ЭлементКоллекции Из КоллекцияЗначений Цикл
							Если ЭлементКоллекции.Ключ = ИмяТекущегоСлова Тогда
								ЭлементСхемы = ЭлементКоллекции.Значение;
								Прервать;
							КонецЕсли;
						КонецЦикла;
					Иначе
						Попытка
							ЭлементСхемы = КоллекцияЗначений.Найти(ИмяТекущегоСлова);
						Исключение КонецПопытки;
						Если ЭлементСхемы = Неопределено Тогда
							Для Каждого ЭлементКоллекции Из КоллекцияЗначений Цикл
								Если ЭлементКоллекции.Имя = ИмяТекущегоСлова Тогда
									ЭлементСхемы = ЭлементКоллекции;
									Прервать;
								КонецЕсли;
							КонецЦикла;
						КонецЕсли;
					КонецЕсли;
					КоллекцияЗначений = Новый Соответствие;
					Если ЭлементСхемы <> Неопределено Тогда
						КоллекцияЗначений.Вставить(ИмяТекущегоСлова, ЭлементСхемы); 
					КонецЕсли;
				КонецЕсли;
			Иначе
				Если Слово <> Неопределено Тогда
					Попытка
						ЭлементСхемы = КоллекцияЗначений[ИмяТекущегоСлова];
					Исключение
					КонецПопытки;
					КоллекцияЗначений = Новый Соответствие;
					Если ЭлементСхемы <> Неопределено Тогда
						КоллекцияЗначений.Вставить(ИмяТекущегоСлова, ЭлементСхемы); 
					КонецЕсли;
				КонецЕсли;
			КонецЕсли;
			
			Если КоллекцияЗначений = Неопределено Тогда
				КоллекцияЗначений = Новый Массив();
			КонецЕсли; 
			
			Для Каждого ЭлементКоллекции Из КоллекцияЗначений Цикл
				Если ТипЗнч(ЭлементКоллекции) = Тип("КлючИЗначение") Тогда 
					ИмяСвойства = ЭлементКоллекции.Ключ;
					ЗначениеСвойства = ЭлементКоллекции.Значение;
				Иначе 
					ИмяСвойства = ЭлементКоллекции.Имя;
					ЗначениеСвойства = ЭлементКоллекции;
				КонецЕсли;
				КонечноеСлово = СтрЗаменить(СтрокаВида.Слово, ИмяЭлементаКоллекции, ИмяСвойства);
				ТаблицаСтруктурТипов = Неопределено;
				Если ВычислятьТипы Тогда
					ТаблицаСтруктурТипов = ПолучитьНовуюТаблицуСтруктурТипа();
					МассивТипов = Новый Массив;
					ОписаниеТиповЗначения = Неопределено;
					Если СхемаКоллекции.Количество() > 0 Тогда
						Если Ложь
							Или СтрокаВида.ТипЗначения = "Произвольный"
							Или СтрокаВида.ТипЗначения = "Набор записей регистра"
							Или Найти(СтрокаВида.ТипЗначения, "<") > 0
						Тогда 
							Если ТипЗнч(ЗначениеСвойства) = Тип("ОписаниеТипов") Тогда
								ОписаниеТиповЗначения = ЗначениеСвойства;
							КонецЕсли;
							Если Истина
								И ЯзыкПрограммы = 1
								И РодительскаяСтруктураТипа.ТипЯзыка <> "ЗначениеВЗапросе"
								И КорневойТипРодителя <> Неопределено
								И КорневойТипРодителя <> "ВнешнийИсточникДанных"
							Тогда 
								ДоступноеПолеСлова = ПостроительЗапросаРодителя.ДоступныеПоля.Найти(КонечноеСлово);
								Если ДоступноеПолеСлова = Неопределено Тогда
									Продолжить;
								КонецЕсли;
								Если ДоступноеПолеСлова.ТипЗначения <> Новый ОписаниеТипов("ТаблицаЗначений") Тогда
									ОписаниеТиповЗначения = ДоступноеПолеСлова.ТипЗначения;
								КонецЕсли; 
							КонецЕсли;
							Если Истина 
								И ОписаниеТиповЗначения = Неопределено
								И СтрокаОписанияВида.ИмяКоллекции <> "КритерииОтбора"
								И СтрокаОписанияВида.ИмяКоллекции <> "ПланыВидовХарактеристик"
								И ИмяОбщегоТипа <> "Константа"
							Тогда
								Попытка 
									ОписаниеТиповЗначения = ЗначениеСвойства.Тип;
								Исключение
								КонецПопытки;
								Если ТипЗнч(ОписаниеТиповЗначения) <> Тип("ОписаниеТипов") Тогда
									ОписаниеТиповЗначения = Неопределено;
								КонецЕсли;
							КонецЕсли;
							Если ТипЗнч(ОписаниеТиповЗначения) = Тип("ОписаниеТипов") Тогда
								МассивТипов = ОписаниеТиповЗначения.Типы();
							ИначеЕсли ТипЗнч(ЗначениеСвойства) = Тип("Массив") Тогда
								МассивТипов = ЗначениеСвойства;
							КонецЕсли;
						КонецЕсли;
					Иначе
						МассивТипов = ирОбщий.БыстрыйМассивЛкс(ТипЗнч(ЗначениеСвойства));
					КонецЕсли;
					Если Истина
						//И ОписаниеТиповЗначения <> Неопределено
						И МассивТипов.Количество() > 0
						И СтрокаОписанияВида.ИмяКоллекции <> "<Имя коллекции метаданных>"
						И (Ложь
							Или СтрокаОписанияВида.ИмяКоллекции <> "Константы"
							Или ЯзыкПрограммы = 1)
					Тогда
						ШаблонСтруктурыТипа = Новый Структура("СтрокаОписания, ТипЯзыка, Метаданные, ДержательМетаданных");
						ШаблонСтруктурыТипа.СтрокаОписания = СтрокаВида;
						ШаблонСтруктурыТипа.ТипЯзыка = РодительскаяСтруктураТипа.ТипЯзыка;
						ШаблонСтруктурыТипа.ДержательМетаданных = РодительскаяСтруктураТипа.ДержательМетаданных;
						//ШаблонСтруктурыТипа.Метаданные = МетаданныеРодителя;
						Для Каждого Тип Из МассивТипов Цикл
							
							//Если Истина
							//	И Тип = ТипЗнч(ЗначениеСвойства)
							//	И (Ложь
							//		Или мМассивТиповВключающихМетаданные.Найти(Тип) <> Неопределено 
							//		Или мМассивТиповЭлементовУправления.Найти(Тип) <> Неопределено)
							//Тогда 
							//	ШаблонСтруктурыТипа.Метаданные = ЗначениеСвойства;
							//	СтруктураТипаСвойства = ПолучитьСтруктуруТипаИзЗначения(ЗначениеСвойства, ЯзыкПрограммы, ШаблонСтруктурыТипа);
							//Иначе
							//	ШаблонСтруктурыТипа.Метаданные = МетаданныеРодителя;
							//	СтруктураТипаСвойства = ПолучитьСтруктуруТипаИзКонкретногоТипа(Тип, ЯзыкПрограммы, ШаблонСтруктурыТипа);
							//КонецЕсли;
							Если Истина
								И Тип = ТипЗнч(ЗначениеСвойства)
								//И (Ложь
								//	Или мМассивТиповВключающихМетаданные.Найти(Тип) <> Неопределено 
								//	Или мМассивТиповЭлементовУправления.Найти(Тип) <> Неопределено)
							Тогда 
								ШаблонСтруктурыТипа.Метаданные = ЗначениеСвойства;
								СтруктураТипаСвойства = ПолучитьСтруктуруТипаИзЗначения(ЗначениеСвойства, ЯзыкПрограммы, ШаблонСтруктурыТипа);
							ИначеЕсли Истина
								И Это2iS
								И ТипЗнч(Тип) = Тип("СправочникСсылка.ОбъектыМетаданных2iS") 
							Тогда 
								СтруктураТипаСвойства = ПолучитьНовуюСтруктуруТипа();
								СтруктураТипаСвойства.Метаданные = Тип;
								ТипОбъект = КэшОбъект(Тип);
								ОбъектСистемы = ТипОбъект.ОбъектСистемы;
								Расширение = Вычислить("Ядро2iS.ПолучитьРасширениеСсылкиОбъектаСистемы(ОбъектСистемы)");
								Если ЗначениеЗаполнено(Расширение) Тогда
									СтруктураТипаСвойства.ИмяОбщегоТипа = Расширение.ИмяОбщегоТипа;
								Иначе
									СтруктураТипаСвойства.ИмяОбщегоТипа = ТипОбъект.Наименование;
								КонецЕсли; 
							ИначеЕсли Истина
								И ЭтоИнтеграция
								И ТипЗнч(Тип) = Тип("СправочникСсылка.МетаданныеИис") 
							Тогда 
								СтруктураТипаСвойства = ПолучитьНовуюСтруктуруТипа();
								СтруктураТипаСвойства.Метаданные = Тип;
								ТипОбъект = КэшОбъект(Тип);
								//ОбъектСистемы = ТипОбъект.ОбъектСистемы;
								//Расширение = Вычислить("Ядро2iS.ПолучитьРасширениеСсылкиОбъектаСистемы(ОбъектСистемы)");
								//Если ЗначениеЗаполнено(Расширение) Тогда
								//	СтруктураТипаСвойства.ИмяОбщегоТипа = Расширение.ИмяОбщегоТипа;
								//Иначе
									СтруктураТипаСвойства.ИмяОбщегоТипа = ТипОбъект.Наименование;
								//КонецЕсли; 
							Иначе
								ШаблонСтруктурыТипа.Метаданные = МетаданныеРодителя;
								СтруктураТипаСвойства = ПолучитьСтруктуруТипаИзКонкретногоТипа(Тип, ЯзыкПрограммы, ШаблонСтруктурыТипа);
							КонецЕсли;
							
							ДобавитьВТаблицуСтруктурТипов(ТаблицаСтруктурТипов, СтруктураТипаСвойства);
						КонецЦикла;
					Иначе
						СтруктураТипаСвойства = ПолучитьНовуюСтруктуруТипа();
						ЗаполнитьЗначенияСвойств(СтруктураТипаСвойства, РодительскаяСтруктураТипа, "ТипЯзыка");
						Если РодительскаяСтруктураТипа.ТипЯзыка = "ИмяТипа" Тогда
							СтруктураТипаСвойства.ИмяОбщегоТипа = СтрокаВида.Слово;
							Если СтрокаВида.ТипКонтекста <> "" Тогда
								СтруктураТипаСвойства.ИмяОбщегоТипа = СтрокаВида.ТипКонтекста + "." + СтруктураТипаСвойства.ИмяОбщегоТипа;
							КонецЕсли;
						Иначе
							СтруктураТипаСвойства.ИмяОбщегоТипа = СтрокаВида.ТипЗначения;
							СтруктураТипаСвойства.СтрокаОписания = СтрокаВида;
						КонецЕсли;
						СтруктураТипаСвойства.Метаданные = ЗначениеСвойства;
						ДобавитьВТаблицуСтруктурТипов(ТаблицаСтруктурТипов, СтруктураТипаСвойства);
					КонецЕсли;
				КонецЕсли; 
				ДобавитьВТаблицуСлов(ВнутренняяТаблицаСлов, КонечноеСлово, СтрокаВида.ТипСлова, ТаблицаСтруктурТипов);
			КонецЦикла;
		КонецЦикла;
	КонецЦикла;
	Если Истина
		// Для того, чтобы постоянно не присваивался тип <ОбщийМодуль>
		И ИмяОбщегоТипа <> "Глобальный контекст"
		И НайденныеСтроки.Количество() > 0 
	Тогда
		Если Истина
			И Слово <> Неопределено
			И ВнутренняяТаблицаСлов.Количество() = 0
			И НайденныеСтроки.Количество() = 1 
		Тогда
			// Шаблон только один. Берем его даже если имя элемента коллекции не подошло.
			СтрокаВида = НайденныеСтроки[0];
			СтруктураТипа = ПолучитьНовуюСтруктуруТипа();
			СтруктураТипа.ИмяОбщегоТипа = СтрокаВида.ТипЗначения;
			СтруктураТипа.СтрокаОписания = СтрокаВида;
			СтруктураТипа.Метаданные = МетаданныеРодителя;
			ТаблицаСтруктурТипов = ПолучитьНовуюТаблицуСтруктурТипа();
			ДобавитьВТаблицуСтруктурТипов(ТаблицаСтруктурТипов, СтруктураТипа);
			ДобавитьВТаблицуСлов(ВнутренняяТаблицаСлов, СтрокаВида.Слово, СтрокаВида.ТипСлова, ТаблицаСтруктурТипов);
		КонецЕсли;
	КонецЕсли;
	Возврат ВнутренняяТаблицаСлов;
	
КонецФункции // ПолучитьВнутреннююТаблицуМетаданныхСлов()

// Получает внутреннюю таблицу предопределенных слов заданного родительского типа.
//
// Параметры:
//  РодительскаяСтруктураТипа – Структура;
//  *Слово       – Строка, *Неопределено – для отбора;
//  *ТипСлова    – Строка, *Неопределено – для отбора;
//  *ВиртуальнаяТаблица - Структура, *Неопределено - описание виртуальной таблицы;
//  *ЯзыкПрограммы - *Число, 0;
//
// Возвращаемое значение:
//  ТаблицаЗначений – с колонками "Слово", "ТипСлова", "ТаблицаСтруктурТипов".
//
Функция ПолучитьВнутреннююТаблицуПредопределенныхСлов(РодительскаяСтруктураТипа,
	Слово = Неопределено, ТипСлова = Неопределено, ВиртуальнаяТаблица = Неопределено, ЯзыкПрограммы = 0,
	Конфигурация = Неопределено, ВычислятьТипы = Истина) Экспорт 
	
	ВнутренняяТаблицаСлов = ПолучитьНовуюВнутреннююТаблицуСлов();
	
	КлючПоискаКонструктора = Новый Структура;
	Если РодительскаяСтруктураТипа.Конструктор Тогда
		КлючПоискаКонструктора = Новый Структура("ЕстьКонструктор, ЯзыкПрограммы, НСлово", Истина, ЯзыкПрограммы);
	КонецЕсли;
	
	ИмяОбщегоТипа = РодительскаяСтруктураТипа.ИмяОбщегоТипа; 
	Если ирОбщий.СтрокиРавныЛкс(МаркерCOMОбъекта + ".{V", Лев(ИмяОбщегоТипа, СтрДлина(МаркерCOMОбъекта + ".{V"))) Тогда
		Если Найти(ИмяОбщегоТипа, ".COMConnector}") > 0 Тогда 
			РодительскаяСтруктураТипа.ИмяОбщегоТипа = "COM-соединитель";
		ИначеЕсли Найти(ИмяОбщегоТипа, ".Application}") > 0 Тогда  
			РодительскаяСтруктураТипа.ИмяОбщегоТипа = "Automation сервер";
		КонецЕсли;
	КонецЕсли; 
	МассивОбщихТипов = ПолучитьТаблицуОбщихТиповСтруктурыТипа(РодительскаяСтруктураТипа);
	
	Для Каждого СтрокаОбщегоТипа Из МассивОбщихТипов Цикл
		ИмяОбщегоТипа = СтрокаОбщегоТипа.ИмяОбщегоТипа;
		МетаданныеРодителя = СтрокаОбщегоТипа.Метаданные;
		КорневойТипРодителя = Неопределено;
		ПостроительЗапросаРодителя = Неопределено;
		ТипМетаданныхРодителя = ТипЗнч(МетаданныеРодителя);
		Если Истина
			//И
			И (Ложь
				Или ТипМетаданныхРодителя = Тип("ОбъектМетаданных")
				Или (Истина
					И Это2iS
					И (Ложь
						Или ТипМетаданныхРодителя = Тип("СправочникСсылка.ОбъектыМетаданных2iS")
						Или ТипМетаданныхРодителя = Тип("СправочникСсылка.СвойстваМетаданных2iS")))
				Или (Истина
					И ЭтоИнтеграция
					И (Ложь
						Или ТипМетаданныхРодителя = Тип("СправочникСсылка.МетаданныеИис")
						Или ТипМетаданныхРодителя = Тип("СправочникСсылка.СвойстваМетаданныхИис"))))
			И РодительскаяСтруктураТипа.ТипЯзыка <> "ИмяТипа"
		Тогда 
			Если ТипМетаданныхРодителя = Тип("ОбъектМетаданных") Тогда
				КорневойТипРодителя = ирОбщий.ПолучитьКорневойТипКонфигурацииЛкс(МетаданныеРодителя);
			Иначе
				КорневойТипРодителя = ирОбщий.ПолучитьКорневойТипКонфигурацииЛкс(КэшОбъект(МетаданныеРодителя).ПолноеИмя);
			КонецЕсли; 
			ПостроительЗапросаРодителя = ПолучитьПостроительЗапросаПоСтруктуреТипа(СтрокаОбщегоТипа,
				РодительскаяСтруктураТипа.ВиртуальнаяТаблица);
		КонецЕсли;
		
		НайденныеСтроки = Неопределено;
		
		#Если Клиент Тогда	
		// COM-объекты
		Если Найти(ИмяОбщегоТипа, МаркерCOMОбъекта) = 1 Тогда
			ИмяБиблиотеки = "";
			ИнфоТипа = ПолучитьИнфоТипаCOMОбъекта(МетаданныеРодителя, ИмяОбщегоТипа, ИмяБиблиотеки);
			Если ИнфоТипа = Неопределено Тогда
				Продолжить;
			КонецЕсли; 
			//Если ИмяCOMКласса = "" Тогда 
			//	Если Описатель.Parent.Name = "V" + ирКэш.НомерИзданияПлатформыЛкс() Тогда 
			//		ИмяОбщегоТипа = "COM-соединитель";
			//	КонецЕсли;
			//КонецЕсли;
			НайденныеСтроки = ТаблицаКонтекстов.СкопироватьКолонки();
			//Для Счетчик = 1 По ИнфоТипа.Members.Count Цикл
			//	Член = ИнфоТипа.Members(Счетчик);
			Если НРег(ИнфоТипа.TypeKindString) = "coclass" Тогда
				МассивИнфоТипа = ИнфоТипа.Interfaces;
			Иначе
				МассивИнфоТипа = Новый Массив;
				МассивИнфоТипа.Добавить(ИнфоТипа);
			КонецЕсли;
			Для Каждого ИнфоТипа Из МассивИнфоТипа Цикл
				Для Каждого Член Из ИнфоТипа.Members Цикл
					ИмяЧлена = Член.Name;
					Если Член.InvokeKind = 1 Тогда 
						лТипСлова = "Метод";
					Иначе
						лТипСлова = "Свойство";
					КонецЕсли;
					Если Слово <> Неопределено Тогда
						Если Не ирОбщий.СтрокиРавныЛкс(Слово, ИмяЧлена) Тогда
							Продолжить;
						КонецЕсли; 
						Если Не ирОбщий.СтрокиРавныЛкс(ТипСлова, лТипСлова) Тогда
							Продолжить;
						КонецЕсли; 
					КонецЕсли; 
					Если Член.AttributeMask = 1 Тогда
						// Это члены IDispatch
						Продолжить;
					КонецЕсли; 
					СтруктураКлюча = Новый Структура("НСлово, ТипСлова", НРег(ИмяЧлена), лТипСлова);
					НайденныеСтроки2 = НайденныеСтроки.НайтиСтроки(СтруктураКлюча);
					Если НайденныеСтроки2.Количество() > 0 Тогда
						СтрокаКонтекста = НайденныеСтроки2[0];
						//СтрокаКонтекста.ТипЗначения = СтрокаКонтекста.ТипЗначения + ", " + Член.ReturnType.VarType;
					Иначе
						СтрокаКонтекста = НайденныеСтроки.Добавить();
						ЗаполнитьЗначенияСвойств(СтрокаКонтекста, СтруктураКлюча);
						СтрокаКонтекста.Слово = ИмяЧлена;
						СтрокаКонтекста.ТипЗначения = ПолучитьТипЗначенияЧленаИнтерфейса(ИмяБиблиотеки, Член.ReturnType);
					КонецЕсли;
					//Член.Parameters.Count + " // " + 
				КонецЦикла;
			КонецЦикла;
		КонецЕсли;
		#КонецЕсли
		
		Если НайденныеСтроки = Неопределено Тогда 
			СтруктураКлюча = Новый Структура("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка",
				ИмяОбщегоТипа, ЯзыкПрограммы, РодительскаяСтруктураТипа.ТипЯзыка);
			Если ТипСлова <> Неопределено Тогда
				СтруктураКлюча.Вставить("ТипСлова", ТипСлова);
			КонецЕсли;
			Если Слово <> Неопределено Тогда
				СтруктураКлюча.Вставить("НСлово", НРег(Слово));
			КонецЕсли;
			НайденныеСтроки = ТаблицаКонтекстов.НайтиСтроки(СтруктураКлюча);
		КонецЕсли;
		Для Каждого СтрокаСлова Из НайденныеСтроки Цикл
			Если Истина
				И СтрокаСлова.ТипСлова = "Метод" 
				И СтрокаОбщегоТипа.НеВключатьМетоды
			Тогда
				Продолжить;
			КонецЕсли;
			Если РодительскаяСтруктураТипа.Конструктор Тогда 
				КлючПоискаКонструктора.НСлово = НРег(СтрокаСлова.Слово);
				Если ТаблицаОбщихТипов.НайтиСтроки(КлючПоискаКонструктора).Количество() = 0 Тогда 
					Продолжить;
				КонецЕсли;
			КонецЕсли; 
			Если Ложь
				Или СтрокаСлова.ТипСлова = "Событие"
				Или СтрокаСлова.ТипСлова = "Параметр"
				Или СтрокаСлова.ТипСлова = "Конструктор"
			Тогда
				// Это пока не нужно
				Продолжить;
			КонецЕсли;
			ТаблицаСтруктурТипов = Неопределено;
			Если ВычислятьТипы Тогда
				ТаблицаСтруктурТипов = ПолучитьНовуюТаблицуСтруктурТипа();
				ЛиДобавляемСлово = Истина;
				МассивТиповЗначения = ирОбщий.ПолучитьМассивИзСтрокиСРазделителемЛкс(СтрокаСлова.ТипЗначения, ", ");
				Для Каждого ИмяОбщегоТипа Из МассивТиповЗначения Цикл
					СтруктураТипа = ПолучитьНовуюСтруктуруТипа();
					СтруктураТипа.СтрокаОписания = СтрокаСлова;
					ЗаполнитьЗначенияСвойств(СтруктураТипа, РодительскаяСтруктураТипа, , "ИмяОбщегоТипа, СтрокаОписания, Метаданные");
					Если Истина
						И ТипЗнч(МетаданныеРодителя) <> Тип("COMОбъект")
						//И ИмяОбщегоТипа <> 
						//И СтрокаСлова.ТипСлова = "Свойство"
					Тогда
						ЗаполнитьЗначенияСвойств(СтруктураТипа, СтрокаОбщегоТипа, "Метаданные");
					КонецЕсли; 
					Если ИмяОбщегоТипа = "ОбъектМетаданныхКонфигурация" Тогда
						//СтруктураТипа.Метаданные = Конфигурация;
						Если Конфигурация <> Неопределено Тогда
							СтруктураТипа.Метаданные = Конфигурация;
						Иначе
							СтруктураТипа.Метаданные = мМетаданные;
						КонецЕсли; 
					ИначеЕсли ИмяОбщегоТипа = "Отбор" Тогда 
						// %%%% Недокументированная особенность платформы
						КонкретныйТип = ПолучитьСтрокуКонкретногоТипа(СтрокаОбщегоТипа);
						Если Найти(КонкретныйТип, "<") = 0 Тогда
							Попытка
								Образователь = Новый (КонкретныйТип);
								СтруктураТипа.Метаданные = Образователь;
							Исключение
								// Срабатывает для табличных полей
							КонецПопытки;
						КонецЕсли; 
					КонецЕсли;
					СтруктураТипа.ИмяОбщегоТипа = ИмяОбщегоТипа;
					Если ВиртуальнаяТаблица <> Неопределено Тогда
						ЗаполнитьЗначенияСвойств(СтруктураТипа.ВиртуальнаяТаблица, ВиртуальнаяТаблица);
					КонецЕсли;
					
					Если РодительскаяСтруктураТипа.ТипЯзыка = "ИмяТипа" Тогда
						СтруктураТипа.ИмяОбщегоТипа = СтрокаСлова.Слово;
						Если СтрокаСлова.ТипКонтекста <> "" Тогда
							СтруктураТипа.ИмяОбщегоТипа = СтрокаСлова.ТипКонтекста + "." + СтруктураТипа.ИмяОбщегоТипа;
						КонецЕсли;
					КонецЕсли;
					
					Если Истина
						И СтруктураТипа.ИмяОбщегоТипа = "Строка табличной части"
						И Найти(РодительскаяСтруктураТипа.ИмяОбщегоТипа, "ТабличнаяЧасть.") > 0
					Тогда
						СтруктураТипа.ИмяОбщегоТипа = СтрЗаменить(РодительскаяСтруктураТипа.ИмяОбщегоТипа, "ТабличнаяЧасть.", "ТабличнаяЧастьСтрока.");
					КонецЕсли;
					
					МаркерРасширений = "Расширение ";
					Если Истина
						И Лев(РодительскаяСтруктураТипа.ИмяОбщегоТипа, СтрДлина(МаркерРасширений)) = МаркерРасширений
						И СтрокаСлова.Слово = "Значение"
					Тогда
						Если РодительскаяСтруктураТипа.Метаданные <> Неопределено Тогда
							СтруктураТипа = ПолучитьСтруктуруТипаИзЗначения(РодительскаяСтруктураТипа.Метаданные.Значение);
						Иначе
							СтрокаРасширения = ТаблицаРасширенийТипов.Найти(РодительскаяСтруктураТипа.ИмяОбщегоТипа, "Расширение");
							//Если СтрокаРасширения <> Неопределено Тогда
								СтруктураТипа.ИмяОбщегоТипа = СтрокаРасширения.РасширяющийТип;
							//КонецЕсли;
						КонецЕсли;
					КонецЕсли;
					Если Истина
						И МетаданныеРодителя <> Неопределено
						И СтрокаСлова.ТипСлова = "Свойство"
					Тогда
						Если Ложь
							Или (Истина // Нельзя допускать неявного выполнения запроса при обращении к свойству "Результат" построителя
								И СтруктураТипа.ИмяОбщегоТипа = "РезультатЗапроса"
								И ТипЗнч(МетаданныеРодителя) = Тип("ПостроительЗапроса"))
							Или (Истина // Здесь свойство есть у объекта метаданных, но имеет другой смысл
								И СтрокаСлова.Слово = "ВидыСубконто"
								И СтруктураТипа.ИмяОбщегоТипа = "ПланСчетовВидыСубконто.<Имя плана счетов>")
						Тогда
							ЗначениеСвойства = МетаданныеРодителя;
						Иначе
							Если Истина
								#Если Клиент Тогда
									И ТипЗнч(МетаданныеРодителя) = Тип("ТабличноеПоле")
								#Иначе
									И Ложь
								#КонецЕсли 
								И СтрокаСлова.Слово = "ТекущийРодитель"
							Тогда
								// Антибаг платформы 8.2.16. Вывести в чистом виде не удалось. Падает при вычислении свойства ТекущийРодитель в форме списка РС.ООП_ВаучерыТез
								ЗначениеСвойства = Неопределено;
							Иначе
								Попытка
									ЗначениеСвойства = МетаданныеРодителя[СтрокаСлова.Слово];
								Исключение
									ЗначениеСвойства = Неопределено;
								КонецПопытки;
							КонецЕсли; 
						КонецЕсли; 
						Если ЗначениеСвойства <> Неопределено Тогда
							Если мМассивТиповВключающихМетаданные.Найти(ТипЗнч(ЗначениеСвойства)) <> Неопределено Тогда 
								СтруктураТипа.Метаданные = ЗначениеСвойства;
							КонецЕсли;
						КонецЕсли;
					КонецЕсли;
					
					// Для методов метаданных нужна специфическая обработка для усечения типов
					Если Истина
						И СтрокаСлова.ТипСлова = "Метод"
						И Лев(ИмяОбщегоТипа, СтрДлина(МаркерОбъектаМетаданных)) = МаркерОбъектаМетаданных
						И СтрокаСлова.Слово = "Родитель"
					Тогда
						Родитель = Неопределено;
						Если ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") Тогда
							Родитель = МетаданныеРодителя.Родитель();
						КонецЕсли;
						Если Родитель <> Неопределено Тогда
							МассивФрагментов = ирОбщий.ПолучитьМассивИзСтрокиСРазделителемЛкс(Родитель.ПолноеИмя());
							СтруктураТипа.ИмяОбщегоТипа = МаркерОбъектаМетаданных + ": " + МассивФрагментов[МассивФрагментов.ВГраница() - 1];
						Иначе
							СтруктураТипа.ИмяОбщегоТипа = "Неопределено";
						КонецЕсли; 
						СтруктураТипа.Метаданные = Родитель;
						ДобавитьВТаблицуСтруктурТипов(ТаблицаСтруктурТипов, СтруктураТипа);
						Прервать;
					ИначеЕсли Истина
						И СтрокаСлова.ТипСлова = "Метод"
						И Лев(ИмяОбщегоТипа, СтрДлина(МаркерКоллекцииОбъектовМетаданных)) = МаркерКоллекцииОбъектовМетаданных
						И (Ложь
							Или СтрокаСлова.Слово = "Найти"
							Или СтрокаСлова.Слово = "Получить")
					Тогда
						СтруктураКлюча = Новый Структура("БазовыйТип, ЯзыкПрограммы", ИмяОбщегоТипа, ЯзыкПрограммы);
						НайденныеСтроки = ТаблицаОбщихТипов.НайтиСтроки(СтруктураКлюча);
						СтруктураТипа.ИмяОбщегоТипа = НайденныеСтроки[0].ТипЭлементаКоллекции;
						ДобавитьВТаблицуСтруктурТипов(ТаблицаСтруктурТипов, СтруктураТипа);
						Прервать;
					КонецЕсли;
					
					Если КорневойТипРодителя <> Неопределено Тогда 
						ДоступноеПолеСлова = ПостроительЗапросаРодителя.ДоступныеПоля.Найти(СтрокаСлова.Слово);
						// Частные случаи
						Если Ложь
							Или СтрокаСлова.ТипСлова = "Поле"
							Или СтрокаСлова.Слово = "Активность"
							Или СтрокаСлова.Слово = "Владелец"
							Или СтрокаСлова.Слово = "ВидДвижения"
							Или СтрокаСлова.Слово = "Период"
							Или СтрокаСлова.Слово = "Регистратор"
							Или СтрокаСлова.Слово = "МоментВремени"
							Или СтрокаСлова.Слово = "НомерСтроки"
							//Или СтрокаСлова.Слово = "СубконтоДт" // Закомментировано 14.04.2012
							//Или СтрокаСлова.Слово = "СубконтоКт" // Закомментировано 14.04.2012
							Или СтрокаСлова.Слово = "СчетДт"
							Или СтрокаСлова.Слово = "СчетКт"
						Тогда
							Если ДоступноеПолеСлова = Неопределено Тогда
								ЛиДобавляемСлово = Ложь;
							Иначе
								ТипыЗначенияСлова = ДоступноеПолеСлова.ТипЗначения.Типы();
								Для Каждого ТипЗначенияСлова Из ТипыЗначенияСлова Цикл
									ШаблонСтруктурыТипа = Новый Структура("СтрокаОписания, ТипЯзыка");
									ШаблонСтруктурыТипа.СтрокаОписания = СтрокаСлова;
									ЗаполнитьЗначенияСвойств(ШаблонСтруктурыТипа, РодительскаяСтруктураТипа, "ТипЯзыка");
									СтруктураТипа = ПолучитьСтруктуруТипаИзКонкретногоТипа(ТипЗначенияСлова, ЯзыкПрограммы, ШаблонСтруктурыТипа);
									ДобавитьВТаблицуСтруктурТипов(ТаблицаСтруктурТипов, СтруктураТипа);
								КонецЦикла;
							КонецЕсли;
							Прервать;
						ИначеЕсли Ложь
							Или (Истина
								И ИмяОбщегоТипа = "КонстантаМенеджер.<Имя константы>" 
								И СтрокаСлова.Слово = "Получить")
							Или (Истина
								И ИмяОбщегоТипа = "КонстантаМенеджерЗначения.<Имя константы>" 
								И СтрокаСлова.Слово = "Значение")
						Тогда
							ТипыЗначенияКонстанты = МетаданныеРодителя.Тип.Типы();
							Для Каждого ТипЗначенияКонстанты Из ТипыЗначенияКонстанты Цикл
								ШаблонСтруктурыТипа = Новый Структура("СтрокаОписания, ТипЯзыка");
								ШаблонСтруктурыТипа.СтрокаОписания = СтрокаСлова;
								ЗаполнитьЗначенияСвойств(ШаблонСтруктурыТипа, РодительскаяСтруктураТипа, "ТипЯзыка");
								СтруктураТипа = ПолучитьСтруктуруТипаИзКонкретногоТипа(ТипЗначенияКонстанты, ЯзыкПрограммы, ШаблонСтруктурыТипа);
								ДобавитьВТаблицуСтруктурТипов(ТаблицаСтруктурТипов, СтруктураТипа);
							КонецЦикла;
						ИначеЕсли Истина
							И СтрокаСлова.ТипСлова = "Метод"
							И (Ложь
								Или СтрокаСлова.Слово = "Выгрузить"
								Или СтрокаСлова.Слово = "ВыгрузитьКолонки")
						Тогда 
							КонкретныйТип = ПолучитьСтрокуКонкретногоТипа(СтрокаОбщегоТипа);
							Образователь = Неопределено;
							Если Истина
								И НРег(КонкретныйТип) = Нрег("Табличная часть")
								И ТипЗнч(СтрокаОбщегоТипа.Метаданные) = Тип("ОбъектМетаданных")
							Тогда
								МассивФрагментов = ирОбщий.ПолучитьМассивИзСтрокиСРазделителемЛкс(СтрокаОбщегоТипа.Метаданные.ПолноеИмя());
								СсылочныйОбъект = Новый (МассивФрагментов[0] + "Объект." + МассивФрагментов[1]);
								Образователь = СсылочныйОбъект[МассивФрагментов[3]];
							//ИначеЕсли Истина
							//	И НРег(СтрокаОбщегоТипа.ИмяОбщегоТипа) = Нрег("ПланСчетовВидыСубконто.<Имя плана счетов>")
							//	И ТипЗнч(СтрокаОбщегоТипа.Метаданные) = Тип("ОбъектМетаданных")
							//Тогда
							// Тут метаданные от ПВХ уже, а надо сделать чтобы были от плана счетов
							//	МассивФрагментов = ирОбщий.ПолучитьМассивИзСтрокиСРазделителемЛкс(СтрокаОбщегоТипа.Метаданные.ПолноеИмя());
							//	СчетОбъект = Новый (МассивФрагментов[0] + "Объект." + МассивФрагментов[1]);
							//	Образователь = Вычислить("СчетОбъект.ВидыСубконто");
							ИначеЕсли Найти(КонкретныйТип, "<") = 0 Тогда
								Попытка
									Образователь = Новый (КонкретныйТип);
								Исключение
									// Срабатывает например для ВидыСубконто
								КонецПопытки;
							КонецЕсли;
							Если Образователь <> Неопределено Тогда
								СтруктураТипа.Метаданные = Образователь.ВыгрузитьКолонки();
							КонецЕсли; 
						ИначеЕсли Истина
							И (Ложь
								Или СтрокаСлова.Слово = "СрезПервых"
								Или СтрокаСлова.Слово = "СрезПоследних")
							И КорневойТипРодителя = "РегистрСведений"
							И МетаданныеРодителя.ПериодичностьРегистраСведений = мМетаданные.СвойстваОбъектов.ПериодичностьРегистраСведений.Непериодический
						Тогда
							ЛиДобавляемСлово = Ложь;
							Прервать;
						ИначеЕсли Истина
							И (Ложь
								Или СтрокаСлова.Слово = "Остатки"
								Или СтрокаСлова.Слово = "ОстаткиИОбороты")
							И КорневойТипРодителя = "РегистрНакопления"
							И МетаданныеРодителя.ВидРегистра = мМетаданные.СвойстваОбъектов.ВидРегистраНакопления.Обороты
						Тогда
							ЛиДобавляемСлово = Ложь;
							Прервать;
						ИначеЕсли Истина
							И (Ложь
								Или СтрокаСлова.Слово = "ОборотыДтКт")
							И КорневойТипРодителя = "РегистрБухгалтерии"
							И Не МетаданныеРодителя.Корреспонденция
						Тогда
							ЛиДобавляемСлово = Ложь;
							Прервать;
						Иначе
							ДобавитьВТаблицуСтруктурТипов(ТаблицаСтруктурТипов, СтруктураТипа);
						КонецЕсли;
					Иначе
						Если Истина
							И ИмяОбщегоТипа = "Форма" 
							И СтрокаСлова.Слово = "ЭтаФорма"
						Тогда
							ДобавитьВТаблицуСтруктурТипов(ТаблицаСтруктурТипов, РодительскаяСтруктураТипа, Истина);
						Иначе
							ДобавитьВТаблицуСтруктурТипов(ТаблицаСтруктурТипов, СтруктураТипа, Ложь);
						КонецЕсли;
					КонецЕсли;
				КонецЦикла;
				Если Не ЛиДобавляемСлово Тогда
					Продолжить;
				КонецЕсли;
				Если ТаблицаСтруктурТипов.Количество() = 0 Тогда
					ДобавитьВТаблицуСтруктурТипов(ТаблицаСтруктурТипов, СтруктураТипа);
				КонецЕсли;
			КонецЕсли; 
			ДобавитьВТаблицуСлов(ВнутренняяТаблицаСлов, СтрокаСлова.Слово, СтрокаСлова.ТипСлова, ТаблицаСтруктурТипов, СтрокаСлова.ТипЗначения);
		КонецЦикла;
	КонецЦикла;
	Возврат ВнутренняяТаблицаСлов;

КонецФункции // ПолучитьВнутреннююТаблицуПредопределенныхСлов()

Функция ПолучитьТипЗначенияЧленаИнтерфейса(ИмяБиблиотеки, ОписаниеРезультата) Экспорт

	//Тест = ПолучитьИмяТипаCOMVariant(Член);
	ИнфоТипаРезультата = ОписаниеРезультата.TypeInfo;
	Если ИнфоТипаРезультата <> Неопределено Тогда
		ТипЗначенияРезультата = ПолучитьПолноеИмяТипаCOMОбъектаИзИнфоТипа(ИнфоТипаРезультата, ИмяБиблиотеки);
	Иначе
		НомерТипа = ОписаниеРезультата.VarType;
		Если НомерТипа = 0 Тогда
			ТипЗначенияРезультата = Неопределено;
		ИначеЕсли НомерТипа = 1 Тогда
			ТипЗначенияРезультата = Null;
		ИначеЕсли НомерТипа >= 2 И НомерТипа <= 5 Тогда
			ТипЗначенияРезультата = "Число";
		ИначеЕсли НомерТипа = 7 Тогда
			ТипЗначенияРезультата = "Дата";
		ИначеЕсли НомерТипа = 8 Тогда
			ТипЗначенияРезультата = "Строка";
		ИначеЕсли НомерТипа = 11 Тогда
			ТипЗначенияРезультата = "Булево";
		ИначеЕсли НомерТипа >= 14 И НомерТипа <= 23 Тогда
			ТипЗначенияРезультата = "Число";
		ИначеЕсли НомерТипа = 24 Тогда
			ТипЗначенияРезультата = "";
		Иначе
			ТипЗначенияРезультата = "Произвольный" + ", " + НомерТипа;
		КонецЕсли; 
	КонецЕсли;

	Возврат ТипЗначенияРезультата;

 //'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Объект); // Тут падает для некоторых объектов (например ADODB.Recorset.Fields(*).Precision
		Исключение
			ОписаниеОшибки = ОписаниеОшибки();
			//Сообщить(ОписаниеОшибки);
			Возврат Неопределено;
		КонецПопытки; 
	КонецЕсли; 
	Если ЗначениеЗаполнено(ИмяОбщегоТипа) Тогда
		выхПолноеИмяОсновногоКласса = ирОбщий.ПолучитьСтрокуМеждуМаркерамиЛкс(ИмяОбщегоТипа, "{", "}", Ложь);
		ИмяОбщегоТипа = СтрЗаменить(ИмяОбщегоТипа, ".{" + выхПолноеИмяОсновногоКласса + "}", ""); 
	КонецЕсли; 
	Если Не ЗначениеЗаполнено(выхПолноеИмяОсновногоКласса) Тогда
		Если ТипЗнч(выхCOMОбъект) = Тип("COMОбъект") Тогда 
			ИмяБиблиотеки = ИнфоИнтерфейса.Parent.Name;
			ИмяОсновногоКласса = мИменаОсновныхКлассовБиблиотекCOM[ИмяБиблиотеки];
			Если ИмяОсновногоКласса = Неопределено Тогда
				ПробныйОбъект = Неопределено;
				Для Каждого Претендент Из ИнфоИнтерфейса.Parent.CoClasses Цикл
					Попытка
						ПробныйОбъект = Новый COMОбъект(ИмяБиблиотеки + "." + Претендент.Name);
					Исключение
						Продолжить;
					КонецПопытки;
					Прервать;
				КонецЦикла;
				Если ПробныйОбъект <> Неопределено Тогда
					ПробныйОбъект = Неопределено;
					ИмяОсновногоКласса = Претендент.Name;
				Иначе
					ИмяОсновногоКласса = "?";
				КонецЕсли; 
				мИменаОсновныхКлассовБиблиотекCOM[ИмяБиблиотеки] = ИмяОсновногоКласса;
			КонецЕсли; 
			выхПолноеИмяОсновногоКласса = ИмяБиблиотеки + "." + ИмяОсновногоКласса;
		Иначе
			Возврат Неопределено;
		КонецЕсли;
	КонецЕсли;
	Если ИнфоИнтерфейса = Неопределено Тогда
		выхCOMОбъект = ПолучитьОбразецCOMОбъекта(выхПолноеИмяОсновногоКласса);
		Попытка
			ИнфоИнтерфейса = COMНавигатор.InterfaceInfoFromObject(выхCOMОбъект);
		Исключение
			//Сообщить(ОписаниеОшибки());
			Возврат Неопределено;
		КонецПопытки; 
		МассивФрагментов = ирОбщий.ПолучитьМассивИзСтрокиСРазделителемЛкс(ИмяОбщегоТипа);
		Если МассивФрагментов.Количество() > 1 Тогда
			лИнфоИнтерфейса = ИнфоИнтерфейса.Parent.TypeInfos.NamedItem(МассивФрагментов[1]);
			Если лИнфоИнтерфейса <> Неопределено Тогда
				ИнфоИнтерфейса = лИнфоИнтерфейса;
			Иначе
				// Например для Shell.Application выполняется
			КонецЕсли; 
		КонецЕсли; 
	КонецЕсли;
	Возврат ИнфоИнтерфейса;

КонецФункции

Функция ПолучитьОбразецCOMОбъекта(ПолноеИмяОсновногоКлассаCOM) Экспорт

	КлючКэша = НРег(ПолноеИмяОсновногоКлассаCOM);
	Результат = мОбразцыCOMОбъектов[КлючКэша];
	Если Результат <> Неопределено Тогда
		ИнфоИнтерфейса = ПолучитьИнфоТипаCOMОбъекта(Результат,,ПолноеИмяОсновногоКлассаCOM);
		Если ИнфоИнтерфейса = Неопределено Тогда
			// Объект испорчен
			Результат = Неопределено;
		КонецЕсли; 
	КонецЕсли; 
	Если Результат = Неопределено Тогда
		Попытка
			Результат = Новый COMОбъект(ПолноеИмяОсновногоКлассаCOM);
		Исключение
			Возврат Неопределено;
		КонецПопытки;
		мОбразцыCOMОбъектов[КлючКэша] = Результат;
	КонецЕсли; 
	Возврат Результат;

КонецФункции

// Получает новый экземпляр ком-объекта парсера.
//
// Параметры:
//  Нет.
//
// Возвращаемое значение:
//  Com-объект, Неопределено.
//
Функция ПолучитьCOMНавигатор() Экспорт

	Если COMНавигатор = "НеИнициализирован" Тогда
		COMНавигатор = ПолучитьCOMОбъектИзМакета("TLBINF32", "TLI.TLIApplication");
	КонецЕсли;
	Возврат COMНавигатор;

КонецФункции // ПолучитьCOMНавигатор()

Функция ПолучитьТипыЭлементовКоллекции(СтруктураТипаКоллекции, ЯзыкПрограммы = 0) Экспорт
	
	ТипыЭлементовКоллекции = Новый Массив();
	Если Найти(СтруктураТипаКоллекции.ИмяОбщегоТипа, МаркерCOMОбъекта) = 1 Тогда
		ИмяОбщегоТипа = СтруктураТипаКоллекции.ИмяОбщегоТипа;
		ТаблицаСтруктурТипаЭлемента = ПолучитьНовуюТаблицуСтруктурТипа();
		ИмяБиблиотеки = "";
		МетаданныеОбъекта = СтруктураТипаКоллекции.Метаданные;
		ИнфоТипа = ПолучитьИнфоТипаCOMОбъекта(МетаданныеОбъекта, ИмяОбщегоТипа, ИмяБиблиотеки);
		Если ИнфоТипа = Неопределено Тогда
			Возврат ТаблицаСтруктурТипаЭлемента;
		КонецЕсли; 
		Если НРег(ИнфоТипа.TypeKindString) = "coclass" Тогда
			МассивИнфоТипа = ИнфоТипа.Interfaces;
		Иначе
			МассивИнфоТипа = Новый Массив;
			МассивИнфоТипа.Добавить(ИнфоТипа);
		КонецЕсли;
		Для Каждого ИнфоТипа Из МассивИнфоТипа Цикл
			Для Каждого Член Из ИнфоТипа.Members Цикл
				Если Истина
					//И Член.InvokeKind = 1 // метод // почему то иногда у него стоит 2 (например ADODB.Fields)
					И ирОбщий.СтрокиРавныЛкс(Член.Name, "Item") 
				Тогда
					ИнфоТипаЭлемента = Член.ReturnType.TypeInfo;
					ИмяОбщегоТипаЭлемента = ПолучитьТипЗначенияЧленаИнтерфейса(ИмяБиблиотеки, Член.ReturnType);
					ТипыЭлементовКоллекции.Добавить(ИмяОбщегоТипаЭлемента);
					Прервать;
				КонецЕсли; 
			КонецЦикла;
		КонецЦикла;
	Иначе
		СтруктураКлюча = Новый Структура("Слово, ЯзыкПрограммы", СтруктураТипаКоллекции.ИмяОбщегоТипа, ЯзыкПрограммы);
		НайденныеСтроки = ТаблицаОбщихТипов.НайтиСтроки(СтруктураКлюча);
		Если НайденныеСтроки.Количество() > 0 Тогда
			Если НайденныеСтроки[0].ТипЭлементаКоллекции <> "" Тогда
				ТипыЭлементовКоллекции = ирОбщий.ПолучитьМассивИзСтрокиСРазделителемЛкс(НайденныеСтроки[0].ТипЭлементаКоллекции, ",", Истина);
			КонецЕсли;
		КонецЕсли; 
	КонецЕсли; 
	Возврат ТипыЭлементовКоллекции;

КонецФункции

// Добавляет и заполяет строку в таблицу слов при условии отсутствия там строк по ключу (Слово, ТипСлова)
//
// Параметры:
//  ТаблицаСлов  – ТаблицаЗначений – ПолучитьНовуюВнутреннююТаблицуСлов();
//  Слово        – Строка;
//  ТипСлова     – Строка;
//  ТаблицаСтруктурТипов - ТаблицаЗначений.
//
Функция ДобавитьВТаблицуСлов(ТаблицаСлов, Слово, ТипСлова, ТаблицаСтруктурТипов =  Неопределено, ТипЗначения = "") Экспорт

	КлючПоиска = Новый Структура("Слово, ТипСлова", Слово, ТипСлова);
	НайденныеСтроки = ТаблицаСлов.НайтиСтроки(КлючПоиска);
	Если НайденныеСтроки.Количество() > 0 Тогда
		Возврат НайденныеСтроки[0];
	КонецЕсли;
	СтрокаСлова = ТаблицаСлов.Добавить();
	ЗаполнитьЗначенияСвойств(СтрокаСлова, КлючПоиска);
	СтрокаСлова.ТипЗначения = ТипЗначения;
	Если ТаблицаСтруктурТипов <> Неопределено Тогда
		СтрокаСлова.ТаблицаСтруктурТипов = ТаблицаСтруктурТипов;
	КонецЕсли; 
	Возврат СтрокаСлова;

КонецФункции // ДобавитьВТаблицуСлов()

// Получает таблицу слов указанной структуры типа.
//
// Параметры:
// СтруктураТипа – Структура – описание типа.
//
// Возвращаемое значение:
//  ТаблицаЗначений – с колонками "Слово", "ТипСлова", "ТаблицаСтруктурТипов", "Определение".
//
Функция ПолучитьТаблицуСловСтруктурыТипа(СтруктураТипа, ЯзыкПрограммы = 0, Конфигурация = Неопределено, ВнешниеФункцииКомпоновкиДанных = Истина, ВычислятьТипы = Истина,
	РазрешитьСозданиеОбъектаИзТипа = Истина) Экспорт 

	ИнициализацияОписанияМетодовИСвойств();
	ВнутренняяТаблицаСлов = ПолучитьВнутреннююТаблицуПредопределенныхСлов(СтруктураТипа,,,,ЯзыкПрограммы, Конфигурация, ВычислятьТипы);
	ВнутренняяТаблицаСлов.Колонки.Добавить("Определение");
	ВнутренняяТаблицаСлов.ЗаполнитьЗначения("Предопределенный", "Определение");
	ВнутренняяТаблицаМетаданныхСлов = ПолучитьВнутреннююТаблицуМетаданныхСлов(СтруктураТипа,,,,ЯзыкПрограммы,, ВнешниеФункцииКомпоновкиДанных, ВычислятьТипы);
	ВнутренняяТаблицаМетаданныхСлов.Колонки.Добавить("Определение");
	ВнутренняяТаблицаМетаданныхСлов.ЗаполнитьЗначения("Метаданные", "Определение");
	// ЗагрузитьВТаблицуЗначений()
	Для каждого СтрокаТаблицыИсточника Из ВнутренняяТаблицаМетаданныхСлов Цикл
		СтрокаТаблицыПриемника = ВнутренняяТаблицаСлов.Добавить();
		ЗаполнитьЗначенияСвойств(СтрокаТаблицыПриемника, СтрокаТаблицыИсточника);
	КонецЦикла;
	#Если Клиент Тогда
		// Дополнительные свойства от информатора
		Если Истина
			//И Не ЗначениеЗаполнено(Конфигурация) 
			//И ирКэш.НомерИзданияПлатформыЛкс() <> "83" // Антибаг информатора. Падает на 8.3
			И (Ложь
				Или ЯзыкПрограммы = 0
				Или (Истина
					И ЯзыкПрограммы = 2
					И ВнешниеФункцииКомпоновкиДанных
					И ирОбщий.ПолучитьПервыйФрагментЛкс(СтруктураТипа.ИмяОбщегоТипа) = "ОбщийМодуль"))
		Тогда
			ЗначениеПолучено = Ложь;
			Если Ложь
				Или СтруктураТипа.ИмяОбщегоТипа = "Глобальный контекст"
				Или СтруктураТипа.ИмяОбщегоТипа = "Локальный контекст"
				Или ирОбщий.ПолучитьПервыйФрагментЛкс(СтруктураТипа.ИмяОбщегоТипа) = "ОбщийМодуль"
			Тогда
				ЗначениеДляИнформатора = Неопределено;
				Если ирОбщий.ПолучитьПервыйФрагментЛкс(СтруктураТипа.ИмяОбщегоТипа) = "ОбщийМодуль" Тогда
					ЗначениеДляИнформатора = СтруктураТипа.Метаданные;
				КонецЕсли; 
				ЗначениеПолучено = Истина;
			Иначе
				КонкретныйТип = ПолучитьСтрокуКонкретногоТипа(СтруктураТипа);
				Если РазрешитьСозданиеОбъектаИзТипа И ЛиИнформаторДоступен() Тогда
					Попытка
						ЗначениеДляИнформатора = Новый (КонкретныйТип); // Опасно. Возможны падения.
						ЗначениеПолучено = Истина;
					Исключение
					КонецПопытки; 
				КонецЕсли; 
			КонецЕсли; 
			Если ЗначениеПолучено Тогда
				ВнутренняяТаблицаСлов.Индексы.Добавить("Слово, ТипСлова");
				ТаблицаМетодовИнформатора = ПолучитьТаблицуСвойствОбъектаИнформатором(ЗначениеДляИнформатора, "Метод");
				Для Каждого СтрокаМетода Из ТаблицаМетодовИнформатора Цикл
					НоваяСтрока = ДобавитьВТаблицуСлов(ВнутренняяТаблицаСлов, СтрокаМетода.Name, "Метод");
					Если ЗначениеЗаполнено(НоваяСтрока.Определение) Тогда
						Продолжить;
					КонецЕсли; 
					НоваяСтрока.Определение = "Локальный";
					Если СтрокаМетода.Val > 0 Тогда
						НоваяСтрока.ТипЗначения = "Произвольный";
						//НоваяСтрока.ТаблицаСтруктурТипов = ПолучитьНовуюТаблицуСтруктурТипа();
						//СтруктураТипаРезультата = ПолучитьНовуюСтруктуруТипа();
						//СтруктураТипаРезультата.ИмяОбщегоТипа = "Произвольный";
						//ЗаполнитьЗначенияСвойств(НоваяСтрока.ТаблицаСтруктурТипов.Добавить(), СтруктураТипаРезультата);
					КонецЕсли; 
				КонецЦикла; 
				ТаблицаСвойствИнформатора = ПолучитьТаблицуСвойствОбъектаИнформатором(ЗначениеДляИнформатора, "Свойство");
				Для Каждого СтрокаСвойства Из ТаблицаСвойствИнформатора Цикл
					НоваяСтрока = ДобавитьВТаблицуСлов(ВнутренняяТаблицаСлов, СтрокаСвойства.Name, "Свойство");
					Если ЗначениеЗаполнено(НоваяСтрока.Определение) Тогда
						Продолжить;
					КонецЕсли; 
					НоваяСтрока.Определение = "Локальный";
					//НоваяСтрока.ТаблицаСтруктурТипов = ПолучитьНовуюТаблицуСтруктурТипа();
				КонецЦикла; 
			КонецЕсли; 
		КонецЕсли; 
	#КонецЕсли
		
	Возврат ВнутренняяТаблицаСлов;

КонецФункции // ПолучитьТаблицуСловОбъекта()

// Получает новую структуру типа.
//
// Параметры:
//  Нет.
//
// Возвращаемое значение:
//   Структура - "ИмяОбщегоТипа", "Метаданные", "СтрокаОписания", "ТипЯзыка", "ВиртуальнаяТаблица".
//
Функция ПолучитьНовуюТаблицуДополнительныхТипов() Экспорт

	ТаблицаСтруктурТипа = Новый ТаблицаЗначений;
	ТаблицаСтруктурТипа.Колонки.Добавить("ИмяОбщегоТипа", Новый ОписаниеТипов("Строка"));
	ТаблицаСтруктурТипа.Колонки.Добавить("Метаданные");
	//ТаблицаСтруктурТипа.Колонки.Добавить("ВключатьСвойства", Новый  ОписаниеТипов("Булево"));
	ТаблицаСтруктурТипа.Колонки.Добавить("НеВключатьМетоды", Новый  ОписаниеТипов("Булево"));
	Возврат ТаблицаСтруктурТипа;

КонецФункции // ПолучитьНовуюТаблицуДополнительныхТипов()

// Получает допустимые типы (строку) из таблицы структур типа.
//
// Параметры:
//  ТаблицаСтруктурТипов – ТаблицаЗначений.
//
// Возвращаемое значение:
//  Строка.
//
Функция ПолучитьДопустимыеТипыИзТаблицыСтруктурТипа(ТаблицаСтруктурТипов) Экспорт

	СтрокаСериализованныхТипов = "";
	Для Каждого СтруктураТипа Из ТаблицаСтруктурТипов Цикл
		СтрокаСериализованныхТипов = СтрокаСериализованныхТипов + ";" + СтруктураТипаВСтрокуВнутр(СтруктураТипа);
	КонецЦикла;
	СтрокаСериализованныхТипов = Сред(СтрокаСериализованныхТипов, 2);
	Возврат СтрокаСериализованныхТипов;

КонецФункции // ПолучитьДопустимыеТипыИзТаблицыСтруктурТипа()

Функция ПолучитьДопустимыеТипыИзОписанияТипов(ОписаниеТипов) Экспорт

	ТаблицаСтруктурТипов = ПолучитьТаблицуСтруктурТиповИзОписанияТипов(ОписаниеТипов);
	ДопустимыеТипы = ПолучитьДопустимыеТипыИзТаблицыСтруктурТипа(ТаблицаСтруктурТипов);
	Возврат ДопустимыеТипы;

КонецФункции // ПолучитьДопустимыеТипыИзТаблицыСтруктурТипа()

// Получает представление допустимых типов.
//
// Параметры:
//  ДопустимыеТипы – Строка.
//
// Возвращаемое значение:
//  СтрокаПредставления – Строка.
//
Функция ПолучитьПредставлениеДопустимыхТипов(ДопустимыеТипы) Экспорт

	ТаблицаСтруктурТипов = ПолучитьТаблицуСтруктурТиповИзДопустимыхТипов(ДопустимыеТипы);
	СтрокаПредставления = "";
	Для Каждого СтруктураТипа Из ТаблицаСтруктурТипов Цикл
		СтрокаПредставления = СтрокаПредставления + ", " + ПолучитьСтрокуКонкретногоТипа(СтруктураТипа);
		ТипМетаданных = ТипЗнч(СтруктураТипа.Метаданные);
		Если ТипМетаданных = Тип("КвалификаторыДаты") Тогда 
			Квалификаторы = СтруктураТипа.Метаданные;
			Если Квалификаторы.ЧастиДаты = ЧастиДаты.Время Тогда
				ПредставлениеСоставаДаты = "В";
			ИначеЕсли Квалификаторы.ЧастиДаты = ЧастиДаты.Дата Тогда
				ПредставлениеСоставаДаты = "Д";
			ИначеЕсли Квалификаторы.ЧастиДаты = ЧастиДаты.ДатаВремя Тогда
				ПредставлениеСоставаДаты = "ДВ";
			КонецЕсли;
			СтрокаПредставления = СтрокаПредставления + "(" + ПредставлениеСоставаДаты + ")";
		ИначеЕсли ТипМетаданных = Тип("КвалификаторыСтроки") Тогда 
			Квалификаторы = СтруктураТипа.Метаданные;
			СтрокаПредставления = СтрокаПредставления + "(" 
				+ Квалификаторы.Длина + "," 
				+ ?(Квалификаторы.ДопустимаяДлина = ДопустимаяДлина.Фиксированная, "Ф", "П") + ")";
		ИначеЕсли ТипМетаданных = Тип("КвалификаторыЧисла") Тогда 
			Квалификаторы = СтруктураТипа.Метаданные;
			СтрокаПредставления = СтрокаПредставления + "("
				+ ?(Квалификаторы.ДопустимыйЗнак = ДопустимыйЗнак.Неотрицательный, "Н", "")
				+ Квалификаторы.Разрядность + "," 
				+ Квалификаторы.РазрядностьДробнойЧасти + ")";
        КонецЕсли; 
	КонецЦикла;
	СтрокаПредставления = Сред(СтрокаПредставления, 3);
	Возврат СтрокаПредставления;

КонецФункции // ПолучитьПредставлениеДопустимыхТипов()

// Получает структуру типа из значения.
//
// Параметры:
//  Значение – Произвольный;
//  *ЯзыкПрограммы - Число, *0;
//  *ШаблонСтруктурыТипа - Структура, *Неопределено - содержит значения по умолчанию для новой структуры типа.
//
// Возвращаемое значение:
//  Структура – структура типа.
//
Функция ПолучитьСтруктуруТипаИзЗначения(Значение, ЯзыкПрограммы = 0, ШаблонСтруктурыТипа = Неопределено) Экспорт
	
	Если Истина
		И ШаблонСтруктурыТипа = Неопределено
		//И (Ложь
		//	#Если Клиент Тогда
		//	Или ТипЗнч(Значение) = Тип("Форма")
		//	Или ТипЗнч(Значение) = Тип("ПолеВвода")
		//	//Или ТипЗнч(Значение) = Тип("КолонкаТабличногоПоля")
		//	Или ТипЗнч(Значение) = Тип("ТабличноеПоле")
		//	#КонецЕсли 
		//	Или ТипЗнч(Значение) = Тип("Структура")
		//	Или ТипЗнч(Значение) = Тип("ТаблицаЗначений")
		//	Или ТипЗнч(Значение) = Тип("ДеревоЗначений")
		//	Или ТипЗнч(Значение) = Тип("ОбъектМетаданных"))
		И мМассивТиповВключающихМетаданные.Найти(ТипЗнч(Значение)) <> Неопределено

	Тогда
		ШаблонСтруктурыТипа = Новый Структура("Метаданные", Значение);
	КонецЕсли; 
	СтруктураТипа = ПолучитьСтруктуруТипаИзКонкретногоТипа(ТипЗнч(Значение), ЯзыкПрограммы, ШаблонСтруктурыТипа);
	Если СтруктураТипа.ИмяОбщегоТипа = "COMОбъект" Тогда
		СтруктураТипа.ИмяОбщегоТипа = ПолучитьПолноеИмяТипаCOMОбъекта(Значение);
	КонецЕсли; 
	ИмяОбщегоТипа = СтруктураТипа.ИмяОбщегоТипа;
	Если Ложь
		Или (Истина
			И ИмяОбщегоТипа = "СтрокаТаблицыЗначений"
			И ТипЗнч(СтруктураТипа.Метаданные) <> Тип("ТаблицаЗначений"))
		Или (Истина
			И ИмяОбщегоТипа = "СтрокаДереваЗначений"
			И ТипЗнч(СтруктураТипа.Метаданные) <> Тип("ДеревоЗначений"))
		Или (Истина
			И ИмяОбщегоТипа = "ВыборкаИзРезультатаЗапроса"
			И ТипЗнч(СтруктураТипа.Метаданные) <> Тип("РезультатЗапроса"))
	Тогда 
		Попытка
			СтруктураТипа.Метаданные = Значение.Владелец();
		Исключение
			// Строка была удалена из коллекции
		КонецПопытки; 
	КонецЕсли;
	Если Ложь
		Или ИмяОбщегоТипа = "ВнешняяОбработкаОбъект.<Имя внешней обработки>"
		Или ИмяОбщегоТипа = "ВнешнийОтчетОбъект.<Имя внешнего отчета>"
	Тогда
		МетаданныеЗначения = Значение.Метаданные();
		ЛиНеУчитыватьПодтип = (ЯзыкПрограммы <> 0) И СтруктураТипа.ТипЯзыка <> "ЗначениеВЗапросе";
		ИмяОбщегоТипа = ПолучитьИмяОбщегоТипаПоТипуЗначенияСМетаданными(ТипЗнч(Значение), МетаданныеЗначения, ЛиНеУчитыватьПодтип);
		СтруктураТипа.Метаданные = МетаданныеЗначения;
		КлючПоиска = Новый Структура("Слово", ИмяОбщегоТипа);
		НайденныеСтроки = ТаблицаОбщихТипов.НайтиСтроки(КлючПоиска);
		Если НайденныеСтроки.Количество() > 0 Тогда
			СтруктураТипа.ИмяОбщегоТипа = НайденныеСтроки[0].Слово;
			Если СтруктураТипа.СтрокаОписания = Неопределено Тогда
				СтруктураТипа.СтрокаОписания = НайденныеСтроки[0];
			КонецЕсли;
		КонецЕсли;
	КонецЕсли;
	
	#Если Клиент Тогда
	МаркерРасширений = "Расширение ";
	Если Ложь
		Или ИмяОбщегоТипа = "Форма"
		Или ИмяОбщегоТипа = "ПолеВвода"
		//Или ИмяОбщегоТипа = "КолонкаТабличногоПоля"
		Или ИмяОбщегоТипа = "ТабличноеПоле"
	Тогда
		РасширяющийТип = Неопределено;
		Если ИмяОбщегоТипа = "Форма" Тогда
			ОсновнойРеквизитФормы = ПолучитьИмяОсновногоРеквизитаФормы(Значение);
			Если ЗначениеЗаполнено(ОсновнойРеквизитФормы) Тогда
			    СтруктураРасширяющегоТипа = ПолучитьСтруктуруТипаИзЗначения(Значение[ОсновнойРеквизитФормы]);
				РасширяющийТип = СтруктураРасширяющегоТипа.ИмяОбщегоТипа;
			КонецЕсли;
		Иначе
			Попытка
				ДанныеЭлементаФормы = Значение.Значение;
			Исключение
				// Случается из-за особенностей платформы. Иногда она убирает это свойство из элемента управления.
			КонецПопытки;
			СтруктураРасширяющегоТипа = ПолучитьСтруктуруТипаИзЗначения(ДанныеЭлементаФормы);
			РасширяющийТип = СтруктураРасширяющегоТипа.ИмяОбщегоТипа;
			Попытка 
				Пустышка = Тип("Перечисление" + СтруктураРасширяющегоТипа.ИмяОбщегоТипа);
				РасширяющийТип = "Системное перечисление";
			Исключение
			КонецПопытки;
		КонецЕсли;
		
		Если РасширяющийТип <> Неопределено Тогда
			Если РасширяющийТип = "ВнешняяОбработкаОбъект.<Имя внешней обработки>" Тогда 
				РасширяющийТип = "ОбработкаОбъект.<Имя обработки>";
			ИначеЕсли РасширяющийТип = "ВнешнийОтчетОбъект.<Имя внешнего отчета>" Тогда 
				РасширяющийТип = "ОтчетОбъект.<Имя отчета>";
			КонецЕсли;
			СтруктураКлюча = Новый Структура("РасширяющийТип, ОсновнойТип", РасширяющийТип, ИмяОбщегоТипа);
			МассивНайденных = ТаблицаРасширенийТипов.НайтиСтроки(СтруктураКлюча);
			Если МассивНайденных.Количество() > 0 Тогда
				СтруктураТипа.ИмяОбщегоТипа = МассивНайденных[0].Расширение;
			КонецЕсли;
		КонецЕсли;
	КонецЕсли;
	Если ИмяОбщегоТипа = "Форма" Тогда 
		СтруктураТипа.ДержательМетаданных = Значение;
	КонецЕсли;

	#КонецЕсли

	Возврат СтруктураТипа;

КонецФункции // ПолучитьСтруктуруТипаИзЗначения()

// <Описание функции>
//
// Параметры:
//  <Параметр1>  – <Тип.Вид> – <описание параметра>
//                 <продолжение описания параметра>;
//  <Параметр2>  – <Тип.Вид> – <описание параметра>
//                 <продолжение описания параметра>.
//
// Возвращаемое значение:
//               – <Тип.Вид> – <описание значения>
//                 <продолжение описания значения>;
//  <Значение2>  – <Тип.Вид> – <описание значения>
//                 <продолжение описания значения>.
//
Функция ПолучитьУникальныйИдентификаторИзСтроки(Текст) Экспорт

	Цифра = "[a-fA-F0-9]";
	RegExp.Pattern = "(" + ирОбщий.ПолучитьСтрокуПовторомЛкс(Цифра, 32) + ")|(" 
		+ ирОбщий.ПолучитьСтрокуПовторомЛкс(Цифра, 8) + "-" 
		+ ирОбщий.ПолучитьСтрокуПовторомЛкс(Цифра, 4) + "-"
		+ ирОбщий.ПолучитьСтрокуПовторомЛкс(Цифра, 4) + "-"
		+ ирОбщий.ПолучитьСтрокуПовторомЛкс(Цифра, 4) + "-"
		+ ирОбщий.ПолучитьСтрокуПовторомЛкс(Цифра, 12) + ")";
	Вхождения = RegExp.Execute(Текст);
	Если Вхождения.Count > 0 Тогда
		Вхождение = Вхождения.Item(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 
	Тогда
		Подтип = "МенеджерЗначения";
	ИначеЕсли Ложь
		Или Найти(КонкрентыйТип, "табличная часть:") > 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, ШаблонСтруктурыТипа = Неопределено) Экспорт
	
	СтруктураТипа = ПолучитьНовуюСтруктуруТипа();
	СтруктураТипа.Метаданные = мМетаданные;
	Если ШаблонСтруктурыТипа <> Неопределено Тогда
		ЗаполнитьЗначенияСвойств(СтруктураТипа, ШаблонСтруктурыТипа);
	КонецЕсли;
	Если КонкрентыйТип = Тип("ОбъектМетаданных") Тогда
		Если Истина
			И ШаблонСтруктурыТипа <> Неопределено // было закомментировано
			И ТипЗнч(ШаблонСтруктурыТипа.Метаданные) = Тип("ОбъектМетаданных")
		Тогда
			МассивФрагментов = ирОбщий.ПолучитьМассивИзСтрокиСРазделителемЛкс(ШаблонСтруктурыТипа.Метаданные.ПолноеИмя());
			СтруктураТипа.ИмяОбщегоТипа = МаркерОбъектаМетаданных + ": " + МассивФрагментов[МассивФрагментов.ВГраница() - 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 По МассивФрагментов.Количество() / 2 - 1 Цикл
			ИмяЭлементаКоллекции = ирОбщий.ПолучитьСтрокуМеждуМаркерамиЛкс(КонкретныйТип, "<", ">", Ложь, Истина);
			КонкретныйТип = СтрЗаменить(КонкретныйТип, ИмяЭлементаКоллекции, МассивФрагментов[Счетчик * 2 + 1]);
		КонецЦикла;
	ИначеЕсли Истина
		И Это2iS
		И (Ложь
			Или ТипМетаданных = Тип("СправочникСсылка.ОбъектыМетаданных2iS")
			Или ТипМетаданных = Тип("СправочникСсылка.СвойстваМетаданных2iS"))
	Тогда
		ОбъектМД = КэшОбъект(СтруктураТипа.Метаданные);
		ПолноеИмя = ОбъектМД.ПолноеИмя;
		МассивФрагментов = ирОбщий.ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмя);
		Если МассивФрагментов[0] = "ТабличнаяЧасть" Тогда
			// Баг платформы. У внешних метаданных полное имя не включает сам внешний метаобъект
			МассивФрагментов.Вставить(0, "Имя");
			МассивФрагментов.Вставить(0, "");
		КонецЕсли;
		Для Счетчик = 0 По МассивФрагментов.Количество() / 2 - 1 Цикл
			ИмяЭлементаКоллекции = ирОбщий.ПолучитьСтрокуМеждуМаркерамиЛкс(КонкретныйТип, "<", ">", Ложь, Истина);
			КонкретныйТип = СтрЗаменить(КонкретныйТип, ИмяЭлементаКоллекции, МассивФрагментов[Счетчик * 2 + 1]);
		КонецЦикла;
	//ИначеЕсли ТипЗнч(СтруктураТипа.Метаданные) = Тип("Соответствие") Тогда
	//	Для Каждого ЭлементВида Из СтруктураТипа.Метаданные Цикл
	//		КонкретныйТип = СтрЗаменить(КонкретныйТип, ЭлементВида.Ключ, ЭлементВида.Значение);
	//	КонецЦикла;
	КонецЕсли;
    Возврат КонкретныйТип;
	
КонецФункции // ПолучитьСтрокуКонкретногоТипа()

// Получает новую структуру типа.
//
// Параметры:
//  Нет.
//
// Возвращаемое значение:
//   Структура - "ИмяОбщегоТипа", "Метаданные", "СтрокаОписания", "ТипЯзыка", "ВиртуальнаяТаблица".
//
Функция ПолучитьНовуюСтруктуруТипа() Экспорт

	Возврат Новый Структура("ИмяОбщегоТипа, Метаданные, СтрокаОписания, ТипЯзыка, Конструктор, ВиртуальнаяТаблица, ДополнительныеТипы, ДержательМетаданных",
		"Неизвестный контекст", Неопределено, Неопределено, "", Ложь, Новый Структура("Выражение, НомерСтроки", "", 0));

КонецФункции // ПолучитьНовуюСтруктуруТипа()

// Десериализатор структуры типа из неполной сериализации.
//
// Параметры:
//  СтрокаСтруктурыТипа – Строка.
//
// Возвращаемое значение:
// СтруктураТипа – Структура.
//
Функция СтруктураТипаИзСтрокиВнутр(СтрокаСтруктурыТипа) Экспорт

	СтруктураТипа = ПолучитьНовуюСтруктуруТипа();
	Если ПустаяСтрока(СтрокаСтруктурыТипа) Тогда
		Возврат СтруктураТипа;
	КонецЕсли;
	Успех = Ложь;
	Попытка
		ОписательТипа = ЗначениеИзСтрокиВнутр(СтрокаСтруктурыТипа);
		Успех = Истина;
	Исключение
		ОписательТипа = ПолучитьНовуюСтруктуруТипа();
		ОписательТипа.ИмяОбщегоТипа = "<Ошибка преобразования>";
	КонецПопытки;
	Если Успех Тогда
		СтруктураТипа.ИмяОбщегоТипа = ОписательТипа.ИмяОбщегоТипа;
		Если ТипЗнч(ОписательТипа.Метаданные) = Тип("Строка") Тогда
			//СтруктураТипа.Метаданные = мМетаданные.НайтиПоПолномуИмени(ОписательТипа.Метаданные);
			СтруктураТипа.Метаданные = ПолучитьОбъектМДПоПолномуИмени(ОписательТипа.Метаданные);
		ИначеЕсли ТипЗнч(ОписательТипа.Метаданные) = Тип("ХранилищеЗначения") Тогда
			Поток = Новый ЧтениеXML;
			Поток.УстановитьСтроку(ОписательТипа.Метаданные.Получить());
			// Тут тормоз
			СтруктураТипа.Метаданные = СериализаторXDTO.ПрочитатьXML(Поток);
		Иначе
			СтруктураТипа.Метаданные = ОписательТипа.Метаданные;
		КонецЕсли;
	КонецЕсли; 
	Возврат СтруктураТипа;

КонецФункции // СтруктураТипаВСтрокуВнутр()

// Получает новую структуру типа.
//
// Параметры:
//  Нет.
//
// Возвращаемое значение:
//   Структура - "ИмяОбщегоТипа", "Метаданные", "СтрокаОписания", "ТипЯзыка", "ВиртуальнаяТаблица".
//
Функция ПолучитьНовуюТаблицуСтруктурТипа() Экспорт

	Возврат мТаблицаСтруктурТипа.СкопироватьКолонки();

КонецФункции // ПолучитьНовуюСтруктуруТипа()

// Добавляет структуру типа в таблицу структур типов.
//
// Параметры:
//  ТаблицаСтруктурТипов – ТаблицаЗначений;
//  СтруктураТипа – Структура.
//
Процедура ДобавитьВТаблицуСтруктурТипов(ТаблицаСтруктурТипов, СтруктураТипа, ПередаватьДополнительныеТипы = Ложь) Экспорт 

	ИсключаемыеСвойства = Неопределено;
	Если Не ПередаватьДополнительныеТипы Тогда
		ИсключаемыеСвойства = "ДополнительныеТипы";
	КонецЕсли;
	ЗаполнитьЗначенияСвойств(ТаблицаСтруктурТипов.Добавить(), СтруктураТипа, , ИсключаемыеСвойства);

КонецПроцедуры // ДобавитьВТаблицуСтруктурТипов()

// Получает массив структур типов из строки допустимых типов.
//
// Параметры:
//  ДопустимыеТипы – Строка;
//  *ШаблонСтруктурыТипа - Структура, *Неопределено - содержит значения по умолчанию для новой структуры типа.
//
// Возвращаемое значение:
//  Структура – структура типа.
//
Функция ПолучитьТаблицуСтруктурТиповИзДопустимыхТипов(ДопустимыеТипы, ШаблонСтруктурыТипа = Неопределено) Экспорт 

	ТаблицаСтруктурТипов = ПолучитьНовуюТаблицуСтруктурТипа();
	Если ПустаяСтрока(ДопустимыеТипы) Тогда
		Возврат ТаблицаСтруктурТипов;
	КонецЕсли;
	МассивСериализованныхТипов = ирОбщий.ПолучитьМассивИзСтрокиСРазделителемЛкс(ДопустимыеТипы, ";");
	Для Каждого СериализованныйТип Из МассивСериализованныхТипов Цикл
		СтруктураТипа = СтруктураТипаИзСтрокиВнутр(СериализованныйТип);
		Если ШаблонСтруктурыТипа <> Неопределено Тогда
			ЗаполнитьЗначенияСвойств(СтруктураТипа, ШаблонСтруктурыТипа);
		КонецЕсли;
		ДобавитьВТаблицуСтруктурТипов(ТаблицаСтруктурТипов, СтруктураТипа);
	КонецЦикла;
	Возврат ТаблицаСтруктурТипов;

КонецФункции // ПолучитьТаблицуСтруктурТиповИзДопустимыхТипов()

// Получает описание типов из допустимых типов.
//
// Параметры:
//  ДопустимыеТипы – Строка;
//  ТипЗначенияЭУ  - ОписаниеТипов - все возможные типы из элемента управления.
//
// Возвращаемое значение:
//  ОписаниеТипов.
//
Функция ПолучитьОписаниеТиповИзДопустимыхТипов(ДопустимыеТипы, ТипЗначенияЭУ = Неопределено) Экспорт

	ТаблицаСтруктурТипов = ПолучитьТаблицуСтруктурТиповИзДопустимыхТипов(ДопустимыеТипы);
	ОписаниеТипов = ПолучитьОписаниеТиповИзТаблицыСтруктурТипов(ТаблицаСтруктурТипов, ТипЗначенияЭУ);
	Возврат ОписаниеТипов;

КонецФункции // ПолучитьОписаниеТиповИзДопустимыхТипов()

// Получает описание типов из таблицы структур типов.
//
// Параметры:
//  ДопустимыеТипы – Строка;
//  ТипЗначенияЭУ  - ОписаниеТипов - все возможные типы из элемента управления.
//
// Возвращаемое значение:
//  ОписаниеТипов.
//
Функция ПолучитьОписаниеТиповИзТаблицыСтруктурТипов(ТаблицаСтруктурТипов, ТипЗначенияЭУ = Неопределено) Экспорт

	Если ТаблицаСтруктурТипов = Неопределено Тогда
		Возврат Новый ОписаниеТипов;
	КонецЕсли; 
	МассивТипов = Новый Массив;
	Для Каждого СтруктураТипа Из ТаблицаСтруктурТипов Цикл
		СтрокаКонкретногоТипа = ПолучитьСтрокуКонкретногоТипа(СтруктураТипа);
		Попытка
			ТекущийТип = Тип(СтрокаКонкретногоТипа);
		Исключение
			Продолжить;
		КонецПопытки;
		ТипМетаданных = ТипЗнч(СтруктураТипа.Метаданные);
		Если ТипМетаданных = Тип("КвалификаторыСтроки") Тогда
			КвалификаторыСтроки = СтруктураТипа.Метаданные;
		ИначеЕсли ТипМетаданных = Тип("КвалификаторыЧисла") Тогда
			КвалификаторыЧисла = СтруктураТипа.Метаданные;
		ИначеЕсли ТипМетаданных = Тип("КвалификаторыДаты") Тогда
			КвалификаторыДаты = СтруктураТипа.Метаданные;
		КонецЕсли; 
		Если ТипЗначенияЭУ <> Неопределено Тогда
			Если Не ТипЗначенияЭУ.СодержитТип(ТекущийТип) Тогда
				Продолжить;
			КонецЕсли;
		КонецЕсли;
		МассивТипов.Добавить(ТекущийТип);
	КонецЦикла;
	ОписаниеТипов = Новый ОписаниеТипов(МассивТипов, КвалификаторыЧисла, КвалификаторыСтроки, КвалификаторыСтроки);
	Возврат ОписаниеТипов;

КонецФункции // ПолучитьОписаниеТиповИзДопустимыхТипов()

// Получает строку типа метаобъектов по единственному или множественному числу.
//
// Параметры:
//  *Единственное – Строка, *Неопределено - единственное число типа;
//  *Множественное – Строка, *Неопределено - множественное число типа.
//  *Категория  – Число, *Неопределено.
//
// Возвращаемое значение:
//  СтрокаТаблицыЗначений - найденная строка типа;
//  Неопределено – корневой тип не найден.
//
Функция ПолучитьСтрокуТипаМетаОбъектов(Единственное = Неопределено, Множественное = Неопределено, Категория = Неопределено) Экспорт
	
	СтруктураПоиска = Новый Структура;
	Если Категория <> Неопределено Тогда
		СтруктураПоиска.Вставить("Категория", Категория);
	КонецЕсли;
	Если Единственное = Неопределено Тогда
		СтруктураПоиска.Вставить("Множественное", Множественное);
	Иначе
		СтруктураПоиска.Вставить("Единственное", Единственное);
	КонецЕсли;
	НайденныеСтроки = ТаблицаТиповМетаОбъектов.НайтиСтроки(СтруктураПоиска);
	Если НайденныеСтроки.Количество() = 0 Тогда
		Результат = Неопределено;
	Иначе
		Результат = НайденныеСтроки[0];
	КонецЕсли;
	Возврат Результат;

КонецФункции // ПолучитьСтрокуТипаМетаОбъектов()

// Проверяет общий тип на агрегатность.
//
// Параметры:
//  ИмяОбщегоТипа - Строка;
//  *ЯзыкПрограммы - *Число, 0.
//
// Возвращаемое значение:
//  Булево.
//
Функция ЭтоАгрегатныйОбщийТип(ИмяОбщегоТипа, ЯзыкПрограммы = 0) Экспорт 

	Если ИмяОбщегоТипа = "" Тогда
		Возврат Ложь;
	КонецЕсли;
	
	СтруктураКлюча = Новый Структура("ТипКонтекста, ЯзыкПрограммы", ИмяОбщегоТипа, ЯзыкПрограммы);
	Если Истина
		И ТаблицаКонтекстов.НайтиСтроки(СтруктураКлюча).Количество() = 0
		И ТаблицаШаблоновКонтекстов.НайтиСтроки(СтруктураКлюча).Количество() = 0
		И Лев(ИмяОбщегоТипа, СтрДлина(МаркерCOMОбъекта)) <> МаркерCOMОбъекта
	Тогда
		Результат = Ложь;
	Иначе
		Результат = Истина;
	КонецЕсли;
	
	Возврат Результат;

КонецФункции // ЭтоАгрегатныйОбщийТип()

#Если Клиент Тогда

Функция ПолучитьСписокИнструментов() Экспорт 
	
	ТабличныйДокумент = ПолучитьМакет("СписокИнструментов");
	Список = ирОбщий.ПолучитьТаблицуИзТабличногоДокументаЛкс(ТабличныйДокумент,,,, Истина);
	Возврат Список;
	
КонецФункции

// Инициализирует полное дерево типов платформы.
//
// Параметры:
//  Нет.
//
Процедура ИнициализироватьДеревоТипов() Экспорт

	ИнициализацияОписанияМетодовИСвойств();
	
	Состояние("Инициализация дерева типов...");
	
	Если ДеревоТипов <> Неопределено Тогда
		Возврат;
	КонецЕсли;
	ДеревоТипов = Новый ДеревоЗначений;
	ДеревоТипов.Колонки.Добавить("Пометка", Новый ОписаниеТипов("Булево"));
	ДеревоТипов.Колонки.Добавить("Имя");
	ДеревоТипов.Колонки.Добавить("ИндексКартинки", Новый ОписаниеТипов("Число"));
	ДеревоТипов.Колонки.Добавить("СтруктураТипа");
	лТаблицаТипов = ТаблицаОбщихТипов.Скопировать(Новый Структура("ЯзыкПрограммы", 0), "Слово");
	лТаблицаТипов.Колонки.Слово.Имя = "Имя";
	Для Каждого СтрокаТипа Из лТаблицаТипов Цикл
		ЗаполнитьЗначенияСвойств(ДеревоТипов.Строки.Добавить(), СтрокаТипа);
	КонецЦикла;
	СтруктураТипа = ПолучитьНовуюСтруктуруТипа();
	СтруктураТипа.Метаданные = мМетаданные;
	СтруктураТипа.ТипЯзыка = "ИмяТипа";
	СтруктураТипа.ИмяОбщегоТипа = "";
	ОбработатьСтрокиДереваТипов(ДеревоТипов.Строки, СтруктураТипа);
	ДеревоТипов.Строки.Сортировать("Имя", Истина);
	ТаблицаТипов.Сортировать("Имя");
	МассивВажныхТипов = Новый Массив;
	МассивВажныхТипов.Добавить("Булево");
	МассивВажныхТипов.Добавить("Дата");
	МассивВажныхТипов.Добавить("Строка");
	МассивВажныхТипов.Добавить("Число");
	Для Каждого ВажныйТип Из МассивВажныхТипов Цикл
		СтрокаТипа = ТаблицаТипов.Найти(ВажныйТип, "Имя");
		ТаблицаТипов.Сдвинуть(СтрокаТипа, -ТаблицаТипов.Индекс(СтрокаТипа));
		СтрокаТипа = ДеревоТипов.Строки.Найти(ВажныйТип, "Имя");
		ДеревоТипов.Строки.Сдвинуть(СтрокаТипа, -ДеревоТипов.Строки.Индекс(СтрокаТипа));
	КонецЦикла; 
	Состояние("");

КонецПроцедуры // ИнициализироватьДеревоТипов()

Процедура ОбработатьСтрокиДереваТипов(Строки, КорневаяСтруктураТипа = Неопределено, ОкончаниеСтрокиТипа = "",
	МетаданныеТипа = Неопределено) Экспорт

	МассивСтрокКУдалению = Новый Массив;
	Для Каждого СтрокаТипа Из Строки Цикл
		ТекущееИмяТипа = СтрокаТипа.Имя;
		СтрокаТипа.Имя = СтрокаТипа.Имя + ОкончаниеСтрокиТипа;
		Уровень = СтрокаТипа.Уровень();
		ФрагментыОбщегоТипа = Неопределено;
		Если Уровень = 0 Тогда
			Если Найти(ТекущееИмяТипа, ".") > 0 Тогда
				ФрагментыОбщегоТипа = ирОбщий.ПолучитьМассивИзСтрокиСРазделителемЛкс(ТекущееИмяТипа);
				ТекущееИмяТипа = ФрагментыОбщегоТипа[0];
			КонецЕсли;
			СтрокаТипаМетаОбъектов = ПолучитьСтрокуТипаМетаОбъектов(ТекущееИмяТипа);
			Если СтрокаТипаМетаОбъектов <> Неопределено Тогда
				СтрокаТипа.ИндексКартинки = СтрокаТипаМетаОбъектов.ИндексКартинкиЕдинственное;
			КонецЕсли;
			Уровень = 0;
			//СтрокаТипа.ИмяОбщегоТипа = ТекущееИмяТипа;
		Иначе
			Если КорневаяСтруктураТипа <> Неопределено Тогда
				КорневаяСтруктураТипа.Свойство("ФрагментыОбщегоТипа", ФрагментыОбщегоТипа);
			КонецЕсли; 
			СтрокаТипа.ИндексКартинки = Строки.Родитель.ИндексКартинки;
		КонецЕсли; 
		Если ФрагментыОбщегоТипа <> Неопределено Тогда
			Если ФрагментыОбщегоТипа.ВГраница() > Уровень Тогда
				ТекущийФрагмент = ФрагментыОбщегоТипа[Уровень + 1];
			КонецЕсли; 
			Если Найти(ТекущийФрагмент, "<") > 0 Тогда
				Если Истина
					И КорневаяСтруктураТипа = Неопределено 
				Тогда
					КорневаяСтруктураТипа = ПолучитьНовуюСтруктуруТипа();
					КорневаяСтруктураТипа.Метаданные = мМетаданные;
					КорневаяСтруктураТипа.ТипЯзыка = "ИмяТипа";
					КорневаяСтруктураТипа.ИмяОбщегоТипа = СтрокаТипа.Имя;
				КонецЕсли; 
				Если Уровень = 0 Тогда
					КорневаяСтруктураТипа.Вставить("ФрагментыОбщегоТипа", ФрагментыОбщегоТипа);
					СтруктураТипа = ПолучитьНовуюСтруктуруТипа();
					ЗаполнитьЗначенияСвойств(СтруктураТипа, КорневаяСтруктураТипа);
					СтруктураТипа.ИмяОбщегоТипа = ТекущееИмяТипа;
				Иначе
					СтруктураТипа = СтрокаТипа.СтруктураТипа;
				КонецЕсли;
				
				Попытка
					ВнутренняяТаблицаСлов = ПолучитьВнутреннююТаблицуМетаданныхСлов(СтруктураТипа, , "Свойство");
				Исключение
					ВнутренняяТаблицаСлов = Новый ТаблицаЗначений;
				КонецПопытки;
				Если Истина
					И Уровень > 0
					И ВнутренняяТаблицаСлов.Количество() = 0
				Тогда
					МассивСтрокКУдалению.Добавить(СтрокаТипа);
					Продолжить;
				Иначе
					ОкончаниеСтрокиТипаВниз = "";
					Для Счетчик = Уровень + 2 По ФрагментыОбщегоТипа.ВГраница() Цикл 
						Фрагмент = ФрагментыОбщегоТипа[Счетчик];
						ОкончаниеСтрокиТипаВниз = ОкончаниеСтрокиТипаВниз + "." + Фрагмент;
					КонецЦикла;
					Для Каждого СтрокаСлова Из ВнутренняяТаблицаСлов Цикл
						НоваяСтрока = СтрокаТипа.Строки.Добавить();
						СтруктураТипаВниз = СтрокаСлова.ТаблицаСтруктурТипов[0];
						НоваяСтрока.СтруктураТипа = СтруктураТипаВниз;
						//НоваяСтрока.Имя = ПолучитьСтрокуКонкретногоТипа(СтруктураТипаВниз);
						НоваяСтрока.Имя = ТекущееИмяТипа + "." + СтруктураТипаВниз.Метаданные.Имя;
					КонецЦикла;
					ОбработатьСтрокиДереваТипов(СтрокаТипа.Строки, КорневаяСтруктураТипа, ОкончаниеСтрокиТипаВниз);
				КонецЕсли;
			КонецЕсли;
		КонецЕсли; 
		//ЗаполнитьЗначенияСвойств(СтруктураТипа, КорневаяСтруктураТипа, "ИмяОбщегоТипа");
		ЗаполнитьЗначенияСвойств(ТаблицаТипов.Добавить(), СтрокаТипа);
	КонецЦикла;
	РодительСтрок = Строки.Родитель;
	Для Каждого СтрокаКУдалению Из МассивСтрокКУдалению Цикл
		РодительСтрок.Строки.Удалить(СтрокаКУдалению);
	КонецЦикла;

КонецПроцедуры // ОбработатьСтрокиДерева()

// Открыть диалог для редактирования допустимых типов.
//
// Параметры:
//  ДопустимыеТипы – Строка – сериализованные допустимые типы;
//  *ТолькоПросмотр – Булево, *Истина – открыть только для просмотра.
//
// Возвращаемое значение:
//  Строка - сериализованных допустимых типов;
//  Неопределено - отмена.
//
Функция РедактироватьДопустимыеТипы(ДопустимыеТипы, ТолькоПросмотр = Ложь) Экспорт

	ФормаРедактора = ПолучитьФорму("РедакторДопустимыхТипов");
	ФормаРедактора.ДопустимыеТипы = ДопустимыеТипы;
	ФормаРедактора.ТолькоПросмотр = ТолькоПросмотр;
	Если ФормаРедактора.ОткрытьМодально() = Истина Тогда 
		Возврат ФормаРедактора.ДопустимыеТипы;
	Иначе
		Возврат Неопределено;
	КонецЕсли;

КонецФункции // РедактироватьДопустимыеТипы()

// Убирает из строки лишние кавычки.
//
// Параметры:
//  ПервичнаяСтрока – Строка.
//
// Возвращаемое значение:
//  Строка.
//
Функция ИзвлечьСтрокуШаблонаТекста(ПервичнаяСтрока)

	RegExp.Global = Истина;
	СтрокаБезГраниц = Сред(ПервичнаяСтрока, 2, СтрДлина(ПервичнаяСтрока) - 2);
	RegExp.Pattern = "([^""]*"")""";
	Результат = RegExp.Replace(СтрокаБезГраниц, "$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;
	КонецЕсли;
	Возврат Результат;
	
КонецФункции

#КонецЕсли

////////////////////////////////////////////////////////////////////////////////
// РАБОТА С АЛГОРИТМАМИ

// Выполняет текст программы.
//
// Параметры:
//  ТекстДляВыполнения – Строка;
//  *ЛиСинтаксическийКонтроль - Булево, *Ложь - признак вызова только для синтаксического контроля.
//
Функция ВыполнитьЛокально(ТекстДляВыполнения, ЛиСинтаксическийКонтроль = Ложь) Экспорт 
	
	Если ЛиСинтаксическийКонтроль Тогда
		ирОбщий.ВыполнитьАлгоритмБезРезультата(ТекстДляВыполнения);
	Иначе
		ирОбщий.ВыполнитьАлгоритм(ТекстДляВыполнения);
	КонецЕсли; 

КонецФункции // ВыполнитьЛокально()

// Выполняет программный код в контексте.
//
// Параметры:
//  ТекстДляВыполнения – Строка;
//  *ЛиСинтаксическийКонтроль - Булево, *Ложь - признак вызова только для синтаксического контроля.
//
Функция ВыполнитьПрограммныйКодВКонтексте(КонтекстВыполнения, МетодВыполнения = "ВыполнитьЛокально", ТекстДляВыполнения, ЛиСинтаксическийКонтроль = Ложь) Экспорт 

	Если ПустаяСтрока(МетодВыполнения) Тогда
		ВызватьИсключение "Не указан метод выполнения";
	КонецЕсли; 
	Если КонтекстВыполнения = Неопределено Тогда
		ИнформацияОбОшибке = Вычислить(МетодВыполнения + "(ТекстДляВыполнения, ЛиСинтаксическийКонтроль)");
	Иначе
		ИнформацияОбОшибке = Вычислить("КонтекстВыполнения." + МетодВыполнения + "(ТекстДляВыполнения, ЛиСинтаксическийКонтроль)");
	КонецЕсли;
	Возврат ИнформацияОбОшибке;

КонецФункции // ВыполнитьПрограммныйКодВКонтексте()

//#КонецЕсли

#Если Клиент Тогда

Функция ПолучитьИдентификаторПроцессаОтладчика() Экспорт
	
	Перем Результат;
	ПолучитьПортДляПодключенияОтладчика(Результат);
	Возврат Результат;
	
КонецФункции

Функция ПолучитьПортДляПодключенияОтладчика(ИдентификаторПроцессаОтладчика) Экспорт
		
	ИдентификаторПроцесса = ПолучитьИдентификаторПроцессаОС();
	Команда = "netstat -n -a -o";
	ТекстРезультата = ПолучитьТекстРезультатаКомандыСистемы(Команда);
	RegExp.Global = Истина;
	RegExp.Pattern = "TCP(?:\s+)0\.0\.0\.0:(\d+)(?:\s+)(?:[0-9]{1,3}\.){3}[0-9]{1,3}:(\d+)(?:\s+)LISTENING(?:\s+)"
		+ Формат(ИдентификаторПроцесса, "ЧГ=");
	Вхождения = RegExp.Execute(ТекстРезультата);
	//Сообщить(ТекстРезультата);
	МассивСлушающихПортов = Новый Массив;
	СтрокаПоиска = "";
	// Т.к. неясно какой из портов для отладки, используем все
	Для Каждого Вхождение Из Вхождения Цикл
		МассивСлушающихПортов.Добавить(Вхождение.SubMatches(0));
		СтрокаПоиска = СтрокаПоиска + "|" + Вхождение.SubMatches(0);
	КонецЦикла;
	Если МассивСлушающихПортов.Количество() = 0 Тогда
		Результат = Неопределено;
		Возврат Результат;
	КонецЕсли;
	СтрокаПоиска = Сред(СтрокаПоиска, 2);
	ИдентификаторПроцессаОтладчика = Неопределено;
	RegExp.Pattern = "TCP(?:\s+)127\.0\.0\.1:(?:\d+)(?:\s+)127\.0\.0\.1:(" + СтрокаПоиска + ")(?:\s+)ESTABLISHED(?:\s+)(\d+)";
	Вхождения = RegExp.Execute(ТекстРезультата);
	Для Каждого Вхождение Из Вхождения Цикл
		ИдентификаторПроцессаКорреспондента = Вхождение.SubMatches(1);
		Если ИдентификаторПроцессаКорреспондента <> Формат(ИдентификаторПроцесса, "ЧГ=") Тогда
			ИдентификаторПроцессаОтладчика = ИдентификаторПроцессаКорреспондента;
		Иначе
			МассивСлушающихПортов.Удалить(МассивСлушающихПортов.Найти(Вхождение.SubMatches(0)));
		КонецЕсли;
	КонецЦикла;
	Если МассивСлушающихПортов.Количество() > 0 Тогда
		Результат = МассивСлушающихПортов[0];
	КонецЕсли;
	Возврат Результат;
	
КонецФункции
	
// <Описание функции>
//
// Параметры:
//  <Параметр1>  – <Тип.Вид> – <описание параметра>
//                 <продолжение описания параметра>;
//  <Параметр2>  – <Тип.Вид> – <описание параметра>
//                 <продолжение описания параметра>.
//
// Возвращаемое значение:
//               – <Тип.Вид> – <описание значения>
//                 <продолжение описания значения>;
//  <Значение2>  – <Тип.Вид> – <описание значения>
//                 <продолжение описания значения>.
//
Функция ПолучитьФайлСтилейСинтаксПомощника() Экспорт 

	Если ФайлСтилейСинтаксПомощника = Неопределено Тогда 
		ФайлСтилейСинтаксПомощника = Новый Файл(ПолучитьИмяВременногоФайла("css"));
		ТекстовыйДокумент = ПолучитьМакет("СтилиСинтаксПомощника");
		ТекстовыйДокумент.Вывод = ИспользованиеВывода.Разрешить;
		ТекстовыйДокумент.Записать(ФайлСтилейСинтаксПомощника.ПолноеИмя);
	КонецЕсли;
	Возврат ФайлСтилейСинтаксПомощника;

КонецФункции // ПолучитьФайлСтилейСинтаксПомощника()

// Получает zip-архив синтакс-помощника из файла "shcntx_ru.hbk" в каталоге установки платформы.
//
// Параметры:
//  ЭлементСтруктуры - Число, *0 - 0 - архив страниц, 1 - содержание книги, 2 - индекс книги
//
Функция ПолучитьАрхивСинтаксПомощникаПоИмени(ЭлементСтруктуры = 0, ИмяАрхива = "shcntx_ru") Экспорт

	Если АрхивСинтаксПомощника = Неопределено Тогда
		АрхивСинтаксПомощника = Новый Структура;
	КонецЕсли; 
	ФайлАрхива = Неопределено;
	КлючСтруктуры = "_" + ИмяАрхива + ЭлементСтруктуры;
	Если Не АрхивСинтаксПомощника.Свойство(КлючСтруктуры, ФайлАрхива) Тогда
		ИмяВременногоФайла = ПолучитьИмяВременногоФайла("zip");
		Если ЭлементСтруктуры = 0 Тогда
			ИмяБлока = "FileStorage.data";
		ИначеЕсли ЭлементСтруктуры = 1 Тогда
			ИмяБлока = "PackBlock.data";
		ИначеЕсли ЭлементСтруктуры = 2 Тогда
			ИмяБлока = "IndexPackBlock.data";
		КонецЕсли; 
		ИмяФайлаПлатформы = ИмяАрхива + ".hbk";
		ТекущийКаталог = КаталогВременныхФайлов();
		ФайлПлатформы = Новый Файл(КаталогПрограммы() + ИмяФайлаПлатформы);
		//ФайлПлатформы = Новый Файл(ПолучитьИмяФайлаВФорматеDOS(ФайлПлатформы.ПолноеИмя));
		ФайлБлока = Новый Файл(ТекущийКаталог + ИмяБлока);
		#Если Клиент Тогда
		Состояние("Распаковка синтакс-помощника");
		#КонецЕсли 
		РаспаковатьФайлВнешнейОбработки(ФайлПлатформы.ПолноеИмя, ТекущийКаталог);
		Попытка
			ПереместитьФайл(ФайлБлока.ПолноеИмя, ИмяВременногоФайла);
		Исключение
			// Если файл залочен на чтение (открыт синтакс-помощник в конфигураторе)
			КопияФайлаПлатформы = Новый Файл(ПолучитьИмяВременногоФайла());
			КопироватьФайл(ФайлПлатформы.ПолноеИмя, КопияФайлаПлатформы.ПолноеИмя);
			ФайлПлатформы = Новый Файл(ПолучитьИмяФайлаВФорматеDOS(КопияФайлаПлатформы.ПолноеИмя));
			ФайлБлока = Новый Файл(ТекущийКаталог + ИмяБлока);
			РаспаковатьФайлВнешнейОбработки(ФайлПлатформы.ПолноеИмя, ТекущийКаталог);
			ПереместитьФайл(ФайлБлока.ПолноеИмя, ИмяВременногоФайла);
		КонецПопытки;
		УдалитьФайлы(ТекущийКаталог + Лев(ФайлПлатформы.ИмяБезРасширения, 8));
		#Если Клиент Тогда
		Состояние("");
		#КонецЕсли 
		ФайлАрхива = Новый Файл(ИмяВременногоФайла);
		АрхивСинтаксПомощника.Вставить(КлючСтруктуры, ФайлАрхива);
	КонецЕсли;
	Возврат ФайлАрхива;

КонецФункции // ПолучитьАрхивСинтаксПомощника()

// 
//
// Параметры:
//  ПутьКЭлементу  - Строка - модифицируется
//  ИмяАрхива    – Строка – входное значение игнорируется, на выход подается вычисленное имя файла архива;
//
// Возвращаемое значение:
//               – <Тип.Вид> – <описание значения>
//                 <продолжение описания значения>;
//  <Значение2>  – <Тип.Вид> – <описание значения>
//                 <продолжение описания значения>.
//
Функция ПолучитьАрхивСинтаксПомощникаПоПутиКЭлементу(ПутьКЭлементу, ЭлементСтруктуры = 0, ЛиОбрезатьПутьДоОтносительного = Ложь, ИмяАрхива = "") Экспорт

	МаркерДопАрхива = "//";
	Если Найти(ПутьКЭлементу, МаркерДопАрхива) = 1 Тогда
		ИмяАрхива = ирОбщий.ПолучитьПервыйФрагментЛкс(Сред(ПутьКЭлементу, СтрДлина(МаркерДопАрхива) + 1), "/");
		Если ЛиОбрезатьПутьДоОтносительного Тогда
			ПутьКЭлементу = Сред(ПутьКЭлементу, СтрДлина(МаркерДопАрхива) + 1 + СтрДлина(ИмяАрхива) + 1);
		КонецЕсли;
		ФайлАрхива = ПолучитьАрхивСинтаксПомощникаПоИмени(ЭлементСтруктуры, ИмяАрхива);
	Иначе
		ФайлАрхива = ПолучитьАрхивСинтаксПомощникаПоИмени(ЭлементСтруктуры);
	КонецЕсли;
	Возврат ФайлАрхива;

КонецФункции // ПолучитьИмяАрхиваСинтаксПомощника()

// <Описание функции>
//
// Параметры:
//  <Параметр1>  – <Тип.Вид> – <описание параметра>
//                 <продолжение описания параметра>;
//  <Параметр2>  – <Тип.Вид> – <описание параметра>
//                 <продолжение описания параметра>.
//
// Возвращаемое значение:
//               – <Тип.Вид> – <описание значения>
//                 <продолжение описания значения>;
//  <Значение2>  – <Тип.Вид> – <описание значения>
//                 <продолжение описания значения>.
//
Функция РаспаковатьФайлАрхиваСинтаксПомощника(Знач ПутьКЭлементу, ПрефиксСсылки = "") Экспорт

	ФайлАрхива = ПолучитьАрхивСинтаксПомощникаПоПутиКЭлементу(ПутьКЭлементу,, Истина);
	Если ФайлАрхива = Неопределено Тогда
		Возврат Неопределено;
	КонецЕсли;
	Если Лев(ПутьКЭлементу, 1) = "/" Тогда
		ПутьКЭлементу = Сред(ПутьКЭлементу, 2);
	КонецЕсли;
	МассивФрагментов = ирОбщий.ПолучитьМассивИзСтрокиСРазделителемЛкс(ПутьКЭлементу, "#");
	ПутьКЭлементу = МассивФрагментов[0];
	ФайлРаспаковщикаZIP = ПолучитьФайлРаспаковщикаZIP(Истина);
	ВременныйФайл = Новый Файл(ПолучитьИмяВременногоФайла("html"));
	
	ЗапуститьСкрытоеПриложениеИДождатьсяЗавершения(ФайлРаспаковщикаZIP.Имя + " -j " + ФайлАрхива.Имя 
		+ " """ + ПутьКЭлементу + """", КаталогВременныхФайлов(), Истина);
	ПолноеИмяРаспакованногоФайла = КаталогВременныхФайлов() + ирОбщий.ПолучитьПоследнийФрагментЛкс(ПутьКЭлементу, "/");
	Попытка
		ПереместитьФайл(ПолноеИмяРаспакованногоФайла, ВременныйФайл.ПолноеИмя);
	Исключение
		// для примитивных типов видимо лежат файлы в другом архиве
		Возврат Неопределено;
	КонецПопытки;
	УдалитьФайлы(ПолноеИмяРаспакованногоФайла);
	ТекстовыйДокумент = Новый ТекстовыйДокумент;
	ТекстовыйДокумент.Прочитать(ВременныйФайл.ПолноеИмя);
	СодержаниеСтраницы = ТекстовыйДокумент.ПолучитьТекст();
	Если Найти(СодержаниеСтраницы, "<head>") > 0 Тогда
		Маркер = "<head>";
	ИначеЕсли Найти(СодержаниеСтраницы, "<HEAD>") > 0 Тогда
		Маркер = "<HEAD>";
	ИначеЕсли Найти(СодержаниеСтраницы, "<Head>") > 0 Тогда
		Маркер = "<Head>";
	КонецЕсли;
	Если Маркер <> Неопределено Тогда
		ТегБазы = "<base href=""" + ПрефиксСсылки + "/" + ПутьКЭлементу + """>";
		СодержаниеСтраницы = СтрЗаменить(СодержаниеСтраницы, Маркер, Маркер + ТегБазы);
		ТекстовыйДокумент.УстановитьТекст(СодержаниеСтраницы);
		ТекстовыйДокумент.Вывод = ИспользованиеВывода.Разрешить;
		ТекстовыйДокумент.Записать(ВременныйФайл.ПолноеИмя);
	КонецЕсли;
	ВременныйАдрес = ВременныйФайл.ПолноеИмя;
	Если МассивФрагментов.Количество() > 1 Тогда
		ВременныйАдрес = ВременныйАдрес + "#" + МассивФрагментов[1];
	КонецЕсли; 
	Возврат ВременныйАдрес;

КонецФункции // РаспаковатьФайлАрхиваСинтаксПомощника()

Функция ПолучитьДокумент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;
	Если Не МакетыКомпонент.Свойство(Компонента.ИмяКласса, Макет) Тогда
		Макет = Компонента.ПолучитьФорму("ФормаМакет");
		МакетыКомпонент.Вставить(Компонента.ИмяКласса, Макет);
	КонецЕсли;
	Возврат Макет;

КонецФункции // ПолучитьМакетКомпоненты()

// Получает новый экземпляр ком-объекта парсера.
//
// Параметры:
//  Нет.
//
// Возвращаемое значение:
//  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;

КонецФункции // мПолучитьADOUtils()

// Пауза.
//
// Параметры:
//  Длительность – Число – секунд, можно дробное при использовании DynamicWrapperX.
//
Процедура Sleep(КоличествоСекунд) Экспорт

	Если ПолучитьWinAPI() <> Неопределено Тогда 
		WinAPI.Sleep(КоличествоСекунд * 1000);
	Иначе
		//Для Счетчик = 1 По КоличествоСекунд Цикл
		//	ЗапуститьСкрытоеПриложениеИДождатьсяЗавершения("ping -n 2 127.0.0.1");
		//КонецЦикла; 
	  	ЗапуститьСкрытоеПриложениеИДождатьсяЗавершения("ping localhost -n " + XMLСтрока(КоличествоСекунд + 1),, Истина);
	КонецЕсли;

КонецПроцедуры // Sleep()

// <Описание функции>
//
// Параметры:
//  <Параметр1>  – <Тип.Вид> – <описание параметра>
//                 <продолжение описания параметра>;
//  <Параметр2>  – <Тип.Вид> – <описание параметра>
//                 <продолжение описания параметра>.
//
// Возвращаемое значение:
//               – <Тип.Вид> – <описание значения>
//                 <продолжение описания значения>;
//  <Значение2>  – <Тип.Вид> – <описание значения>
//                 <продолжение описания значения>.
//
Функция ПолучитьТекстМодуляВнешнейОбработкиАлгоритма(ФайлВнешнейОбработки) Экспорт

	Если Не ФайлВнешнейОбработки.Существует() Тогда
		Возврат Неопределено;
	КонецЕсли; 
	ТекстМодуля = ПолучитьТекстМодуляВнешнейОбработки(ФайлВнешнейОбработки);
	Если ТекстМодуля = Неопределено Тогда
		Возврат Неопределено;
	КонецЕсли;
	ТекстАлгоритма = ирОбщий.ПолучитьСтрокуМеждуМаркерамиЛкс(ТекстМодуля, МаркерНачалаАлгоритма, МаркерКонцаАлгоритма);
	Результат = "";
	ТекстАлгоритмаТД = Новый ТекстовыйДокумент;
	ТекстАлгоритмаТД.УстановитьТекст(ТекстАлгоритма);
	Для Счетчик = 1 По ТекстАлгоритмаТД.КоличествоСтрок() Цикл
		СтрокаАлгоритма = ТекстАлгоритмаТД.ПолучитьСтроку(Счетчик);
		Если Лев(СтрокаАлгоритма, 1) = Символы.Таб Тогда
			СтрокаАлгоритма = Сред(СтрокаАлгоритма, 2);
		КонецЕсли;
		Результат = Результат + СтрокаАлгоритма + Символы.ПС;
	КонецЦикла;
		
	Возврат Результат;

КонецФункции // ПолучитьТекстМодуляВнешнейОбработкиАлгоритма()

// <Описание функции>
//
// Параметры:
//  <Параметр1>  – <Тип.Вид> – <описание параметра>
//                 <продолжение описания параметра>;
//  <Параметр2>  – <Тип.Вид> – <описание параметра>
//                 <продолжение описания параметра>.
//
// Возвращаемое значение:
//               – <Тип.Вид> – <описание значения>
//                 <продолжение описания значения>;
//  <Значение2>  – <Тип.Вид> – <описание значения>
//                 <продолжение описания значения>.
//
Функция ПолучитьТекстМодуляВнешнейОбработки(ФайлВнешнейОбработки) Экспорт 

	КаталогРаспаковки = ПолучитьИмяВременногоФайла();
	СоздатьКаталог(КаталогРаспаковки);
	РаспаковатьФайлВнешнейОбработки(ФайлВнешнейОбработки.ПолноеИмя, КаталогРаспаковки);
	ФайлТекстаМодуляОбработки = Новый Файл(КаталогРаспаковки + "\" + СубПутьКФайлуПотокаМодуляВнешнейОбработки);
	ТекстовыйДокументМодуля = Новый ТекстовыйДокумент();
	ТекстовыйДокументМодуля.Прочитать(ФайлТекстаМодуляОбработки.ПолноеИмя);
	ТекстМодуля = ТекстовыйДокументМодуля.ПолучитьТекст();
	УдалитьФайлы(КаталогРаспаковки);
	Возврат ТекстМодуля;

КонецФункции // ПолучитьТекстМодуляВнешнейОбработки()

// Открывает модуль внешней обработки алгоритма в конфигураторе.
//
// Параметры:
//  АлгоритмОбъект – СправочникОбъект.Сервисы2iS;
//  *НомерСтрокиВМодуле – Число, *0 - если указана, устанавливает текущую строку в модуле;
//  *ИдентификаторПроцесса – Число, *0 - если указан, будет открываться только в заданном процессе;
//  *Переоткрыть   - Булево, *Истина - переоткрыть, если уже открыт
//
Процедура ОткрытьАлгоритмВОтладчике(АлгоритмОбъект, НомерСтрокиВМодуле = 0, ИдентификаторПроцесса = 0, Переоткрыть = Истина) Экспорт 

	Если Не ВыполнятьАлгоритмыЧерезВнешниеОбработки Тогда
		Сообщить("Данная функция доступна только в режиме выполнения сервисов через внешние обработки", СтатусСообщения.Информация);
		Возврат;
	КонецЕсли; 
	Если Не ФайловыйКэшАлгоритмовДопускаетРедактирование Тогда
		Сообщить("Изменения файла будут игнорироваться, т.к. в настройках алгоритмов не включено разрешение редактирования файлового кэша",
			СтатусСообщения.Информация);
	КонецЕсли;
	ПолучитьФайлОткрывателя1С();
	ФайлВнешнейОбработки = ПолучитьОбновитьФайлВнешнейОбработкиАлгоритма(АлгоритмОбъект);
	Если ФайлВнешнейОбработки <> Неопределено Тогда
		СтрокаЗапуска = """" + ФайлОткрывателя1С.ПолноеИмя + """ -com -ob1""" + ФайлВнешнейОбработки.ПолноеИмя + """";
		Если ЗначениеЗаполнено(НомерСтрокиВМодуле) Тогда
			СтрокаЗапуска = СтрокаЗапуска + " -num" + Формат(НомерСтрокиВМодуле, "ЧГ=");
		КонецЕсли;
		Если ЗначениеЗаполнено(ИдентификаторПроцесса) Тогда
			СтрокаЗапуска = СтрокаЗапуска + " -pid" + Формат(ИдентификаторПроцесса, "ЧГ=");
		КонецЕсли;
		Если Переоткрыть Тогда
			СтрокаЗапуска = СтрокаЗапуска + " -reopen";
		КонецЕсли;
		WshShell.Run(СтрокаЗапуска, 0, Ложь);
	КонецЕсли;

КонецПроцедуры 

// Открывает модуль внешней обработки в конфигураторе.
//
// Параметры:
//  ПолноеИмяФайла – Строка;
//  *НомерСтрокиВМодуле – Число, *0 - если указана, устанавливает текущую строку в модуле;
//  *ИдентификаторПроцесса – Число, *0 - если указан, будет открываться только в заданном процессе;
//  *Переоткрыть   - Булево, *Истина - переоткрыть, если уже открыт
//
Процедура ОткрытьМодульВнешнейОбработкиВОтладчике(ПолноеИмяФайла, НомерСтрокиВМодуле = 0, ИдентификаторПроцесса = 0, Переоткрыть = Истина) Экспорт 

	ПолучитьФайлОткрывателя1С();
	ФайлВнешнейОбработки = Новый Файл(ПолноеИмяФайла);
	Если ФайлВнешнейОбработки <> Неопределено Тогда
		СтрокаЗапуска = """" + ФайлОткрывателя1С.ПолноеИмя + """ -com -ob1""" + ФайлВнешнейОбработки.ПолноеИмя + """";
		Если НомерСтрокиВМодуле > 0 Тогда
			СтрокаЗапуска = СтрокаЗапуска + " -num" + Формат(НомерСтрокиВМодуле, "ЧГ=");
		КонецЕсли;
		Если ИдентификаторПроцесса > 0 Тогда
			СтрокаЗапуска = СтрокаЗапуска + " -pid" + Формат(ИдентификаторПроцесса, "ЧГ=");
		КонецЕсли;
		Если Переоткрыть Тогда
			СтрокаЗапуска = СтрокаЗапуска + " -reopen";
		КонецЕсли;
		WshShell.Run(СтрокаЗапуска, 0, Ложь);
	КонецЕсли;

КонецПроцедуры 

// Открывает файл в конфигураторе.
//
// Параметры:
//  ПолноеИмя    – Строка;
//  *ЭлементОбработки – "Форма", "Модуль", *Неопределено$
//  *ИдентификаторПроцесса – Число, *0 - если указан, будет открываться только в заданном процессе.
//
Процедура ОткрытьФайлВКонфигураторе(ПолноеИмя, ЭлементОбработки = "", ИдентификаторПроцесса = 0) Экспорт 

	ПолучитьФайлОткрывателя1С();
	ФайлВнешнейОбработки = Новый Файл(ПолноеИмя);
	Если ФайлВнешнейОбработки.Существует() Тогда
		//WshShell = Новый COMОбъект("WScript.Shell");
		СтрокаЗапуска = """" + ФайлОткрывателя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>  – <Тип.Вид> – <описание параметра>
//                 <продолжение описания параметра>.
//
Процедура СохранитьНастройкиАлгоритмов() Экспорт 

	//ирОбщий.СохранитьЗначениеЛкс("ирПлатформа.ФиксироватьВнешниеИсключенияАлгоритмов", ФиксироватьВнешниеИсключенияАлгоритмов);
	ирОбщий.СохранитьЗначениеЛкс("ФиксироватьВнешниеИсключенияАлгоритмов", ФиксироватьВнешниеИсключенияАлгоритмов);
	//ирОбщий.СохранитьЗначениеЛкс("ирПлатформа.СинтаксическийКонтрольПередЗаписью", СинтаксическийКонтрольПередЗаписью);
	ирОбщий.СохранитьЗначениеЛкс("СинтаксическийКонтрольПередЗаписью", СинтаксическийКонтрольПередЗаписью);
	//ирОбщий.СохранитьЗначениеЛкс("ирПлатформа.ВыполнятьАлгоритмыЧерезВнешниеОбработки", ВыполнятьАлгоритмыЧерезВнешниеОбработки);
	ирОбщий.СохранитьЗначениеЛкс("ВыполнятьАлгоритмыЧерезВнешниеОбработки", ВыполнятьАлгоритмыЧерезВнешниеОбработки);
	ирОбщий.СохранитьЗначениеЛкс("ФайловыйКэшАлгоритмовДопускаетРедактирование", ФайловыйКэшАлгоритмовДопускаетРедактирование);
	//ирОбщий.СохранитьЗначениеЛкс("ирПлатформа.ПоказыватьВнешниеИсключенияПриВыполненииАлгоритмов", ПоказыватьВнешниеИсключенияПриВыполненииАлгоритмов);
	ирОбщий.СохранитьЗначениеЛкс("ПоказыватьВнешниеИсключенияПриВыполненииАлгоритмов", ПоказыватьВнешниеИсключенияПриВыполненииАлгоритмов);

КонецПроцедуры // СохранитьНастройкиАлгоритмов()

// Получает структуру для индикации прогресса цикла.
//
// Параметры:
//  КоличествоПроходов – Число - максимальное значение счетчика;
//  ПредставлениеПроцесса – Строка, "Выполнено" – отображаемое название процесса;
//  ВнутреннийСчетчик - Булево, *Истина - использовать внутренний счетчик с начальным значением 1,
//                    иначе нужно будет передавать значение счетчика при каждом вызове обновления индикатора;
//  КоличествоОбновлений - Число, *0 - всего количество обновлений индикатора, 0 - по минимальному периоду;
//  ЛиВыводитьВремя - Булево, *Истина - выводить приблизительное время до окончания процесса;
//  РазрешитьПрерывание - Булево, *Истина - разрешает пользователю прерывать процесс.
//  МинимальныйПериодОбновления - Число, *0.5 - с, обновлять не чаще чем этот период, 0 - по количеству обновлений;
//
// Возвращаемое значение:
//  Структура - которую потом нужно будет передавать в метод ирОбщий.ОбработатьИндикаторЛкс.
//
Функция ПолучитьИндикаторПроцесса(Знач КоличествоПроходов = 0, ПредставлениеПроцесса = "Выполнение", ВнутреннийСчетчик = Истина,
	Знач КоличествоОбновлений = 0, ЛиВыводитьВремя = Истина, РазрешитьПрерывание = Истина, МинимальныйПериодОбновления = 0.5) Экспорт 

	//ПолучитьWinAPI();
	Индикатор = Новый Структура;
	Если КоличествоПроходов = 0 Тогда
		Состояние(ПредставлениеПроцесса + "...");
		КоличествоПроходов = 1;
	КонецЕсли;
	Индикатор.Вставить("КоличествоПроходов", КоличествоПроходов);
	Индикатор.Вставить("ПредставлениеПроцесса", ПредставлениеПроцесса);
	Индикатор.Вставить("ЛиВыводитьВремя", ЛиВыводитьВремя);
	Индикатор.Вставить("РазрешитьПрерывание", РазрешитьПрерывание);
	Индикатор.Вставить("МинимальныйПериодОбновления", МинимальныйПериодОбновления);
	
	Индикатор.Вставить("ДатаНачалаПроцесса", ТекущаяДата());
	Индикатор.Вставить("ДатаСледующегоОбновления", Дата('00010101'));
	
	Индикатор.Вставить("ВремяНачалаПроцесса", ПолучитьТекущееВремяВМиллисекундах());
	Индикатор.Вставить("ВремяСледующегоОбновления", 0);
	
	Индикатор.Вставить("ВнутреннийСчетчик", ВнутреннийСчетчик);
	Если КоличествоОбновлений > 0 Тогда
		Шаг = КоличествоПроходов / КоличествоОбновлений;
	Иначе
		Шаг = 0;
	КонецЕсли; 
	Индикатор.Вставить("Шаг", Шаг);
	Индикатор.Вставить("СледующийСчетчик", 0);
	Индикатор.Вставить("Счетчик", 0);
	//ВложенностьИндикации = ВложенностьИндикации + 1;
	Возврат Индикатор;

КонецФункции // ирОбщий.ПолучитьИндикаторПроцессаЛкс()

// Проверяет и обновляет индикатор. Нужно вызывать на каждом проходе индицируемого цикла.
//
// Параметры:
//  Индикатор    – Структура – индикатора, полученная методом ирОбщий.ПолучитьИндикаторПроцессаЛкс;
//  Счетчик      – Число – внешний счетчик цикла, используется при ВнутреннийСчетчик = Ложь.
//
Процедура ОбработатьИндикатор(Индикатор, Счетчик = Неопределено) Экспорт 

	Если Счетчик = Неопределено Тогда
		Счетчик = Индикатор.Счетчик + 1;
		Индикатор.Счетчик = Счетчик;
	КонецЕсли;
	Если Индикатор.РазрешитьПрерывание Тогда
		ОбработкаПрерыванияПользователя();
	КонецЕсли;
	ОбновитьИндикатор = Истина;
	Если Счетчик < Индикатор.КоличествоПроходов Тогда 
		ТекущееВремя = ПолучитьТекущееВремяВМиллисекундах();
		Если Индикатор.МинимальныйПериодОбновления > 0 Тогда
			Если ТекущееВремя >= Индикатор.ВремяСледующегоОбновления Тогда
				Индикатор.ВремяСледующегоОбновления = ТекущееВремя + Индикатор.МинимальныйПериодОбновления * 1000;
			Иначе
				ОбновитьИндикатор = Ложь;
			КонецЕсли;
		КонецЕсли;
		Если ОбновитьИндикатор Тогда
			Если Индикатор.Шаг > 0 Тогда
				Если Счетчик >= Индикатор.СледующийСчетчик Тогда
					Индикатор.СледующийСчетчик = Цел(Счетчик + Индикатор.Шаг);
				Иначе
					ОбновитьИндикатор = Ложь;
				КонецЕсли;
			КонецЕсли;
		КонецЕсли;
	КонецЕсли; 
	Если ОбновитьИндикатор Тогда
		Если Истина
			И Индикатор.ЛиВыводитьВремя 
			И Счетчик > 0
			И Счетчик < Индикатор.КоличествоПроходов
		Тогда
			ПрошлоВремени = (ТекущееВремя - Индикатор.ВремяНачалаПроцесса) / 1000;
			Осталось = ПрошлоВремени * (Индикатор.КоличествоПроходов / Счетчик - 1);
			Часов = Цел(Осталось / 3600);
			Осталось = Осталось - (Часов * 3600);
			Минут = Цел(Осталось / 60);
			Секунд = Цел(Цел(Осталось - (Минут * 60)));
			ОсталосьВремени = Формат(Часов, "ЧЦ=2; ЧН=00; ЧВН=") + ":" 
				+ Формат(Минут, "ЧЦ=2; ЧН=00; ЧВН=") + ":" 
				+ Формат(Секунд, "ЧЦ=2; ЧН=00; ЧВН=");
			ТекстОсталось = ", Осталось: ~" + ОсталосьВремени;
		Иначе
			ТекстОсталось = "";
		КонецЕсли;
		ТекстСостояния = Индикатор.ПредставлениеПроцесса + ": " 
			+ Формат(Счетчик / Индикатор.КоличествоПроходов * 100, "ЧЦ=3; ЧДЦ=0; ЧН=") + "%" + ТекстОсталось;
		Если ТипЗнч(Индикатор) = Тип("СтрокаТаблицыЗначений") Тогда
			ТаблицаИндикаторов = Индикатор.Владелец();
			ИндексИндикатора = ТаблицаИндикаторов.Индекс(Индикатор);
			Если ИндексИндикатора > 0 Тогда
				ТекстСостояния = ТаблицаИндикаторов[ИндексИндикатора - 1].ТекстСостояния + ".>> " + ТекстСостояния;
			КонецЕсли;
			Индикатор.ТекстСостояния = ТекстСостояния;
		КонецЕсли; 
		Состояние(ТекстСостояния);
	КонецЕсли;
	//Если Счетчик = Индикатор.КоличествоПроходов Тогда
	//	Состояние("");
	//КонецЕсли;

КонецПроцедуры // ирОбщий.ОбработатьИндикаторЛкс()

Процедура ЗаполнитьТаблицуРедактируемыхТипов() Экспорт
	
	ОписаниеТипов = ирОбщий.ОписаниеТиповВсеРедактируемыеТипыЛкс();
	Для Каждого Тип Из ОписаниеТипов.Типы() Цикл
		СтрокаТипа = ТаблицаРедактируемыхТипов.Добавить();
		//СтрокаТипа.Представление = "" + Тип;
		ТипXML = СериализаторXDTO.XMLТип(Тип);
		Если Тип = Тип("Число") Тогда
			СтрокаТипа.Порядок = -4;
		ИначеЕсли Тип = Тип("Строка") Тогда
			СтрокаТипа.Порядок = -3;
		ИначеЕсли Тип = Тип("Дата") Тогда
			СтрокаТипа.Порядок = -2;
		ИначеЕсли Тип = Тип("Булево") Тогда
			СтрокаТипа.Порядок = -1;
		ИначеЕсли Истина
			И ТипXML <> Неопределено
			И Найти(ТипXML.ИмяТипа, ".") > 0
		Тогда
			СтрокаТипа.Порядок = 100;
			ОбъектМД = Метаданные.НайтиПоТипу(Тип);
			ТекущееИмяТипа = ОбъектМД.ПолноеИмя();
			ИмяТипаМетаданных = ирОбщий.ПолучитьПервыйФрагментЛкс(ТекущееИмяТипа);
			СтрокаТипаМетаОбъектов = ПолучитьСтрокуТипаМетаОбъектов(ИмяТипаМетаданных);
			Если СтрокаТипаМетаОбъектов <> Неопределено Тогда
				СтрокаТипа.ИндексКартинки = СтрокаТипаМетаОбъектов.ИндексКартинкиЕдинственное;
			КонецЕсли;
		КонецЕсли; 
		СтрокаТипа.Имя = ТипXML.ИмяТипа;
		СтрокаТипа.URIПространстваИмен = ТипXML.URIПространстваИмен;
		СтрокаТипа.Представление = "" + Тип;
	КонецЦикла;
	ТаблицаРедактируемыхТипов.Сортировать("Порядок, Имя");
	
КонецПроцедуры

Функция ЛиКомпонентаFormsTextBoxДоступна() Экспорт 
	
	Если ЛиКомпонентаFormsTextBoxДоступна = Неопределено Тогда
		ЛиКомпонентаFormsTextBoxДоступна = Истина;
		ИдентификаторКласса = "Forms.TextBox.1";
		Попытка
			Пустышка = Новый COMОбъект(ИдентификаторКласса);
		Исключение
			ИмяМакетаДополнительнойБиблиотеки = "FM20ENU";
			ИмяМакетаКомпоненты = "FM20";
			Пустышка = ПолучитьCOMОбъектИзМакета(ИмяМакетаКомпоненты, ИдентификаторКласса,, ИмяМакетаДополнительнойБиблиотеки);
			Если Пустышка = Неопределено Тогда
				Сообщить("Для полной функциональности контекстной подсказки необходимо:
				|1. Использовать 32б приложение
				|2. Зарегистрировать библиотеки FM20.dll и FM20ENU.dll из состава MS Office 97-2007. Это можно сделать с помощью формы ""Административная регистрация COM компонент"" из состава подсистемы");
				ЛиКомпонентаFormsTextBoxДоступна = Ложь;
			КонецЕсли; 
		КонецПопытки;
	КонецЕсли; 
	Возврат ЛиКомпонентаFormsTextBoxДоступна;
	
КонецФункции

#КонецЕсли

////////////////////////////////////////////////////////////////////////////////////////////////////

// <Описание функции>
//
// Параметры:
//  <Параметр1>  – <Тип.Вид> – <описание параметра>
//                 <продолжение описания параметра>;
//  <Параметр2>  – <Тип.Вид> – <описание параметра>
//                 <продолжение описания параметра>.
//
// Возвращаемое значение:
//               – <Тип.Вид> – <описание значения>
//                 <продолжение описания значения>;
//  <Значение2>  – <Тип.Вид> – <описание значения>
//                 <продолжение описания значения>.
//
Функция ПолучитьИдентификаторПроцессаОС() Экспорт

	Если Не ЗначениеЗаполнено(ИдентификаторПроцессаОС) Тогда
		Если Получить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(); // Может выполняться долго!
		КонецЕсли; 
	КонецЕсли;
	Возврат ИдентификаторПроцессаОС;

КонецФункции // ПолучитьИдентификаторПроцессаОС()

// Получает новый экземпляр ком-объекта парсера.
//
// Параметры:
//  Нет.
//
// Возвращаемое значение:
//  Com-объект, Неопределено.
//
Функция мПолучитьПарсер(ИмяГрамматики, Кэшировать = Истина) Экспорт

	Если Кэшировать Тогда
		Если Парсеры.Свойство(ИмяГрамматики) Тогда
			Парсер = Парсеры[ИмяГрамматики];
			Если Парсер <> Неопределено Тогда
				Парсер.Restart(); // Без этого что то не очищается и приводит к зависанию парсинга.
			КонецЕсли; 
			Возврат Парсер;
		КонецЕсли; 
	КонецЕсли;
	//Парсер = ПолучитьCOMОбъектИзМакета("GoldParser", "GOLDParserEngine.GOLDParser");
	Парсер = ПолучитьCOMОбъектИзМакета("GoldParser", "GoldParserForNet.Parser"); // Новый Parser
	Если Парсер <> Неопределено Тогда 
        Парсер.TrimReductions = Истина;
		МакетГрамматики = ПолучитьМакет(ИмяГрамматики);
		ФайлСкомпилированнойГрамматики = ПолучитьИмяВременногоФайла("cgt");
		МакетГрамматики.Записать(ФайлСкомпилированнойГрамматики);
		Если Не Парсер.LoadCompiledGrammar(ФайлСкомпилированнойГрамматики) Тогда
			ирОбщий.СообщитьСУчетомМодальностиЛкс("Не удалось загрузить файл грамматики """ + ФайлСкомпилированнойГрамматики + """",
				Истина, СтатусСообщения.Важное);
			Парсер = Неопределено;
		КонецЕсли;
		УдалитьФайлы(ФайлСкомпилированнойГрамматики);
	КонецЕсли;
	Если Кэшировать Тогда
		Парсеры.Вставить(ИмяГрамматики, Парсер);
	КонецЕсли;
	Возврат Парсер;

КонецФункции // ИнициализироватьПарсер()

// Получает идентификатор из любой строки.
// "3-я Дебиторка По контрагентам с интервалами СНГ (для  Руководства)" => "_3_яДебиторкаПоКонтрагентамСИнтерваламиСНГ_дляРуководства_".
//
// Параметры:
//  Представление – Строка.
//
// Возвращаемое значение:
//  Строка.
//
Функция ПолучитьИдентификаторИзПредставления(Знач Представление, ЗаменаПустойСтроки = "_") Экспорт

	Если ПустаяСтрока(Представление) Тогда
		Представление = ЗаменаПустойСтроки;
	КонецЕсли;
	Если СокрЛП(Представление) = Представление Тогда
		Попытка
			Пустышка = Новый Структура(Представление);
			Возврат Представление;
		Исключение КонецПопытки;
	КонецЕсли; 
	VBRegExp.Pattern = "\d";
	НовоеПредставление = Представление;
	ПервыйСимвол = Сред(Представление, 1, 1);
	Если VBRegExp.Test(ПервыйСимвол) Тогда
		// Первый символ - цифра
		НовоеПредставление = "_" + НовоеПредставление;
	КонецЕсли;
	ПредыдущийСимвол = " ";
	ТекущаяСтрока = "";
	Для Счетчик = 1 По СтрДлина(НовоеПредставление) Цикл
		ТекущийСимвол = Сред(НовоеПредставление, Счетчик, 1);
		VBRegExp.Pattern = "\s";
		Если VBRegExp.Test(ПредыдущийСимвол) Тогда
			// Предыдущий символ - непечатаемый
			ТекущийСимвол = ВРег(ТекущийСимвол);
		КонецЕсли;
		VBRegExp.Pattern = "[" + шБуква + "\d]";
		Если VBRegExp.Test(ТекущийСимвол) Тогда
			// Предыдущий символ - непечатаемый
			ТекущаяСтрока = ТекущаяСтрока + ТекущийСимвол;
		Иначе
			VBRegExp.Pattern = "[\S]";
			Если VBRegExp.Test(ТекущийСимвол) Тогда
				ТекущаяСтрока = ТекущаяСтрока + "_";
			КонецЕсли;
		КонецЕсли;
		ПредыдущийСимвол = ТекущийСимвол;
	КонецЦикла;
	Результат = ТекущаяСтрока;
	Возврат ТекущаяСтрока;

КонецФункции // ПолучитьИдентификаторИзПредставления()

// Добавляет новую строку в таблицу корневых объектов.
//
// Параметры:
//  Таблица      – ТаблицаЗначений;
//  *Категория   - Число, *0;
//  Единственное – Строка;
//  ИндексКартинкиЕдинственное – Число;
//  Множественное – Строка;
//  ИндексКартинкиМножественное – Число;
//
Процедура ДобавитьВТаблицуТиповМетаОбъектов(Таблица, Категория = 0, Единственное, ИндексКартинкиЕдинственное,
	Множественное, ИндексКартинкиМножественное)

	НовыйКорневойОбъект = Таблица.Добавить();
	НовыйКорневойОбъект.Категория = Категория;
	НовыйКорневойОбъект.Единственное = Единственное;
	НовыйКорневойОбъект.ИндексКартинкиЕдинственное = ИндексКартинкиЕдинственное;
	НовыйКорневойОбъект.Множественное = Множественное;
	НовыйКорневойОбъект.ИндексКартинкиМножественное = ИндексКартинкиМножественное;

КонецПроцедуры // ДобавитьВТаблицуТиповМетаОбъектов()

// <Описание процедуры>
//
// Параметры:
//  <Параметр1>  – <Тип.Вид> – <описание параметра>
//                 <продолжение описания параметра>;
//  <Параметр2>  – <Тип.Вид> – <описание параметра>
//                 <продолжение описания параметра>.
//
Процедура ПроверитьСтруктуруФайловогоКэша() Экспорт 

	ПроверитьКаталогФайловогоКэша();
	СтруктураПодкаталоговФайловогоКэша = Новый Структура;
	СтруктураПодкаталоговФайловогоКэша.Вставить("a"); // Внешние обработки алгоритмов
	СтруктураПодкаталоговФайловогоКэша.Вставить("b"); // Внешние обработки архива 2iS 
	СтруктураПодкаталоговФайловогоКэша.Вставить("c"); // Внешние компоненты
	Для Каждого ЭлементПодкаталога Из СтруктураПодкаталоговФайловогоКэша Цикл
		ПолныйПутьКаталога = КаталогФайловогоКэша + "\" + ЭлементПодкаталога.Ключ;
		ФайлКаталога = Новый Файл(ПолныйПутьКаталога);
		Если Не ФайлКаталога.Существует() Тогда
			Попытка
				СоздатьКаталог(ФайлКаталога.ПолноеИмя);
				ПробныйФайл = Новый ТекстовыйДокумент;
				ПробныйФайл.Записать(ФайлКаталога.ПолноеИмя + "\1.txt");
			Исключение
				Сообщить("Дополнительный кэш """ + ЭлементПодкаталога.Ключ + """ отключен.", СтатусСообщения.Важное);
				Продолжить;
			КонецПопытки;
		КонецЕсли;
		СтруктураПодкаталоговФайловогоКэша[ЭлементПодкаталога.Ключ] = ФайлКаталога;
		Если ЭлементПодкаталога.Ключ = "a" Тогда
			//КаталогДинамическихВнешнихОбработок = ПолныйПутьКаталога;
			ПапкаКешаВнешнихОбработокАлгоритмов = ФайлКаталога;
			
			ТекущаяДатаДвижка = Дата("20100927"); // Здесь меняем редко. Будет приводить к разовой очистке кэша перед началом его использования
			ФайлКэшаДвижка = Новый Файл(ПолныйПутьКаталога + "\_EngineTimeStamp.mll");
			ДатаКэшаДвижка = Неопределено;
			Если ФайлКэшаДвижка.Существует() Тогда
				Попытка
					ДатаКэшаДвижка = ЗначениеИзФайла(ФайлКэшаДвижка.ПолноеИмя);
				Исключение КонецПопытки;
			КонецЕсли;
			Если ДатаКэшаДвижка <> ТекущаяДатаДвижка Тогда
				Попытка
					УдалитьФайлы(ПолныйПутьКаталога + "\", "*.*");
				Исключение
					Неудача = Истина;
				КонецПопытки; 
				Если Неудача <> Истина Тогда
					ЗначениеВФайл(ФайлКэшаДвижка.ПолноеИмя, ТекущаяДатаДвижка);
				КонецЕсли; 
			КонецЕсли;
		ИначеЕсли ЭлементПодкаталога.Ключ = "b" Тогда
			ПапкаКешаВнешнихОбработокАрхива = ФайлКаталога;
		ИначеЕсли ЭлементПодкаталога.Ключ = "c" Тогда
			ПапкаВнешнихКомпонент = ФайлКаталога;
		КонецЕсли;
	КонецЦикла;
	
	ПутьККаталогуСлужебныхВременныхФайлов = КаталогВременныхФайлов() + "temp1template\";
	СоздатьКаталог(ПутьККаталогуСлужебныхВременныхФайлов);
	МассивЗамков = НайтиФайлы(ПутьККаталогуСлужебныхВременныхФайлов, "*.lck");
	Для Каждого Замок Из МассивЗамков Цикл
		Попытка
			УдалитьФайлы(Замок.ПолноеИмя);
			УдалитьФайлы(Замок.Путь + Замок.ИмяБезРасширения);
		Исключение
		КонецПопытки; 
	КонецЦикла;
	
КонецПроцедуры // ПроверитьСтруктуруФайловогоКэша()

// Получает таблицу единственных и множественных чисел корневых типов.
//
// Параметры:
//  *ЛиВключатьНехранимые - Булево, *Истина - включать ли нехранимые корневые типы;
//  *ЛиВключатьДочерние - Булево, *Истина - включать ли дочерние корневые типы;
//  *ЛиВключатьВнешние - Булево, *Истина - включать ли внешние корневые типы.
//
// Возвращаемое значение:
//  Массив – имен хранимых типов
//
Функция ПолучитьТаблицуТиповМетаОбъектов(ЛиВключатьНехранимые = Истина, ЛиВключатьДочерние = Истина, ЛиВключатьВнешние = Истина) Экспорт

	Таблица = Новый ТаблицаЗначений;
	Таблица.Колонки.Добавить("Категория", Новый ОписаниеТипов("Число")); // 0 - корневой, 1 - нехранимый, 2 - дочерний, 3 - внешний
	Таблица.Колонки.Добавить("Единственное");
	Таблица.Колонки.Добавить("ИндексКартинкиЕдинственное");
	Таблица.Колонки.Добавить("Множественное");
	Таблица.Колонки.Добавить("ИндексКартинкиМножественное");
	
	// Корневые типы
	Если ЛиВключатьНехранимые Тогда
		// Главным образом эти строки нужны для связи с пиктограммами этих коллекций
		ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 1, "WebСервис", ,          "WebСервисы", );
		ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 1, "WSCсылка", ,           "WSСсылки", );
		ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 1, "ГруппаКоманд", ,       "ГруппыКоманд", );
		ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 1, "Интерфейс", ,          "Интерфейсы", );
		ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 1, "Нумератор", ,          "НумераторыДокументов", );
		ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 1, "Обработка", 19,        "Обработки", 18);
		ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 1, "ОбщаяКартинка", ,      "ОбщиеКартинки", );
		ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 1, "ОбщаяКоманда", ,       "ОбщиеКоманды", );
		ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 1, "ОбщаяФорма", ,         "ОбщиеФормы", );
		ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 1, "ОбщийМакет", ,         "ОбщиеМакеты", );
		ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 1, "ОбщийМодуль", ,        "ОбщиеМодули", );
		Если ирКэш.НомерРежимаСовместимостиЛкс() >= 802014 Тогда
			ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 1, "ОбщийРеквизит", ,      "ОбщиеРеквизиты", );
		КонецЕсли; 
		Если ирКэш.НомерРежимаСовместимостиЛкс() >= 803003 Тогда
			ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 1, "ОпределяемыйТип", ,    "ОпределяемыеТипы", );
		КонецЕсли; 
		ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 1, "Отчет", 24,            "Отчеты", 23);
		ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 1, "ПараметрСеанса", ,     "ПараметрыСеанса", );
		ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 1, "ПараметрФункциональныхОпций", , "ПараметрыФункциональныхОпций", );
		ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 1, "ПакетXDTO", ,          "ПакетыXDTO", );
		ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 1, "ПодпискаНаСобытие", ,  "ПодпискиНаСобытия", );
		ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 1, "Подсистема", ,         "Подсистемы", );
		ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 1, "РегламентноеЗадание", , "РегламентныеЗадания", );
		ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 1, "Роль", ,               "Роли", );
		ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 1, "Стиль", ,              "Стили", );
		ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 1, "ФункциональнаяОпция", ,"ФункциональныеОпции", );
		ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 1, "ХранилищеНастроек", ,  "ХранилищаНастроек", );
		ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 1, "ЭлементСтиля", ,       "ЭлементыСтиля", );
		ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 1, "Язык", ,               "Языки", );
	КонецЕсли;
	Если ирКэш.НомерРежимаСовместимостиЛкс() >= 802014 Тогда
		ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 0, "ВнешнийИсточникДанных", ,  "ВнешниеИсточникиДанных", ); // Перенес из категории 1 02.03.2012
	КонецЕсли; 
	ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 0, "ПланОбмена", 52,           "ПланыОбмена", 51);
	ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 0, "Константа", 0,             "Константы", 1);
	ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 0, "Справочник", 3,            "Справочники", 2);
	ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 0, "Последовательность", 30,   "Последовательности", 29);
	ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 0, "Документ", 13,             "Документы", 12);
	ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 0, "Перечисление", 10,         "Перечисления", 9);
	ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 0, "ПланВидовХарактеристик", 38, "ПланыВидовХарактеристик", 37);
	ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 0, "ПланСчетов", 40,           "ПланыСчетов",39 );
	ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 0, "ПланВидовРасчета", 48,     "ПланыВидовРасчета", 47);
	ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 0, "РегистрСведений", 34,      "РегистрыСведений", 33);
	ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 0, "РегистрНакопления", 32,    "РегистрыНакопления", 31);
	ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 0, "РегистрБухгалтерии", 42,   "РегистрыБухгалтерии", 41);
	ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 0, "РегистрРасчета", 50,       "РегистрыРасчета", 49);
	ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 0, "БизнесПроцесс", 44,        "БизнесПроцессы", 43);
	ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 0, "Задача", 46,               "Задачи", 45);
	ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 0, "Перерасчет", 57,           "Перерасчеты", 57);
	
	ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 0, "КритерийОтбора", ,         "КритерииОтбора", );
	ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 0, "ЖурналДокументов", 16,     "ЖурналыДокументов", 15);
	
	// Дочерние типы
	Если ЛиВключатьДочерние Тогда
		ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 2, "Графа", ,                 "Графы", );
		ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 2, "ЗначениеПеречисления", ,  "ЗначенияПеречисления", );
		ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 2, "Измерение", ,             "Измерения", );
		ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 2, "Команда", ,               "Команды", );
		ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 2, "Макет", ,                 "Макеты", );
		ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 2, "Операция", ,              "Операции", );
		ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 2, "Параметр", ,              "Параметры", );
		ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 2, "Поле", ,                  "Поля", );
		ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 2, "ПризнакУчета", ,          "ПризнакиУчета", );
		ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 2, "ПризнакУчетаСубконто", ,  "ПризнакиУчетаСубконто", );
		ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 2, "Реквизит", ,              "Реквизиты", );
		ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 2, "РеквизитАдресации", ,     "РеквизитыАдресации", );
		ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 2, "Ресурс", ,                "Ресурсы", );
		ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 2, "ТабличнаяЧасть", 55,      "ТабличныеЧасти", 54);
		ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 2, "Таблица", ,               "Таблицы", );
		ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 2, "Форма", ,                 "Формы", );
		Если ирКэш.НомерРежимаСовместимостиЛкс() >= 803003 Тогда
			ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 2, "ТаблицаИзмерения", ,   "ТаблицыИзмерений", );
		КонецЕсли; 
	КонецЕсли;
	
	// Внешние типы
	Если ЛиВключатьВнешние Тогда
		ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 3, "ВнешняяОбработка", ,      "ВнешниеОбработки", );
		ДобавитьВТаблицуТиповМетаОбъектов(Таблица, 3, "ВнешнийОтчет", ,          "ВнешниеОтчеты", );
	КонецЕсли;
	
	Возврат Таблица;

КонецФункции // ПолучитьТаблицуКорневыхОбъектов()

Функция ПолучитьТекстРезультатаКомандыСистемы(Знач Команда = "", Знач ИмяСервера = "", Знач _ИспользоватьWSH = Истина, Элевация = Ложь) Экспорт
	
	Если Не ЗначениеЗаполнено(ИмяСервера) Тогда
		ФайлРезультата = Новый Файл(ПолучитьИмяВременногоФайла());
		СтрокаЗапуска = Команда;
		ЗапуститьСкрытоеПриложениеИДождатьсяЗавершения(СтрокаЗапуска, ФайлРезультата.Путь, _ИспользоватьWSH, ФайлРезультата.Имя, , Элевация);
		Если ФайлРезультата.Существует() Тогда 
			ТекстовыйДокумент = Новый ТекстовыйДокумент;
			ТекстовыйДокумент.Прочитать(ФайлРезультата.ПолноеИмя, КодировкаТекста.OEM);
			УдалитьФайлы(ФайлРезультата.ПолноеИмя);
			Результат = ТекстовыйДокумент.ПолучитьТекст();
		Иначе
			Результат = "Файл результата команды системы не найден! Попробуйте отключить антивирусное ПО.";
		КонецЕсли;
	Иначе
		ВызватьИсключение "Получение результата команды системы на удаленном сервере не реализовано";
	КонецЕсли;
	Возврат Результат;
	
КонецФункции

Функция ЗарегистрироватьПолучитьCOMОбъект(КлассКомпоненты, ПолноеИмяDll, Административная = Ложь, ИмяТипаВК = Ложь, ИмяМакетаКомпоненты = "") Экспорт
	
	Если ирКэш.Это64битныйПроцессЛкс() Тогда 
		ТипПроцесса = "64";
	Иначе
		ТипПроцесса = "32";
	КонецЕсли; 
	Если Найти(КлассКомпоненты, "ForNet") > 0 Тогда
		ТипCOMКомпоненты = "-Net";
	Иначе
		ТипCOMКомпоненты = "";
	КонецЕсли; 
	Если Не Административная И ЗначениеЗаполнено(ИмяМакетаКомпоненты) Тогда
		Если Метаданные().Макеты.Найти(ИмяМакетаКомпоненты + "Reg") <> Неопределено Тогда 
			// http://stackoverflow.com/questions/35782404/registering-a-com-without-admin-rights
			// http://stackoverflow.com/questions/37193356/registering-net-com-dlls-without-admin-rights-regasm
			СкриптРегистрации = ПолучитьМакет(ИмяМакетаКомпоненты + "Reg");
			Если ТипПроцесса = "64" Тогда
				СтрокаЗамены = "HKEY_CURRENT_USER\Software\Classes\Wow6432Node";
			Иначе
				СтрокаЗамены = "HKEY_CURRENT_USER\Software\Classes";
			КонецЕсли; 
			СкриптРегистрации.УстановитьТекст(СтрЗаменить(СкриптРегистрации.ПолучитьТекст(), "HKEY_CLASSES_ROOT", СтрокаЗамены));
			СкриптРегистрации.УстановитьТекст(СтрЗаменить(СкриптРегистрации.ПолучитьТекст(), "%ComDllFilename%", ПолноеИмяDll));
			ИмяФайлаСкрипта = ПолучитьИмяВременногоФайла("reg");
			СкриптРегистрации.Записать(ИмяФайлаСкрипта, КодировкаТекста.ANSI);
			РезультатКоманды = ПолучитьТекстРезультатаКомандыСистемы("regedit /s """ + ИмяФайлаСкрипта + """");
			Компонента = ПолучитьПроверитьCOMОбъект(КлассКомпоненты, ИмяТипаВК);
			Если Компонента <> Неопределено Тогда 
				Сообщить("Зарегистрирована COM" + ТипCOMКомпоненты + "-компонента " + КлассКомпоненты, СтатусСообщения.Информация);
				Возврат Компонента;
			Иначе
				Сообщить(РезультатКоманды);
			КонецЕсли;
		КонецЕсли; 
	КонецЕсли; 
	Если ТипCOMКомпоненты = "-Net" Тогда
		Если Административная Тогда
			Если ФайлРегистратораNetКомпонент = Неопределено Тогда
				ФайлРегистратораNetКомпонент = ПроверитьЗаписатьКомпонентуИзМакетаВФайл("Regasm" + ТипПроцесса, , "exe");
			КонецЕсли;
			КоманднаяСтрока = """" + ФайлРегистратораNetКомпонент.ПолноеИмя + """ """ + ПолноеИмяDll + """ /unregister"; // сначала надо отменить регистрацию, иначе новая может не выполниться
			ИмяФайлаРезультата = "";
			РезультатКоманды = ПолучитьТекстРезультатаКомандыСистемы(КоманднаяСтрока, , Истина, Административная);
			КоманднаяСтрока = """" + ФайлРегистратораNetКомпонент.ПолноеИмя + """ """ + ПолноеИмяDll + """ /codebase";
			ИмяФайлаРезультата = "";
			РезультатКоманды = ПолучитьТекстРезультатаКомандыСистемы(КоманднаяСтрока, , Истина, Административная);
			Компонента = ПолучитьПроверитьCOMОбъект(КлассКомпоненты, ИмяТипаВК);
			Если Компонента <> Неопределено Тогда 
				Сообщить("Зарегистрирована COM" + ТипCOMКомпоненты + "-компонента " + КлассКомпоненты, СтатусСообщения.Информация);
				Возврат Компонента;
			Иначе
				Сообщить(РезультатКоманды);
			КонецЕсли;
		КонецЕсли; 
	Иначе
		Если Не Административная Тогда
			// HKCU через сторонний регистратор. Обычно это срабатывает
			Если ФайлРегистратораКомпонентCU = Неопределено Тогда
				ФайлРегистратораКомпонентCU = ПроверитьЗаписатьКомпонентуИзМакетаВФайл("RegsvrPower", , "exe");
				ПроверитьЗаписатьКомпонентуИзМакетаВФайл("TLBINF32");
			КонецЕсли;
			//Regsvrex тут иногда аварийно завершается
			//КоманднаяСтрока = """" + ФайлРегистратораКомпонент.ПолноеИмя + """ /c /s /i """ + ПолноеИмяDll + """"; // RegsvrEx
			ФайлКомпоненты = Новый Файл(ПолноеИмяDll);
			КоманднаяСтрока = """" + ФайлРегистратораКомпонентCU.ПолноеИмя + """ " + ФайлКомпоненты.Имя + " /s"; // RegsvrPower не понимает длинные пути
			ЗапуститьСкрытоеПриложениеИДождатьсяЗавершения(КоманднаяСтрока, ФайлКомпоненты.Путь, Истина);
			Компонента = ПолучитьПроверитьCOMОбъект(КлассКомпоненты, ИмяТипаВК);
			Если Компонента <> Неопределено Тогда 
				Сообщить("В HKCU зарегистрирована COM" + ТипCOMКомпоненты + "-компонента " + КлассКомпоненты, СтатусСообщения.Информация);
				Возврат Компонента;
			КонецЕсли;
		Иначе
			// HKLM с DLLInstall
			КоманднаяСтрока = "regsvr32 /s /i """ + ПолноеИмяDll + """";
			ЗапуститьСкрытоеПриложениеИДождатьсяЗавершения(КоманднаяСтрока, , Истина,,, Административная);
			Компонента = ПолучитьПроверитьCOMОбъект(КлассКомпоненты, ИмяТипаВК);
			Если Компонента <> Неопределено Тогда 
				Сообщить("Зарегистрирована COM" + ТипCOMКомпоненты + "-компонента " + КлассКомпоненты, СтатусСообщения.Информация);
				Возврат Компонента;
			КонецЕсли;
			
			// HKLM
			КоманднаяСтрока = "regsvr32 /s """ + ПолноеИмяDll + """";
			//ТекстРезультата = ПолучитьТекстРезультатаКомандыСистемы(КоманднаяСтрока,, Истина);
			ЗапуститьСкрытоеПриложениеИДождатьсяЗавершения(КоманднаяСтрока, , Истина,,, Административная);
			Компонента = ПолучитьПроверитьCOMОбъект(КлассКомпоненты, ИмяТипаВК);
			Если Компонента <> Неопределено Тогда 
				Сообщить("Зарегистрирована COM" + ТипCOMКомпоненты + "-компонента " + КлассКомпоненты, СтатусСообщения.Информация);
				Возврат Компонента;
			КонецЕсли;
		КонецЕсли;
	КонецЕсли; 
	//Если ирКэш.Это64битныйПроцессЛкс() Тогда
	//	Сообщить("Невозможно загрузить 32-битную COM" + ТипCOMКомпоненты + "-компоненту " + КлассКомпоненты + " в 64-битном приложении. Запустите 32-битное приложение.", СтатусСообщения.Внимание);
	//Иначе
		ТекстСообщения = "Не удалось зарегистрировать COM" + ТипCOMКомпоненты + "-компоненту " + КлассКомпоненты;
		Если Истина
			И Административная
			И (Ложь
				Или ирКэш.ВКОбщая().IsAdmin() 
				//Или ЕстьАдминистративныеПраваУУчетнойЗаписиОС()
				) 
		Тогда
			ТекстСообщения = ТекстСообщения + " от имени администратора!"
		Иначе
			ТекстСообщения = ТекстСообщения + ". Запустите приложение от имени администратора или используйте инструмент ""Административная регистрация COM компонент"" для ее регистрации"
		КонецЕсли; 
	//КонецЕсли; 
	Сообщить(ТекстСообщения, СтатусСообщения.Внимание);
	Возврат Неопределено;
	
КонецФункции // ЗарегистрироватьПолучитьCOMОбъект

Функция ПолучитьПроверить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Объект(КлассКомпоненты, ФайлКомпоненты.ПолноеИмя, , ИмяТипаВК, ИмяМакетаКомпоненты);
	КонецЕсли; 
	Возврат Результат;

КонецФункции // ПолучитьCOMОбъектИзМакета()

// Параметры:
//   ИмяКомпоненты - Строка - имя макета компоненты
//   КлассКомпоненты - Строка - имя 
//   ТипВнешнейКомпоненты - ТипВнешнейКомпоненты, * - по умолчанию Native
Функция ПолучитьОбъектВнешнейКомпонентыИзМакета(ИмяМакетаКомпоненты, ИмяОбъекта, ИмяКомпоненты = Неопределено, Знач ТипКомпоненты = Неопределено,
	ИмяМакетаДополнительнойБиблиотеки = "") Экспорт
	
	Если ТипКомпоненты = Неопределено Тогда
		ТипКомпоненты = ТипВнешнейКомпоненты.Native;
	КонецЕсли; 
	Попытка
		Результат = Новый (ИмяОбъекта);
	Исключение
		Если ИмяКомпоненты = Неопределено Тогда
			ИмяКомпоненты = ИмяМакетаКомпоненты;
		КонецЕсли;
		ФайлКомпоненты = ПроверитьЗаписатьКомпонентуИзМакетаВФайл(ИмяМакетаКомпоненты);
		Если ЗначениеЗаполнено(ИмяМакетаДополнительнойБиблиотеки) Тогда
			ФайлДополнительнойБиблиотеки = ПроверитьЗаписатьКомпонентуИзМакетаВФайл(ИмяМакетаДополнительнойБиблиотеки);
		КонецЕсли; 
		ПодключитьВнешнююКомпоненту(ФайлКомпоненты.ПолноеИмя, ИмяКомпоненты, ТипКомпоненты);
		ПодключитьВнешнююКомпоненту(ИмяОбъекта);
		Попытка
			Результат = Новый (ИмяОбъекта);
		Исключение
		КонецПопытки;
	КонецПопытки;
	Возврат Результат;
	
КонецФункции

Функция ПроверитьЗаписатьКомпонентуИзМакетаВФайл(Знач ИмяМакетаКомпоненты, КаталогУстановки = "", Расширение = "dll") Экспорт 

	Если Не ЗначениеЗаполнено(КаталогУстановки) Тогда
		КаталогУстановки = ПапкаВнешнихКомпонент.ПолноеИмя;
	КонецЕсли;
	ДвоичныеДанныеМакета = ПолучитьДвоичныеДанныеКомпоненты(ИмяМакетаКомпоненты);
	ФайлКомпоненты = Новый Файл(КаталогУстановки + "\" + ИмяМакетаКомпоненты + "." + Расширение);
	ВременныйФайл = Новый Файл(ПолучитьИмяВременногоФайла());
	ДвоичныеДанныеМакета.Записать(ВременныйФайл.ПолноеИмя);
	Счетчик = 1;
	ФайлПодходит = Ложь;
	Пока ФайлКомпоненты.Существует() Цикл
		#Если Клиент Тогда
		СравнениеФайлов = Новый СравнениеФайлов;
		СравнениеФайлов.СпособСравнения = СпособСравненияФайлов.Двоичное;
		СравнениеФайлов.ПервыйФайл = ВременныйФайл.ПолноеИмя;
		СравнениеФайлов.ВторойФайл = ФайлКомпоненты.ПолноеИмя;
		Если СравнениеФайлов.Сравнить() Тогда
			ФайлПодходит = Истина;
			Прервать;
		КонецЕсли; 
		#Иначе
			Если ВременныйФайл.Размер() = ФайлКомпоненты.Размер() Тогда // Опасно. Переделать на Хэш
				ФайлПодходит = Истина;
				Прервать;
			КонецЕсли; 
		#КонецЕсли
		ФайлКомпоненты = Новый Файл(КаталогУстановки + "\" + ИмяМакетаКомпоненты +  "_" + Формат(Счетчик, "ЧГ=") + "." + Расширение);
		Счетчик = Счетчик + 1;
	КонецЦикла; 
	Если Не ФайлПодходит Тогда
		Попытка
			ПереместитьФайлКакАдминистратор(ВременныйФайл.ПолноеИмя, ФайлКомпоненты.ПолноеИмя);
		Исключение
			УдалитьФайлы(ВременныйФайл.ПолноеИмя);
			Сообщить("Файл """ + ФайлКомпоненты.ПолноеИмя + """ недоступен для изменения и не был перезаписан.", СтатусСообщения.Внимание);
			Возврат Неопределено;
		КонецПопытки; 
	КонецЕсли; 
	Возврат ФайлКомпоненты;

КонецФункции

Функция ПолучитьДвоичныеДанныеКомпоненты(БазовоеИмяМакетаКомпоненты) Экспорт 
	
	Если Метаданные().Макеты.Найти(БазовоеИмяМакетаКомпоненты) = Неопределено Тогда
		Если ирКэш.Это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.ИзвлечьВсе(лПутьКШаблонуВнешнейОбработки);
	ФайлСИменем = Новый Файл(лПутьКШаблонуВнешнейОбработки + "\" + СубПутьКФайлуПотокаЗаголовкаВнешнейОбработки);
	ПотокСИменемОбработки = Новый ТекстовыйДокумент;
	ПотокСИменемОбработки.Прочитать(ФайлСИменем.ПолноеИмя);
	ТекстПотокаСИменем = ПотокСИменемОбработки.ПолучитьТекст();
	СоздатьКомандныйФайлДляУпаковкиФайлаВнешнейОбработки(лПутьКШаблонуВнешнейОбработки);
	
	Возврат лПутьКШаблонуВнешнейОбработки;

КонецФункции // РазвернутьШаблонВнешнейОбработки()

Процедура СоздатьКомандныйФайлДляУпаковкиФайлаВнешнейОбработки(Каталог) Экспорт

	ПолучитьМакет("v8unpack").Записать(Каталог + "\" + ИмяФайлаПакера);
	ПолучитьМакет("Zlib1").Записать(Каталог + "\" + "Zlib1.dll");
	ТекстовыйДокумент = Новый ТекстовыйДокумент;
	ТекстовыйДокумент.УстановитьТекст("
	|FOR /D %%I IN (*.unp) DO " + ИмяФайлаПакера + " -pack    %%I %%~nI
	|FOR    %%I IN (*.und) DO " + ИмяФайлаПакера + " -deflate %%I %%~nI
	|" + ИмяФайлаПакера + " -pack .\ %1");
	ТекстовыйДокумент.Записать(Каталог + "\" + "pack.bat", КодировкаТекста.ANSI);

КонецПроцедуры // СоздатьКомандныйФайлДляУпаковкиФайлаВнешнейОбработки()

Процедура УпаковатьФайлВнешнейОбработки(КаталогРаспаковки, ПолноеИмяФайлаВнешнейОбработки) Экспорт

	СоздатьКомандныйФайлДляУпаковкиФайлаВнешнейОбработки(КаталогРаспаковки);
	ЗапуститьСкрытоеПриложениеИДождатьсяЗавершения("pack.bat """ + ПолноеИмяФайлаВнешнейОбработки + """", КаталогРаспаковки);

КонецПроцедуры // УпаковатьФайлВнешнейОбработки()

Процедура РаспаковатьФайлВнешнейОбработки(ПолноеИмяФайла, ПутьРаспаковки) Экспорт 

	//ПроверитьСоздатьФайлЗапаковщика1С();
	ПолучитьМакет("v8unpack").Записать(ПутьРаспаковки + "\" + ИмяФайлаПакера);
	ПолучитьМакет("Zlib1").Записать(ПутьРаспаковки + "\" + "Zlib1.dll");
	ТекстовыйДокумент = Новый ТекстовыйДокумент;
	ТекстовыйДокумент.УстановитьТекст("
	|" + ИмяФайлаПакера + " -unpack  %1 .\
	|FOR %%I IN (*.data) DO " + ИмяФайлаПакера + " -undeflate %%I %%~nI.data.und
	|FOR %%I IN (*.und)  DO " + ИмяФайлаПакера + " -unpack    %%I %%~nI.und.unp
	|");
	ТекстовыйДокумент.Записать(ПутьРаспаковки + "\" + "unpack.bat", КодировкаТекста.ANSI);
	ЗапуститьСкрытоеПриложениеИДождатьсяЗавершения("unpack.bat """ + ПолноеИмяФайла + """", ПутьРаспаковки);

КонецПроцедуры // РаспаковатьВнешнююОбработку()

// <Описание функции>
//
// Параметры:
//  <Параметр1>  – <Тип.Вид> – <описание параметра>
//                 <продолжение описания параметра>;
//  <Параметр2>  – <Тип.Вид> – <описание параметра>
//                 <продолжение описания параметра>.
//
// Возвращаемое значение:
//               – <Тип.Вид> – <описание значения>
//                 <продолжение описания значения>;
//  <Значение2>  – <Тип.Вид> – <описание значения>
//                 <продолжение описания значения>.
//
Функция СформироватьВнешнююОбработку(ИмяОбработки, ФайлОбработки, ТекстМодуля, ТекстМакета = Неопределено, ДляИДВерсииПлатформы = "") Экспорт
	
	#Если Сервер И Не Сервер Тогда
	    ФайлОбработки = Новый файл;
	#КонецЕсли
	// Начиная с 8.3.11 кэширование внешних обработок проверяет только контрольные суммы, которые в старом способе не меняются, поэтому на 8.3.11+ используется штатный долгий метод генерации внешней обработки
	Если ирКэш.НомерВерсииПлатформыЛкс() >= 803011 Тогда
		// Штатный способ платформы, но работает только на 8.3.8+
		Если ТекстМакета <> Неопределено Тогда
			ВызватьИсключение "Парамер ТекстМакета для 8.3.11+ не поддерживается";
		КонецЕсли; 
		ШаблонВнешнейОбработки = ШаблоныВнешнейОбработки["8"];
		Если ШаблонВнешнейОбработки = Неопределено Тогда
			ИмяВременногоФайла = ПолучитьИмяВременногоФайла("epf");
			ПолучитьМакет("ВнешняяОбработка").Записать(ИмяВременногоФайла);
			ШаблонВнешнейОбработки = ПолучитьИмяВременногоФайла();
			СоздатьКаталог(ШаблонВнешнейОбработки);
			ТекстЛога = Неопределено;
			Если Не ирОбщий.ВыполнитьКомандуКонфигуратораЛкс("/DumpExternalDataProcessorOrReportToFiles """ + ШаблонВнешнейОбработки + """ """ + ИмяВременногоФайла + """",, ТекстЛога, Истина) Тогда 
				УдалитьФайлы(ШаблонВнешнейОбработки);
				УдалитьФайлы(ИмяВременногоФайла);
				Сообщить(ТекстЛога);
				Возврат Ложь;
			КонецЕсли; 
			ШаблоныВнешнейОбработки["8"] = ШаблонВнешнейОбработки;
		КонецЕсли; 
		Файлы = НайтиФайлы(ШаблонВнешнейОбработки, "ObjectModule.bsl", Истина);
		ТекстовыйДокумент = Новый ТекстовыйДокумент;
		ТекстовыйДокумент.УстановитьТекст(ТекстМодуля);
		ТекстовыйДокумент.Записать(Файлы[0].ПолноеИмя);
		ТекстЛога = Неопределено;
		ИмяКорневогоФайла = ШаблонВнешнейОбработки + "\ИмяВнешнейОбработки.xml";
		Если Не ирОбщий.ВыполнитьКомандуКонфигуратораЛкс("/LoadExternalDataProcessorOrReportFromFiles """ + ИмяКорневогоФайла + """ """ + ФайлОбработки.ПолноеИмя + """", , ТекстЛога, Истина) Тогда 
			УдалитьФайлы(ШаблонВнешнейОбработки);
			УдалитьФайлы(ИмяВременногоФайла);
			Сообщить(ТекстЛога);
			Возврат Ложь;
		КонецЕсли; 
		Результат = Истина;
	Иначе
		Если ПустаяСтрока(ДляИДВерсииПлатформы) Тогда
			ДляИДВерсииПлатформы = ирКэш.НомерИзданияПлатформыЛкс();
		КонецЕсли; 
		Если ДляИДВерсииПлатформы = "83" Тогда
			ДляИДВерсииПлатформы = "82";
		КонецЕсли; 

		Если ТекстМакета <> Неопределено Тогда
			ШаблонВнешнейОбработкиСМакетом = ШаблоныВнешнейОбработкиСМакетом[ДляИДВерсииПлатформы];
			Если ШаблонВнешнейОбработкиСМакетом = Неопределено Тогда
				ШаблонВнешнейОбработкиСМакетом = Новый Структура("Путь, ФайлСИменем, ФайлЗамок, ТекстПотокаСИменем");
				ШаблонВнешнейОбработкиСМакетом.Путь = РазвернутьНовыйШаблонВнешнейОбработки(Истина,,
					ШаблонВнешнейОбработкиСМакетом.ФайлСИменем, ШаблонВнешнейОбработкиСМакетом.ТекстПотокаСИменем, ДляИДВерсииПлатформы);
				ФайлЗамокШаблонаСМакетом = Новый ЗаписьТекста;
				ФайлЗамокШаблонаСМакетом.Открыть(ШаблонВнешнейОбработкиСМакетом.Путь + ".lck");
				ШаблонВнешнейОбработкиСМакетом.ФайлЗамок = ФайлЗамокШаблонаСМакетом;
				ШаблоныВнешнейОбработкиСМакетом[ДляИДВерсииПлатформы] = ШаблонВнешнейОбработкиСМакетом;
			КонецЕсли;
			ПутьКШаблону = ШаблонВнешнейОбработкиСМакетом.Путь;
			ФайлСИменем = ШаблонВнешнейОбработкиСМакетом.ФайлСИменем;
			ТекстПотокаСИменем = ШаблонВнешнейОбработкиСМакетом.ТекстПотокаСИменем;
		Иначе
			ШаблонВнешнейОбработки = ШаблоныВнешнейОбработки[ДляИДВерсииПлатформы];
			Если ШаблонВнешнейОбработки = Неопределено Тогда
				ШаблонВнешнейОбработки = Новый Структура("Путь, ФайлСИменем, ФайлЗамок, ТекстПотокаСИменем");
				ШаблонВнешнейОбработки.Путь = РазвернутьНовыйШаблонВнешнейОбработки(,,
					ШаблонВнешнейОбработки.ФайлСИменем, ШаблонВнешнейОбработки.ТекстПотокаСИменем, ДляИДВерсииПлатформы);
				ФайлЗамокШаблона = Новый ЗаписьТекста;
				ФайлЗамокШаблона.Открыть(ШаблонВнешнейОбработки.Путь + ".lck");
				ШаблонВнешнейОбработки.ФайлЗамок = ФайлЗамокШаблона;
				ШаблоныВнешнейОбработки[ДляИДВерсииПлатформы] = ШаблонВнешнейОбработки;
			КонецЕсли;
			ПутьКШаблону = ШаблонВнешнейОбработки.Путь;
			ФайлСИменем = ШаблонВнешнейОбработки.ФайлСИменем; 
			ТекстПотокаСИменем = ШаблонВнешнейОбработки.ТекстПотокаСИменем;
		КонецЕсли;
		
		ПутьКШаблону = ПутьКШаблону + "\";
		ТекстПотокаСИменем = СтрЗаменить(ТекстПотокаСИменем, "ИмяВнешнейОбработки", ИмяОбработки);
		ПотокСИменемОбработки = Новый ТекстовыйДокумент;
		ПотокСИменемОбработки.УстановитьТекст(ТекстПотокаСИменем);
		ПотокСИменемОбработки.Записать(ФайлСИменем.ПолноеИмя);
		
		ФайлТекстаМодуляОбработки = Новый Файл(ПутьКШаблону + СубПутьКФайлуПотокаМодуляВнешнейОбработки);
		ТекстовыйДокументМодуля = Новый ТекстовыйДокумент();
		ТекстовыйДокументМодуля.УстановитьТекст(ТекстМодуля);
		ТекстовыйДокументМодуля.Записать(ФайлТекстаМодуляОбработки.ПолноеИмя);
		
		Если ТекстМакета <> Неопределено Тогда
			ФайлТекстаМакетаПараметров = Новый Файл(ПутьКШаблону + СубПутьКФайлуПотокаМакетаВнешнейОбработки);
			ТекстовыйДокументМакета = Новый ТекстовыйДокумент();
			ТекстовыйДокументМакета.УстановитьТекст(ТекстМакета);
			ТекстовыйДокументМакета.Записать(ФайлТекстаМакетаПараметров.ПолноеИмя);
		КонецЕсли;
		
		Результат = УпаковатьВнешнююОбработку(ПутьКШаблону, ФайлОбработки.ПолноеИмя);
	КонецЕсли; 
	Возврат Результат;

КонецФункции // СформироватьВнешнююОбработку()

// Файлы "Zlib1.dll" и "v8unpack.exe" должны быть в этом каталоге.
Функция УпаковатьВнешнююОбработку(ПутьКШаблонуВнешнейОбработки, ИмяВыходногоФайла, СоздатьФайлыУпаковщика = Ложь) Экспорт

	// Небольшой накладной расход, но надежность повышаем
	УдалитьФайлы(ПутьКШаблонуВнешнейОбработки + СубПутьККонтрольномуФайлуВнешнейОбработки);
	Попытка
		УдалитьФайлы(ИмяВыходногоФайла);
	Исключение
		Событие = "Ошибка создания служебного объекта (1)";
		//Сообщить(Событие, СтатусСообщения.Важное);
		//ЗаписьЖурналаРегистрации(Событие, УровеньЖурналаРегистрации.Ошибка);
		//Возврат Неопределено;
		ВызватьИсключение Событие;
	КонецПопытки;
	
	Если СоздатьФайлыУпаковщика Тогда 
		ПолучитьМакет("v8unpack").Записать(ПутьКШаблонуВнешнейОбработки + ИмяФайлаПакера);
		ПолучитьМакет("Zlib1").Записать(ПутьКШаблонуВнешнейОбработки + "Zlib1.dll");
	КонецЕсли;

	ЗапуститьСкрытоеПриложениеИДождатьсяЗавершения("pack.bat """ + ИмяВыходногоФайла + """", ПутьКШаблонуВнешнейОбработки);
	
	КонтрольныйФайл1 = Новый Файл(ПутьКШаблонуВнешнейОбработки + СубПутьККонтрольномуФайлуВнешнейОбработки);
	КонтрольныйФайл2 = Новый Файл(ИмяВыходногоФайла);
	Если Ложь
		Или Не КонтрольныйФайл1.Существует() 
		//Или Не КонтрольныйФайл2.Существует()  // Отключил для повышения скорости
	Тогда
		Событие = "Ошибка создания служебного объекта (2)";
		//Сообщить(Событие, СтатусСообщения.Важное);
		//ЗаписьЖурналаРегистрации(Событие, УровеньЖурналаРегистрации.Ошибка);
		//Возврат Неопределено;
		ВызватьИсключение Событие;
	КонецЕсли;
	Возврат Истина;

КонецФункции // УпаковатьВнешнююОбработку()

// <Описание функции>
//
// Параметры:
//  <Параметр1>  – <Тип.Вид> – <описание параметра>
//                 <продолжение описания параметра>;
//  <Параметр2>  – <Тип.Вид> – <описание параметра>
//                 <продолжение описания параметра>.
//
// Возвращаемое значение:
//               – <Тип.Вид> – <описание значения>
//                 <продолжение описания значения>;
//  <Значение2>  – <Тип.Вид> – <описание значения>
//                 <продолжение описания значения>.
//
Функция ПолучитьФайлВнешнейОбработкиАлгоритма(АлгоритмОбъект) Экспорт 

	Если Ложь
		Или СтрДлина(ПапкаКешаВнешнихОбработокАлгоритмов.ПолноеИмя) + СтрДлина(АлгоритмОбъект.Наименование) > 250
	Тогда
		// Ограничение WinAPI на путь к файлу
		КлючСервиса = "" + АлгоритмОбъект.Ссылка.УникальныйИдентификатор();
	Иначе
		КлючСервиса = АлгоритмОбъект.Наименование;
	КонецЕсли; 
	ИмяФайла = КлючСервиса + ".epf";
	ФайлВнешнейОбработки = Новый Файл(ПапкаКешаВнешнихОбработокАлгоритмов.ПолноеИмя + "\" + ИмяФайла);
	Возврат ФайлВнешнейОбработки;

КонецФункции // ПолучитьФайлВнешнейОбработкиАлгоритма()

// <Описание функции>
//
// Параметры:
//  <Параметр1>  – <Тип.Вид> – <описание параметра>
//                 <продолжение описания параметра>;
//  <Параметр2>  – <Тип.Вид> – <описание параметра>
//                 <продолжение описания параметра>.
//
// Возвращаемое значение:
//               – <Тип.Вид> – <описание значения>
//                 <продолжение описания значения>;
//  <Значение2>  – <Тип.Вид> – <описание значения>
//                 <продолжение описания значения>.
//
Функция ПолучитьОбновитьФайлВнешнейОбработкиАлгоритма(ДескрипторСервиса, ЭлементКэша = Неопределено,
	ДатаИзмененияКэша = Неопределено) Экспорт

	ВнешняяОбработка = Неопределено;
	ФайлВнешнейОбработкиАктуален = Ложь;
	КэшВнешнейОбработкиАктуален = Ложь;
	ФайлВнешнейОбработки = ПолучитьФайлВнешнейОбработкиАлгоритма(ДескрипторСервиса);
	ДатаИзмененияОбъекта = ДескрипторСервиса.ДатаИзмененияКонтекста;
	
	//// Условие добавлено для мягкого перехода на новый кэш параметров сервисов 21.10.2010. Потом нужно убрать
	//Если ЗначениеЗаполнено(ДескрипторСервиса.ДатаИзмененияКэша) Тогда 
		ПроверитьАктуальностьКэшаВнешнейОбработки(ЭлементКэша, ДатаИзмененияКэша, ФайлВнешнейОбработки, ДатаИзмененияОбъекта, 
			КэшВнешнейОбработкиАктуален, ФайлВнешнейОбработкиАктуален, ФайловыйКэшАлгоритмовДопускаетРедактирование);
	//КонецЕсли; 
	Если Истина
		И Не КэшВнешнейОбработкиАктуален
		И Не ФайлВнешнейОбработкиАктуален
	Тогда
		СервисОбъект = ПроверитьПолучитьОбъектСервиса(ДескрипторСервиса); 
		СервисОбъект.СобратьКонтекст();
		СформироватьВнешнююОбработку(СервисОбъект.Наименование, ФайлВнешнейОбработки,
			СервисОбъект.ПолучитьТекстМодуляОбработки()
			//, СервисОбъект.ПолучитьТекстМакетаПараметров()
			);
		Попытка
			ФайлВнешнейОбработки.УстановитьВремяИзменения(СервисОбъект.ДатаИзмененияКонтекста);
		Исключение
			Если Не ФайлВнешнейОбработки.Существует() Тогда
				ПроверитьСистемнуюКодовуюСтраницуОС();
				ВызватьИсключение "Файл внешней обработки сервиса """ + СервисОбъект.Наименование + """ не сформирован";
			Иначе
				ВызватьИсключение;
			КонецЕсли; 
		КонецПопытки;
	КонецЕсли; 
	Если КэшВнешнейОбработкиАктуален Тогда 
		Возврат Неопределено;
	Иначе
		Возврат ФайлВнешнейОбработки;
	КонецЕсли;

КонецФункции // ПолучитьОбновитьФайлВнешнейОбработкиАлгоритма()

Функция ПроверитьСистемнуюКодовуюСтраницуОС() Экспорт
	Локатор = Новый COMОбъект("WbemScripting.SwbemLocator");
	ПространствоИмен1 = Локатор.ConnectServer(, "Root\CIMV2");
	ВыборкаОС = ПространствоИмен1.ExecQuery("Select * from Win32_OperatingSystem");
	Для Каждого ОперационнаяСистема Из ВыборкаОС Цикл
		Прервать;
	КонецЦикла;
	Если ОперационнаяСистема.Locale <> "0419" Тогда
		ВызватьИсключение "Russian system locale (0419) in OS required for this function";
	КонецЕсли; 
КонецФункции

// <Описание функции>
//
// Параметры:
//  <Параметр1>  – <Тип.Вид> – <описание параметра>
//                 <продолжение описания параметра>;
//  <Параметр2>  – <Тип.Вид> – <описание параметра>
//                 <продолжение описания параметра>.
//
// Возвращаемое значение:
//               – <Тип.Вид> – <описание значения>
//                 <продолжение описания значения>;
//  <Значение2>  – <Тип.Вид> – <описание значения>
//                 <продолжение описания значения>.
//
Функция ПолучитьВнешнююОбработкуПоАлгоритму(ДескрипторСервиса) Экспорт

	// %%%% Здесь можно было бы структуру попробовать вместо ТЗ
	//ЭлементКэша = 0;
	//КешВнешнихОбработокАлгоритмов.Свойство(ДескрипторСервиса.Наименование, ЭлементКэша);
	ЭлементКэша = ДескрипторСервиса.мСтруктураВнешнейОбработки;
	Если Ложь
		Или ЭлементКэша = Неопределено
		Или ЭлементКэша.ДатаИзменения < ДескрипторСервиса.ДатаИзмененияКонтекста
		Или ФайловыйКэшАлгоритмовДопускаетРедактирование
	Тогда
		ДатаИзмененияКэша = ДескрипторСервиса.ДатаИзмененияКонтекста;
		// Для обхода бага платформы WSHShell.Run(,,True)
		Для Счетчик = 1 По 3 Цикл
			
			ФайлВнешнейОбработки = ПолучитьОбновитьФайлВнешнейОбработкиАлгоритма(ДескрипторСервиса, ЭлементКэша,
				ДатаИзмененияКэша);
			Если ФайлВнешнейОбработки <> Неопределено Тогда
				ВнешняяОбработка = СоздатьВнешнююОбработкуАлгоритма(ДескрипторСервиса, ФайлВнешнейОбработки.ПолноеИмя);
				
				// Для обхода бага платформы.
				Если ВнешняяОбработка <> Неопределено Тогда
					ИмяАлгоритмаВнешнейОбработки = ВнешняяОбработка.Метаданные().Имя;
					Если ИмяАлгоритмаВнешнейОбработки <> ДескрипторСервиса.Наименование Тогда
						ЗаписьЖурналаРегистрации("Несоответствие внешней обработки и сервиса", УровеньЖурналаРегистрации.Ошибка, ,
							ДескрипторСервиса.Ссылка, "Попытка №" + Счетчик + ". Внешняя обработка """ + ИмяАлгоритмаВнешнейОбработки + """");
						УдалитьФайлы(ФайлВнешнейОбработки.ПолноеИмя);
						Продолжить;
					КонецЕсли;
				КонецЕсли;
			КонецЕсли;
			Прервать;
		КонецЦикла;
		Если ФайлВнешнейОбработки <> Неопределено Тогда
			Если ЭлементКэша = Неопределено Тогда
				ЭлементКэша = Новый Структура("ДатаИзменения, ВнешняяОбработка");
				//КешВнешнихОбработокАлгоритмов.Вставить(ДескрипторСервиса.Наименование, ЭлементКэша);
				ДескрипторСервиса.мСтруктураВнешнейОбработки = ЭлементКэша;
			КонецЕсли;
			Если ВнешняяОбработка <> Неопределено Тогда
				ЭлементКэша.ДатаИзменения = ДатаИзмененияКэша;
				ЭлементКэша.ВнешняяОбработка = ВнешняяОбработка;
			Иначе
				ЭлементКэша.ДатаИзменения = Дата("00010101");
			КонецЕсли;
		КонецЕсли;
	КонецЕсли;
	Если ЭлементКэша <> Неопределено Тогда
		Результат = ЭлементКэша.ВнешняяОбработка;
	Иначе
		Результат = Неопределено;
	КонецЕсли;
	Возврат Результат;

КонецФункции // ПолучитьВнешнююОбработкуПоАлгоритму()

// <Описание процедуры>
//
// Параметры:
//  <Параметр1>  – <Тип.Вид> – <описание параметра>
//                 <продолжение описания параметра>;
//  ИмяФайлаРезультата – Краткое имя файла, в который будет выведен выходной поток, только в текущем каталоге.
//  Элевация     - Булево - используется только если текущая учетная запись Windows входит в группу Администраторы
//
Процедура ЗапуститьСкрытоеПриложениеИДождатьсяЗавершения(Знач СтрокаЗапуска, Знач ТекущийКаталог = "", Знач _ИспользоватьWSH = Истина,
	КраткоеИмяФайлаРезультата = "", ОжидатьЗавершения = Истина, Элевация = Ложь) Экспорт 
	
	Если Не ЗначениеЗаполнено(ТекущийКаталог) Тогда
		ТекущийКаталог = КаталогВременныхФайлов();
	КонецЕсли; 
	СтрокаЗапуска = "cmd.exe /c """ + СтрокаЗапуска + """";
	Если КраткоеИмяФайлаРезультата <> "" Тогда
		СтрокаЗапуска = СтрокаЗапуска + " > """ + ТекущийКаталог + КраткоеИмяФайлаРезультата + """";
		СтрокаЗапуска = СтрокаЗапуска + " 2>&1"; //stderr
	КонецЕсли;
	ИмяКомандногоФайла = ирОбщий.СоздатьСамоудаляющийсяКомандныйФайлЛкс(СтрокаЗапуска);
	ВК = ирКэш.ВКОбщая();
	ВК.Run(ИмяКомандногоФайла, "", ТекущийКаталог, ОжидатьЗавершения, Элевация);
	
КонецПроцедуры // ЗапуститьСкрытоеПриложениеИДождатьсяЗавершения()

Функция ЕстьАдминистративныеПраваУУчетнойЗаписиОС() Экспорт 
	
	Если мЕстьАдминистративныеПраваУУчетнойЗаписиОС <> Неопределено Тогда
		Возврат мЕстьАдминистративныеПраваУУчетнойЗаписиОС;
	КонецЕсли; 
	Network = Новый COMОбъект("WScript.Network");
	//ПользовательОС = 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*([-0-9A-ZА-ЯЁ]+(\.([-0-9A-ZА-ЯЁ]+))*)\s*";
		Результат = RegExp.Execute(ТекстРезультата);
		Если Результат.Count > 0 Тогда
			ПолноеИмяКомпьютера = Результат.Item(0).SubMatches(0);
		Иначе
			ПолноеИмяКомпьютера = "";
		КонецЕсли;
	КонецЕсли;
	//ASPDNS = ПолучитьCOMОбъектИзМакета("ASPDNS", "ASPDNS.DNSLookup");
	//IP = ASPDNS.GetIPFromName(ИмяКомпьютера);
	//ПолноеИмяКомпьютера = ASPDNS.GetNameFromIP(IP);
	Возврат ПолноеИмяКомпьютера;

КонецФункции // ПолучитьПолноеИмяКомпьютераСетиПоЛюбомуИмени()

Функция ПолучитьИсполнительСкрытыхКомандСистемы() Экспорт
	
	Если ИсполнительСкрытыхКомандСистемы = Неопределено Тогда
		ДвоичныеДанные = ПолучитьМакет("HiddenStart");
		ИсполнительСкрытыхКомандСистемы = ПолучитьИмяВременногоФайла("exe");
		ДвоичныеДанные.Записать(ИсполнительСкрытыхКомандСистемы);
	КонецЕсли;
	Возврат ИсполнительСкрытыхКомандСистемы;
	
КонецФункции

// <Описание процедуры>
//
// Параметры:
//  <Параметр1>  – <Тип.Вид> – <описание параметра>
//                 <продолжение описания параметра>;
//  <Параметр2>  – <Тип.Вид> – <описание параметра>
//                 <продолжение описания параметра>.
//
Функция ПроверитьКаталогФайловогоКэша() Экспорт

	СтрокаСоединения = ирКэш.ПолучитьСтрокуСоединенияСервераЛкс();
	КаталогВерсииПлатформыВПрофиле = ирКэш.КаталогИзданияПлатформыВПрофилеЛкс();
	КаталогФайловогоКэша = КаталогВерсииПлатформыВПрофиле + "\" + ПолучитьИдентификаторИзПредставления(СтрокаСоединения);
	ПапкаФайловогоКэша = Новый Файл(КаталогФайловогоКэша);
	Если Не ПапкаФайловогоКэша.Существует() Тогда
		Попытка
			СоздатьКаталог(ПапкаФайловогоКэша.ПолноеИмя);
			ПробныйФайл = Новый ТекстовыйДокумент;
			ПробныйФайл.Записать(ПапкаФайловогоКэша.ПолноеИмя + "\1.txt");
		Исключение
			Сообщить("Дополнительные кэши отключены.", СтатусСообщения.Важное);
			ВыполнятьАлгоритмыЧерезВнешниеОбработки = Ложь;
			Возврат Ложь;
		КонецПопытки;
	КонецЕсли;
	Возврат Истина;

КонецФункции // ПроверитьКаталогФайловогоКэша()

// <Описание функции>
//
// Параметры:
//  <Параметр1>  – <Тип.Вид> – <описание параметра>
//                 <продолжение описания параметра>;
//  <Параметр2>  – <Тип.Вид> – <описание параметра>
//                 <продолжение описания параметра>.
//
// Возвращаемое значение:
//               – <Тип.Вид> – <описание значения>
//                 <продолжение описания значения>;
//  <Значение2>  – <Тип.Вид> – <описание значения>
//                 <продолжение описания значения>.
//
Функция ПолучитьИмяНеопределеннойПеременнойИзИнформацииОбОшибке(ИнформацияОбОшибке, СообщитьНеобрабатываемуюОшибку = Ложь) Экспорт

	Если ИнформацияОбОшибке <> Неопределено Тогда
		RegExp.Global = Ложь;
		//ОписаниеОшибки = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке);
		Пока ИнформацияОбОшибке.Причина <> Неопределено Цикл // Добавлено 26.07.2011 из-за доработки синтаксического контроля в COM сеансе
			ИнформацияОбОшибке = ИнформацияОбОшибке.Причина;
		КонецЦикла;
		ОписаниеОшибки = ИнформацияОбОшибке.Описание;
		
		RegExp.Pattern = "(?:Переменная не определена |Variable is not defined )\(([_0-9" + шБуква + "]+)\)";
		Результат = RegExp.Execute(ОписаниеОшибки);
		Если Результат.Count > 0 Тогда 
			ИмяПеременнойРезультата = Результат.Item(0).SubMatches(0);
		Иначе
			Если СообщитьНеобрабатываемуюОшибку Тогда
				Сообщить(ПодробноеПредставлениеОшибки(ИнформацияОбОшибке), СтатусСообщения.Важное);
			КонецЕсли;
		КонецЕсли;
	КонецЕсли; 
	Возврат ИмяПеременнойРезультата;

КонецФункции // ПолучитьИмяНеопределеннойПеременнойИзИнформацииОбОшибке()

#Если Клиент Или ВнешнееСоединение Тогда

// Выполняет алгоритм по ссылке.
//
// Параметры:
//  <Параметр1>  – <Тип.Вид> – <описание параметра>
//                 <продолжение описания параметра>;
//  <Параметр2>  – <Тип.Вид> – <описание параметра>
//                 <продолжение описания параметра>.
//
// Возвращаемое значение:
//               – <Тип.Вид> – <описание значения>
//                 <продолжение описания значения>;
//  <Значение2>  – <Тип.Вид> – <описание значения>
//                 <продолжение описания значения>.
//
Функция ВыполнитьАлгоритм(СсылкаАлгоритма, СтруктураПараметров = Неопределено) Экспорт 

	Если СтруктураПараметров = Неопределено Тогда
		СтруктураПараметров = Новый Структура;
	КонецЕсли;
	Результат = Ложь;
	АлгоритмОбъект = Неопределено;
	Если Не КешАлгоритмов.Свойство(СсылкаАлгоритма, АлгоритмОбъект) Тогда
		АлгоритмОбъект = СсылкаАлгоритма.ПолучитьОбъект();
		КешАлгоритмов.Вставить(СсылкаАлгоритма, АлгоритмОбъект);
	КонецЕсли;
	ВыполнитьМетодАлгоритма(АлгоритмОбъект, 1, СтруктураПараметров);

КонецФункции // ВыполнитьАлгоритм()

// <Описание процедуры>
//
// Параметры:
//  <Параметр1>  – <Тип.Вид> – <описание параметра>
//                 <продолжение описания параметра>;
//  <Параметр2>  – <Тип.Вид> – <описание параметра>
//                 <продолжение описания параметра>.
//
Процедура ОчиститьКешАлгоритмов(ОчиститьКэшНаДиске = Ложь) Экспорт 

	КешАлгоритмов.Очистить();
	//КешВнешнихОбработокАлгоритмов.Очистить();
	Если ОчиститьКэшНаДиске Тогда 
		//Для Каждого ЭлементПодкаталога Из СтруктураПодкаталоговФайловогоКэша Цикл
		//	УдалитьФайлы(ЭлементПодкаталога.Значение.ПолноеИмя, "*.dat");
		//	УдалитьФайлы(ЭлементПодкаталога.Значение.ПолноеИмя, "*.epf");
		//КонецЦикла;
		
		ФайлПодкаталога = СтруктураПодкаталоговФайловогоКэша["a"];
		УдалитьФайлы(ФайлПодкаталога.ПолноеИмя + "\", "*.*");
		ПроверитьСтруктуруФайловогоКэша();
	КонецЕсли;

КонецПроцедуры // ОчиститьКешАлгоритмов()

// <Описание процедуры>
//
// Параметры:
//  <Параметр1>  – <Тип.Вид> – <описание параметра>
//                 <продолжение описания параметра>;
//  <Параметр2>  – <Тип.Вид> – <описание параметра>
//                 <продолжение описания параметра>.
//
Процедура ОбновитьАлгоритмВКеше(АлгоритмОбъект) Экспорт 

	КешАлгоритмов.Вставить(АлгоритмОбъект.Ссылка, АлгоритмОбъект);

КонецПроцедуры // УдалитьАлгоритмИзКеша()

// <Описание функции>
//
// Параметры:
//  <Параметр1>  – <Тип.Вид> – <описание параметра>
//                 <продолжение описания параметра>;
//  <Параметр2>  – <Тип.Вид> – <описание параметра>
//                 <продолжение описания параметра>.
//
// Возвращаемое значение:
//               – <Тип.Вид> – <описание значения>
//                 <продолжение описания значения>;
//  <Значение2>  – <Тип.Вид> – <описание значения>
//                 <продолжение описания значения>.
//
Процедура _ПроверитьСоздатьФайлЗапаковщика1С(БыстраяПроверка = Ложь) Экспорт 

	Если Ложь
		Или Не БыстраяПроверка
		Или ФайлЗапаковщика1С = Неопределено
	Тогда
		ИмяФайла = "V8unpack.exe";
		ФайлЗапаковщика1С = Новый Файл(ПапкаКешаВнешнихОбработокАлгоритмов.ПолноеИмя + "\" + ИмяФайла);
		Если Не ФайлЗапаковщика1С.Существует() Тогда
			ДанныеМакета = ПолучитьМакет("v8unpack");
			ЗаписатьМакетСУчетомМаскировки(ДанныеМакета, ФайлЗапаковщика1С.ПолноеИмя);
		КонецЕсли;
	КонецЕсли;
	Если Ложь
		Или Не БыстраяПроверка
		Или ФайлБиблиотекиЗапаковщика = Неопределено
	Тогда
		ФайлБиблиотекиЗапаковщика = Новый Файл(ПапкаКешаВнешнихОбработокАлгоритмов.ПолноеИмя + "\Zlib1.dll");
		Если Не ФайлБиблиотекиЗапаковщика.Существует() Тогда
			ДанныеМакета = ПолучитьМакет("Zlib1");
			ЗаписатьМакетСУчетомМаскировки(ДанныеМакета, ФайлБиблиотекиЗапаковщика.ПолноеИмя);
		КонецЕсли;
	КонецЕсли;

КонецПроцедуры // ПроверитьСоздатьФайлЗапаковщика1С()

// <Описание функции>
//
// Параметры:
//  <Параметр1>  – <Тип.Вид> – <описание параметра>
//                 <продолжение описания параметра>;
//  <Параметр2>  – <Тип.Вид> – <описание параметра>
//                 <продолжение описания параметра>.
//
// Возвращаемое значение:
//               – <Тип.Вид> – <описание значения>
//                 <продолжение описания значения>;
//  <Значение2>  – <Тип.Вид> – <описание значения>
//                 <продолжение описания значения>.
//
Функция ПолучитьФайлОткрывателя1С(БыстраяПроверка = Ложь) Экспорт 

	Если Ложь
		Или Не БыстраяПроверка
		Или ФайлОткрывателя1С = Неопределено
	Тогда
		ФайлОткрывателя1С = Новый Файл(ПолучитьИмяВременногоФайла("exe"));
		ПолучитьМакет("OpenIn1Cv8").Записать(ФайлОткрывателя1С.ПолноеИмя);
	КонецЕсли;
	Возврат ФайлОткрывателя1С;

КонецФункции // ПолучитьФайлОткрывателя1С()

// <Описание функции>
//
// Параметры:
//  <Параметр1>  – <Тип.Вид> – <описание параметра>
//                 <продолжение описания параметра>;
//  <Параметр2>  – <Тип.Вид> – <описание параметра>
//                 <продолжение описания параметра>.
//
// Возвращаемое значение:
//               – <Тип.Вид> – <описание значения>
//                 <продолжение описания значения>;
//  <Значение2>  – <Тип.Вид> – <описание значения>
//                 <продолжение описания значения>.
//
Функция ПолучитьФайлРаспаковщикаZIP(БыстраяПроверка = Ложь) Экспорт 

	Если Ложь
		Или Не БыстраяПроверка
		Или ФайлРаспаковщикаZIP = Неопределено
	Тогда
		ФайлРаспаковщикаZIP = Новый Файл(ПолучитьИмяВременногоФайла("exe"));
		ПолучитьМакет("unzip").Записать(ФайлРаспаковщикаZIP.ПолноеИмя);
	КонецЕсли;
	Возврат ФайлРаспаковщикаZIP;

КонецФункции // ПолучитьФайлРаспаковщикаZIP()

// Получает из длинного пути к файлу короткий в формате DOS (8.3) 
//
// Параметры:
//  ПолноеИмяФайла – Строка;
//
// Возвращаемое значение:
//  Строка;
//
Функция ПолучитьИмяФайлаВФорматеDOS(ПолноеИмяФайла) Экспорт
	
	Если VBScript = Неопределено Тогда
		VBScript = Новый COMОбъект("MSScriptControl.ScriptControl");
		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() Экспорт

	Если 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()

Функция ПолучитьНовыйВычислительРегулярныхВыражений(VBScript = Истина) Экспорт
	
	Если VBScript Тогда
		Результат = Новый COMОбъект("VBScript.RegExp");
	Иначе
		Результат = ПолучитьОбъектВнешнейКомпонентыИзМакета("V8RegEx", "V8RegEx");
	КонецЕсли; 
	Результат.IgnoreCase = Истина;
	Возврат Результат;
	
КонецФункции

Функция ПолучитьИмяТипаCOMVariant(Член) Экспорт
	
	Перем ScrptCtrl;
	
	ТекстМодуля = "
	|Function getMemberReturn( member )
	|  Dim ret
	|    On Error Resume Next
	|    If member.ReturnType Is Nothing Then
	|        ret = """"
	|    ElseIf Not IsEmpty(member.ReturnType.TypedVariant) Then
	|		 ff = member.ReturnType.TypedVariant
	|		 ff.VariantInit()
	|        ret = ff.Name
	|    ElseIf Not member.ReturnType.TypeInfo Is Nothing Then
	|        ret = member.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", Член);
	Возврат Результат;
	
КонецФункции

#Если Клиент Тогда
	
///////////////////////////////////////////////////////////////////
// Информатор. Начало http://www.1cpp.ru/forum/YaBB.pl?num=1313560540/105

Функция ПолучитьОписаниеОбъектаИнформатором(Объект, выхТаблицаОписания, Флаг)
	
	выхТаблицаОписания = Новый ТаблицаЗначений;
	выхТаблицаОписания.Колонки.Добавить("Name");
	выхТаблицаОписания.Колонки.Добавить("Type");
	выхТаблицаОписания.Колонки.Добавить("Val");
	выхТаблицаОписания.Колонки.Добавить("NParams");
	выхТаблицаОписания.Колонки.Добавить("ID");
	выхТаблицаОписания.Колонки.Добавить("ContID");
	Если мОшибкаИнформаторУжеВыводилась = Истина Тогда
		Возврат Неопределено;
	КонецЕсли; 
	ИнициализацияСкриптаИнформатора();
	Если мОшибкаИнформаторУжеВыводилась = Истина Тогда
		Возврат Неопределено;
	КонецЕсли; 
	Попытка
		If Флаг = ФЛАГ_ЗАПОЛНЕНИЯ_ПРОВЕРИТЬ_СУЩЕСТВОВАНИЕ_СВОЙСТВ_И_МЕТОДОВ Then //0
			Рез 		= ПолучитьКоличество_Методов_Свойств(Объект, "Id_getNProps");
			Рез 		= Рез + ПолучитьКоличество_Методов_Свойств(Объект, "Id_getNMethods");
		ElsIf Флаг = ФЛАГ_ЗАПОЛНЕНИЯ_ПРОВЕРИТЬ_СУЩЕСТВОВАНИЕ_СВОЙСТВ Then //1
			Рез 		= ПолучитьКоличество_Методов_Свойств(Объект, "Id_getNProps");
		ElsIf Флаг = ФЛАГ_ЗАПОЛНЕНИЯ_ПРОВЕРИТЬ_СУЩЕСТВОВАНИЕ_МЕТОДОВ Then //2
			Рез 		= ПолучитьКоличество_Методов_Свойств(Объект, "Id_getNMethods");
		//ElsIf Флаг = ФЛАГ_ЗАПОЛНЕНИЯ_ПРОВЕРИТЬ_СУЩЕСТВОВАНИЕ_ЗНАЧЕНИЙ Then
		//	Рез = ТипДоступенДляЗначений(Объект);
		Else
			If Флаг = ФЛАГ_ЗАПОЛНЕНИЯ_ЗАПОЛНИТЬ_СВОЙСТВА Then //3
				ПолучитьТаблицу_Методов_Свойств(Объект, выхТаблицаОписания, "Id_getNProps", "Id_getPropName");
			ElsIf	Флаг = ФЛАГ_ЗАПОЛНЕНИЯ_ЗАПОЛНИТЬ_МЕТОДЫ Then
				ПолучитьТаблицу_Методов_Свойств(Объект, выхТаблицаОписания, "Id_getNMethods", "Id_getMethodName");
			Else
				j = 0;
				Для каждого текЗнач Из Объект Цикл
					новСтрока		= выхТаблицаОписания.Добавить();
					новСтрока.Name	= "Элемент[" + j + "]";
					новСтрока.Val 	= текЗнач; 
					j				= j + 1;
				КонецЦикла;
			EndIf; 
			//Если (Объект <> СТРОКА_ГЛОБАЛЬНЫЙ_КОНТЕКСТ) Тогда
				выхТаблицаОписания.Сортировать("Name");
			//EndIf;	
		EndIf; 
	Исключение
		Сообщить(ОписаниеОшибки());
		ОбработатьВыводОшибкиИнформатора();
	КонецПопытки; 
	Возврат Рез;
	
КонецФункции

//#Область ВспомогательныеФункции
	Функция _offset_jmp()	Возврат	12; КонецФункции	
	
	Функция _hex(_Чсл)
		pMem 	= Wrap.MemAlloc(_SIZE, 1);
		Wrap.NumPut(_Чсл, pMem);
		strHex 	= Wrap.MemRead(pMem, _SIZE, _SIZE);
		
		Рез 	= "";
		While Не ПустаяСтрока(strHex) Do
			Рез 	= Рез + Прав(strHex, 2);
			strHex 	= Лев(strHex, СтрДлина(strHex) - 2);
		EndDo;
		
		Возврат Рез;
	КонецФункции

	Процедура _prepareJMP(pIContext, id_func)
		offset_jmp 	= _offset_jmp();
		Addr 		= Wrap.NumGet(Wrap.NumGet(pIContext), _SIZE * (id_func - 1));
		Wrap.NumPut(Addr - (_BUF + offset_jmp + 1 + 4), 	_BUF, offset_jmp + 1);
	КонецПроцедуры
	
	Функция ПолучитьМассивГК82(addrfunc)
		asmCode 	= "
			|(000)	51					;push ecx	
			|(001)	56                  ;push esi
			|(002)	57                  ;push edi
			|(003)	8B 4B 04			;mov ecx, [ebx+4]
			|(006)	8B 03				;mov eax, [ebx]
			|(008)	39 C8				;cmp eax, ecx
			|(00A)	74 1A				;jz -->
			|(00C)	A3 D0 C0 B0 A0      ;mov [0A0B0C0D0h], eax
			|(011)	89 0D D0 C0 B0 A0	;mov [0A0B0C0D0h], ecx
			|(017)	89 C6				;mov esi, eax
			|(019)	29 C1				;sub ecx, eax
			|(01B)	C1 F9 02			;sar ecx, 2
			|(01E)	BF D0 C0 B0 A0		;mov edi, 0A0B0C0D0h
			|(023)	FC					;cld
			|(024)	F3 A5				;rep movsd
			|(026)	5F                  ;pop edi  l
			|(027)	5E                  ;pop esi
			|(028)	59                  ;pop ecx
			|(029)	8B 43 04            ;mov eax, [ebx+4]
			|(02C)  56          		;push    esi
			|(02D)  57					;push    edi
			|(02E)  E9 00 00 00 00		;jmp --> назад
			|";
		addrCode		= Wrap.RegisterCode(asmCode);	
		
		СигнатураПоиска = "8B430456578B3B3BC77415EB038D4900";
		НачАдрес 		= addrfunc;
		
		Wrap.NumPut(_pMEM, 		addrCode, 13);
		Wrap.NumPut(_pMEM + 4, 	addrCode, 19);
		Wrap.NumPut(_pMEM + 12, addrCode, 31);
		
		Для k = 1 To 10 Цикл
			АдресФункции  = 0;
			Для i = 0 По 1000 Цикл
				str = Wrap.MemRead(НачАдрес, 256, 256);
				j   = Найти(str, СигнатураПоиска);
				Если j > 0  Тогда
					АдресФункции = НачАдрес + (j - 1)/2;
					//Сообщить("Адрес функци для перехвата = " + _hex(АдресФункции));
					Прервать;
				КонецЕсли; 
				НачАдрес = НачАдрес + 256;
			КонецЦикла;
			
			АдресВозврата 	= АдресФункции + 5;
			Дельта 			= АдресВозврата - (addrCode + 51); 
			Wrap.NumPut(Дельта, addrCode, 47);
			
			Дельта1 = addrCode - (АдресФункции + 5);
			
			Wrap.VirtualProtect	(АдресФункции, 5, PAGE_EXECUTE_READWRITE, _pMEM + 8);
			Wrap.NumPut 		(233, 	АдресФункции, 0, "b");	
			Wrap.NumPut 		(Дельта1, 	АдресФункции, 1); 
			
			Выполнить("ИмяПользователя()");
			
			Wrap.MemWrite("8B 43 04 56 57", АдресФункции);
			Wrap.VirtualProtect (АдресФункции, 5, Wrap.NumGet(_pMEM + 8), _pMEM + 8);
			
			pBeg = Wrap.NumGet(_pMEM);
						
			If pBeg <> 0 Then
				Break;
			EndIf;	
			
			НачАдрес = АдресФункции + 10;
		КонецЦикла;	
		
		pBeg = Wrap.NumGet(_pMEM);
		pEnd = Wrap.NumGet(_pMEM, 4);
		
		КоличествоГК 	= (pEnd - pBeg) / 4 - 2;	
		
		//	Сохраняем кол-во ГК
		Wrap.NumPut (КоличествоГК, 	_pMEM, 0);	
	КонецФункции
	
	Функция ПолучитьМассивГК83(addrfunc)
		asmCode 	= "
			|(000)	89 0D 00 00 00 00	;mov [0xA0B0C0D0], ecx
			|(006)	89 15 00 00 00 00   ;mov [0xA0B0C0D0], edx
			|(00C)	57                  ;push edi
			|(00D)	56                  ;push esi
			|(00E)	51                  ;push ecx
			|(00F)	52                  ;push edx
			|(010)	FC                  ;cld
			|(011)	89 CE               ;mov esi, ecx
			|(013)	BF 00 00 00 00   	;mov edi, 0A0B0C0D0h
			|(018)	29 CA               ;sub edx, ecx
			|(01A)	C1 FA 02            ;sar edx, 2
			|(01D)	89 D1               ;mov ecx, edx
			|(01F)	F3 A5               ;rep movsd
			|(021)	5A                  ;pop edx
			|(022)	59                  ;pop eсx
			|(023)	5E                  ;pop esi
			|(024)	5F                  ;pop edi
			|
			|(025)  55          		;push ebp
			|(026)  8B EC				;mov  ebp, esp
			|(028)  53                  ;push ebx
			|(029)  56                  ;push esi
			|(02A)  8B 75 08			;mov esi, [ebp+arg_0]
			|(02D)  E9 00 00 00 00		;jmp --> назад
			|";
			
		addrCode	= Wrap.RegisterCode(asmCode);
		
		// Перехват
		СигнатураПоиска = "558BEC53568B7508578BFA8BD92BFBC1FF0285FF";
		АдресФункции  	= 0;
		Для i = 0 По 1000 Цикл
			str = Wrap.MemRead(addrfunc, 256, 256);
			j   = Найти(str, СигнатураПоиска);
			Если j > 0  Тогда
				АдресФункции = addrfunc + (j - 1)/2;
				//Сообщить("Адрес функци для перехвата = " + _hex(АдресФункции));
				Прервать;
			КонецЕсли; 
			addrfunc = addrfunc + 256;
		КонецЦикла;
		
		Wrap.NumPut(_pMEM, 		addrCode, 2);	// mov [0xA0B0C0D0], ecx
		Wrap.NumPut(_pMEM + 4, 	addrCode, 8);   // mov [0xA0B0C0D0], edx
		Wrap.NumPut(_pMEM + 12, 	addrCode, 20);  // mov edi, 0A0B0C0D0h
		
		АдресВозврата 	= АдресФункции + 8;
		Дельта 			= АдресВозврата - (addrCode + 50); 
		Wrap.NumPut(Дельта, addrCode, 46);
		
		Дельта1 = addrCode - (АдресФункции + 5);
		
		Wrap.VirtualProtect	(АдресФункции, 8, PAGE_EXECUTE_READWRITE, _pMEM + 8);
		st = Wrap.NumGet(_pMEM, 8);
		Wrap.NumPut 		(233, 	АдресФункции, 0, "b");	
		Wrap.NumPut 		(Дельта1, 	АдресФункции, 1); 
		
		Выполнить("ИмяПользователя()");
		
		Wrap.MemWrite("55 8B EC 53 56 8B 75 08", АдресФункции);
		Wrap.VirtualProtect (АдресФункции, 8, st, _pMEM + 8);
		
		pBeg 			= Wrap.NumGet(_pMEM);
		pEnd 			= Wrap.NumGet(_pMEM, 4);
		КоличествоГК 	= (pEnd - pBeg) / 4;	
		
		//	Сохраняем кол-во ГК
		Wrap.NumPut (КоличествоГК, 	_pMEM, 0);	
	КонецФункции
	
	Процедура ПолучитьМассивГК()
		_pMEM 			 		= Wrap.MemAlloc(4 * 100, 1);
		PAGE_EXECUTE_READWRITE	= 64;			//	&h40
		
		Wrap.Register("Kernel32",	"VirtualProtect" , "i=lllp", "r=l");
		
		pStruct 	= Wrap.Register("bsl:SCOM_Main", "SCOM_Main", "r=l");	
		addrfunc 	= Wrap.NumGet(pStruct, 4);
		
		СисИнфо 		 = Новый СистемнаяИнформация;	
		ВерсияПриложения = СисИнфо.ВерсияПриложения;
		Релиз			 = СтрЗаменить(Лев(ВерсияПриложения, 4), ".", "");
		Релиз			 = Число(Релиз);
		
		x = ?(Релиз = 82, ПолучитьМассивГК82(addrfunc), ПолучитьМассивГК83(addrfunc));
	КонецПроцедуры	
	
	Функция ПодготовитьDWX()
		If Wrap.bitness() = 32 Then   	//	x32-сервер
			//	Бинарная вставка
			
			asmCode		= "
				|;	Для получения из IDispatch, 
				|;	который приезжает в DWX, IContextExtImplBase
				|
				|8B 44 E4 04		;MOV EAX,DWORD PTR [ESP + 1 * 4]
				|8B 40 18			;MOV EAX,DWORD PTR [EAX + 6 * 4]
				|C2 04 00			;RET 4
				|90	                ;NOP
				|90					;NOP
				|;......................................
				|;	Для вызова функций интерфейса IContextExtImplBase
				|
				|E9 00 00 00 00		;JMP ...Addr
				|";
		Else	//	x64-сервер
			asmCode		= "
				|;	Для получения из IDispatch, 
				|;	который приезжает в DWX, IContextExtImplBase
				|
				|48 8B 44 24 08		;MOV RAX, [RSP + 1 * 8]
				|48 8B 40 30		;MOV RAX, [RAX + 6 * 8]
				|C2 08 00			;RET 8
				|;......................................
				|;	Для вызова функций интерфейса IContextExtImplBase
				|
				|E9 00 00 00 00		;JMP ...Addr
				|";
		EndIf;
		
		//	offset оператора jmp
		offset_jmp	= _offset_jmp();
		
		//	Регистрация функций в DWX
		_BUF		= Wrap.RegisterCode(asmCode, "getIContext", 		"i=p", 		"r=l");
		Wrap.RegisterAddr(_BUF + offset_jmp, "ImplBase_getName", 	"i=pll", 	"r=l");
		Wrap.RegisterAddr(_BUF + offset_jmp, "ImplBase_getN", 		"i=p", 		"r=l");
			
		Wrap.RegisterAddr(_BUF + offset_jmp, "ImplBase_getNParams", 	"i=pl", 	"r=l");
		Wrap.RegisterAddr(_BUF + offset_jmp, "ImplBase_hasRetVal", 	"i=pl", 	"r=b");
		Wrap.RegisterAddr(_BUF + offset_jmp, "ImplBase_find", 		"i=pp", 	"r=l");
		
		//	IID_IUnknown
		Wrap.RegisterAddr(_BUF + offset_jmp, "IUnknown_QueryInterface", "i=ppp",	"r=l");	//ID 1
		Wrap.RegisterAddr(_BUF + offset_jmp, "AddRef", "i=p",	"r=l");					//ID 2
		Wrap.RegisterAddr(_BUF + offset_jmp, "Release", "i=p",	"r=l");					//ID 3
		
		//	IID_ValueImplBase
		Wrap.RegisterAddr(_BUF + offset_jmp, "ValueImplBase_getIType", "i=p", "r=l");		//	ID 4
		Wrap.RegisterAddr(_BUF + offset_jmp, "ValueImplBase_getString", "i=pp", "r=l");		//	ID 8

		//	IID_ObjectTypeCore
		Wrap.RegisterAddr(_BUF + offset_jmp, "ObjectTypeCore_getTypeString", "i=pl", "r=l");	//	ID 6
		
		Wrap.Register("Ole32"   , "IIDFromString", "i=pp", "r=l");
		
		//ИмяФункции = ?(Wrap.bitness() = 32, "?create_string_value@core@@YAPAVIValue@1@PB_W@Z", "?create_string_value@core@@YAPEAVIValue@1@PEB_W@Z");
		//Wrap.Register("core83:791", "create_string_value", "i=p", "r=p");
		
		ПолучитьМассивГК();
		
		Возврат Wrap;
	КонецФункции
	
	Функция Деструктор() Экспорт 
		Wrap.MemFree(_pMEM);	
	КонецФункции
//#КонецОбласти

//#Область КоличествоПараметровМетода
	Функция _ПолучитьКоличествоПараметров(pIContext, НомерМетода) 
		_prepareJMP(pIContext, НомераМетодовИнтерфейса["Id_getNParams"]);
		Возврат Wrap.ImplBase_getNParams(pIContext, НомерМетода);
	КонецФункции

	Функция ПолучитьКоличествоПараметров(Объект, НомерМетода) 
		pIContext	= Wrap.getIContext(Объект);
		Возврат _ПолучитьКоличествоПараметров(pIContext, НомерМетода);
	КонецФункции
//#КонецОбласти

//#Область ЭтоФункция
	Функция _МетодФункция(pIContext, НомерМетода) Экспорт 
		_prepareJMP(pIContext, НомераМетодовИнтерфейса["Id_hasRetVal"]);
		Возврат Wrap.ImplBase_hasRetVal(pIContext, НомерМетода);
	КонецФункции

	Функция МетодФункция(Объект, НомерМетода) Экспорт 
		pIContext	= Wrap.getIContext(Объект);
		Возврат _МетодФункция(pIContext, НомерМетода);
	КонецФункции
//#КонецОбласти

//#Область ТаблицыСвойствМетодов	
	Функция _ПолучитьКоличество_Методов_Свойств(pIContext, ИмяФункцииКолво)
		//	Подготовим память для вызова функции получения количества методов/свойств
		_prepareJMP(pIContext, НомераМетодовИнтерфейса[ИмяФункцииКолво]);
		
		Возврат Wrap.ImplBase_getN(pIContext);
	КонецФункции

	Функция ПолучитьКоличество_Методов_Свойств(Объект, ИмяФункцииКолво)
		Рез = 0;
		
		If Объект = СТРОКА_ГЛОБАЛЬНЫЙ_КОНТЕКСТ Then
			num = Wrap.NumGet(_pMEM);	// Кол-во ГК
			For j = 0 To num - 2 Do
				pIContext	= Wrap.NumGet(_pMEM, 12 + j * _SIZE);
				Рез 		= Рез + _ПолучитьКоличество_Методов_Свойств(pIContext, ИмяФункцииКолво);
			EndDo;				
		Else	
			pIContext	= Wrap.getIContext(Объект);
			Рез 		= ?(pIContext = 0, 0,_ПолучитьКоличество_Методов_Свойств(pIContext, ИмяФункцииКолво));
		EndIf;	
		
		Возврат Рез;
	КонецФункции
	
	Функция _ПолучитьТаблицу_Методов_Свойств(pIContext, ТЗ, ИмяФункцииКолво, ИмяФункции, ContID)
		Перем LANG_RU;
		
		LANG_RU		= 1;  		//	0-ENG, 1-RU
		
		vtable		= Wrap.NumGet(pIContext);
		Колво		= _ПолучитьКоличество_Методов_Свойств(pIContext, ИмяФункцииКолво);
		
		//	Перебираем в цикле
		For id = 0 To Колво - 1 Do
			Name	= "";
			j		= LANG_RU;
			While j > -1 Do
				_prepareJMP(pIContext, НомераМетодовИнтерфейса[ИмяФункции]);
				pbstrName = Wrap.ImplBase_getName(pIContext, id, j);
				If pbstrName <> 0 Then 
					Name = Wrap.StrGet(pbstrName);
					If НЕ ПустаяСтрока(Name) Then	Прервать; EndIf;
				EndIf;
				j = j - 1;
			EndDo;
			
			нСтрока			= ТЗ.Добавить();
			нСтрока.Name	= Name;
			нСтрока.ContID	= ContID;	// Исправить для ГК
			нСтрока.ID		= id;
			
			If ИмяФункции = "Id_getMethodName" Then
				нСтрока.NParams = _ПолучитьКоличествоПараметров(pIContext, id);
				нСтрока.Val		= _МетодФункция(pIContext, id);
			EndIf;	
		EndDo;
		
		Возврат ТЗ;	
	КонецФункции	
	
	Функция ПолучитьТаблицу_Методов_Свойств(Объект, ТЗ, ИмяФункцииКолво, ИмяФункции)
		
		If Объект = СТРОКА_ГЛОБАЛЬНЫЙ_КОНТЕКСТ Then
			num = Wrap.NumGet(_pMEM);	// Кол-во ГК
			For j = 0 To num - 2 Do
				pIContext	= Wrap.NumGet(_pMEM, 12 + j * _SIZE);
				_ПолучитьТаблицу_Методов_Свойств(pIContext, ТЗ, ИмяФункцииКолво, ИмяФункции, j);
			EndDo;				
		Else	
			pIContext	= Wrap.getIContext(Объект);
			_ПолучитьТаблицу_Методов_Свойств(pIContext, ТЗ, ИмяФункцииКолво, ИмяФункции, -1);
		EndIf;	
		
	КонецФункции
//#КонецОбласти


Процедура ОбработатьВыводОшибкиИнформатора()
	
	мОшибкаИнформаторУжеВыводилась = Истина;
	Сообщить("Отключите опцию ""Низкоуровневое получение описаний объектов"" в общих настройках, либо выполните административную регистрацию COM компонент");

КонецПроцедуры

Процедура ИнициализацияСкриптаИнформатора() //Экспорт
	
	Wrap = ПолучитьWinAPI();
	Если Wrap = Неопределено Then
		Возврат;
	КонецЕсли;
	Если _SIZE = Неопределено Тогда
		_SIZE = ?(Wrap.bitness() = 32, 4, 8);
		ПодготовитьDWX();
		НомераМетодовИнтерфейса = Новый Соответствие;
		НомераМетодовИнтерфейса.Вставить("Id_getNProps", 4);
		НомераМетодовИнтерфейса.Вставить("Id_getPropName", 5);
		НомераМетодовИнтерфейса.Вставить("Id_findProp", 8);
		НомераМетодовИнтерфейса.Вставить("Id_getNMethods", 9);
		НомераМетодовИнтерфейса.Вставить("Id_getMethodName", 10);
		НомераМетодовИнтерфейса.Вставить("Id_getNParams", 11);
		НомераМетодовИнтерфейса.Вставить("Id_hasRetVal", 15);
		НомераМетодовИнтерфейса.Вставить("Id_findMethod", 16);
		НомераМетодовИнтерфейса.Вставить("Id_getPropVal", 18);
		НомераМетодовИнтерфейса.Вставить("Id_setPropVal", 19);
		НомераМетодовИнтерфейса.Вставить("Id_call", 20);
	КонецЕсли; 
	
КонецПроцедуры

// ТипСлов - Строка - "Свойство" или "Метод"
Функция ПолучитьТаблицуСвойствОбъектаИнформатором(Объект, ТипСлов = "Свойство", НеопределеноСчитатьГлобальнымКонтекстом = Истина) Экспорт
	
	Перем ТЗ;
	Если ЛиИнформаторДоступен() Тогда
		Возврат Новый ТаблицаЗначений;
	КонецЕсли; 
	Если Объект = Неопределено Тогда
		Объект = СТРОКА_ГЛОБАЛЬНЫЙ_КОНТЕКСТ;
	КонецЕсли;
	Флаг = ?(НРег(ТипСлов) = НРег("Свойство"),
		ФЛАГ_ЗАПОЛНЕНИЯ_ЗАПОЛНИТЬ_СВОЙСТВА,
		ФЛАГ_ЗАПОЛНЕНИЯ_ЗАПОЛНИТЬ_МЕТОДЫ);
	ПолучитьОписаниеОбъектаИнформатором(Объект, ТЗ, Флаг);
	Возврат ТЗ;
	
КонецФункции

Функция ЛиИнформаторДоступен()
	
	Возврат Ложь
		Или ВерсияПлатформы >= 803011
		Или Не ЛиНизкоуровневоеПолучениеОписанийОбъектов
		Или ирКэш.Это64битныйПроцессЛкс();

КонецФункции

#КонецЕсли

//ирПортативный Контейнер = Новый Структура();
//ирПортативный #Если Клиент Тогда
//ирПортативный Оповестить("ирПолучитьБазовуюФорму", Контейнер);
//ирПортативный #КонецЕсли
//ирПортативный Если Не Контейнер.Свойство("ирПортативный", ирПортативный) Тогда
//ирПортативный 	Файл = Новый Файл(ИспользуемоеИмяФайла);
//ирПортативный 	ПолноеИмяФайлаБазовогоМодуля = Лев(Файл.Путь, СтрДлина(Файл.Путь) - СтрДлина("Модули\")) + "ирПортативный.epf";
//ирПортативный 	ирПортативный = ВнешниеОбработки.Создать(ПолноеИмяФайлаБазовогоМодуля, Ложь); // Это будет второй экземпляр объекта
//ирПортативный КонецЕсли; 
//ирПортативный ирОбщий = ирПортативный.ПолучитьОбщийМодульЛкс("ирОбщий");
//ирПортативный ирКэш = ирПортативный.ПолучитьОбщийМодульЛкс("ирКэш");
//ирПортативный ирСервер = ирПортативный.ПолучитьОбщийМодульЛкс("ирСервер");
//ирПортативный ирПривилегированный = ирПортативный.ПолучитьОбщийМодульЛкс("ирПривилегированный");

///////////////////////////////////////////////////////////////////
// Информатор. Начало

ИМЯ_КЛАССА_DynamicWrapperX = "DynamicWrapperX";
СТРОКА_ГЛОБАЛЬНЫЙ_КОНТЕКСТ = "ГлобальныйКонтекст";
ФЛАГ_ЗАПОЛНЕНИЯ_ПРОВЕРИТЬ_СУЩЕСТВОВАНИЕ_СВОЙСТВ_И_МЕТОДОВ	= 0;
ФЛАГ_ЗАПОЛНЕНИЯ_ПРОВЕРИТЬ_СУЩЕСТВОВАНИЕ_СВОЙСТВ				= 1;
ФЛАГ_ЗАПОЛНЕНИЯ_ПРОВЕРИТЬ_СУЩЕСТВОВАНИЕ_МЕТОДОВ				= 2;
ФЛАГ_ЗАПОЛНЕНИЯ_ПРОВЕРИТЬ_СУЩЕСТВОВАНИЕ_ЗНАЧЕНИЙ			= 3;
ФЛАГ_ЗАПОЛНЕНИЯ_ЗАПОЛНИТЬ_СВОЙСТВА							= 4;
ФЛАГ_ЗАПОЛНЕНИЯ_ЗАПОЛНИТЬ_МЕТОДЫ							= 5;
ФЛАГ_ЗАПОЛНЕНИЯ_ЗАПОЛНИТЬ_ЗНАЧЕНИЯ							= 6;

// Информатор. Конец
///////////////////////////////////////////////////////////////////

ИнициализацияОписанияПараметровИТипов();
мМетаданные = Метаданные;
ОбъектыМДПоПолномуИмени = Новый Соответствие;
КэшОбъектов = Новый Соответствие;
мКэшПустыхЗначений = Новый Соответствие;
СисИнфо = Новый СистемнаяИнформация;
Фрагменты = ирОбщий.ПолучитьМассивИзСтрокиСРазделителемЛкс(СисИнфо.ВерсияПриложения);
ВерсияПлатформы = Число(Фрагменты[0]) * 100 * 1000 + Число(Фрагменты[1]) * 1000 + Число(Фрагменты[2]);
Это2iS = Метаданные.ОбщиеМодули.Найти("Ядро2iS") <> Неопределено;
ЭтоИнтеграция = Метаданные.Справочники.Найти("иисМетаданные") <> Неопределено;
МаркерНачалаАлгоритма = "//НАЧАЛО.СЕРВИС" + Символы.ПС;
МаркерКонцаАлгоритма  = "//КОНЕЦ_.СЕРВИС" + Символы.ПС;
мМаркерИмениЗапросаПакета = "{Запрос: ";
мМаркерИмениЧастиОбъединения = "{Выборка: ";

шБуква = "_ЁА-ЯA-Z";
шКомментарий = "//[^\n]*\n"; 
шРазделитель = "(?:" + шКомментарий + "|\s|^|$)";
шGUID = "[A-F0-9]{8}(?:-[A-F0-9]{4}){3}-[A-F0-9]{12}";
шЧисло = "\d+(\.\d+)?";
шИндекс = "(\[[^\]\[]+?(?:(?:\[[^\]]+?\][^\]\[]*?)*)*\])";
//шСкобки = "(\([^\)\(]*?(?:(?:\([^\)]*?\)[^\)\(]*?)*)*\))";
  шСкобки = "(\([^\(\)]*(?:\([^\(\)]*\)[^\(\)]*)*\))";
шИмя = "[" + шБуква + "][" + шБуква + "\d]*";
шИмяВременнойТаблицы = шИмя + "(?:\." + шИмя + ")*";

VBRegExp = ПолучитьНовыйВычислительРегулярныхВыражений(Истина);
ВложенностьИндикации = 0;
ИмяКластераСерверов = НСтр(СтрокаСоединенияИнформационнойБазы(), "Srvr");
ЭтоФайловаяБаза = ПустаяСтрока(ИмяКластераСерверов);

WshShell = Новый COMОбъект("WScript.Shell");
//JavaScript = Новый COMОбъект("MSScriptControl.ScriptControl");
//JavaScript.Language = "javascript";
//ВремяОбъект = JavaScript.Eval("new Date()");
Если Метаданные.ВариантВстроенногоЯзыка <> Метаданные.СвойстваОбъектов.ВариантВстроенногоЯзыка.Русский Тогда
	Сообщить("Работа инструментов с вариантом встроенного языка, отличающегося от Русский, не поддерживается.");
КонецЕсли; 
ФиксироватьВнешниеИсключенияАлгоритмов = ирОбщий.ВосстановитьЗначениеЛкс("ФиксироватьВнешниеИсключенияАлгоритмов");
Если ФиксироватьВнешниеИсключенияАлгоритмов = Неопределено Тогда
	ФиксироватьВнешниеИсключенияАлгоритмов = Истина;
КонецЕсли;
ФайловыйКэшАлгоритмовДопускаетРедактирование = ирОбщий.ВосстановитьЗначениеЛкс("ФайловыйКэшАлгоритмовДопускаетРедактирование");
Если ФайловыйКэшАлгоритмовДопускаетРедактирование = Неопределено Тогда
	ФайловыйКэшАлгоритмовДопускаетРедактирование = Ложь;
КонецЕсли;
ВыполнятьАлгоритмыЧерезВнешниеОбработки = ирОбщий.ВосстановитьЗначениеЛкс("ВыполнятьАлгоритмыЧерезВнешниеОбработки");
Если ВыполнятьАлгоритмыЧерезВнешниеОбработки = Неопределено Тогда
	// Антибаг http://partners.v8.1c.ru/forum/thread.jsp?id=861032#861032
	ВыполнятьАлгоритмыЧерезВнешниеОбработки = Ложь;
КонецЕсли;
ЛиНизкоуровневоеПолучениеОписанийОбъектов = ирОбщий.ВосстановитьЗначениеЛкс("ЛиНизкоуровневоеПолучениеОписанийОбъектов");
Если ЛиНизкоуровневоеПолучениеОписанийОбъектов = Неопределено Тогда
	ЛиНизкоуровневоеПолучениеОписанийОбъектов = Истина;
КонецЕсли;
АвторегистрацияComКомпонент = ирОбщий.ВосстановитьЗначениеЛкс("АвторегистрацияComКомпонент");
Если АвторегистрацияComКомпонент = Неопределено Тогда
	АвторегистрацияComКомпонент = Истина;
КонецЕсли;
НеИспользоватьИмитаторыОбъектовДанных = ирОбщий.ВосстановитьЗначениеЛкс("НеИспользоватьИмитаторыОбъектовДанных");
Если НеИспользоватьИмитаторыОбъектовДанных = Неопределено Тогда
	НеИспользоватьИмитаторыОбъектовДанных = Ложь;
КонецЕсли;

Парсеры = Новый Структура;
ШаблоныВнешнейОбработки = Новый Соответствие;
ШаблоныВнешнейОбработкиСМакетом = Новый Соответствие;
ПроверитьСтруктуруФайловогоКэша();
ИмяФайлаПакера = "v8unpack.exe";
WinAPI = "НеИнициализирован";
//ПолучитьWinAPI();
МассивОбычныхЭлементовУправления = Новый Массив;

#Если Клиент Тогда
COMНавигатор = "НеИнициализирован";

ПоказыватьВнешниеИсключенияПриВыполненииАлгоритмов = ирОбщий.ВосстановитьЗначениеЛкс("ирПлатформа.ПоказыватьВнешниеИсключенияПриВыполненииАлгоритмов");
Если ПоказыватьВнешниеИсключенияПриВыполненииАлгоритмов = Неопределено Тогда
	ПоказыватьВнешниеИсключенияПриВыполненииАлгоритмов = Ложь;
КонецЕсли;
СинтаксическийКонтрольПередЗаписью = ирОбщий.ВосстановитьЗначениеЛкс("ирПлатформа.СинтаксическийКонтрольПередЗаписью");
Если СинтаксическийКонтрольПередЗаписью = Неопределено Тогда
	СинтаксическийКонтрольПередЗаписью = Истина;
КонецЕсли;
ТаблицаСтатистикиВыбора = ирОбщий.ВосстановитьЗначениеЛкс("ирПлатформа.ТаблицаСтатистикиВыбора");
Если ТаблицаСтатистикиВыбора = Неопределено Тогда
	ТаблицаСтатистикиВыбора = Новый ТаблицаЗначений;
	ТаблицаСтатистикиВыбора.Колонки.Добавить("ТипКонтекста");
	ТаблицаСтатистикиВыбора.Колонки.Добавить("Слово");
	ТаблицаСтатистикиВыбора.Колонки.Добавить("Рейтинг", Новый ОписаниеТипов("Число"));
КонецЕсли;
ОтложенноеОткрытиеИсточникаОшибки = Новый ТаблицаЗначений;
ОтложенноеОткрытиеИсточникаОшибки.Колонки.Добавить("АлгоритмОбъект");
ОтложенноеОткрытиеИсточникаОшибки.Колонки.Добавить("ИнформацияОбОшибке");
ОтложенноеОткрытиеИсточникаОшибки.Колонки.Добавить("РежимВыполненияАлгоритма");
ОтложенноеОткрытиеИсточникаОшибки.Колонки.Добавить("Смещение", Новый ОписаниеТипов("Число"));
СлужебнаяФорма = ПолучитьФорму("Служебная");
Если СлужебнаяФорма <> Неопределено Тогда // Для портативного режима управляемого приложения
	СлужебноеПолеТекстовогоДокумента = СлужебнаяФорма.ЭлементыФормы.Добавить(Тип("ПолеТекстовогоДокумента"), "СлужебноеПолеТекстовогоДокумента", Ложь);
	СлужебноеПолеHtmlДокумента = СлужебнаяФорма.ЭлементыФормы.Добавить(Тип("ПолеHTMLДокумента"), "СлужебноеПолеHTMLДокумента", Ложь);
КонецЕсли; 

МассивОбычныхЭлементовУправления.Добавить("Диаграмма"); 
МассивОбычныхЭлементовУправления.Добавить("ДиаграммаГанта"); 
МассивОбычныхЭлементовУправления.Добавить("Дендрограмма"); 
МассивОбычныхЭлементовУправления.Добавить("Индикатор"); 
МассивОбычныхЭлементовУправления.Добавить("ПолеКалендаря"); 
МассивОбычныхЭлементовУправления.Добавить("Кнопка"); 
МассивОбычныхЭлементовУправления.Добавить("КолонкаТабличногоПоля"); // Возможно что то сломается. Добавил для возможности автоопределения объекта системы
МассивОбычныхЭлементовУправления.Добавить("КоманднаяПанель"); 
МассивОбычныхЭлементовУправления.Добавить("Надпись"); 
МассивОбычныхЭлементовУправления.Добавить("Панель"); 
МассивОбычныхЭлементовУправления.Добавить("Переключатель"); 
МассивОбычныхЭлементовУправления.Добавить("ПолеГрафическойСхемы"); 
МассивОбычныхЭлементовУправления.Добавить("ПолеГеографическойСхемы");
МассивОбычныхЭлементовУправления.Добавить("ПолеТабличногоДокумента"); 
МассивОбычныхЭлементовУправления.Добавить("ПолеHTMLДокумента"); 
МассивОбычныхЭлементовУправления.Добавить("ПолеТекстовогоДокумента"); 
МассивОбычныхЭлементовУправления.Добавить("ПолеВвода"); 
МассивОбычныхЭлементовУправления.Добавить("ПолеВыбора"); 
МассивОбычныхЭлементовУправления.Добавить("ПолеСписка"); 
МассивОбычныхЭлементовУправления.Добавить("ПолеКартинки"); 
МассивОбычныхЭлементовУправления.Добавить("ПолосаРегулирования"); 
МассивОбычныхЭлементовУправления.Добавить("Разделитель"); 
МассивОбычныхЭлементовУправления.Добавить("РамкаГруппы"); 
МассивОбычныхЭлементовУправления.Добавить("СводнаяДиаграмма"); 
МассивОбычныхЭлементовУправления.Добавить("СтраницаПанели");  // Возможно что то сломается. Добавил для возможности автоопределения объекта системы
МассивОбычныхЭлементовУправления.Добавить("ТабличноеПоле"); 
МассивОбычныхЭлементовУправления.Добавить("Флажок"); 

мМассивТиповЭлементовУправления = Новый Массив;
Для Каждого ИмяТипа Из МассивОбычныхЭлементовУправления Цикл
	мМассивТиповЭлементовУправления.Добавить(Тип(ИмяТипа));
КонецЦикла;
СодержанияАрхивовСправки = Новый Соответствие;
ИндексыАрхивовСправки = Новый Соответствие;

#КонецЕсли

МассивУправляемыхЭлементовУправления = Новый Массив;
МассивУправляемыхЭлементовУправления.Добавить("ПолеФормы"); 
МассивУправляемыхЭлементовУправления.Добавить("КнопкаФормы"); 
МассивУправляемыхЭлементовУправления.Добавить("ТаблицаФормы"); 
МассивУправляемыхЭлементовУправления.Добавить("ГруппаФормы"); 
МассивУправляемыхЭлементовУправления.Добавить("ДекорацияФормы"); 

мМассивТиповВключающихМетаданные = Новый Массив;
мМассивТиповВключающихМетаданные.Добавить(Тип("ОбъектМетаданных"));
мМассивТиповВключающихМетаданные.Добавить(Тип("Структура"));
мМассивТиповВключающихМетаданные.Добавить(Тип("ТаблицаЗначений"));
мМассивТиповВключающихМетаданные.Добавить(Тип("ДеревоЗначений"));
мМассивТиповВключающихМетаданные.Добавить(Тип("РезультатЗапроса"));
мМассивТиповВключающихМетаданные.Добавить(Тип("Отбор"));
мМассивТиповВключающихМетаданные.Добавить(Тип("НастройкаОформления"));
мМассивТиповВключающихМетаданные.Добавить(Тип("COMОбъект"));
мМассивТиповВключающихМетаданные.Добавить(Тип("ОбъектXDTO"));
мМассивТиповВключающихМетаданные.Добавить(Тип("СвойствоXDTO"));
мМассивТиповВключающихМетаданные.Добавить(Тип("ОбщийМодуль"));
мМассивТиповВключающихМетаданные.Добавить(Тип("ПостроительЗапроса"));
#Если Клиент Тогда
мМассивТиповВключающихМетаданные.Добавить(Тип("ТабличноеПоле"));
мМассивТиповВключающихМетаданные.Добавить(Тип("Панель"));
мМассивТиповВключающихМетаданные.Добавить(Тип("КнопкаКоманднойПанели"));
мМассивТиповВключающихМетаданные.Добавить(Тип("КоманднаяПанель"));
мМассивТиповВключающихМетаданные.Добавить(Тип("Форма"));
мМассивТиповВключающихМетаданные.Добавить(Тип("УправляемаяФорма"));
мМассивТиповВключающихМетаданные.Добавить(Тип("ПолеВвода"));
#КонецЕсли

мТаблицаСтруктурТипа = Новый ТаблицаЗначений;
мТаблицаСтруктурТипа.Колонки.Добавить("ИмяОбщегоТипа", Новый ОписаниеТипов("Строка"));
мТаблицаСтруктурТипа.Колонки.Добавить("Метаданные");
мТаблицаСтруктурТипа.Колонки.Добавить("СтрокаОписания");
мТаблицаСтруктурТипа.Колонки.Добавить("ТипЯзыка", Новый ОписаниеТипов("Строка"));
мТаблицаСтруктурТипа.Колонки.Добавить("ВиртуальнаяТаблица");
мТаблицаСтруктурТипа.Колонки.Добавить("Конструктор", Новый  ОписаниеТипов("Булево"));
мТаблицаСтруктурТипа.Колонки.Добавить("ДополнительныеТипы");
мТаблицаСтруктурТипа.Колонки.Добавить("ДержательМетаданных");

//#Если Клиент Или ВнешнееСоединение Тогда

СубПутьКФайлуПотокаМодуляВнешнейОбработки    = "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";

//КешВнешнихОбработокАлгоритмов = Новый Структура;

КешАлгоритмов = Новый Структура;

ТаблицаТиповМетаОбъектов = ПолучитьТаблицуТиповМетаОбъектов();
ТаблицаТиповМетаОбъектов.Индексы.Добавить("Единственное,  Категория");
ТаблицаТиповМетаОбъектов.Индексы.Добавить("Множественное, Категория");

МакетыКомпонент = Новый Структура;

МаркерКоллекцииОбъектовМетаданных = "КоллекцияОбъектовМетаданных";
МаркерОбъектаМетаданных = "ОбъектМетаданных";
МаркерCOMОбъекта = "COMОбъект";

МассивИсключенийИменКоллекций = Новый СписокЗначений;
МассивИсключенийИменКоллекций.Добавить("Свойства");
МассивИсключенийИменКоллекций.Добавить("Методы");
МассивИсключенийИменКоллекций.Добавить("");

СоответствиеВидовСравнения = Новый ТаблицаЗначений;
СоответствиеВидовСравнения.Колонки.Добавить("Построитель");
СоответствиеВидовСравнения.Колонки.Добавить("Компоновка");
СоответствиеВидовСравнения.Колонки.Добавить("Имя");
СоответствиеВидовСравнения.Индексы.Добавить("Построитель");
СоответствиеВидовСравнения.Индексы.Добавить("Компоновка");
//Интервал
//ИнтервалВключаяГраницы
//ИнтервалВключаяНачало
//ИнтервалВключаяОкончание
СоответствиеВидовСравнения.Добавить().Имя = "Больше";
СоответствиеВидовСравнения.Добавить().Имя = "БольшеИлиРавно";
СоответствиеВидовСравнения.Добавить().Имя = "ВИерархии";
СоответствиеВидовСравнения.Добавить().Имя = "ВСписке";
СоответствиеВидовСравнения.Добавить().Имя = "ВСпискеПоИерархии";
СоответствиеВидовСравнения.Добавить().Имя = "Меньше";
СоответствиеВидовСравнения.Добавить().Имя = "МеньшеИлиРавно";
СоответствиеВидовСравнения.Добавить().Имя = "НеВИерархии";
СоответствиеВидовСравнения.Добавить().Имя = "НеВСписке";
СоответствиеВидовСравнения.Добавить().Имя = "НеВСпискеПоИерархии";
СоответствиеВидовСравнения.Добавить().Имя = "НеРавно";
СоответствиеВидовСравнения.Добавить().Имя = "НеСодержит";
СоответствиеВидовСравнения.Добавить().Имя = "Равно";
СоответствиеВидовСравнения.Добавить().Имя = "Содержит";
Для Каждого СтрокаСоответствия Из СоответствиеВидовСравнения Цикл
	СтрокаСоответствия.Построитель = Вычислить("ВидСравнения." + СтрокаСоответствия.Имя);
	СтрокаСоответствия.Компоновка  = Вычислить("ВидСравненияКомпоновкиДанных." + СтрокаСоответствия.Имя);
КонецЦикла;

мТаблицаЗамеров = Новый ТаблицаЗначений;
мТаблицаЗамеров.Колонки.Добавить("_0");
мТаблицаЗамеров.Колонки.Добавить("Ключ");
мТаблицаЗамеров.Колонки.Добавить("ДатаНачала");
мТаблицаЗамеров.Колонки.Добавить("Отладчик", Новый ОписаниеТипов("Булево"));
мТаблицаЗамеров.Колонки.Добавить("КоличествоПроходов", Новый ОписаниеТипов("Число"));

мТаблицаИндикаторов = Новый ТаблицаЗначений;
мТаблицаИндикаторов.Колонки.Добавить("КоличествоПроходов", Новый ОписаниеТипов("Число"));
мТаблицаИндикаторов.Колонки.Добавить("ПредставлениеПроцесса", Новый ОписаниеТипов("Строка"));
мТаблицаИндикаторов.Колонки.Добавить("ЛиВыводитьВремя", Новый ОписаниеТипов("Булево"));
мТаблицаИндикаторов.Колонки.Добавить("РазрешитьПрерывание", Новый ОписаниеТипов("Булево"));
мТаблицаИндикаторов.Колонки.Добавить("ДатаНачалаПроцесса", Новый ОписаниеТипов("Дата"));
мТаблицаИндикаторов.Колонки.Добавить("МинимальныйПериодОбновления", Новый ОписаниеТипов("Число"));
мТаблицаИндикаторов.Колонки.Добавить("ДатаСледующегоОбновления", Новый ОписаниеТипов("Дата"));
мТаблицаИндикаторов.Колонки.Добавить("Шаг", Новый ОписаниеТипов("Число"));
мТаблицаИндикаторов.Колонки.Добавить("ТекстСостояния", Новый ОписаниеТипов("Строка"));
мТаблицаИндикаторов.Колонки.Добавить("СледующийСчетчик", Новый ОписаниеТипов("Число"));
мТаблицаИндикаторов.Колонки.Добавить("Счетчик", Новый ОписаниеТипов("Число"));

//#КонецЕсли
RegExp = ПолучитьНовыйВычислительРегулярныхВыражений();
RegExp.IgnoreCase = Истина;
RegExp.MultiLine = Ложь;

RegExp2 = ПолучитьНовыйВычислительРегулярныхВыражений();
RegExp2.IgnoreCase = Истина;
RegExp2.MultiLine = Ложь;

мИменаОсновныхКлассовБиблиотекCOM = Новый Соответствие;
мОбразцыCOMОбъектов = Новый Соответствие;
БуферыСравнения = Новый Соответствие;
