Загрузка данных


// TODO: битые ссылки в правилах конвертации реквизитов, проверка
// TODO: !!!!! перенос значения соствного типа в табличной части /// реквизиты таблиц / значение заполнения
// TODO: перенос длинных строк произвольный запрос в тексте
// TODO: если запрос и правила выгрузки и не стоит &_ОтборПервичныйОсновнаяТаблица_ то типа вообще без отбора работает
// TODO: Алгоритм Таблица решений
// TODO: Алгоритм при регистрации объекта добавить

//Перем мТзКэшЗапросовВыгрузокТаблиц;
Перем мНуженТипЗначенияВСтруктуре; // для того чтобы не тащить через множество процедур при получении структуры в функции СтруктураКонфигурацииПолучитьСтруктуруТаблицы1с
Перем мСоответствиеИмяТаблицыМенеджер;
 
Функция Версия() Экспорт
	Возврат "1.0";
КонецФункции

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

Функция мПараметрыОтбораУстановить(пПараметры)
	Если пПараметры=Неопределено Тогда пПараметры=Новый Структура; КонецЕсли; 
	мСтруктураУстановитьСвойство(пПараметры, "ВидСравнения");
	мСтруктураУстановитьСвойство(пПараметры, "ПроверятьНаЗаполненность", Истина);
	мСтруктураУстановитьСвойство(пПараметры, "Использование", Истина);
	мСтруктураУстановитьСвойство(пПараметры, "Представление");
	мСтруктураУстановитьСвойство(пПараметры, "РежимОтображения");
	мСтруктураУстановитьСвойство(пПараметры, "ИдентификаторПользовательскойНастройки");
КонецФункции

Функция мПолучитьСтандартныйОтбор(пСписок)
	//Если ТсПлатформаОбщий.СуществуетСвойство(пСписок, "КомпоновщикНастроек.Настройки") Тогда Возврат пСписок.КомпоновщикНастроек.Настройки.Отбор; КонецЕсли;
	Возврат ?(ТсПлатформаОбщий.СуществуетСвойство(пСписок, "Отбор"), пСписок.Отбор, пСписок);
КонецФункции

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

	Если Не мТипСправочники.СодержитТип(лТип) и Не мТипПланыВидовХарактеристик.СодержитТип(лТип) Тогда
		Возврат ВидСравненияКомпоновкиДанных.Равно;
	КонецЕсли;
	Возврат ?(ТсПлатформаОбщий.ПолучитьСвойствоНаСервере(пЗначение, "ЭтоГруппа", Ложь), ВидСравненияКомпоновкиДанных.ВИерархии, ВидСравненияКомпоновкиДанных.Равно);
КонецФункции

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

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

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

Функция мАлгоритмПолучитьПараметры(пАлгоритм)
	лСтруктураПараметры=Новый Структура;
	Для Каждого лСтрокаПараметры Из пАлгоритм.Параметры Цикл
		лСтруктураПараметры.Вставить(лСтрокаПараметры.Параметр.Имя, лСтрокаПараметры.Значение);
	КонецЦикла;
	Возврат лСтруктураПараметры;
КонецФункции

Функция мПолучитьЗначениеПараметраВыполнения(пПараметр, пЗначение, пРаботаВРежимеАгента)
	Если пРаботаВРежимеАгента Тогда Возврат пЗначение; КонецЕсли; 
	Если Не пПараметр.СписокЗначений Тогда 
		Если ТипЗнч(пЗначение)=Тип("СправочникСсылка.ТсПлатформаЗначенияПараметров") Тогда Возврат пЗначение.Наименование; КонецЕсли;
		Если ТипЗнч(пЗначение)=Тип("СправочникСсылка.ТсАлгоритмы") Тогда
			Возврат Новый Структура("Имя, ТекстКода, Параметры", пЗначение.Имя, пЗначение.ТекстКода, мАлгоритмПолучитьПараметры(пЗначение));
		КонецЕсли;
		Возврат пЗначение;
	КонецЕсли;
		
	лМассивЗначений=пЗначение.Значения.Выгрузить().ВыгрузитьКолонку("Значение");
	Если пПараметр.ТипЗначения.СодержитТип(Тип("СправочникСсылка.ТсПлатформаЗначенияПараметров")) Тогда
		Для лИнд=1 По лМассивЗначений.Количество() Цикл
			Если ТипЗнч(лМассивЗначений[лИнд-1])<>Тип("СправочникСсылка.ТсПлатформаЗначенияПараметров") Тогда Продолжить; КонецЕсли;
			лМассивЗначений[лИнд-1]=лМассивЗначений[лИнд-1].Наименование;
		КонецЦикла;
	КонецЕсли;
	Возврат лМассивЗначений; 
КонецФункции

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

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

// TODO: Доделать обработку кавычек и комментариев
Функция ТекстЗапросаПолучитьПараметры1с(пТекстЗапроса) Экспорт
	лМассивПараметры=Новый Массив;
	лПозицияВПараметре=Ложь; лИмяПараметра="";
	Для лИнд=1 По СтрДлина(пТекстЗапроса) Цикл
		лСимвол=Сред(пТекстЗапроса, лИнд, 1);
		Если лСимвол="&" Тогда
			Если лПозицияВПараметре Тогда 
				Если ЗначениеЗаполнено(лИмяПараметра) Тогда 
					Если лМассивПараметры.Найти(лИмяПараметра)=Неопределено Тогда лМассивПараметры.Добавить(лИмяПараметра); КонецЕсли;
					лИмяПараметра="";
				Иначе
					лПозицияВПараметре=Ложь;
				КонецЕсли;
			Иначе
				лПозицияВПараметре=Истина; 
			КонецЕсли;
			Продолжить;
		КонецЕсли;
		Если Не лПозицияВПараметре Тогда Продолжить; КонецЕсли;
		Если СтрНайти("ABCDEFGHIJKLMNOPQRSTUVWXYZАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЫЬЪЭЮЯ0123456789_", ВРег(лСимвол)) Тогда 
			лИмяПараметра=лИмяПараметра+лСимвол;
			Продолжить;
		КонецЕсли;
		Если ЗначениеЗаполнено(лИмяПараметра) Тогда 
			Если лМассивПараметры.Найти(лИмяПараметра)=Неопределено Тогда лМассивПараметры.Добавить(лИмяПараметра); КонецЕсли;
			лИмяПараметра="";
			лПозицияВПараметре=Ложь;
		КонецЕсли;
	КонецЦикла;
	Если ЗначениеЗаполнено(лИмяПараметра) Тогда 
		Если лМассивПараметры.Найти(лИмяПараметра)=Неопределено Тогда лМассивПараметры.Добавить(лИмяПараметра); КонецЕсли;
	КонецЕсли;
	Возврат лМассивПараметры;
КонецФункции

#Область Http
// Разбирает строку URI на составные части и возвращает в виде структуры.
// На основе RFC 3986.
//
// Параметры:
//		пСтрокаURI - Строка - ссылка на ресурс в формате:
//		<схема>://<логин>:<пароль>@<хост>:<порт>/<путь>?<параметры>#<якорь>.
//
// Возвращаемое значение:
//		Структура - составные части URI согласно формату:
//			* Схема - Строка.
//			* Логин - Строка.
//			* Пароль - Строка.
//			* ИмяСервера - Строка - часть <хост>:<порт> входного параметра.
//			* Хост - Строка.
//			* Порт - Строка.
//			* ПутьНаСервере - Строка - часть <путь>?<параметры>#<якорь> входного параметра.
//
Функция СтруктураURI(Знач пСтрокаURI) Экспорт
	пСтрокаURI=СокрЛП(пСтрокаURI);
	
	// схема
	лСхема="";
	лПозиция=Найти(пСтрокаURI, "://");
	Если лПозиция>0 Тогда
		лСхема=НРег(Лев(пСтрокаURI, лПозиция-1));
		пСтрокаURI=Сред(пСтрокаURI, лПозиция+3);
	КонецЕсли;
	
	// строка соединения и путь на сервере
	лСтрокаСоединения=пСтрокаURI;
	лПутьНаСервере="";
	лПозиция=Найти(лСтрокаСоединения, "/");
	Если лПозиция>0 Тогда
		лПутьНаСервере=Сред(лСтрокаСоединения, лПозиция+1);
		лСтрокаСоединения=Лев(лСтрокаСоединения, лПозиция-1);
	КонецЕсли;
	
	// информация пользователя и имя сервера
	лСтрокаАвторизации="";
	лИмяСервера=лСтрокаСоединения;
	лПозиция=Найти(лСтрокаСоединения, "@");
	Если лПозиция>0 Тогда
		лСтрокаАвторизации=Лев(лСтрокаСоединения, лПозиция-1);
		лИмяСервера=Сред(лСтрокаСоединения, лПозиция+1);
	КонецЕсли;
	
	// логин и пароль
	лЛогин=лСтрокаАвторизации;
	лПароль="";
	лПозиция=Найти(лСтрокаАвторизации, ":");
	Если лПозиция>0 Тогда
		лЛогин=Лев(лСтрокаАвторизации, лПозиция-1);
		лПароль=Сред(лСтрокаАвторизации, лПозиция+1);
	КонецЕсли;
	
	// хост и порт
	лХост=лИмяСервера;
	лПорт="";
	лПозиция=Найти(лИмяСервера, ":");
	Если лПозиция>0 Тогда
		лХост=Лев(лИмяСервера, лПозиция-1);
		лПорт=Сред(лИмяСервера, лПозиция+1);
	КонецЕсли;
	
	лСтруктураРезультат=Новый Структура;
	лСтруктураРезультат.Вставить("Схема", лСхема);
	лСтруктураРезультат.Вставить("Логин", лЛогин);
	лСтруктураРезультат.Вставить("Пароль", лПароль);
	лСтруктураРезультат.Вставить("ИмяСервера", лИмяСервера);
	лСтруктураРезультат.Вставить("Хост", лХост);
	лСтруктураРезультат.Вставить("Порт", ?(лПорт<>"", Число(лПорт), Неопределено));
	лСтруктураРезультат.Вставить("ПутьНаСервере", лПутьНаСервере);
	Возврат лСтруктураРезультат;
КонецФункции

Функция ЗапросGET(пИмяСервера, пПорт, пПуть, пЛогин="", пПароль="", пИспользоватьЗащищеннуюАвторизацию=Ложь, пСтруктураПараметры=Неопределено, пТекстОшибки=Неопределено) Экспорт
	Попытка	лПорт=Число(пПорт); Исключение лПорт=Неопределено; КонецПопытки;
	Если ТипЗнч(пСтруктураПараметры)<>Тип("Структура") Тогда пСтруктураПараметры=Новый Структура; КонецЕсли;
	
	лИнтернетПрокси=Неопределено;
	Если пСтруктураПараметры.Свойство("Прокси") и пСтруктураПараметры.Прокси<>Неопределено Тогда
		лИнтернетПрокси=Новый ИнтернетПрокси;
		лИнтернетПрокси.Установить("https", пСтруктураПараметры.Прокси.Сервер, пСтруктураПараметры.Прокси.Порт, пСтруктураПараметры.Прокси.Пользователь, пСтруктураПараметры.Прокси.Пароль, Ложь);
	КонецЕсли;
	лЗащищенноеСоединение=Неопределено;
	Если пИспользоватьЗащищеннуюАвторизацию Тогда лЗащищенноеСоединение=Новый ЗащищенноеСоединениеOpenSSL; КонецЕсли;
	
	лТаймаут=ТсПлатформаОбщий.ПолучитьСвойство(пСтруктураПараметры, "Таймаут", 5);
	лHTTPСоединение=Новый HTTPСоединение(пИмяСервера, лПорт, пЛогин, пПароль, лИнтернетПрокси, лТаймаут, лЗащищенноеСоединение, Ложь);
	лЗапросHTTP=Новый HTTPЗапрос(пПуть);
	
	Если ТсПлатформаОбщий.ПолучитьСвойство(пСтруктураПараметры, "Заголовки")=Неопределено Тогда
		лЗапросHTTP.Заголовки.Вставить("Content-Type", "application/json");
		лЗапросHTTP.Заголовки.Вставить("Accept-Language", "ru");
		лЗапросHTTP.Заголовки.Вставить("Accept-Charset", "utf-8");
		лЗапросHTTP.Заголовки.Вставить("Content-Language", "ru");
		лЗапросHTTP.Заголовки.Вставить("Content-Charset", "utf-8");
	Иначе
		Для Каждого лКлючИЗначение Из пСтруктураПараметры.Заголовки Цикл
			лЗапросHTTP.Заголовки.Вставить(лКлючИЗначение.Ключ, лКлючИЗначение.Значение);
		КонецЦикла;
	КонецЕсли;
	
	лТипПолучения="Строка"; лЛогироватьВызовы=Ложь; лРучной=Ложь;
	Если пСтруктураПараметры<>Неопределено Тогда 
		Если пСтруктураПараметры.Свойство("ТипПолучения") Тогда лТипПолучения=пСтруктураПараметры.ТипПолучения; КонецЕсли; 
		Если пСтруктураПараметры.Свойство("Логировать") Тогда лЛогироватьВызовы=пСтруктураПараметры.Логировать; КонецЕсли; 
		Если пСтруктураПараметры.Свойство("Ручной") Тогда лРучной=пСтруктураПараметры.Ручной; КонецЕсли;
	КонецЕсли;
	
	Если лЛогироватьВызовы Тогда лСтруктураЛогирование=ТсПлатформаОбщий.HttpИсходящийВызовЛогироватьНачало(лHTTPСоединение, "GET", лЗапросHTTP, Новый Структура("Ручной", лРучной)); КонецЕсли;
	
	Попытка
		лРезультат=лHTTPСоединение.Получить(лЗапросHTTP);
		Если лТипПолучения="ДвоичныеДанные" Тогда 
			лТело=лРезультат.ПолучитьТелоКакДвоичныеДанные();
		ИначеЕсли лТипПолучения="Поток" Тогда
			лТело=лРезультат.ПолучитьТелоКакПоток();
		Иначе
			лТело=лРезультат.ПолучитьТелоКакСтроку();
		КонецЕсли;
		
		пСтруктураПараметры.Вставить("КодСостояния", лРезультат.КодСостояния);
		пСтруктураПараметры.Вставить("ЗаголовкиОтвета", лРезультат.Заголовки);
		Если лРезультат.КодСостояния=401 Тогда пТекстОшибки="Ошибка авторизации, код: "+лРезультат.КодСостояния; Возврат Неопределено; КонецЕсли; 
		Если лРезультат.КодСостояния=403 Тогда пТекстОшибки="Нет прав для запуска сервиса, код: "+лРезультат.КодСостояния+Символы.ПС+"Убедитесь что пользователь мобильного приложения имеет роль: ""Мобильный клиент"""; Возврат Неопределено; КонецЕсли;
		Если лРезультат.КодСостояния=500 Тогда пТекстОшибки="Ошибка выполнения, код: "+лРезультат.КодСостояния+", текст ошибки: "+Символы.ПС+лТело; Возврат Неопределено; КонецЕсли;
		Если лРезультат.КодСостояния<>200 Тогда пТекстОшибки="Ошибка, код: "+лРезультат.КодСостояния; Возврат Неопределено; КонецЕсли;
		Если лЛогироватьВызовы Тогда ТсПлатформаОбщий.HttpИсходящийВызовЛогироватьКонец(лРезультат, лСтруктураЛогирование); КонецЕсли;
		Возврат лТело;
		
	Исключение
		пСтруктураПараметры.Вставить("КодСостояния", Неопределено);
		пСтруктураПараметры.Вставить("ЗаголовкиОтвета", Новый Массив);
		
		лИнформацияОбОшибке=ИнформацияОбОшибке();
		пТекстОшибки=ТсПлатформаОбщий.ПолучитьПолноеОписаниеОшибки(лИнформацияОбОшибке);
		Возврат Неопределено;
	КонецПопытки;
КонецФункции

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

	лHTTPСоединение=Новый HTTPСоединение(пИмяСервера, лПорт, пЛогин, пПароль, лИнтернетПрокси, лТаймаут, лЗащищенноеСоединение, Ложь);
	лЗапросHTTP=Новый HTTPЗапрос(пПуть);
	Если лОтправкаФайла Тогда 
		лЗапросHTTP.УстановитьИмяФайлаТела(пДанныеЗапроса);
	ИначеЕсли лОтправкаДвоичныхДанных Тогда 
		лЗапросHTTP.УстановитьТелоИзДвоичныхДанных(пДанныеЗапроса);
	Иначе
		лЗапросHTTP.УстановитьТелоИзСтроки(пДанныеЗапроса);
	КонецЕсли;
	
	Если Не пСтруктураПараметры.Свойство("Заголовки") Тогда
		Если лОтправкаДвоичныхДанных Тогда 
			//Заголовки не нужны, сам сделает правильные
			//лЗапросHTTP.Заголовки.Вставить("Content-Type", "application/octet-stream");
			//лЗапросHTTP.Заголовки.Вставить("Content-Length", пДанныеЗапроса.Размер());
		Иначе
			лЗапросHTTP.Заголовки.Вставить("Content-Type", "application/json");
			лЗапросHTTP.Заголовки.Вставить("Content-Language", "ru");
			лЗапросHTTP.Заголовки.Вставить("Content-Charset", "utf-8");
			лЗапросHTTP.Заголовки.Вставить("Accept-Language", "ru");
			лЗапросHTTP.Заголовки.Вставить("Accept-Charset", "utf-8");
		КонецЕсли;
	Иначе
		Для Каждого лКлючИЗначение Из пСтруктураПараметры.Заголовки Цикл
			лЗапросHTTP.Заголовки.Вставить(лКлючИЗначение.Ключ, лКлючИЗначение.Значение);
		КонецЦикла;
	КонецЕсли;
	
	Если лЛогироватьВызовы Тогда лСтруктураЛогирование=ТсПлатформаОбщий.HttpИсходящийВызовЛогироватьНачало(лHTTPСоединение, "POST", лЗапросHTTP, Новый Структура("Ручной", лРучной)); КонецЕсли;
	
	Попытка
		лРезультат=лHTTPСоединение.ОтправитьДляОбработки(лЗапросHTTP);
		Если Не ЗначениеЗаполнено(лТипПолучения) Тогда 
			Если лРезультат.Заголовки.Получить("Content-Type")="application/octet-stream" Тогда лТипПолучения="ДвоичныеДанные"; КонецЕсли;
		КонецЕсли;
		Если лТипПолучения="ДвоичныеДанные" Тогда 
			лТело=лРезультат.ПолучитьТелоКакДвоичныеДанные();
		ИначеЕсли лТипПолучения="Поток" Тогда
			лТело=лРезультат.ПолучитьТелоКакПоток();
		Иначе
			лТело=лРезультат.ПолучитьТелоКакСтроку();
		КонецЕсли;
		пСтруктураПараметры.Вставить("КодСостояния", лРезультат.КодСостояния);
		пСтруктураПараметры.Вставить("ЗаголовкиОтвета", лРезультат.Заголовки);
		Если лРезультат.КодСостояния=401 Тогда пТекстОшибки="Ошибка авторизации, код: "+лРезультат.КодСостояния; Возврат Неопределено; КонецЕсли; 
		Если лРезультат.КодСостояния=403 Тогда пТекстОшибки="Нет прав для запуска сервиса, код: "+лРезультат.КодСостояния+Символы.ПС+"Убедитесь что пользователь мобильного приложения имеет роль: ""Мобильный клиент"""; Возврат Неопределено; КонецЕсли;
		Если лРезультат.КодСостояния=500 Тогда пТекстОшибки="Ошибка выполнения, код: "+лРезультат.КодСостояния+", текст ошибки: "+Символы.ПС+лТело; Возврат Неопределено; КонецЕсли;
		Если лРезультат.КодСостояния<>200 Тогда пТекстОшибки="Ошибка, код: "+лРезультат.КодСостояния; Возврат Неопределено; КонецЕсли;
		Если лЛогироватьВызовы Тогда ТсПлатформаОбщий.HttpИсходящийВызовЛогироватьКонец(лРезультат, лСтруктураЛогирование); КонецЕсли;
		Возврат лТело;
	Исключение
		пСтруктураПараметры.Вставить("КодСостояния", Неопределено);
		пСтруктураПараметры.Вставить("ЗаголовкиОтвета", Новый Массив);
		
		лИнформацияОбОшибке=ИнформацияОбОшибке();
		пТекстОшибки=ТсПлатформаОбщий.ПолучитьПолноеОписаниеОшибки(лИнформацияОбОшибке);
		Возврат Неопределено;
	КонецПопытки;
КонецФункции

Функция ДанныеРазрахивировать(пДвоичныеДанные) Экспорт
	лДанныеXML=Base64Строка(пДвоичныеДанные); // или так: ПолучитьСтрокуИзДвоичныхДанных
	лХранилищеЗначения=XMLЗначение(Тип("ХранилищеЗначения"), лДанныеXML);
	Возврат лХранилищеЗначения.Получить();
КонецФункции

Функция ДанныеАрхивировать(пДанные) Экспорт
	лХранилищеЗначения=Новый ХранилищеЗначения(пДанные, Новый СжатиеДанных(9));
	лДанныеXML=XMLСтрока(лХранилищеЗначения);
	Возврат Base64Значение(лДанныеXML); // или так: ПолучитьДвоичныеДанныеИзBase64Строки
КонецФункции
#КонецОбласти

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

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

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

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

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

Функция мЗаполнитьТзИзМассиваСтруктур(пТз, пМассивСтруктур, пЭтоДерево)
	Для Каждого лСтруктура Из пМассивСтруктур Цикл
		лСтрокаТз=пТз.Добавить();
		ЗаполнитьЗначенияСвойств(лСтрокаТз, лСтруктура,, ?(пЭтоДерево, "Строки", ""));
		Если пЭтоДерево и ТипЗнч(лСтруктура.Строки)=Тип("Массив") Тогда
			мЗаполнитьТзИзМассиваСтруктур(лСтрокаТз.Строки, лСтруктура.Строки, пЭтоДерево);
		КонецЕсли; 
	КонецЦикла; 
КонецФункции

Функция мТзИзМассиваСтруктур(пМассивСтруктур, пЭтоДерево=Ложь) Экспорт
	лТз=?(пЭтоДерево, Новый ДеревоЗначений, Новый ТаблицаЗначений);
	Если пМассивСтруктур.Количество()=0 Тогда Возврат лТз; КонецЕсли;
	Для Каждого лКлючИЗначениеСтруктуры Из пМассивСтруктур[0] Цикл лТз.Колонки.Добавить(лКлючИЗначениеСтруктуры.Ключ); КонецЦикла;
	мЗаполнитьТзИзМассиваСтруктур(?(пЭтоДерево, лТз.Строки, лТз), пМассивСтруктур, пЭтоДерево);
	Возврат лТз;
КонецФункции

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

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

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

Функция мПолучитьПорогСжатияТекста()
	Возврат 500000; // 500 кб
КонецФункции

Функция ЗапросPOSTКСерверуОбмена(пИмяМетода, пПодключение, пПараметры=Неопределено, пПараметрыЗапроса=Неопределено, пТекстОшибки="") Экспорт
	лСтрокаПодключения=пПодключение.СтрокаПодключения;
	Если ПустаяСтрока(лСтрокаПодключения) Тогда пТекстОшибки="Не задана строка подключения!"; Возврат Неопределено; КонецЕсли;
	
	лСтруктураСсылки=ВебСсылкаРазобрать(лСтрокаПодключения, пТекстОшибки);
	Если лСтруктураСсылки=Неопределено Тогда Возврат Неопределено; КонецЕсли;
	
	лРаботаВРежимеАгента=ТсПлатформаОбщий.РаботаВРежимеАгента();
	
	лТаймаут=ТсПлатформаОбщий.ПолучитьСвойство(пПараметрыЗапроса, "Таймаут", 5);
	лКонвертироватьПараметрыВJSON=ТсПлатформаОбщий.ПолучитьСвойство(пПараметрыЗапроса, "КонвертироватьПараметрыВJSON", Истина);
	лДанныеАутентификации=?(Не лРаботаВРежимеАгента и ЗначениеЗаполнено(пПодключение.ДанныеАутентификации), пПодключение.ДанныеАутентификации, пПодключение);
	лТекстДанные=пПараметры;
	Если лКонвертироватьПараметрыВJSON Тогда лТекстДанные=ТсПлатформаОбщий.КонвертироватьВJSON(лТекстДанные); КонецЕсли; 
	
	лПараметрыЗапроса=Новый Структура("Таймаут, Логировать", лТаймаут, ТсПлатформаОбщий.КонстантаПолучить("ТсОбменЛогироватьHttpСервисы", Ложь));
	Если СтрДлина(лТекстДанные)>мПолучитьПорогСжатияТекста() Тогда
		лТекстДанные=ДанныеАрхивировать(лТекстДанные);
		лПараметрыЗапроса.Вставить("ОтправкаДвоичныхДанных", Истина);
	КонецЕсли;
	
	лТекстОтвета=ЗапросPOST(лСтруктураСсылки.ИмяСервера, лСтруктураСсылки.Порт, "/"+лСтруктураСсылки.Путь+"/hs/TsExchange/"+пИмяМетода, лДанныеАутентификации.ИмяПользователя, лДанныеАутентификации.ПарольПользователя, лТекстДанные, лСтруктураСсылки.ИспользоватьЗащищеннуюАвторизацию, лПараметрыЗапроса, пТекстОшибки); // ТсПлатформаМодули.Общий().
	Если ТипЗнч(лТекстОтвета)=Тип("ДвоичныеДанные") Тогда лТекстОтвета=ДанныеРазрахивировать(лТекстОтвета); КонецЕсли;
	Если ТипЗнч(пПараметрыЗапроса)<>Тип("Структура") Тогда пПараметрыЗапроса=Новый Структура; КонецЕсли;
	пПараметрыЗапроса.Вставить("КодСостояния", лПараметрыЗапроса.КодСостояния);
	Если лТекстОтвета=Неопределено Тогда Возврат Неопределено; КонецЕсли;
	Если лПараметрыЗапроса.КодСостояния<>200 Тогда
		Если Не ЗначениеЗаполнено(пТекстОшибки) Тогда
			пТекстОшибки="Ошибка при запросе, код ответа: "+лПараметрыЗапроса.КодСостояния; // +" ("+ТсПлатформаМодули.Общий().ПолучитьИмяСостоянияHTTP(лПараметрыЗапроса.КодСостояния)+")" // может быть запущено в агенте
			Если ЗначениеЗаполнено(лТекстОтвета) Тогда пТекстОшибки=пТекстОшибки+", текст ответа: "+лТекстОтвета; КонецЕсли;
		КонецЕсли;
		Возврат Неопределено;
	КонецЕсли;
	Возврат ТсПлатформаОбщий.КонвертироватьИзJSON(лТекстОтвета);
КонецФункции

Функция ТипЕдинственноеЧисло(пТип) Экспорт
	Если пТип="Справочники" Тогда Возврат "Справочник"; КонецЕсли;
	Если пТип="Документы" Тогда Возврат "Документ"; КонецЕсли;
	Если пТип="Перечисления" Тогда Возврат "Перечисление"; КонецЕсли; 
	Если пТип="ПланыВидовХарактеристик" Тогда Возврат "ПланВидовХарактеристик"; КонецЕсли;
	Если пТип="ЖурналыДокументов" Тогда Возврат "ЖурналДокументов"; КонецЕсли; 
	Если пТип="РегистрыСведений" Тогда Возврат "РегистрСведений"; КонецЕсли;
	Если пТип="РегистрыНакопления" Тогда Возврат "РегистрНакопления"; КонецЕсли;
	Если пТип="РегистрыБухгалтерии" Тогда Возврат "РегистрБухгалтерии"; КонецЕсли;
	Если пТип="РегистрыРасчета" Тогда Возврат "РегистрРасчета"; КонецЕсли;
	Если пТип="ПланыОбмена" Тогда Возврат "ПланОбмена"; КонецЕсли;
	Если пТип="ПланыСчетов" Тогда Возврат "ПланСчетов"; КонецЕсли; 
	Если пТип="ПланыВидовРасчета" Тогда Возврат "ПланВидовРасчета"; КонецЕсли;
	Если пТип="БизнесПроцессы" Тогда Возврат "БизнесПроцесс"; КонецЕсли; 
	Если пТип="Задачи" Тогда Возврат "Задача"; КонецЕсли; 
	Если пТип="Обработки" Тогда Возврат "Обработка"; КонецЕсли; 
	Если пТип="Отчеты" Тогда Возврат "Отчет"; КонецЕсли; 
	ВызватьИсключение "Функция ТипЕдинственноеЧисло, не смогли обработать тип: "+пТип;
КонецФункции
#КонецОбласти

#Область ФункцииДляПоддержкиУниверсальностиСКОМ
Функция мЗначениеВСтроку(пЗначение, пСоединениеКОМ=Неопределено)
	Возврат ?(пСоединениеКОМ=Неопределено, Строка(пЗначение), пСоединениеКОМ.String(пЗначение));
КонецФункции

Функция НовыйОбъект(пСтрокаТип, пСоединениеКОМ=Неопределено, пПараметр1=Неопределено, пПараметр2=Неопределено, пПараметр3=Неопределено, пПараметр4=Неопределено, пПараметр5=Неопределено) Экспорт
	Если пСоединениеКОМ=Неопределено Тогда
		лКоличествоПараметров=?(пПараметр5<>Неопределено, 5, ?(пПараметр4<>Неопределено, 4, ?(пПараметр3<>Неопределено, 3, ?(пПараметр2<>Неопределено, 2, ?(пПараметр1<>Неопределено, 1, 0)))));
		лМассивПараметры=Новый Массив;
		Для лИнд=1 По лКоличествоПараметров Цикл
			лМассивПараметры.Добавить(Вычислить("пПараметр"+лИнд));
		КонецЦикла;
		Попытка
			Возврат Новый(Тип(пСтрокаТип), лМассивПараметры);
		Исключение 
			лИнформацияОбОшибке=ИнформацияОбОшибке();
		КонецПопытки;
		Возврат Неопределено; 
	КонецЕсли;
	Если пПараметр5<>Неопределено Тогда Возврат пСоединениеКОМ.NewObject(пСтрокаТип, пПараметр1, пПараметр2, пПараметр3, пПараметр4, пПараметр5); КонецЕсли;
	Если пПараметр4<>Неопределено Тогда Возврат пСоединениеКОМ.NewObject(пСтрокаТип, пПараметр1, пПараметр2, пПараметр3, пПараметр4); КонецЕсли;
	Если пПараметр3<>Неопределено Тогда Возврат пСоединениеКОМ.NewObject(пСтрокаТип, пПараметр1, пПараметр2, пПараметр3); КонецЕсли;
	Если пПараметр2<>Неопределено Тогда Возврат пСоединениеКОМ.NewObject(пСтрокаТип, пПараметр1, пПараметр2); КонецЕсли;
	Если пПараметр1<>Неопределено Тогда Возврат пСоединениеКОМ.NewObject(пСтрокаТип, пПараметр1); КонецЕсли;
	Возврат пСоединениеКОМ.NewObject(пСтрокаТип);
КонецФункции

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

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

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

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

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

Функция НовыйОбъект5(пСтрокаТип, пСоединениеКОМ=Неопределено, пПараметр1, пПараметр2, пПараметр3, пПараметр4, пПараметр5) Экспорт
	Если пСоединениеКОМ=Неопределено Тогда
		Попытка
			лМассивПараметры=Новый Массив;
			лМассивПараметры.Добавить(пПараметр1);
			лМассивПараметры.Добавить(пПараметр2);
			лМассивПараметры.Добавить(пПараметр3);
			лМассивПараметры.Добавить(пПараметр4);
			лМассивПараметры.Добавить(пПараметр5);
			Возврат Новый(Тип(пСтрокаТип), лМассивПараметры);
		Исключение 
			лИнформацияОбОшибке=ИнформацияОбОшибке();
		КонецПопытки;
		Возврат Неопределено; 
	КонецЕсли;
	Возврат пСоединениеКОМ.NewObject(пСтрокаТип, пПараметр1, пПараметр2, пПараметр3, пПараметр4, пПараметр5);
КонецФункции
#КонецОбласти

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

Функция ТипМножественноеЧисло(пТип) Экспорт
	Если пТип="Справочник" Тогда Возврат "Справочники"; КонецЕсли; 
	Если пТип="Документ" Тогда Возврат "Документы"; КонецЕсли; 
	Если пТип="Перечисление" Тогда Возврат "Перечисления"; КонецЕсли; 
	Если пТип="ПланВидовХарактеристик" Тогда Возврат "ПланыВидовХарактеристик"; КонецЕсли; 
	Если пТип="ЖурналДокументов" Тогда Возврат "ЖурналыДокументов"; КонецЕсли; 
	Если пТип="РегистрСведений" Тогда Возврат "РегистрыСведений"; КонецЕсли;
	Если пТип="РегистрНакопления" Тогда Возврат "РегистрыНакопления"; КонецЕсли;
	Если пТип="РегистрБухгалтерии" Тогда Возврат "РегистрыБухгалтерии"; КонецЕсли;
	Если пТип="РегистрыРасчета" Тогда Возврат "РегистрРасчета"; КонецЕсли;
	Если пТип="ПланОбмена" Тогда Возврат "ПланыОбмена"; КонецЕсли; 
	Если пТип="ПланСчетов" Тогда Возврат "ПланыСчетов"; КонецЕсли;
	Если пТип="ПланВидовРасчета" Тогда Возврат "ПланыВидовРасчета"; КонецЕсли;
	Если пТип="БизнесПроцесс" Тогда Возврат "БизнесПроцессы"; КонецЕсли; 
	Если пТип="Задача" Тогда Возврат "Задачи"; КонецЕсли; 
	Если пТип="Обработка" Тогда Возврат "Обработки"; КонецЕсли; 
	Если пТип="Отчет" Тогда Возврат "Отчеты"; КонецЕсли; 
	Сообщить("Не задано соответствие для типа: "+пТип+" (ТипМножественноеЧисло)");
	Возврат Неопределено; 
КонецФункции

Функция ПолучитьСтруктуруТипа(пТип, пСоединениеКОМ=Неопределено, пКэшСоответствиеТип2СтруктураТипа=Неопределено) Экспорт
	Если пКэшСоответствиеТип2СтруктураТипа=Неопределено Тогда пКэшСоответствиеТип2СтруктураТипа=Новый Соответствие; КонецЕсли; 
	лСтруктураТипаЗначения=пКэшСоответствиеТип2СтруктураТипа.Получить(пТип);
	Если лСтруктураТипаЗначения<>Неопределено Тогда Возврат лСтруктураТипаЗначения; КонецЕсли;
	
	лМетаданные=?(пСоединениеКОМ=Неопределено, Метаданные, пСоединениеКОМ.Метаданные);
	Попытка	лМетаТип=лМетаданные.НайтиПоТипу(пТип); Исключение Возврат Неопределено; КонецПопытки;
	Если лМетаТип=Неопределено Тогда Возврат Неопределено; КонецЕсли;
	лМассивТипа=СтрРазделить(лМетаТип.ПолноеИмя(), ".");
	
	лСтруктураТипаЗначения=Новый Структура("Тип, Вид", ТипМножественноеЧисло(лМассивТипа[0]), лМетаТип.Имя);
	пКэшСоответствиеТип2СтруктураТипа.Вставить(пТип, лСтруктураТипаЗначения);
	Возврат лСтруктураТипаЗначения;
КонецФункции

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

Функция мОписаниеТиповПолучитьМассивТипы(пОписаниеТипов, пПредставление, пСоединениеКОМ=Неопределено, пКэшСоответствиеТип2СтруктураТипа, пСтруктураПримитивныеТипы, пЭтоСсылка1С=Неопределено)
	лМассивТипы=Новый Массив;
	лМассивПредставлениеТипов=Новый Массив;
	
	Для Каждого лТип Из пОписаниеТипов.Типы() Цикл
		Если лТип=пСтруктураПримитивныеТипы.Null Тогда Продолжить; КонецЕсли;
		
		лСтруктураТип=Новый Структура;
		Если лТип=пСтруктураПримитивныеТипы.Строка Тогда 
			лСтруктураТип.Вставить("Тип", "Строка");
			лСтруктураТип.Вставить("Длина", пОписаниеТипов.КвалификаторыСтроки.Длина);
			лМассивПредставлениеТипов.Добавить(СтрокаТипыПолучитьТипСтрока(лСтруктураТип.Тип,,, лСтруктураТип.Длина));
			
		ИначеЕсли лТип=пСтруктураПримитивныеТипы.Число Тогда
			лСтруктураТип.Вставить("Тип", "Число");
			лСтруктураТип.Вставить("Длина", пОписаниеТипов.КвалификаторыЧисла.Разрядность);
			лСтруктураТип.Вставить("Точность", пОписаниеТипов.КвалификаторыЧисла.РазрядностьДробнойЧасти);
			лСтруктураТип.Вставить("Неотрицательный", пОписаниеТипов.КвалификаторыЧисла.ДопустимыйЗнак=ДопустимыйЗнак.Неотрицательный);
			лМассивПредставлениеТипов.Добавить(СтрокаТипыПолучитьТипСтрока(лСтруктураТип.Тип,,, лСтруктураТип.Длина, лСтруктураТип.Точность));
			
		ИначеЕсли лТип=пСтруктураПримитивныеТипы.Дата Тогда 
			лСтруктураТип.Вставить("Тип", "Дата");
			лСтруктураТип.Вставить("ЧастиДаты", мЧастиДатыИдентификатор(пОписаниеТипов.КвалификаторыДаты.ЧастиДаты, пСоединениеКОМ));
			лМассивПредставлениеТипов.Добавить(СтрокаТипыПолучитьТипСтрока(лСтруктураТип.Тип));
			
		ИначеЕсли лТип=пСтруктураПримитивныеТипы.Булево Тогда 
			лСтруктураТип.Вставить("Тип", "Булево");
			лМассивПредставлениеТипов.Добавить(СтрокаТипыПолучитьТипСтрока(лСтруктураТип.Тип));
			
		ИначеЕсли лТип=пСтруктураПримитивныеТипы.ХранилищеЗначения Тогда
			лСтруктураТип.Вставить("Тип", "ДвоичныеДанные");
			лМассивПредставлениеТипов.Добавить(СтрокаТипыПолучитьТипСтрока(лСтруктураТип.Тип));
			
		ИначеЕсли лТип=пСтруктураПримитивныеТипы.ОписаниеТипов Тогда 
			лСтруктураТип.Вставить("Тип", "ОписаниеТипов");
			лМассивПредставлениеТипов.Добавить(СтрокаТипыПолучитьТипСтрока(лСтруктураТип.Тип));
			
		ИначеЕсли лТип=пСтруктураПримитивныеТипы.УникальныйИдентификатор Тогда
			лСтруктураТип.Вставить("Тип", "УникальныйИдентификатор");
			лМассивПредставлениеТипов.Добавить("УникальныйИдентификатор");
			
		Иначе
			лСтруктураТипаЗначения=ПолучитьСтруктуруТипа(лТип, пСоединениеКОМ, пКэшСоответствиеТип2СтруктураТипа);
			Если лСтруктураТипаЗначения=Неопределено Тогда Продолжить; КонецЕсли;
			Если Не ЗначениеЗаполнено(лСтруктураТипаЗначения.Вид) Тогда 
				Сообщить("Не смогли разобрать тип: "+лТип);
				Продолжить;
			КонецЕсли;
			пЭтоСсылка1С=Истина;
			
			лСтруктураТип.Вставить("Тип", "Строка");
			лСтруктураТип.Вставить("ТипТаблицы", ""+лСтруктураТипаЗначения.Тип);
			лСтруктураТип.Вставить("ИмяТаблицы", ""+лСтруктураТипаЗначения.Вид);
			лСтруктураТип.Вставить("Длина", ?(лСтруктураТипаЗначения.Тип="Перечисления", 80, 36)); // Длина имени перечисления и УИД
			
			лМассивПредставлениеТипов.Добавить(СтрокаТипыПолучитьТипСтрока(лСтруктураТип.Тип, лСтруктураТип.ТипТаблицы, лСтруктураТип.ИмяТаблицы));
		КонецЕсли;
		лМассивТипы.Добавить(лСтруктураТип);
	КонецЦикла;
	пПредставление=СтрСоединить(лМассивПредставлениеТипов, ", ");
	Возврат лМассивТипы; 
КонецФункции

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

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

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

Функция мСтруктураКонфигурацииДобавитьРеквизиты(пМета, пМассив, пСоединениеКОМ, пКэшСоответствиеТип2СтруктураТипа, пСтруктураПримитивныеТипы, пЭтоКлюч, пИмяСвойстваРеквизитов="Реквизиты", пЭтоРегБухКорреспонция=Ложь)
	Для Каждого лМетаРеквизит Из пМета[пИмяСвойстваРеквизитов] Цикл
		Если Не пЭтоРегБухКорреспонция или лМетаРеквизит.Балансовый Тогда
			пМассив.Добавить(мСтруктураРеквизитаТаблицыПолучить(лМетаРеквизит, пСоединениеКОМ, пКэшСоответствиеТип2СтруктураТипа, пСтруктураПримитивныеТипы, пЭтоКлюч, Ложь));
			Продолжить;
		КонецЕсли;
		пМассив.Добавить(мСтруктураРеквизитаТаблицыПолучить(лМетаРеквизит, пСоединениеКОМ, пКэшСоответствиеТип2СтруктураТипа, пСтруктураПримитивныеТипы, пЭтоКлюч, Ложь,, "Дт", " дебет"));
		пМассив.Добавить(мСтруктураРеквизитаТаблицыПолучить(лМетаРеквизит, пСоединениеКОМ, пКэшСоответствиеТип2СтруктураТипа, пСтруктураПримитивныеТипы, пЭтоКлюч, Ложь,, "Кт", " кредит"));
	КонецЦикла;
КонецФункции

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

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

Функция мОписаниеТипаСтрока(пСоединениеКОМ, пДлина)
	Возврат НовыйОбъект3("ОписаниеТипов", пСоединениеКОМ, "Строка",, НовыйОбъект1("КвалификаторыСтроки", пСоединениеКОМ, пДлина));
КонецФункции

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

Функция мОписаниеТипаЧисло(пСоединениеКОМ, пДлина, пТочность=0, пДопустимыйЗнак=Неопределено)
	Возврат НовыйОбъект2("ОписаниеТипов", пСоединениеКОМ, "Число", НовыйОбъект3("КвалификаторыЧисла", пСоединениеКОМ, пДлина, пТочность, мДопустимыйЗнакПолучить(пСоединениеКОМ, пДопустимыйЗнак)));
КонецФункции

Функция мДобавитьВерсиюДанных(пМассивРеквизиты, пСоединениеКОМ, пКэшСоответствиеТип2СтруктураТипа, пСтруктураПримитивныеТипы, пИспользование="")
	лОписаниеТипов=мОписаниеТипаСтрока(пСоединениеКОМ, 12);
	мМассивРеквизитыДобавитьСтруктуруРеквизита(пМассивРеквизиты, "ВерсияДанных", "Версия данных", Ложь, Ложь, лОписаниеТипов, пСоединениеКОМ, пКэшСоответствиеТип2СтруктураТипа, пСтруктураПримитивныеТипы, пИспользование);
КонецФункции 

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

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

Функция мПолучитьТипПоМетаОбъекту(пМета, пСоединениеКОМ)
	лМетаданные=?(пСоединениеКОМ=Неопределено, Метаданные, пСоединениеКОМ.Метаданные);
	Для Каждого лИмя Из мМассивОбрабатываемыеТипыМетаданных() Цикл
		Если лМетаданные[лИмя].Содержит(пМета) Тогда Возврат лИмя; КонецЕсли;
	КонецЦикла;
	//Сообщить("Не смогли определить тип по метаданным: "+пМета);
	Возврат Неопределено;
КонецФункции

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

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

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

Функция мСтруктураКонфигурацииПолучитьМассивТаблиц1с(пТип, пПолучитьСтруктуруРеквизитов, пСоединениеКОМ, пКэшСоответствиеТип2СтруктураТипа, пСтруктураПримитивныеТипы)
	лМетаданные=?(пСоединениеКОМ=Неопределено, Метаданные, пСоединениеКОМ.Метаданные);
	
	лМассивТаблиц=Новый Массив;
	Для Каждого лМетаОбъект Из лМетаданные[пТип] Цикл
		лСтруктураТаблицы=СтруктураКонфигурацииПолучитьСтруктуруТаблицы1с(лМетаОбъект, пТип, пПолучитьСтруктуруРеквизитов, пСоединениеКОМ, пКэшСоответствиеТип2СтруктураТипа, пСтруктураПримитивныеТипы);
		лМассивТаблиц.Добавить(лСтруктураТаблицы);
	КонецЦикла;
	Возврат лМассивТаблиц;
КонецФункции

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

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

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

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

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

Функция ПолучитьСтатистикуКонфигурации1с(пСоединениеКОМ=Неопределено) Экспорт
	лМетаданные=?(пСоединениеКОМ=Неопределено, Метаданные, пСоединениеКОМ.Метаданные);
	
	лМассивСтруктурыСтатистики=Новый Массив;
	Для Каждого лТип Из мМассивОбрабатываемыеТипыМетаданных() Цикл
		Для Каждого лМетаОбъект Из лМетаданные[лТип] Цикл
			лСтруктураСтатистикаКонфигурации=ПолучитьСтатистикуТаблицы1с(Новый Структура("Тип, Имя", лТип, лМетаОбъект.Имя), пСоединениеКОМ);
			лМассивСтруктурыСтатистики.Добавить(лСтруктураСтатистикаКонфигурации);
		КонецЦикла;
	КонецЦикла;
	Возврат лМассивСтруктурыСтатистики;
КонецФункции
#КонецОбласти

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

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

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

Функция мРеквизитыТаблицКонфигурацийНайти(пВладелец, пРодитель=Неопределено, пИмя, пЭтоГруппа=Ложь)
	лЗапрос=Новый Запрос;
	лЗапрос.УстановитьПараметр("Владелец", пВладелец);
	лЗапрос.УстановитьПараметр("Родитель", ?(пРодитель=Неопределено, Справочники.ТсКонфигурацииРеквизитыТаблиц.ПустаяСсылка(), пРодитель));
	лЗапрос.УстановитьПараметр("Имя", пИмя);
	лЗапрос.УстановитьПараметр("ЭтоГруппа", пЭтоГруппа);
	лЗапрос.Текст=
	"ВЫБРАТЬ
	|	ТсКонфигурацииРеквизитыТаблиц.Ссылка КАК Ссылка
	|ИЗ
	|	Справочник.ТсКонфигурацииРеквизитыТаблиц КАК ТсКонфигурацииРеквизитыТаблиц
	|ГДЕ
	|	ТсКонфигурацииРеквизитыТаблиц.Владелец = &Владелец
	|	И ТсКонфигурацииРеквизитыТаблиц.Родитель = &Родитель
	|	И ТсКонфигурацииРеквизитыТаблиц.Имя = &Имя
	|	И ТсКонфигурацииРеквизитыТаблиц.ЭтоГруппа = &ЭтоГруппа";
	лВыборка=лЗапрос.Выполнить().Выбрать();
	Возврат ?(лВыборка.Следующий(), лВыборка.Ссылка, Неопределено);
КонецФункции 

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

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

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

#Область ПреобразованиеДанныхДляСервиса
Функция мМаксимальныйРазмерПорции()
	Возврат ТсПлатформаОбщий.КонстантаПолучить("ТсОбменМаксимальнаяПорцияПакета", 1000000000000); // !!!!!!!!!!!!! есть ошибка, после исправления можно снова сделать разделение по пакетам
КонецФункции

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

Функция мПодготовитьДанныеДляВыгрузкиЧерезСервис(пДанные, пСоединениеКОМ, пСоответствиеКодПравила2СтруктураПКТ, пСтруктураКонтекст, пРазрешатьБитьНаПакеты)
	лМассивСтруктурыВыгрузки=Новый Массив;
	Для Каждого лСтруктураДанные Из пДанные Цикл
		лСтруктураВыгрузки=Новый Структура("КодПравила, Данные, РазделеноПоПорциям, ОтборПоСсылкам");
		ЗаполнитьЗначенияСвойств(лСтруктураВыгрузки, лСтруктураДанные);
		
		Если лСтруктураДанные.ПравилоКонвертацииТаблицы.События<>Неопределено Тогда лСтруктураВыгрузки.Вставить("События", лСтруктураДанные.ПравилоКонвертацииТаблицы.События); КонецЕсли;
		
		Если лСтруктураДанные.Данные<>Неопределено Тогда
			лСтруктураПКТ=Новый Структура("Параметры");
			ЗаполнитьЗначенияСвойств(лСтруктураПКТ, пСоответствиеКодПравила2СтруктураПКТ.Получить(лСтруктураДанные.КодПравила));
			
			лРеквизитыИсточника=лСтруктураДанные.ПравилоКонвертацииТаблицы.ТаблицаИсточник.Реквизиты; лРеквизитыПриемника=лСтруктураДанные.ПравилоКонвертацииТаблицы.ТаблицаПриемник.Реквизиты;
			лСтруктураВыгрузки.РазделеноПоПорциям=пРазрешатьБитьНаПакеты и лСтруктураДанные.ДанныеТч.Количество()=0; // TODO: доделать разделение на порции для объектов с табличными частями!
			лСтруктураВыгрузки.Данные=мПреобразоватьТзВМассивСтруктурДляВыгрузкиЧерезСервис(лСтруктураДанные.Данные, лРеквизитыИсточника, лРеквизитыПриемника, лСтруктураДанные.ПравилоКонвертацииТаблицы.ПравилаКонвертацииРеквизитов, лСтруктураДанные, пСтруктураКонтекст, лСтруктураВыгрузки.РазделеноПоПорциям, пСоединениеКОМ);
			Если лСтруктураДанные.ДанныеТч.Количество()<>0 Тогда 
				лМассивДанныеТч=Новый Массив;
				Для Каждого лСтруктураДанныеТч Из лСтруктураДанные.ДанныеТч Цикл
					лСтруктураПКРТч=лСтруктураДанные.ПравилоКонвертацииТаблицы.ПравилаКонвертацииРеквизитов[лСтруктураДанныеТч.Индекс];
					лРеквизитыТчИсточника=мМассивНайтиВМассивеСтруктур(лРеквизитыИсточника, "Имя", лСтруктураПКРТч.РеквизитИсточникИмя).Реквизиты;
					лРеквизитыТчПриемника=мМассивНайтиВМассивеСтруктур(лРеквизитыПриемника, "Имя", лСтруктураПКРТч.РеквизитПриемникИмя).Реквизиты;
					лДанныеПреобразованные=мПреобразоватьТзВМассивСтруктурДляВыгрузкиЧерезСервис(лСтруктураДанныеТч.Данные, лРеквизитыТчИсточника, лРеквизитыТчПриемника, лСтруктураПКРТч.ПравилаКонвертацииРеквизитов, лСтруктураДанные, пСтруктураКонтекст, Ложь, пСоединениеКОМ, лСтруктураПКРТч.РеквизитИсточникИмя);
					лМассивДанныеТч.Добавить(Новый Структура("Данные, Индекс", лДанныеПреобразованные, лСтруктураДанныеТч.Индекс));
				КонецЦикла;
				лСтруктураВыгрузки.Вставить("ДанныеТч", лМассивДанныеТч);
			КонецЕсли;
		КонецЕсли;
		
		лМассивСтруктурыВыгрузки.Добавить(лСтруктураВыгрузки);
	КонецЦикла;
	Возврат лМассивСтруктурыВыгрузки;
КонецФункции 
#КонецОбласти

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

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

Функция АлгоритмПолучитьСтруктуру(пАлгоритм) Экспорт
	Возврат Новый Структура("Имя, ТекстКода, Параметры, Тестирование", пАлгоритм.Имя, пАлгоритм.ТекстКода, мПолучитьСтруктуруПараметры(пАлгоритм.Параметры), пАлгоритм.Тестирование); 
КонецФункции

Функция ТаблицаПолучитьСобытия(пИмяСправочника, пСсылка, пИмяТч="События") Экспорт
	Если ТипЗнч(пСсылка)=Тип("Структура") Тогда
		Возврат ?(пСсылка.Свойство("События"), пСсылка[пИмяТч], Новый Структура); 
	КонецЕсли; 
	лЗапрос=Новый Запрос;
	лЗапрос.УстановитьПараметр("Ссылка", пСсылка);
	лЗапрос.Текст=
	"ВЫБРАТЬ
	|	ИсходныеДанные.Событие КАК Событие,
	|	ИсходныеДанные.Алгоритм.Имя КАК Имя,
	|	ИсходныеДанные.Алгоритм.ТекстКода КАК ТекстКода,
	|	ИсходныеДанные.Алгоритм.Параметры КАК Параметры,
	|	ИсходныеДанные.Алгоритм.Тестирование КАК Тестирование
	|ИЗ
	|	Справочник."+пИмяСправочника+"."+пИмяТч+" КАК ИсходныеДанные
	|ГДЕ
	|	ИсходныеДанные.Ссылка = &Ссылка
	|	И ИсходныеДанные.Включен
	|
	|УПОРЯДОЧИТЬ ПО
	|	ИсходныеДанные.НомерСтроки
	|ИТОГИ ПО
	|	Событие";
	лРезультатЗапроса=лЗапрос.Выполнить();
	Если лРезультатЗапроса.Пустой() Тогда Возврат Неопределено; КонецЕсли; 
	
	лСтруктураСобытия=Новый Структура;
	лВыборка=лРезультатЗапроса.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам, "Событие");
	
	Пока лВыборка.Следующий() Цикл
		лМассивАлгоритмы=Новый Массив;
		лВыборкаАлгоритмы=лВыборка.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
		Пока лВыборкаАлгоритмы.Следующий() Цикл
			лСтруктураСобытие=Новый Структура("Имя, Параметры, ТекстКода, Тестирование");
			ЗаполнитьЗначенияСвойств(лСтруктураСобытие, лВыборкаАлгоритмы);
			лМассивАлгоритмы.Добавить(АлгоритмПолучитьСтруктуру(лСтруктураСобытие));
		КонецЦикла;
		лСтруктураСобытия.Вставить(ТсПлатформаОбщий.ПеречислениеИмя(лВыборка.Событие), лМассивАлгоритмы);
	КонецЦикла;
	Возврат лСтруктураСобытия; 
КонецФункции

Функция мПолучитьТзДанныеПеречисления(пСтруктураТаблицы, пСоединениеКОМ, пИмяКакСсылку=Ложь)
	лТзДанные=НовыйОбъект0("ТаблицаЗначений", пСоединениеКОМ);
	
	Если пИмяКакСсылку Тогда 
		лТзДанные.Колонки.Добавить("Имя", Новый ОписаниеТипов("ПеречислениеСсылка."+пСтруктураТаблицы.Имя));
	Иначе
		лКвалификаторСтроки80=НовыйОбъект1("КвалификаторыСтроки", пСоединениеКОМ, 80);
		лОписаниеТипаСтрока80=НовыйОбъект3("ОписаниеТипов", пСоединениеКОМ, "Строка",, лКвалификаторСтроки80);
		лТзДанные.Колонки.Добавить("Имя", лОписаниеТипаСтрока80);
	КонецЕсли; 
	
	лТзДанные.Колонки.Добавить("Порядок", НовыйОбъект1("ОписаниеТипов", пСоединениеКОМ, "Число"));
	лКвалификаторСтроки255=НовыйОбъект1("КвалификаторыСтроки", пСоединениеКОМ, 255);
	лОписаниеТипаСтрока255=НовыйОбъект3("ОписаниеТипов", пСоединениеКОМ, "Строка",, лКвалификаторСтроки255);
	лТзДанные.Колонки.Добавить("Наименование", лОписаниеТипаСтрока255);
	лТзДанные.Колонки.Добавить("Комментарий", лОписаниеТипаСтрока255);
	
	лПеречисления=?(пСоединениеКОМ=Неопределено, Перечисления, пСоединениеКОМ.Перечисления);
	лМетаПеречисление=?(пСоединениеКОМ=Неопределено, Метаданные, пСоединениеКОМ.Метаданные).Перечисления[пСтруктураТаблицы.Имя];
	
	Если пИмяКакСсылку Тогда лМенеджер=лПеречисления[пСтруктураТаблицы.Имя]; КонецЕсли;
	лПорядок=0;
	Для Каждого лМетаЗначение Из лМетаПеречисление.ЗначенияПеречисления Цикл
		лСтрокаТзДанные=лТзДанные.Добавить();
		лСтрокаТзДанные.Порядок=лПорядок;
		лСтрокаТзДанные.Имя=?(пИмяКакСсылку, лМенеджер[лМетаЗначение.Имя], лМетаЗначение.Имя);
		лСтрокаТзДанные.Наименование=лМетаЗначение.Представление();
		лСтрокаТзДанные.Комментарий=лМетаЗначение.Комментарий;
		лПорядок=лПорядок+1;
	КонецЦикла;
	Если пСтруктураТаблицы.Свойство("КоличествоСтрокДляЧтения") Тогда 
		Пока лТзДанные.Количество()>пСтруктураТаблицы.КоличествоСтрокДляЧтения Цикл // Не оптимально но не критично, используется только для теста
			лТзДанные.Удалить(лТзДанные.Количество()-1)
		КонецЦикла; 
	КонецЕсли;
	Возврат лТзДанные;
КонецФункции

Функция мВыгрузитьТзПеречисленияВоВременнуюТаблицу(пТз, пИмяВременнойТаблицы, пМенеджерВременныхТаблиц, пСоединениеКОМ)
	лЗапрос=НовыйОбъект0("Запрос", пСоединениеКОМ);
	лЗапрос.МенеджерВременныхТаблиц=пМенеджерВременныхТаблиц;
	лЗапрос.УстановитьПараметр("Тз", пТз);
	лЗапрос.Текст=
	"ВЫБРАТЬ
	|	ИсходныеДанные.Имя КАК Имя,
	|	ИсходныеДанные.Порядок КАК Порядок,
	|	ИсходныеДанные.Наименование КАК Наименование,
	|	ИсходныеДанные.Комментарий КАК Комментарий
	|ПОМЕСТИТЬ "+пИмяВременнойТаблицы+"
	|ИЗ
	|	&Тз КАК ИсходныеДанные";
	лЗапрос.Выполнить();
КонецФункции

Функция мТекстЗапросаДобавлениеУничтоженияВТ(пИмяВТ)
	Возврат Символы.ПС+";"+Символы.ПС+Символы.ПС+"УНИЧТОЖИТЬ "+пИмяВТ;
КонецФункции

Функция мЗаполнитьИсточникДанныхЗапросаВыгрузкиПоПодключению(пДрайверПодключения, пПодключение, пСтруктураПКТ, пЗапрос, пСтруктураКонтекст, пМассивПараметры, пСтрУсловияОтбора, пСтрУсловияОтбораПоСсылке, пСоединениеКОМ, пТекстОшибки) // пЭтоЗапросТаблицыИсточника, 
	лСтруктураТаблицы=пСтруктураПКТ.ТаблицаИсточник; //?(пЭтоЗапросТаблицыИсточника, пСтруктураПКТ.ТаблицаИсточник, пСтруктураПКТ.ТаблицаПриемник);
	Если пПодключение<>Неопределено Тогда
		лИмяВТ="ВТТаблицаЗапроса"+Формат(пСтруктураПКТ.КодПравила, "ЧГ=");
		Если пЗапрос.МенеджерВременныхТаблиц.Таблицы.Найти(лИмяВТ)=Неопределено Тогда // Для отладки: ТсПлатформаОбщий.ПолучитьВТ(пЗапрос)
			//Нужно запихнуть обязательно сначала во временную таблицу, иначе могут быть отборы и не будет работать
			лСтруктураДанные=пДрайверПодключения.ЗаполнитьИсточникДанныхЗапроса(пПодключение, пСтруктураПКТ, пСтруктураКонтекст, пМассивПараметры, пСоединениеКОМ);
			Если лСтруктураДанные=Неопределено Тогда пТекстОшибки="Не смогли получить данные таблицы!"; Возврат Ложь; КонецЕсли;
			
			лТипДанныхСтруктура=ТипЗнч(лСтруктураДанные)=Тип("Структура");
			лЕстьТч=лТипДанныхСтруктура и лСтруктураДанные.Свойство("ДанныеТч");
			Если лЕстьТч Тогда 
				пЗапрос.УстановитьПараметр("ТзДанные", лСтруктураДанные.Данные);
				Для Каждого лКлючИЗначениеТабличныеЧасти Из лСтруктураДанные.ДанныеТч Цикл
					лИмяПараметра="ТзДанные"+лКлючИЗначениеТабличныеЧасти.Ключ;
					пЗапрос.УстановитьПараметр(лИмяПараметра, лКлючИЗначениеТабличныеЧасти.Значение);
					пЗапрос.Текст=
					"ВЫБРАТЬ * ПОМЕСТИТЬ "+лИмяВТ+лКлючИЗначениеТабличныеЧасти.Ключ+" ИЗ &"+лИмяПараметра+" КАК ИсходныеДанные;
					|
					|////////////////////////////////////////////////////////////////////////////////
					|
					|"+пЗапрос.Текст;
				КонецЦикла;
			Иначе
				пЗапрос.УстановитьПараметр("ТзДанные", ?(лТипДанныхСтруктура, лСтруктураДанные.Данные, лСтруктураДанные));
			КонецЕсли;
			
			пЗапрос.Текст=
			"ВЫБРАТЬ * ПОМЕСТИТЬ "+лИмяВТ+" ИЗ &ТзДанные КАК ИсходныеДанные;
			|
			|////////////////////////////////////////////////////////////////////////////////
			|
			|"+пЗапрос.Текст;
		КонецЕсли;
		пЗапрос.Текст=СтрЗаменить(пЗапрос.Текст, "%ИмяТаблицы%", лИмяВТ);
		
	Иначе // Выгрузка в 1с
		лТекстЗапроса="";
		Если лСтруктураТаблицы.Свойство("ТекстЗапроса", лТекстЗапроса) Тогда
			лИмяТаблицы=лСтруктураТаблицы.ИмяВременнойТаблицы;
			
			пЗапрос.Текст=лТекстЗапроса+Символы.ПС+";"+Символы.ПС+Символы.ПС+пЗапрос.Текст+мТекстЗапросаДобавлениеУничтоженияВТ(лИмяТаблицы);
			Для Каждого лСтруктураВременныеТаблицыТабличныхЧастей Из лСтруктураТаблицы.ВременныеТаблицыТабличныхЧастей Цикл
				пЗапрос.Текст=пЗапрос.Текст+мТекстЗапросаДобавлениеУничтоженияВТ(лСтруктураВременныеТаблицыТабличныхЧастей.ИмяВременнойТаблицы);
			КонецЦикла;
			Для Каждого лСтруктураВременныеТаблицыПрочие Из лСтруктураТаблицы.ВременныеТаблицыПрочие Цикл
				пЗапрос.Текст=пЗапрос.Текст+мТекстЗапросаДобавлениеУничтоженияВТ(лСтруктураВременныеТаблицыПрочие.ИмяВременнойТаблицы);
			КонецЦикла;
			
			мЗапросУстановитьПараметрыЗапроса(пЗапрос, лСтруктураТаблицы, пМассивПараметры);
			
		ИначеЕсли лСтруктураТаблицы.Тип="Перечисления" Тогда 
			лИмяТаблицы="ВтДанныеПеречисления"+Формат(пСтруктураПКТ.КодПравила, "ЧГ=");
			// Напрямую нельзя так как там идет отбор, а помещать можно только без отбора иначе он не работает!
			Если пЗапрос.МенеджерВременныхТаблиц.Таблицы.Найти(лИмяТаблицы)=Неопределено Тогда
				лТзДанныеПеречисления=мПолучитьТзДанныеПеречисления(лСтруктураТаблицы, пСоединениеКОМ, Истина);
				мВыгрузитьТзПеречисленияВоВременнуюТаблицу(лТзДанныеПеречисления, лИмяТаблицы, пЗапрос.МенеджерВременныхТаблиц, пСоединениеКОМ);
			КонецЕсли;
		Иначе
			лИмяТаблицы=ПолучитьИмяТаблицы1с(лСтруктураТаблицы);
			
			Если СтрНачинаетсяС(лИмяТаблицы, "РегистрБухгалтерии") Тогда
				лСтрУсловияОтбораРегистраБухгалтерии=?(лСтруктураТаблицы.Свойство("Отбор"), лСтруктураТаблицы.Отбор.Условие, "");
				Если ЗначениеЗаполнено(лСтрУсловияОтбораРегистраБухгалтерии) Тогда лСтрУсловияОтбораРегистраБухгалтерии=СтрЗаменить(лСтрУсловияОтбораРегистраБухгалтерии, "#ИсходныеДанные#.", ""); КонецЕсли;
				лИмяТаблицы=лИмяТаблицы+".ДвиженияССубконто(, , &_ВставкаУсловия_"
					+?(ЗначениеЗаполнено(лСтрУсловияОтбораРегистраБухгалтерии), " И "+лСтрУсловияОтбораРегистраБухгалтерии, "")
					+?(ЗначениеЗаполнено(пСтрУсловияОтбораПоСсылке), " И "+пСтрУсловияОтбораПоСсылке, "")+", , )";
			КонецЕсли; // TODO: тут 2 раза условие по регистратору накладывается!!! нужно поправить
		КонецЕсли;
		пЗапрос.Текст=СтрЗаменить(пЗапрос.Текст, "%ИмяТаблицы%", лИмяТаблицы);
		
		Если лСтруктураТаблицы.Свойство("ВременныеТаблицыТабличныхЧастей")
			и лСтруктураТаблицы.ВременныеТаблицыТабличныхЧастей.Количество()<>0 
		Тогда
			пЗапрос.Текст=СтрЗаменить(пЗапрос.Текст, "&_ОтборТабличнаяЧасть_", лСтруктураТаблицы.ИмяРеквизитаПервичногоКлюча+" В (ВЫБРАТЬ ИсходныеДанные.Ссылка ИЗ "+лСтруктураТаблицы.ИмяВременнойТаблицы+" КАК ИсходныеДанные)");
		КонецЕсли;
	КонецЕсли;
	Если ЗначениеЗаполнено(пСтрУсловияОтбора) или ЗначениеЗаполнено(пСтрУсловияОтбораПоСсылке) Тогда
		лСтрУсловияОтбораОбщие=?(ЗначениеЗаполнено(пСтрУсловияОтбора), пСтрУсловияОтбора+?(ЗначениеЗаполнено(пСтрУсловияОтбораПоСсылке), " И ", ""), "")+?(ЗначениеЗаполнено(пСтрУсловияОтбораПоСсылке), пСтрУсловияОтбораПоСсылке, "");
		Если лСтруктураТаблицы.ПроизвольныйЗапрос Тогда
			Если СтрНайти(пЗапрос.Текст, "&_ОтборПервичныйОсновнаяТаблица_") Тогда 
				пЗапрос.Текст=СтрЗаменить(пЗапрос.Текст, "&_ОтборОсновнаяТаблица_", "("+?(ЗначениеЗаполнено(пСтрУсловияОтбора), пСтрУсловияОтбора, "ИСТИНА")+")");
				пЗапрос.Текст=СтрЗаменить(пЗапрос.Текст, "&_ОтборПервичныйОсновнаяТаблица_", "("+?(ЗначениеЗаполнено(пСтрУсловияОтбораПоСсылке), пСтрУсловияОтбораПоСсылке, "ИСТИНА")+")");
			Иначе
				пЗапрос.Текст=СтрЗаменить(пЗапрос.Текст, "&_ОтборОсновнаяТаблица_", "("+лСтрУсловияОтбораОбщие+")");
			КонецЕсли; 
			
		Иначе
			пЗапрос.Текст=СтрЗаменить(пЗапрос.Текст, "&_ВставкаУсловия_", ?(ЗначениеЗаполнено(лСтрУсловияОтбораОбщие), лСтрУсловияОтбораОбщие, "ИСТИНА"));
		КонецЕсли;
		
	ИначеЕсли лСтруктураТаблицы.ПроизвольныйЗапрос Тогда 
		пЗапрос.Текст=СтрЗаменить(пЗапрос.Текст, "&_ОтборОсновнаяТаблица_", "ИСТИНА");
		пЗапрос.Текст=СтрЗаменить(пЗапрос.Текст, "&_ОтборПервичныйОсновнаяТаблица_", "ИСТИНА");
	КонецЕсли;
	пЗапрос.Текст=СтрЗаменить(пЗапрос.Текст, "&_ВставкаУсловия_", "ИСТИНА");
	
	Если пПодключение=Неопределено Тогда // только для 1с, для других драйверов должно вызываться в драйвере
		лМассивСобытия=ТсПлатформаОбщий.ПолучитьСвойство(лСтруктураТаблицы, "События.ПриПолучении");
		ВызватьМассивСобытий(лМассивСобытия, "ПриПолучении", Новый Структура("Запрос, Контекст, СоединениеКОМ", пЗапрос, пСтруктураКонтекст, пСоединениеКОМ), пМассивПараметры);
		
		лМассивСобытия=ТсПлатформаОбщий.ПолучитьСвойство(пСтруктураПКТ, "События.ПриПолучении");
		ВызватьМассивСобытий(лМассивСобытия, "ПриПолучении", Новый Структура("Запрос, Контекст, СоединениеКОМ", пЗапрос, пСтруктураКонтекст, пСоединениеКОМ), пМассивПараметры);
	КонецЕсли;
	Возврат Истина;
КонецФункции

Функция мПолучитьОписаниеТиповПримитивныеТипы(пСоединениеКОМ)
	лКвалификаторСтроки=НовыйОбъект1("КвалификаторыСтроки", пСоединениеКОМ, 500);
	лМассивТипы=НовыйОбъект0("Массив", пСоединениеКОМ);
	Для Каждого мКлючИЗначениеСтруктураПримитивныеТипы Из мПолучитьСтруктуруПримитивныеТипы(пСоединениеКОМ) Цикл
		Если мКлючИЗначениеСтруктураПримитивныеТипы.Ключ="ОписаниеТипов" Тогда Продолжить; КонецЕсли;
		Если мКлючИЗначениеСтруктураПримитивныеТипы.Ключ="ХранилищеЗначения" Тогда Продолжить; КонецЕсли;
		Если мКлючИЗначениеСтруктураПримитивныеТипы.Ключ="УникальныйИдентификатор" Тогда Продолжить; КонецЕсли;
		
		лМассивТипы.Добавить(мКлючИЗначениеСтруктураПримитивныеТипы.Значение);
	КонецЦикла;
	Возврат НовыйОбъект3("ОписаниеТипов", пСоединениеКОМ, лМассивТипы,, лКвалификаторСтроки);	
КонецФункции 

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

Функция мПолучитьПутьДоРеквизита(пСтруктураПКТ, пСтруктураПКР, пРеквизитИсточникИмяТч)
	Перем лСтруктураРеквизита;
	
	Если Не ЗначениеЗаполнено(пСтруктураПКР.РеквизитИсточникИмя) Тогда
		Если ЗначениеЗаполнено(пСтруктураПКР.ЗначениеЗаполнения) Тогда
			лТипЗначения=ТипЗнч(пСтруктураПКР.ЗначениеЗаполнения);
			Если лТипЗначения=Тип("Число") Тогда
				Возврат Формат(пСтруктураПКР.ЗначениеЗаполнения, "ЧГ=");
				
			ИначеЕсли лТипЗначения=Тип("Строка") Тогда
				Возврат """"+пСтруктураПКР.ЗначениеЗаполнения+""""; 
				
			ИначеЕсли лТипЗначения=Тип("Булево") Тогда
				Возврат Формат(пСтруктураПКР.ЗначениеЗаполнения, "БЛ=ЛОЖЬ; БИ=ИСТИНА"); 
			КонецЕсли;
			ВызватьИсключение "Тип значения заполнения: "+лТипЗначения+", не обрабатывается!";
		КонецЕсли;
		Возврат "Неопределено";
	КонецЕсли;
	
	лСтруктураРеквизиты=пСтруктураПКТ.ТаблицаИсточник.СтруктураРеквизиты;
	Если пРеквизитИсточникИмяТч<>Неопределено Тогда 
		лСтруктураРеквизиты=лСтруктураРеквизиты[пРеквизитИсточникИмяТч].СтруктураРеквизиты;
	КонецЕсли;
	
	лПуть="ИсходныеДанные."+пСтруктураПКР.РеквизитИсточникИмя;
	Если Не лСтруктураРеквизиты.Свойство(пСтруктураПКР.РеквизитИсточникИмя, лСтруктураРеквизита) Тогда 
		Возврат лПуть; // TODO: не понятно как такое может быть разобраться
	КонецЕсли;
	
	Если лСтруктураРеквизита.Типы.Количество()=0 Тогда Возврат лПуть; КонецЕсли;
	лТип=лСтруктураРеквизита.Типы[0].Тип;
	Если лТип="УникальныйИдентификатор" Тогда 
	    лПуть="ПРЕДСТАВЛЕНИЕ("+лПуть+")";
		
	ИначеЕсли лТип<>"ОписаниеТипов" Тогда // TODO: Доделать ! все оборачиваем это неправильно и долго, нужно анализировать! обязательно обернуть составной тип и используемые только в группах и элементах реквизиты
		лПуть="ЕСТЬNULL("+лПуть+", "+мПолучитьЗначениеПоУмолчаниюДляNULL(лСтруктураРеквизита)+")";
	КонецЕсли;
	Возврат лПуть;
КонецФункции 

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

#Область ПолучениеТаблицыВТТипыПоСтруктуреТаблицыИлиСтруктуреПКТ
Функция мТекстЗапросаДляВТТипыПоТипуИмениДобавить(пМассивТекстыЗапросов, пТипТаблицы, пИмяТаблицы, пМассивТипыОбработанные, пПервый)
	лТип=пТипТаблицы+"."+пИмяТаблицы;
	Если пМассивТипыОбработанные.Найти(лТип)<>Неопределено Тогда Возврат Ложь; КонецЕсли; 
	пМассивТипыОбработанные.Добавить(лТип);
	лТипЕдиничный=ТипЕдинственноеЧисло(пТипТаблицы)+"."+пИмяТаблицы;
	
	лТекстЗапроса=
	"ВЫБРАТЬ 
	|	ТИП("+лТипЕдиничный+")"+?(пПервый, " КАК Тип", "")+",
	|	"""+лТип+""""+?(пПервый, " КАК ТипСтрокой"+Символы.ПС+"ПОМЕСТИТЬ ВТТипы", "");
	пМассивТекстыЗапросов.Добавить(лТекстЗапроса);
	пПервый=Ложь;
	Возврат Истина;
КонецФункции 

Функция мСоздатьВТПоСоставнымТипамПоПКТОбработатьМассивПКР(пМассивПКР, пСтруктураРеквизиты, пМенеджерВременныхТаблиц, пМассивТекстыЗапросов, пМассивТипыОбработанные)
	Перем лМассивПКРТч;
	лПервый=пМассивТекстыЗапросов.Количество()=0;
	Для Каждого лСтруктураПКР Из пМассивПКР Цикл
		Если лСтруктураПКР.Свойство("ПравилаКонвертацииРеквизитов", лМассивПКРТч) Тогда 
			мСоздатьВТПоСоставнымТипамПоПКТОбработатьМассивПКР(лМассивПКРТч, пСтруктураРеквизиты[лСтруктураПКР.РеквизитИсточникИмя].СтруктураРеквизиты, пМенеджерВременныхТаблиц, пМассивТекстыЗапросов, пМассивТипыОбработанные);
			Продолжить;
		КонецЕсли;
		Если Не лСтруктураПКР.Составной Тогда Продолжить; КонецЕсли;
		Если ТипЗнч(лСтруктураПКР.КодПравила)=Тип("Массив") Тогда 
			Для Каждого лСтруктураКодПравила Из лСтруктураПКР.КодПравила Цикл
				мТекстЗапросаДляВТТипыПоТипуИмениДобавить(пМассивТекстыЗапросов, лСтруктураКодПравила.Источник.Тип, лСтруктураКодПравила.Источник.Имя, пМассивТипыОбработанные, лПервый);
			КонецЦикла;
			
		Иначе
			Для Каждого лСтруктураТип Из пСтруктураРеквизиты[лСтруктураПКР.РеквизитИсточникИмя].Типы Цикл
				Если Не ЗначениеЗаполнено(лСтруктураТип.ИмяТаблицы) Тогда Продолжить; КонецЕсли;
				мТекстЗапросаДляВТТипыПоТипуИмениДобавить(пМассивТекстыЗапросов, лСтруктураТип.ТипТаблицы, лСтруктураТип.ИмяТаблицы, пМассивТипыОбработанные, лПервый);
			КонецЦикла;
		КонецЕсли;
	КонецЦикла;
КонецФункции
	
Функция мСоздатьВТПоСоставнымТипамПоПКТ(пМассивПКТ, пМенеджерВременныхТаблиц)
	лМассивТекстыЗапросов=Новый Массив; 
	лМассивТипыОбработанные=Новый Массив; 
	Для Каждого лСтруктураПКТ Из пМассивПКТ Цикл
		мСоздатьВТПоСоставнымТипамПоПКТОбработатьМассивПКР(лСтруктураПКТ.ПравилаКонвертацииРеквизитов, лСтруктураПКТ.ТаблицаИсточник.СтруктураРеквизиты, пМенеджерВременныхТаблиц, лМассивТекстыЗапросов, лМассивТипыОбработанные);
	КонецЦикла;
	Если лМассивТекстыЗапросов.Количество()=0 Тогда Возврат Истина; КонецЕсли;
	лЗапрос=Новый Запрос;
	лЗапрос.МенеджерВременныхТаблиц=пМенеджерВременныхТаблиц;
	лЗапрос.Текст=СтрСоединить(лМассивТекстыЗапросов, Символы.ПС+Символы.ПС+"ОБЪЕДИНИТЬ ВСЕ "+Символы.ПС+Символы.ПС);
	лРезультат=лЗапрос.Выполнить(); // Для отладки: ТсПлатформаОбщий.ПолучитьВТ(лЗапрос)
КонецФункции 

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

Функция мСоздатьВТПоСоставнымТипамПоСтруктуреТаблицы(пСтруктураТаблицы, пМенеджерВременныхТаблиц)
	лМассивТекстыЗапросов=Новый Массив; 
	лМассивТипыОбработанные=Новый Массив; 
	мСоздатьВТПоСоставнымТипамПоСтруктуреТаблицыОбработатьМассивРеквизиты(пСтруктураТаблицы.Реквизиты, пМенеджерВременныхТаблиц, лМассивТекстыЗапросов, лМассивТипыОбработанные);
	Если лМассивТекстыЗапросов.Количество()=0 Тогда Возврат Истина; КонецЕсли;
	лЗапрос=Новый Запрос;
	лЗапрос.МенеджерВременныхТаблиц=пМенеджерВременныхТаблиц;
	лЗапрос.Текст=СтрСоединить(лМассивТекстыЗапросов, Символы.ПС+Символы.ПС+"ОБЪЕДИНИТЬ ВСЕ "+Символы.ПС+Символы.ПС);
	лРезультат=лЗапрос.Выполнить(); // Для отладки: ТсПлатформаОбщий.ПолучитьВТ(лЗапрос)
КонецФункции 
#КонецОбласти 

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

Функция мСтруктураПараметрыКонвертацииОбработатьСтрокуПравила(пЗапрос, пСтруктураПКТ, пСтруктураПКР, пМассивСтрРеквизиты, пМассивСтрСоединения, пЭтоСтандартныйДрайвер1с, пРеквизитИсточникИмяТч=Неопределено)
	Перем лТипИсточника;
	лПуть=мПолучитьПутьДоРеквизита(пСтруктураПКТ, пСтруктураПКР, пРеквизитИсточникИмяТч);
	Если пЭтоСтандартныйДрайвер1с Тогда 
		Если пСтруктураПКТ.ТаблицаИсточник.Тип="РегистрыНакопления" и пСтруктураПКР.РеквизитИсточникИмя="ВидДвижения" Тогда
			лПуть="ВЫБОР КОГДА "+лПуть+" = ЗНАЧЕНИЕ(ВидДвиженияНакопления.Приход) ТОГДА ИСТИНА ИНАЧЕ ЛОЖЬ КОНЕЦ";
		КонецЕсли;
		Если пСтруктураПКТ.ТаблицаИсточник.Тип="РегистрыБухгалтерии" Тогда
			Если пСтруктураПКР.Составной Тогда лПуть="ЕСТЬNULL("+лПуть+", НЕОПРЕДЕЛЕНО)"; КонецЕсли; // Составной путь в регистре возвращает NULL если не заполнен
			Если пСтруктураПКР.РеквизитИсточникИмя="ВидДвижения" Тогда
				лПуть="ВЫБОР КОГДА "+лПуть+" = ЗНАЧЕНИЕ(ВидДвиженияБухгалтерии.Дебет) ТОГДА ИСТИНА ИНАЧЕ ЛОЖЬ КОНЕЦ";
			КонецЕсли;
		КонецЕсли;
	КонецЕсли; 
	лИмяРеквизита=пСтруктураПКР.РеквизитПриемникИмя;
	Если Не ЗначениеЗаполнено(лИмяРеквизита) Тогда лИмяРеквизита=пСтруктураПКР.ИмяПараметра; КонецЕсли; 
	Если Не ЗначениеЗаполнено(лИмяРеквизита) Тогда лИмяРеквизита=пСтруктураПКР.РеквизитИсточникИмя; КонецЕсли; 
	пМассивСтрРеквизиты.Добавить("	"+лПуть+" КАК "+лИмяРеквизита);
	
	Если пЭтоСтандартныйДрайвер1с и пСтруктураПКР.Составной Тогда
		лИмяТаблицыДляСоединения="ВТТипы_"+Формат(пСтруктураПКР.Индекс, "ЧГ=");
		лСтрСоединение=
		"	ЛЕВОЕ СОЕДИНЕНИЕ ВТТипы КАК "+лИмяТаблицыДляСоединения+"
		|		ПО ТИПЗНАЧЕНИЯ(ИсходныеДанные."+пСтруктураПКР.РеквизитИсточникИмя+") = "+лИмяТаблицыДляСоединения+".Тип";
		
		пМассивСтрСоединения.Добавить(лСтрСоединение);
		пМассивСтрРеквизиты.Добавить("	ЕСТЬNULL("+лИмяТаблицыДляСоединения+".ТипСтрокой, НЕОПРЕДЕЛЕНО) КАК "+лИмяРеквизита+"__Тип__");
	КонецЕсли;
	
	Если ТипЗнч(пСтруктураПКР.КодПравила)=Тип("Массив") Тогда
		Если Не пЭтоСтандартныйДрайвер1с Тогда
			лПуть="ВЫБОР"+Символы.ПС;
			Для Каждого лСтруктураКодПравила Из пСтруктураПКР.КодПравила Цикл
				лИмяТаблицыИсточника=лСтруктураКодПравила.Источник.Тип+"."+лСтруктураКодПравила.Источник.Имя;
				лИмяТаблицыПриемника=лСтруктураКодПравила.Приемник.Тип+"."+лСтруктураКодПравила.Приемник.Имя;
				лСтрУсловие="ИсходныеДанные."+пСтруктураПКР.РеквизитИсточникИмя+"__Тип__ = """+лИмяТаблицыИсточника+"""";
				лПуть=лПуть+"		КОГДА "+лСтрУсловие+" ТОГДА """+лИмяТаблицыПриемника+""""+Символы.ПС;
			КонецЦикла;
			лПуть=лПуть+"		ИНАЧЕ """" КОНЕЦ";
			пМассивСтрРеквизиты.Добавить("	"+лПуть+" КАК "+лИмяРеквизита+"__Тип__");
		КонецЕсли;
		
		лПуть="ВЫБОР"+Символы.ПС;
		Для Каждого лСтруктураКодПравила Из пСтруктураПКР.КодПравила Цикл
			Если пЭтоСтандартныйДрайвер1с Тогда 
				лИмяТаблицыИсточника=ТипЕдинственноеЧисло(лСтруктураКодПравила.Источник.Тип)+"."+лСтруктураКодПравила.Источник.Имя;
				лИмяТаблицыПриемника=лСтруктураКодПравила.Приемник.Тип+"."+лСтруктураКодПравила.Приемник.Имя;
				лСтрУсловие="ИсходныеДанные."+пСтруктураПКР.РеквизитИсточникИмя+" ССЫЛКА "+лИмяТаблицыИсточника;
			Иначе
				лИмяТаблицыИсточника=лСтруктураКодПравила.Источник.Тип+"."+лСтруктураКодПравила.Источник.Имя;
				лИмяТаблицыПриемника=лСтруктураКодПравила.Приемник.Тип+"."+лСтруктураКодПравила.Приемник.Имя;
				лСтрУсловие="ИсходныеДанные."+пСтруктураПКР.РеквизитИсточникИмя+"__Тип__ = """+лИмяТаблицыИсточника+"""";
			КонецЕсли;
			лПуть=лПуть+"		КОГДА "+лСтрУсловие+" ТОГДА "+Формат(лСтруктураКодПравила.КодПравила, "ЧГ=")+Символы.ПС;
		КонецЦикла;
		лПуть=лПуть+"		ИНАЧЕ 0 КОНЕЦ";
		пМассивСтрРеквизиты.Добавить("	"+лПуть+" КАК "+лИмяРеквизита+"__КодПравила__");
	КонецЕсли;
	Возврат Истина;
КонецФункции

Функция мСтруктураПараметрыКонвертацииПолучитьТекстЗапросаТч(пЗапрос, пСтруктураПКТ, пСтруктураПравилаКонвертацииТч, пМассивСтруктурыПКРТч, пМассивСтруктурыТч, пЭтоСтандартныйДрайвер1с, пСтруктураКонтекст, пМассивПараметры, пСоединениеКОМ)
	лСтруктураТч=пСтруктураПКТ.ТаблицаИсточник.СтруктураРеквизиты[пСтруктураПравилаКонвертацииТч.РеквизитИсточникИмя];
	лСтруктураКлюча=мМассивНайтиВМассивеСтруктур(лСтруктураТч.Реквизиты, "ЭтоКлюч", Истина);
	Если лСтруктураКлюча=Неопределено Тогда 
		ВызватьИсключение "Для табличной части: "+пСтруктураПравилаКонвертацииТч.РеквизитИсточникИмя+", не определено ключевое поле!";
	КонецЕсли;
	
	лМассивСтрРеквизиты=Новый Массив; лМассивСтрСоединения=Новый Массив;
	лМассивСтрРеквизиты.Добавить("ИсходныеДанные."+лСтруктураКлюча.Имя+" КАК _КлючИсточника_");
	
	лМассивРеквизитыПоиска=Новый Массив;
	Для Каждого лСтруктураПКР Из пМассивСтруктурыПКРТч Цикл
		мСтруктураПараметрыКонвертацииОбработатьСтрокуПравила(пЗапрос, пСтруктураПКТ, лСтруктураПКР, лМассивСтрРеквизиты, лМассивСтрСоединения, пЭтоСтандартныйДрайвер1с, пСтруктураПравилаКонвертацииТч.РеквизитИсточникИмя);
		// TODO: Доделать поиск в тч
		//Если лСтруктураРеквизита.Поиск или лСтруктураРеквизита.ПравилоКонвертацииКлюча Тогда
		//	лМассивРеквизитыПоиска.Добавить(лСтруктураПКР.РеквизитПриемникИмя);
		//КонецЕсли;
	КонецЦикла;
	
	лИспользуютсяОтборыПоТч=пСтруктураПравилаКонвертацииТч.Свойство("Отбор");
	Если лИспользуютсяОтборыПоТч Тогда 
		мЗаписатьПараметрыЗапросаВЗапрос(пЗапрос, пСтруктураПравилаКонвертацииТч.Отбор.ПараметрыОтбора); //, пСтруктураКонтекст, пМассивПараметры, пСоединениеКОМ);
		лСтрУсловияОтбора=СтрЗаменить(пСтруктураПравилаКонвертацииТч.Отбор.Условие, "#ИсходныеДанные#.", "ИсходныеДанные.");
	КонецЕсли; 
	
	Если пСтруктураПКТ.ТаблицаИсточник.ПроизвольныйЗапрос Тогда 
		лСтрокаВременныеТаблицыТабличныхЧастей=мМассивНайтиВМассивеСтруктур(пСтруктураПКТ.ТаблицаИсточник.ВременныеТаблицыТабличныхЧастей, "ИмяТабличнойЧасти", пСтруктураПравилаКонвертацииТч.РеквизитИсточникИмя);
		Если лСтрокаВременныеТаблицыТабличныхЧастей=Неопределено Тогда 
			ВызватьИсключение "Таблица: "+пСтруктураПКТ.ТаблицаИсточник.Имя+", не нашли имя временной таблицы для табличной части: "+пСтруктураПравилаКонвертацииТч.РеквизитИсточникИмя;
		КонецЕсли;
		лИмяТаблицы=лСтрокаВременныеТаблицыТабличныхЧастей.ИмяВременнойТаблицы;
	Иначе
		лИмяТаблицы="%ИмяТаблицы%"+?(пЭтоСтандартныйДрайвер1с, ".", "")+пСтруктураПравилаКонвертацииТч.РеквизитИсточникИмя;
	КонецЕсли;
	
	пМассивСтруктурыТч.Добавить(Новый Структура("Индекс, РеквизитыПоиска", пСтруктураПравилаКонвертацииТч.Индекс, лМассивРеквизитыПоиска));
	лТекстЗапроса=
	";
	|
	|ВЫБРАТЬ
	|"+СтрСоединить(лМассивСтрРеквизиты, ","+Символы.ПС+Символы.Таб)+"
	|ПОМЕСТИТЬ %ИмяВТ%Тч"+Формат(пСтруктураПравилаКонвертацииТч.Индекс, "ЧГ=")+"
	|ИЗ
	|	"+лИмяТаблицы+" КАК ИсходныеДанные
	|"+СтрСоединить(лМассивСтрСоединения, Символы.ПС);
	Если Не пСтруктураПКТ.ТаблицаИсточник.ПроизвольныйЗапрос Тогда // Для произвольного запроса отбор делается ранее
		лТекстЗапроса=лТекстЗапроса+"
		|ГДЕ
		|	ИсходныеДанные."+лСтруктураКлюча.Имя+" В (ВЫБРАТЬ РАЗЛИЧНЫЕ ОсновнаяТаблица._КлючИсточника_ ИЗ %ИмяВТ% КАК ОсновнаяТаблица)"
		+?(лИспользуютсяОтборыПоТч, Символы.ПС+"	И "+лСтрУсловияОтбора, "");
	КонецЕсли; 
	Возврат лТекстЗапроса;
КонецФункции

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

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

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

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

Функция мТаблицаКонфигурацииВыполнитьЗапросВыгрузки(пДрайверПодключения, пПодключение, пЗапрос, пСтруктураПКТ, пСтруктураКонтекст, пМассивПараметры, пТаблицаИсточник, пСоединениеКОМ, пИмяКолонкиВТПоиска, пТзДанныеТаблиц, пИндексТч, пИмяВТПоиска, пИмяКолонкиСвязи, пНомерВыгрузки, пМассивСтруктурыТч, пСтрокаТзДанныеТаблиц=Неопределено, пТекстОшибки="")
	Для Каждого лКлючИЗначениеПараметрыЗапроса Из пСтруктураПКТ.ПараметрыЗапроса Цикл
		пЗапрос.УстановитьПараметр(лКлючИЗначениеПараметрыЗапроса.Ключ, лКлючИЗначениеПараметрыЗапроса.Значение);
	КонецЦикла;
	
	лСтруктураТаблицы=пСтруктураПКТ.ТаблицаИсточник;
	лСтрУсловияОтбора="";
	Если лСтруктураТаблицы.Свойство("Отбор") Тогда
		лСтрУсловияОтбора=лСтруктураТаблицы.Отбор.Условие;
		мЗаписатьПараметрыЗапросаВЗапрос(пЗапрос, лСтруктураТаблицы.Отбор.ПараметрыОтбора); //, пСтруктураКонтекст, пМассивПараметры, пСоединениеКОМ);
		Если Не лСтруктураТаблицы.ПроизвольныйЗапрос и лСтруктураТаблицы.Тип="РегистрыБухгалтерии" Тогда // Заплатка в другом месте будем делать
			лСтрУсловияОтбора="";
		Иначе
			лСтрУсловияОтбора=СтрЗаменить(лСтрУсловияОтбора, "#ИсходныеДанные#.", ?(лСтруктураТаблицы.ПроизвольныйЗапрос, "", "ИсходныеДанные."));
		КонецЕсли;
	КонецЕсли;
	лСтрУсловияОтбораПоСсылке="";
	Если Не пСтруктураПКТ.НеДелатьЗапросКИсточнику // это для отбора по требованию, только для стандартных
		и пСтруктураПКТ.Свойство("ОтборПоСсылкам") 
		и пИмяКолонкиВТПоиска=Неопределено // Если имя колонки поиска задано, то мы выгружаем по ссылкам, и следовательно отбор по ссылке (используется для правил выгрузки) делать не надо
	Тогда
		лИмяРеквизитаСсылки=?(пСтруктураПКТ.Свойство("ИмяРеквизитаРегистрации") и ЗначениеЗаполнено(пСтруктураПКТ.ИмяРеквизитаРегистрации), пСтруктураПКТ.ИмяРеквизитаРегистрации, лСтруктураТаблицы.ИмяРеквизитаПервичногоКлюча);
		Если Не ЗначениеЗаполнено(лИмяРеквизитаСсылки) Тогда 
			пТекстОшибки="В таблице: "+лСтруктураТаблицы.Тип+"."+лСтруктураТаблицы.Имя+" не задан первичный ключ и не задано имя реквизита регистрации!";
			Возврат Ложь;
		КонецЕсли;
		лСтрУсловияОтбораПоСсылке=?((лСтруктураТаблицы.Тип="РегистрыНакопления" или лСтруктураТаблицы.Тип="РегистрыБухгалтерии") и Не лСтруктураТаблицы.ПроизвольныйЗапрос, "", "ИсходныеДанные.") // Для регистра накопления отбор по ссылке должен стоять в виртуальной таблице, поэтому имя таблицы не надо
			+лИмяРеквизитаСсылки+" В (&ОтборПоСсылкам)";
		пЗапрос.УстановитьПараметр("ОтборПоСсылкам", пСтруктураПКТ.ОтборПоСсылкам);
	КонецЕсли;
	
	пСтрокаТзДанныеТаблиц=?(пТзДанныеТаблиц=Неопределено, Неопределено, пТзДанныеТаблиц.Найти(пСтруктураПКТ.КодПравила, "КодПравила"));
	Если пСтрокаТзДанныеТаблиц<>Неопределено Тогда лИмяВТПредыдущая=пСтрокаТзДанныеТаблиц.ИмяВТ; КонецЕсли; 
	
	пМассивСтруктурыТч=Новый Массив;
	мСтруктураПараметрыКонвертацииУстановитьТекстЗапроса(пЗапрос, пСтруктураПКТ, пСтруктураКонтекст, пМассивПараметры, пСоединениеКОМ, пМассивСтруктурыТч, пПодключение=Неопределено); // пЭтоЗапросТаблицыИсточника, 
	
	лИмяВТНовыеДанные=Неопределено;
	Если пСтруктураПКТ.ТолькоПоиск или ЗначениеЗаполнено(пИмяКолонкиВТПоиска) Тогда
		лИмяВТНовыеДанные="ВТДанные"+Формат(пНомерВыгрузки, "ЧЦ=10; ЧВН=; ЧГ=")+"_"+Формат(пСтруктураПКТ.КодПравила, "ЧГ=")+пИмяКолонкиВТПоиска;
		
		лИмяКлючаИсточника=?(пИмяКолонкиСвязи=Неопределено, лСтруктураТаблицы.ИмяРеквизитаПервичногоКлюча, пИмяКолонкиСвязи);
		пЗапрос.Текст=СтрЗаменить(пЗапрос.Текст, "%ИмяВТ%", лИмяВТНовыеДанные);
		Если пИмяКолонкиСвязи=Неопределено Тогда // Для связанных правил нужен отбор!
			лСтрУсловияОтбора=""; // нам не нужно делать отбор по таблицам так как мы выгружаем только по ссылкам!
			
			Если лСтруктураТаблицы.Свойство("ОтборПриВызовеИзДругихПравил") Тогда
				лСтрУсловияОтбора=лСтруктураТаблицы.ОтборПриВызовеИзДругихПравил.Условие;
				мЗаписатьПараметрыЗапросаВЗапрос(пЗапрос, лСтруктураТаблицы.ОтборПриВызовеИзДругихПравил.ПараметрыОтбора); //, пСтруктураКонтекст, пМассивПараметры, пСоединениеКОМ);
				Если Не лСтруктураТаблицы.ПроизвольныйЗапрос И лСтруктураТаблицы.Тип="РегистрыБухгалтерии" Тогда // Заплатка в другом месте будем делать
					лСтрУсловияОтбора="";
				Иначе
					лСтрУсловияОтбора=СтрЗаменить(лСтрУсловияОтбора, "#ИсходныеДанные#.", ?(лСтруктураТаблицы.ПроизвольныйЗапрос, "", "ИсходныеДанные."));
				КонецЕсли;
			КонецЕсли;
		КонецЕсли;
		лСтрУсловияОтбораПоСсылке=?(ЗначениеЗаполнено(лСтрУсловияОтбораПоСсылке), лСтрУсловияОтбораПоСсылке+" И ", "")
			+?((лСтруктураТаблицы.Тип="РегистрыНакопления" или лСтруктураТаблицы.Тип="РегистрыБухгалтерии") и Не лСтруктураТаблицы.ПроизвольныйЗапрос, "", "ИсходныеДанные.") // Для регистра накопления отбор по ссылке должен стоять в виртуальной таблице, поэтому имя таблицы не надо
			+лИмяКлючаИсточника+" В (%ТекстЗапросаПоиска%)";
		
		лТекстЗапросаПоиска= // "+?(пСтрокаТзДанныеТаблиц<>Неопределено, "", " //_ПЕРВЫЕ_")+" вроде не нужно, так как не первичная выборка
		"ВЫБРАТЬ
		|	ИсходныеДанные."+пИмяКолонкиВТПоиска+" КАК Значение
		|ИЗ
		|	"+пИмяВТПоиска+?(пИндексТч<>Неопределено, "Тч"+пИндексТч, "")+" КАК ИсходныеДанные";
		лТекстОтбораДляНевхожденияПредыдущихДанных=""; // только для связанных таблиц
		
		Если пСтрокаТзДанныеТаблиц<>Неопределено Тогда // Объединим с предыдущей выгрузкой
			// К примеру у регистра нет такой возможности, будем пока все выгружать, по идее тоже надо по ключам проверить
			// TODO: поправить, вместо первичного ключа в случаях когда его нет использовать ключевые поля
			Если ЗначениеЗаполнено(лСтруктураТаблицы.ИмяРеквизитаПервичногоКлюча) Тогда 
				лТекстОтбораДляНевхожденияПредыдущихДанных=
				"НЕ ИсходныеДанные."+лСтруктураТаблицы.ИмяРеквизитаПервичногоКлюча+" В (
				|		ВЫБРАТЬ
				|			ДанныеПредыдущие._КлючИсточника_ КАК Значение
				|		ИЗ
				|			"+пСтрокаТзДанныеТаблиц.ИмяВТСсылки+" КАК ДанныеПредыдущие)";
			КонецЕсли;
		КонецЕсли;
		
		Если пСтруктураПКТ.НеДелатьЗапросКИсточнику и пТаблицаИсточник<>Неопределено Тогда // Добавим отбор по типу для составных полей при выгрузке по ссылке
			лТекстЗапросаПоиска=лТекстЗапросаПоиска+Символы.ПС+"ГДЕ"+Символы.ПС+"	ИсходныеДанные."+пИмяКолонкиВТПоиска+"__Тип__ = """+пТаблицаИсточник.Тип+"."+пТаблицаИсточник.Имя+"""";
		КонецЕсли;
		
		лСтрУсловияОтбораПоСсылке=СтрЗаменить(лСтрУсловияОтбораПоСсылке, "%ТекстЗапросаПоиска%", лТекстЗапросаПоиска);
		Если ЗначениеЗаполнено(лТекстОтбораДляНевхожденияПредыдущихДанных) Тогда
			лСтрУсловияОтбораПоСсылке=?(ЗначениеЗаполнено(лСтрУсловияОтбораПоСсылке), лСтрУсловияОтбораПоСсылке+Символы.ПС+"	И ", "")+лТекстОтбораДляНевхожденияПредыдущихДанных;
		КонецЕсли;
		пЗапрос.Текст=СтрЗаменить(пЗапрос.Текст, "%ТекстЗапросаПоиска%", лТекстЗапросаПоиска);
		
	Иначе
		лИмяВТНовыеДанные="ВТДанные"+Формат(пНомерВыгрузки, "ЧГ=")+"_"+Формат(пСтруктураПКТ.КодПравила, "ЧГ=");
		пЗапрос.Текст=СтрЗаменить(пЗапрос.Текст, "%ИмяВТ%", лИмяВТНовыеДанные);
		
		Если пСтрокаТзДанныеТаблиц<>Неопределено Тогда
			Если ЗначениеЗаполнено(лСтруктураТаблицы.ИмяРеквизитаПервичногоКлюча) Тогда // TODO: тут в целом надо сделать очень редкий случай когда мы выгружаем для регистра отдельно и нужно выгрузить по тому же правилу и не выгружать лишнее
				лСтрУсловияОтбора=?(ЗначениеЗаполнено(лСтрУсловияОтбора), "("+лСтрУсловияОтбора+") И ", "")
					+"(НЕ ИсходныеДанные."+лСтруктураТаблицы.ИмяРеквизитаПервичногоКлюча
					+" В (ВЫБРАТЬ _ИсходныеДанные_._КлючИсточника_ КАК Значение ИЗ "+пСтрокаТзДанныеТаблиц.ИмяВТСсылки+" КАК _ИсходныеДанные_))";
			КонецЕсли;
		КонецЕсли;
	КонецЕсли;
	
	Если Не пСтруктураПКТ.НеДелатьЗапросКИсточнику Тогда 
		Если Не мЗаполнитьИсточникДанныхЗапросаВыгрузкиПоПодключению(пДрайверПодключения, пПодключение, пСтруктураПКТ, пЗапрос, пСтруктураКонтекст, пМассивПараметры, лСтрУсловияОтбора, лСтрУсловияОтбораПоСсылке, пСоединениеКОМ, пТекстОшибки) Тогда Возврат Ложь; КонецЕсли; // пЭтоЗапросТаблицыИсточника, 
	КонецЕсли;
	пЗапрос.Текст=СтрЗаменить(пЗапрос.Текст, "&_ВставкаУсловия_", ?(ЗначениеЗаполнено(лСтрУсловияОтбора), лСтрУсловияОтбора, "ИСТИНА")); // Нужно ли???
	
	Попытка	// Чтобы было понятно на каком запросе отвалилось
		лРезультатЗапроса=пЗапрос.Выполнить(); // Для отладки: ТсПлатформаОбщий.ПолучитьВТ(пЗапрос)
		Если лРезультатЗапроса<>Неопределено Тогда // Если в конце УНИЧТОЖИТЬ, то количество получить нельзя
			лВыборка=лРезультатЗапроса.Выбрать();
			лКоличество=?(лВыборка.Следующий(), лВыборка.Количество, 0);
			лМаксимальныйРазмерВыборки=ТсПлатформаОбщий.КонстантаПолучить("ТсОбменМаксимальныйРазмерЗапросаВыборки");
			Если ЗначениеЗаполнено(лМаксимальныйРазмерВыборки) и лКоличество>лМаксимальныйРазмерВыборки Тогда
				пТекстОшибки="При выгрузке по правилу: "+пСтруктураПКТ.НаименованиеПравила+", размер выборки: "+лКоличество+", превысил максимальную заданную: "+лМаксимальныйРазмерВыборки;
				Возврат Ложь;
			КонецЕсли;
		КонецЕсли;
		
	Исключение
		лИнформацияОбОшибке=ИнформацияОбОшибке();
		пТекстОшибки="При выгрузке по правилу: "+пСтруктураПКТ.НаименованиеПравила+", возникла ошибка: "+Символы.ПС+ТсПлатформаОбщий.ПолучитьПолноеОписаниеОшибки(лИнформацияОбОшибке);
		Возврат Ложь;
	КонецПопытки;
	
	Если пЗапрос.МенеджерВременныхТаблиц.Таблицы.Получить(лИмяВТНовыеДанные).ПолучитьДанные().Пустой() Тогда 
		пЗапрос.Текст="УНИЧТОЖИТЬ "+лИмяВТНовыеДанные;
		пЗапрос.Выполнить();
		Возврат Истина;
	КонецЕсли;
	
	Возврат лИмяВТНовыеДанные;
КонецФункции

//	Нужна для того чтобы иметь список всех текущих выгруженных ссылок
Функция мВыгрузкаДанныхЗаписатьКлючиВВТСсылки(пМенеджерВременныхТаблиц, пСтрокаТзДанныеТаблиц, пИмяВТ, пНомерВыгрузки)
	Если Не пСтрокаТзДанныеТаблиц.ПравилоКонвертацииТаблицы.ИспользуетсяДляПоиска Тогда Возврат Ложь; КонецЕсли;
	
	лИмяВТНовая="ВТКлючи"+Формат(пНомерВыгрузки, "ЧГ=")+пСтрокаТзДанныеТаблиц.ПравилоКонвертацииТаблицы.ТаблицаИсточник.Имя;
	лЗапрос=Новый Запрос;
	лЗапрос.МенеджерВременныхТаблиц=пМенеджерВременныхТаблиц; // Для отладки: ТсПлатформаОбщий.ПолучитьВТ(пМенеджерВременныхТаблиц)
	лЗапрос.Текст=
	"ВЫБРАТЬ 
	|	_ИсходныеДанные_._КлючИсточника_ КАК _КлючИсточника_
	|ПОМЕСТИТЬ "+лИмяВТНовая+"
	|ИЗ 
	|	"+пИмяВТ+" КАК _ИсходныеДанные_";
	Если ЗначениеЗаполнено(пСтрокаТзДанныеТаблиц.ИмяВТСсылки) Тогда
		лЗапрос.Текст=лЗапрос.Текст+"
		|
		|ОБЪЕДИНИТЬ ВСЕ
		|
		|ВЫБРАТЬ 
		|	_ИсходныеДанные_._КлючИсточника_
		|ИЗ 
		|	"+пСтрокаТзДанныеТаблиц.ИмяВТСсылки+" КАК _ИсходныеДанные_;
		|
		|УНИЧТОЖИТЬ "+пСтрокаТзДанныеТаблиц.ИмяВТСсылки;
	КонецЕсли;
	лЗапрос.Выполнить();
	пСтрокаТзДанныеТаблиц.ИмяВТСсылки=лИмяВТНовая;
КонецФункции

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

Функция мСоздатьВременныеТаблицыЗаменыЗначенийДляСтроки(пСоединениеКОМ, пЗапрос, пИнд, пСтруктураПКР, пСтруктураПКТ);
	пСтруктураПКР.Вставить("ИмяВТЗамены", "ВТЗамена"+Формат(пСтруктураПКТ.КодПравила, "ЧГ=")+"_"+пИнд);
	лИмяПараметраТз="ТзЗамены"+пИнд;
	
	лСтруктураТаблицы=Неопределено;
	//лМенеджерТаблицы=мПравилоЗаменыПолучитьМенеджерТаблицыПриемника(пСтруктураПКТ, пСтруктураПКР, лСтруктураТаблицы, пСоединениеКОМ);
	пЗапрос.УстановитьПараметр(лИмяПараметраТз, мПолучитьТзЗаменыПоМассивуЗаменЗначений(пСтруктураПКР.ПравилаЗамены, лСтруктураТаблицы, пСоединениеКОМ));
	пЗапрос.Текст=
	"ВЫБРАТЬ
	|	ИсходныеДанные.ЗначениеСтарое КАК ЗначениеСтарое,
	|	ИсходныеДанные.ЗначениеНовое КАК ЗначениеНовое
	|ПОМЕСТИТЬ "+пСтруктураПКР.ИмяВТЗамены+"
	|ИЗ
	|	&"+лИмяПараметраТз+" КАК ИсходныеДанные";
	пЗапрос.Выполнить(); // Для отладки: ТсПлатформаОбщий.ПолучитьВТ(пЗапрос)
КонецФункции 

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

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

Функция мСоответствиеЗначенияПеречисленийДобавитьЗначения(пСоответствиеЗначенияПеречислений, пИмяПеречисления)
	// TODO: тут сделать оптимизацию чтобы несколько раз одно и тоже перечисление не добавлять
	лМенеджерПеречисления=Перечисления[пИмяПеречисления];
	пСоответствиеЗначенияПеречислений.Вставить(лМенеджерПеречисления.ПустаяСсылка(), "");
	лМетаПеречисление=Метаданные.Перечисления[пИмяПеречисления]; 
	Для Каждого лМетаЗначение Из лМетаПеречисление.ЗначенияПеречисления Цикл
		пСоответствиеЗначенияПеречислений.Вставить(лМенеджерПеречисления[лМетаЗначение.Имя], лМетаЗначение.Имя);
	КонецЦикла;
КонецФункции 

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

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

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

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

Функция ТзДанныеТаблицЗаменитьСсылки1СНаУИД(пТзДанныеТаблиц, пСоответствиеКодПравила2СтруктураПКТ, пСоединениеКОМ, пМенеджерВременныхТаблиц) Экспорт
	лЗапрос=НовыйОбъект0("Запрос", пСоединениеКОМ);
	лЗапрос.МенеджерВременныхТаблиц=пМенеджерВременныхТаблиц;
	лМассивКодыПравилИспользуемыхВСвязанных=мМассивКодыПравилИспользуемыхВСвязанныхПолучить(пСоответствиеКодПравила2СтруктураПКТ);
	
	лСоответствиеЗначенияПеречислений=Новый Соответствие;
	лМассивТекстыЗапросов=Новый Массив;
	Для Каждого лСтрокаТзДанныеТаблиц Из пТзДанныеТаблиц Цикл // !!!! что то делать с тем что ссылка и ключисточника повторяются, плюс первичные ключи выгружаемых по ссылкам не надо
		лСтруктураПКТ=пСоответствиеКодПравила2СтруктураПКТ.Получить(лСтрокаТзДанныеТаблиц.КодПравила);
		
		лДобавитьПервичныйКлюч=(Не лСтруктураПКТ.ТолькоПоиск или лМассивКодыПравилИспользуемыхВСвязанных.Найти(лСтрокаТзДанныеТаблиц.КодПравила)<>Неопределено) и ЗначениеЗаполнено(лСтрокаТзДанныеТаблиц.ПравилоКонвертацииТаблицы.ТаблицаИсточник.ИмяРеквизитаПервичногоКлюча);
		лПервичныйКлюч=?(лДобавитьПервичныйКлюч, лСтрокаТзДанныеТаблиц.ПравилоКонвертацииТаблицы.ТаблицаИсточник.ИмяРеквизитаПервичногоКлюча, "");
		// замена лСтруктураПКТ.ИспользуетсяДляПоиска >> ЗначениеЗаполнено(лСтрокаТзДанныеТаблиц.ПравилоКонвертацииТаблицы.ТаблицаИсточник.ИмяРеквизитаПервичногоКлюча), нужно для пакетов
		// !!! и Не лСтруктураПКТ.ТолькоПоиск, не надо может быть ситуация когда первичный ключ не участвует в правилах конвертации реквизитов
		// !!!!!!! не понятно зачем убирали, потому как если только поиск, то данный ключ будет участвовать как первичный в исходной таблице!!!
		
		мДобавитьЗапросПолученияСсылокПоПравилуКонвертацииРеквизитов(лМассивТекстыЗапросов, лСтрокаТзДанныеТаблиц.ПравилоКонвертацииТаблицы.ПравилаКонвертацииРеквизитов, лСтрокаТзДанныеТаблиц.ПравилоКонвертацииТаблицы.ТаблицаИсточник.Реквизиты, лПервичныйКлюч, лСтрокаТзДанныеТаблиц.ИмяВТ,, лСоответствиеЗначенияПеречислений);
	КонецЦикла;
	Если лМассивТекстыЗапросов.Количество()=0 Тогда Возврат Истина; КонецЕсли;
	
	лЗапрос.Текст=СтрСоединить(лМассивТекстыЗапросов, Символы.ПС+Символы.ПС+"ОБЪЕДИНИТЬ ВСЕ"+Символы.ПС+Символы.ПС)+";
	|
	|////////////////////////////////////////////////////////////////////////////////
	|ВЫБРАТЬ РАЗЛИЧНЫЕ
	|	ИсходныеДанные.Ссылка КАК Ссылка,
	|	ВЫБОР
	|		КОГДА ТИПЗНАЧЕНИЯ(ИсходныеДанные.Ссылка) = ТИП(СТРОКА)
	|			ИЛИ ТИПЗНАЧЕНИЯ(ИсходныеДанные.Ссылка) = ТИП(ЧИСЛО)
	|			ИЛИ ТИПЗНАЧЕНИЯ(ИсходныеДанные.Ссылка) = ТИП(ДАТА)
	|			ИЛИ ТИПЗНАЧЕНИЯ(ИсходныеДанные.Ссылка) = ТИП(БУЛЕВО)
	|		ТОГДА ИСТИНА
	|		ИНАЧЕ ЛОЖЬ
	|	КОНЕЦ КАК ЭтоПростойТип
	|ИЗ
	|	ВТВсеСсылки КАК ИсходныеДанные
	|ГДЕ
	|	НЕ ИсходныеДанные.Ссылка ЕСТЬ NULL";
	
	лТзКлючи=лЗапрос.Выполнить().Выгрузить(); // Для отладки: ТсПлатформаОбщий.ПолучитьВТ(лЗапрос)
	Если лТзКлючи.Найти(NULL, "Ссылка")<>Неопределено Тогда
		ВызватьИсключение "Одно из ссылочных полей содержит тип NULL, нужно обернуть все ссылочные поля в запросе которые могут содерать тип NULL в конструкцию ЕСТЬNULL";
	КонецЕсли;
	
	лСтруктураПримитивныеТипы=мПолучитьСтруктуруПримитивныеТипы(пСоединениеКОМ);
	лОписаниеТипов=лТзКлючи.Колонки.Ссылка.ТипЗначения;
	Если Не лОписаниеТипов.СодержитТип(лСтруктураПримитивныеТипы.Строка)
		или (лОписаниеТипов.КвалификаторыСтроки.Длина<>0 и лОписаниеТипов.КвалификаторыСтроки.Длина<80)
	Тогда // если типа строка 80 нет, то его надо добавить, 80 в них помещается ссылка 36 и это максимальная длина имени перечисления
		лКвалификаторСтроки=НовыйОбъект1("КвалификаторыСтроки", пСоединениеКОМ, 80);
		лОписаниеТипов=НовыйОбъект5("ОписаниеТипов", пСоединениеКОМ, лОписаниеТипов, "Строка",,, лКвалификаторСтроки);
	КонецЕсли;
	лТзКлючи.Колонки.Добавить("УИД", лОписаниеТипов);
	
	Для Каждого лСтрокаТзКлючи Из лТзКлючи Цикл
		Если лСтрокаТзКлючи.Ссылка=Неопределено Тогда // Если составной тип и тип не выбрано то будет Неопределено
			лСтрокаТзКлючи.УИД="00000000-0000-0000-0000-000000000000"; 
		ИначеЕсли лСтрокаТзКлючи.ЭтоПростойТип Тогда // нужно в случае если мы уже правилами замены заменили ссылки, или есть значения простых типов в этой колонке
			лСтрокаТзКлючи.УИД=лСтрокаТзКлючи.Ссылка;
		Иначе
			лСтрокаТзКлючи.УИД=мПолучитьУИД(лСтрокаТзКлючи.Ссылка, пСоединениеКОМ, лСоответствиеЗначенияПеречислений);
		КонецЕсли;
	КонецЦикла;
	
	//	Поместим соответствие ключей во временную таблицу
	лЗапрос.УстановитьПараметр("ТзКлючи", лТзКлючи);
	лЗапрос.Текст=
	"ВЫБРАТЬ
	|	ИсходныеДанные.Ссылка КАК Ссылка,
	|	ИсходныеДанные.УИД КАК УИД
	|ПОМЕСТИТЬ ВТВсеСсылкиСУИД
	|ИЗ
	|	&ТзКлючи КАК ИсходныеДанные"; // TODO: нужно индексировать таблицу ВТВсеСсылкиСУИД!!!
	лЗапрос.Выполнить(); // Для отладки: ТсПлатформаОбщий.ПолучитьВТ(лЗапрос)
	
	Для Каждого лСтрокаТзДанныеТаблиц Из пТзДанныеТаблиц Цикл
		лСтруктураПКТ=пСоответствиеКодПравила2СтруктураПКТ.Получить(лСтрокаТзДанныеТаблиц.КодПравила);
		лМассивРеквизиты=мПолучитьМассивРеквизитыВключаяПервичныйКлюч(лСтруктураПКТ);
		
		лИмяВТЗамененныеСсылки="ВТЗамененныеСсылки"+Формат(лСтрокаТзДанныеТаблиц.КодПравила, "ЧГ=")+"_"+Формат(лСтрокаТзДанныеТаблиц.Порядок, "ЧГ=");
		
		лМассивТекстыЗапросов=Новый Массив; // Не нужно соединять тексты для всех правил конвертации, иначе может вылететь из за очень большого запроса
		мТзДанныеТаблицЗаменитьСсылки1СНаУИДДобавитьЗапросЗаменыСсылокНаУИД(лМассивТекстыЗапросов, лМассивРеквизиты, лИмяВТЗамененныеСсылки, лСтрокаТзДанныеТаблиц.ИмяВТ);
		лЗапрос.Текст=СтрСоединить(лМассивТекстыЗапросов, Символы.ПС+";"+Символы.ПС+Символы.ПС);
		лЗапрос.Выполнить(); // Для отладки: ТсПлатформаОбщий.ПолучитьВТ(лЗапрос)
		
		лСтрокаТзДанныеТаблиц.ИмяВТ=лИмяВТЗамененныеСсылки;
	КонецЦикла;
	лЗапрос.Текст="УНИЧТОЖИТЬ ВТВсеСсылки; УНИЧТОЖИТЬ ВТВсеСсылкиСУИД";
	лЗапрос.Выполнить();
КонецФункции

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

Функция ПакетОбменаПолучитьСтруктуру(пПакет) Экспорт
	Возврат Новый Структура("Ссылка, Код, Дата", ""+пПакет.УникальныйИдентификатор(), пПакет.Код, пПакет.Дата);
КонецФункции

Функция мПолучитьКлючИсточника(пСтрокаДанныеТзДанныеТаблиц)
	// так делаем потому что сложно проверить есть в таблице ключ источника или нет
	Попытка	Возврат пСтрокаДанныеТзДанныеТаблиц._КлючИсточника_; Исключение КонецПопытки;
	Попытка	Возврат пСтрокаДанныеТзДанныеТаблиц.Регистратор; Исключение КонецПопытки;
КонецФункции

Функция мСжатиеДанныхДляХраненияПакетов()
	Возврат Новый СжатиеДанных(9); 
КонецФункции 

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

Функция мКонвертироватьЗначенияДляJSON(пЗначение, пСоединениеКОМ)
	Попытка	
		лТип=XMLТипЗнч(пЗначение); // TODO: возможно тут нужно через пСоединениеКОМ
		Если СтрНачинаетсяС(лТип.ИмяТипа, "EnumRef.") Тогда
			Возврат ТсПлатформаОбщий.ПеречислениеИмя(пЗначение, пСоединениеКОМ);
		КонецЕсли;
	Исключение
	КонецПопытки; 
	Возврат ""+пЗначение.УникальныйИдентификатор();
КонецФункции

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

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

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

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

Функция мТаблицаНетДанных(пТаблицаКонфигурации, пДрайверПодключения)
	Если пДрайверПодключения<>Неопределено Тогда Возврат Ложь; КонецЕсли; // только для 1с оптимизация
	Если пТаблицаКонфигурации.ПроизвольныйЗапрос Тогда Возврат Ложь; КонецЕсли; 
	
	лЗапрос=Новый Запрос;
	лЗапрос.Текст="ВЫБРАТЬ ПЕРВЫЕ 1 * ИЗ "+ПолучитьИмяТаблицы1с(пТаблицаКонфигурации)+" КАК _Данные_";
	Возврат лЗапрос.Выполнить().Пустой();
КонецФункции

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

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

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

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

Функция мОбработатьПараметрыЗапросаВЗапрос(пПараметрыОтбора, пСтруктураКонтекст, пМассивПараметры, пСоединениеКОМ)
	МассивПараметрыПреобразоватьПараметрыТипаДата(пПараметрыОтбора);
	ПараметрыОтбораВычислитьЗначения(пПараметрыОтбора, пСтруктураКонтекст, пМассивПараметры);
	мПараметрыОтбораЗаменитьМассивыНаМассивыКОМ(пПараметрыОтбора, пСоединениеКОМ);
	мПараметрыОтбораПреобразоватьГуидыВСсылки(пПараметрыОтбора, пСоединениеКОМ);
КонецФункции

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

Функция мМассивСсылкиВМассивУИД(пМассивСсылки)
	лМассивУИД=Новый Массив; 
	Для Каждого лСсылка Из пМассивСсылки Цикл
		лМассивУИД.Добавить(""+лСсылка.УникальныйИдентификатор());
	КонецЦикла; 
	Возврат лМассивУИД;
КонецФункции

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

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

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

#Область ЗагрузкаДанных
Функция мМассивСоздатьПоЗначениям1(пЭлемент1)
	лМассив=Новый Массив;
	лМассив.Добавить(пЭлемент1);
	Возврат лМассив;
КонецФункции

Функция мМассивСоздатьПоЗначениям3(пЭлемент1, пЭлемент2, пЭлемент3)
	лМассив=Новый Массив;
	лМассив.Добавить(пЭлемент1);
	лМассив.Добавить(пЭлемент2);
	лМассив.Добавить(пЭлемент3);
	Возврат лМассив;
КонецФункции

Функция мПолучитьТзИзМассивСтруктур(пМассивДанные, пСоединениеКОМ=Неопределено, пТолькоПримитивныеТипы=Истина, пСтруктураПКТ=Неопределено, пМассивСтруктурыПКР=Неопределено)
	лТзРезультат=НовыйОбъект0("ТаблицаЗначений", пСоединениеКОМ);
	лТзРезультат.Колонки.Добавить("_Номер_", мОписаниеТипаЧисло(пСоединениеКОМ, 10,, "Неотрицательный"));
	Если пТолькоПримитивныеТипы Тогда
		лСтруктураПримитивныеТипы=мПолучитьСтруктуруПримитивныеТипы(пСоединениеКОМ);
		лМассивТипы=НовыйОбъект0("Массив", пСоединениеКОМ);
		лМассивТипы.Добавить(лСтруктураПримитивныеТипы.Булево);
		лМассивТипы.Добавить(лСтруктураПримитивныеТипы.Дата);
		лМассивТипы.Добавить(лСтруктураПримитивныеТипы.Число);
		лМассивТипы.Добавить(лСтруктураПримитивныеТипы.Строка);
		
		лКвалификаторСтроки=НовыйОбъект1("КвалификаторыСтроки", пСоединениеКОМ, 500);
		лОписаниеТипа=НовыйОбъект3("ОписаниеТипов", пСоединениеКОМ, лМассивТипы,, лКвалификаторСтроки);
		лОписаниеТипаБулево=НовыйОбъект1("ОписаниеТипов", пСоединениеКОМ, "Булево");
		лОписаниеТипаСтрокаНеограниченная=НовыйОбъект1("ОписаниеТипов", пСоединениеКОМ, "Строка");
	Иначе
		лОписаниеТипаКолонки=Новый ОписаниеТипов;
	КонецЕсли;
	
	Если пСтруктураПКТ<>Неопределено Тогда 
		Если ЗначениеЗаполнено(пСтруктураПКТ.ТаблицаИсточник.ИмяРеквизитаПервичногоКлюча) Тогда 
			лСтруктураРеквизитСсылка=мМассивНайтиВМассивеСтруктур(пСтруктураПКТ.ТаблицаИсточник.Реквизиты, "Имя", пСтруктураПКТ.ТаблицаИсточник.ИмяРеквизитаПервичногоКлюча);
			лСтрокаТипы=лСтруктураРеквизитСсылка.Типы[0]; // Тип не может быть не заполнен и не может быть составным
			лОписаниеТипаСсылки=Новый ОписаниеТипов(лСтрокаТипы.Тип, Новый КвалификаторыЧисла(лСтрокаТипы.Длина, лСтрокаТипы.Точность), Новый КвалификаторыСтроки(лСтрокаТипы.Длина)); 
		КонецЕсли;
		
		Если ЗначениеЗаполнено(пСтруктураПКТ.ТаблицаПриемник.ИмяРеквизитаПервичногоКлюча) Тогда 
			лСтруктураРеквизитСсылкаПриемник=мМассивНайтиВМассивеСтруктур(пСтруктураПКТ.ТаблицаПриемник.Реквизиты, "Имя", пСтруктураПКТ.ТаблицаПриемник.ИмяРеквизитаПервичногоКлюча);
			лСтрокаТипыПриемник=лСтруктураРеквизитСсылкаПриемник.Типы[0]; // Тип не может быть не заполнен и не может быть составным
			лОписаниеТипаСсылкиПриемник=Новый ОписаниеТипов(лСтрокаТипыПриемник.Тип, Новый КвалификаторыЧисла(лСтрокаТипыПриемник.Длина, лСтрокаТипыПриемник.Точность), Новый КвалификаторыСтроки(лСтрокаТипыПриемник.Длина)); 
		КонецЕсли;
	КонецЕсли; 
	
	Если пМассивДанные.Количество()=0 Тогда Возврат лТзРезультат; КонецЕсли;
	Для Каждого лСтруктураДанныеКлючИЗначение Из пМассивДанные[0] Цикл
		лТип=ТипЗнч(лСтруктураДанныеКлючИЗначение.Значение);
		#Если Не МобильноеПриложениеСервер Тогда
			Если лТип=Тип("COMОбъект") Тогда ВызватьИсключение "Неожиданный тип: COM объект! Вероятно не поставлена галка ссылка 1с у реквизитов таблицы конфигурации: "+лСтруктураДанныеКлючИЗначение.Ключ+"!"; КонецЕсли;
		#КонецЕсли
		Если пТолькоПримитивныеТипы Тогда 
			// TODO: переделать!!! типы указать правильно
			лОписаниеТипаКолонки=лОписаниеТипа;
			
			Если лСтруктураДанныеКлючИЗначение.Ключ="_КлючПриемникаНайденЧерезТаблицуСоответствий_" Тогда
				лОписаниеТипаКолонки=лОписаниеТипаБулево;
				
			ИначеЕсли пСтруктураПКТ<>Неопределено Тогда
				Если лСтруктураДанныеКлючИЗначение.Ключ="_КлючИсточника_" или лСтруктураДанныеКлючИЗначение.Ключ=пСтруктураПКТ.ТаблицаИсточник.ИмяРеквизитаПервичногоКлюча Тогда
					лОписаниеТипаКолонки=лОписаниеТипаСсылки;
					
				ИначеЕсли лСтруктураДанныеКлючИЗначение.Ключ="_КлючПриемника_" Тогда
					лОписаниеТипаКолонки=лОписаниеТипаСсылкиПриемник;
				КонецЕсли;
			КонецЕсли;
			Если пСтруктураПКТ<>Неопределено Тогда // TODO: Добавить правильную обработку типов неограниченная длина
				лСтруктураПКР=мМассивНайтиВМассивеСтруктур(пМассивСтруктурыПКР, "РеквизитПриемникИмя", лСтруктураДанныеКлючИЗначение.Ключ);
				Если лСтруктураПКР=Неопределено Тогда
					лСтруктураПКР=мМассивНайтиВМассивеСтруктур(пМассивСтруктурыПКР, "ИмяПараметра", лСтруктураДанныеКлючИЗначение.Ключ);
				КонецЕсли;
				Если лСтруктураПКР<>Неопределено Тогда
					Если лСтруктураПКР.ЭтоДвоичныеДанные или лСтруктураПКР.ДлинаСтроки=0 Тогда
						лОписаниеТипаКолонки=лОписаниеТипаСтрокаНеограниченная;
						
					ИначеЕсли лСтруктураПКР.ДлинаСтроки<>Неопределено и лСтруктураПКР.ДлинаСтроки>500 Тогда
						лКвалификаторСтроки=НовыйОбъект1("КвалификаторыСтроки", пСоединениеКОМ, лСтруктураПКР.ДлинаСтроки);
						лОписаниеТипа=НовыйОбъект3("ОписаниеТипов", пСоединениеКОМ, лМассивТипы,, лКвалификаторСтроки);
					КонецЕсли;
				КонецЕсли;
			КонецЕсли;
		КонецЕсли;
		лТзРезультат.Колонки.Добавить(лСтруктураДанныеКлючИЗначение.Ключ, лОписаниеТипаКолонки);
	КонецЦикла;
	лНомер=0;
	Для Каждого лСтруктураМассивДанные Из пМассивДанные Цикл
		лНомер=лНомер+1;
		лСтрокаТзРезультат=лТзРезультат.Добавить();
		лСтрокаТзРезультат._Номер_=лНомер;
		ЗаполнитьЗначенияСвойств(лСтрокаТзРезультат, лСтруктураМассивДанные);
	КонецЦикла;
	Возврат лТзРезультат; 
КонецФункции

Функция мПолучитьМенеджерТаблицыПоИмени(пИмяМенеджера, пСоединениеКОМ=Неопределено, пТекстОшибки="")
	Попытка	
		Возврат Вычислить(?(пСоединениеКОМ=Неопределено, "", "пСоединениеКОМ.")+пИмяМенеджера);
	Исключение
		лИнформацияОбОшибке=ИнформацияОбОшибке();
		пТекстОшибки=ТсПлатформаОбщий.ПолучитьПолноеОписаниеОшибки(лИнформацияОбОшибке);
	КонецПопытки;
	//ВызватьИсключение "Ошибка при вычислении менеджера: "+пИмяМенеджера+"!";
	Возврат Неопределено;
КонецФункции

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

Функция ДанныеПоместитьТзВоВременнуюТаблицу(пЗапрос, пДанные, пИмяВТ, пСоединениеКОМ=Неопределено, пСтруктураПКТ=Неопределено, пМассивСтруктурыПКР=Неопределено) Экспорт
	Если пДанные.Количество()=0 Тогда Возврат Ложь; КонецЕсли; 
	лТзДанные=?(ТипЗнч(пДанные)=Тип("Массив"), мПолучитьТзИзМассивСтруктур(пДанные, пСоединениеКОМ,, пСтруктураПКТ, пМассивСтруктурыПКР), пДанные);
	пЗапрос.УстановитьПараметр("ТзДанные", лТзДанные);
	пЗапрос.Текст=
	"ВЫБРАТЬ
	|	*
	|ПОМЕСТИТЬ "+пИмяВТ+"
	|ИЗ
	|	&ТзДанные КАК __ИсходныеДанные__";
	пЗапрос.Выполнить();
	Возврат Истина;
КонецФункции

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

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

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

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

Функция мДанныеЗагрузкиПоискПервичныхКлючей(пДанные, пЗапрос, пДрайверПодключения, пПодключение, пСтруктураКонтекст, пМассивПараметры, пСоединениеКОМ, пСоответствиеКодПравила2Данные, пЕстьНеобработанныеПравила, пЕстьОбработанныеПравила, пСуффиксВТ)
	Для Каждого лСтруктураДанные Из пДанные Цикл
		Если лСтруктураДанные.Данные=Неопределено Тогда Продолжить; КонецЕсли; // Для запросов на стороне приемника
		Если Не лСтруктураДанные.Свойство("СоответствиеИмяРеквизитаКодПравила") Тогда Продолжить; КонецЕсли; // Пустая таблица
		Если лСтруктураДанные.Этап<>"ДанныеПолучены" Тогда Продолжить; КонецЕсли; // Уже обработали
		
		лИспользуютсяСоответствияКлючей=ЗначениеЗаполнено(лСтруктураДанные.ПравилоКонвертацииТаблицы.СоответствиеКлючей) и ТсПлатформаОбщий.ПолучитьСвойство(лСтруктураДанные, "ЕстьСохраненныеСоответствияКлючей", Ложь);
		лКоличествоРеквизитовПоиска=лСтруктураДанные.ПравилоКонвертацииТаблицы.РеквизитыПоиска.Количество();
		лБезСоединенияСТаблицейПриемника=Ложь;
		Если лКоличествоРеквизитовПоиска=0 Тогда 
			лСтруктураДанные.Этап="КлючиЗаменены"; // Не требует обработки
			пЕстьОбработанныеПравила=Истина;
			Продолжить; 
		КонецЕсли;
		Если лКоличествоРеквизитовПоиска=1 Тогда // Если ищем по первичному ключу то поиск не нужен, уже имеем первичный ключ
			лСтруктураПравилаПоиска=мМассивНайтиВМассивеСтруктур(лСтруктураДанные.ПравилоКонвертацииТаблицы.ПравилаКонвертацииРеквизитов, "Поиск", Истина);
			Если лСтруктураПравилаПоиска=Неопределено Тогда 
				лСтруктураПравилаПоиска=мМассивНайтиВМассивеСтруктур(лСтруктураДанные.ПравилоКонвертацииТаблицы.ПравилаКонвертацииРеквизитов, "ПравилоКонвертацииКлюча", Истина);
			КонецЕсли;
			Если лСтруктураПравилаПоиска.РеквизитПриемникИмя=лСтруктураДанные.ПравилоКонвертацииТаблицы.ТаблицаПриемник.ИмяРеквизитаПервичногоКлюча Тогда
				лПоискИдетПоПервичномуКлючуИсточника=лСтруктураПравилаПоиска.РеквизитИсточникИмя=лСтруктураДанные.ПравилоКонвертацииТаблицы.ТаблицаИсточник.ИмяРеквизитаПервичногоКлюча;
				лСтруктураДанные.Вставить("ИмяРеквизитаПервичногоКлюча", лСтруктураДанные.ПравилоКонвертацииТаблицы.ТаблицаПриемник.ИмяРеквизитаПервичногоКлюча);
				//Если Не лИспользуютсяСоответствияКлючей и лПоискИдетПоПервичномуКлючуИсточника Тогда Продолжить; КонецЕсли; ????
				лБезСоединенияСТаблицейПриемника=Истина;
			КонецЕсли;
		КонецЕсли;
		лСтруктураДанные.Вставить("БезСоединенияСТаблицейПриемника", лБезСоединенияСТаблицейПриемника);
		
		лНеПродолжатьОбработкуПравила=Ложь;
		лСтрСоединение="";
		лСтрУсловияСоединения="";
		Для Каждого лСтруктураПравилаПравилаКонвертацииРеквизитов Из лСтруктураДанные.ПравилоКонвертацииТаблицы.ПравилаКонвертацииРеквизитов Цикл
			Если Не лСтруктураПравилаПравилаКонвертацииРеквизитов.Поиск Тогда Продолжить; КонецЕсли; 
			лИмяРеквизитыПоиска=лСтруктураПравилаПравилаКонвертацииРеквизитов.РеквизитПриемникИмя;
			//Если лИмяРеквизитыПоиска=лСтруктураДанные.ПравилоКонвертацииТаблицы.ТаблицаПриемник.ИмяРеквизитаПервичногоКлюча Тогда Продолжить; КонецЕсли;
			Если лСтруктураПравилаПравилаКонвертацииРеквизитов.ПравилоКонвертацииКлюча Тогда Продолжить; КонецЕсли;
			
			лИмяРеквизитаПрисоединения="Таблица."+лИмяРеквизитыПоиска;
			// Это нужно если будем когда то искать по табличной части и обновлять тч
			//Если ЗначениеЗаполнено(лСтруктураДанные.ПравилоКонвертацииТаблицы.ТабличнаяЧастьПриемник) и Не ЗначениеЗаполнено(лСтруктураПравилаПравилаКонвертацииРеквизитов.РеквизитПриемникИмяТч) Тогда
			//	лИмяРеквизитаПрисоединения="Таблица.Ссылка."+лИмяРеквизитыПоиска;
			//КонецЕсли;
			
			Если мСтруктураТаблицыРеквизитИмеетТипСтрокаНеограниченнаяДлина(лСтруктураДанные.ПравилоКонвертацииТаблицы.ТаблицаПриемник, лИмяРеквизитыПоиска, лСтруктураДанные.ПравилоКонвертацииТаблицы.ТабличнаяЧастьПриемник) Тогда 
				лИмяРеквизитаПрисоединения="ВЫРАЗИТЬ("+лИмяРеквизитаПрисоединения+" КАК СТРОКА(500))";
			КонецЕсли;
			
			лПутьДоРеквизита="ИсходныеДанные."+лИмяРеквизитыПоиска;
			лСтруктураПравилаПоиска=мМассивНайтиВМассивеСтруктур(лСтруктураДанные.ПравилоКонвертацииТаблицы.ПравилаКонвертацииРеквизитов, "РеквизитПриемникИмя", лИмяРеквизитыПоиска);
			
			Если лСтруктураПравилаПоиска.КодПравила<>Неопределено Тогда
				Если ТипЗнч(лСтруктураПравилаПоиска.КодПравила)=Тип("Массив") Тогда ВызватьИсключение "Не доделано для составных"; КонецЕсли; 
				
				лСтруктураДанныеРеквизитаПоиска=пСоответствиеКодПравила2Данные.Получить(лСтруктураПравилаПоиска.КодПравила);
				Если лСтруктураДанныеРеквизитаПоиска.Этап<>"КлючиЗаменены" Тогда // пропустим, обработаем в следующей итерации
					лНеПродолжатьОбработкуПравила=Истина;
					пЕстьНеобработанныеПравила=Истина;
					Прервать;
				КонецЕсли;
			КонецЕсли;
			
			лСтрУсловияСоединения=?(ПустаяСтрока(лСтрУсловияСоединения), "", лСтрУсловияСоединения+Символы.ПС+"		И ")+лПутьДоРеквизита+" = "+лИмяРеквизитаПрисоединения
		КонецЦикла;
		Если лНеПродолжатьОбработкуПравила Тогда Продолжить; КонецЕсли; 
		
		Если лСтруктураДанные.ПравилоКонвертацииТаблицы.ТаблицаПриемник.Свойство("Отбор") Тогда
			Если Не ЗначениеЗаполнено(лСтрУсловияСоединения) Тогда
				ВызватьИсключение "Установлен отбор на таблицу приемник: "+лСтруктураДанные.ПравилоКонвертацииТаблицы.ТаблицаПриемник.Наименование+", должен быть выбран хотя бы один поиск по реквизитам (исключая поиск по ключу), остальные варианты не реализованы!";
			КонецЕсли;
			
			лСтрУсловияСоединения=лСтрУсловияСоединения+Символы.ПС+"		И "+СтрЗаменить(лСтруктураДанные.ПравилоКонвертацииТаблицы.ТаблицаПриемник.Отбор.Условие, "#ИсходныеДанные#", "Таблица");
			
			лМассивПараметры=?(пМассивПараметры=Неопределено, Новый Массив, ПолучитьКопиюОбъекта(пМассивПараметры));
			мОбработатьПараметрыЗапросаВЗапрос(лСтруктураДанные.ПравилоКонвертацииТаблицы.ТаблицаПриемник.Отбор.ПараметрыОтбора, пСтруктураКонтекст, лМассивПараметры, пСоединениеКОМ);
			мЗаписатьПараметрыЗапросаВЗапрос(пЗапрос, лСтруктураДанные.ПравилоКонвертацииТаблицы.ТаблицаПриемник.Отбор.ПараметрыОтбора); //, пСтруктураКонтекст, лМассивПараметры, пСоединениеКОМ);
		КонецЕсли;
		
		лМассивСтрРеквизиты=Новый Массив; лМассивСтрРеквизитыОбработка=Новый Массив;
		лМассивСтрРеквизиты.Добавить("ИсходныеДанные._Номер_ КАК _Номер_");
		лМассивСтрРеквизитыОбработка.Добавить("_Номер_ КАК _Номер_");
		
		Если ЗначениеЗаполнено(лСтруктураДанные.ПравилоКонвертацииТаблицы.ТаблицаПриемник.ИмяРеквизитаПервичногоКлюча) Тогда
			лПутьДоКлюча=?(лБезСоединенияСТаблицейПриемника, "ИсходныеДанные", "Таблица")+"."+лСтруктураДанные.ПравилоКонвертацииТаблицы.ТаблицаПриемник.ИмяРеквизитаПервичногоКлюча;
			лПутьДоКлюча2="ИсходныеДанные._КлючПриемника_";
			
			Если (лИспользуютсяСоответствияКлючей или лБезСоединенияСТаблицейПриемника)
				и мМассивНайтиВМассивеСтруктур(лСтруктураДанные.ПравилоКонвертацииТаблицы.ТаблицаПриемник.Реквизиты, "Имя", лСтруктураДанные.ПравилоКонвертацииТаблицы.ТаблицаПриемник.ИмяРеквизитаПервичногоКлюча).Типы[0].Тип<>"Строка"
			Тогда
			    ВызватьИсключение "Для типов отличных от строки не работает!";
			КонецЕсли;
			
			Если лИспользуютсяСоответствияКлючей Тогда
				лПутьДоКлюча=
				"ВЫБОР 
				|	КОГДА ИсходныеДанные._КлючПриемника_ = """"
				|		ТОГДА "+лПутьДоКлюча+"
				|		ИНАЧЕ ИсходныеДанные._КлючПриемника_
				|	КОНЕЦ";
			КонецЕсли;
			Если лИспользуютсяСоответствияКлючей или лБезСоединенияСТаблицейПриемника Тогда
				лПутьДоКлюча2=
				"ВЫБОР
				|	КОГДА Таблица._КлючПриемникаОбработанный_ ЕСТЬ NULL ИЛИ Таблица._КлючПриемникаОбработанный_ = НЕОПРЕДЕЛЕНО ИЛИ Таблица._КлючПриемника_ = """"
				|		ТОГДА "+лПутьДоКлюча2+"
				|		ИНАЧЕ Таблица._КлючПриемникаОбработанный_
				|	КОНЕЦ";
			КонецЕсли;
			
			лМассивСтрРеквизиты.Добавить(лПутьДоКлюча+" КАК _КлючПриемника_");
			лМассивСтрРеквизитыОбработка.Добавить(лПутьДоКлюча2+" КАК _КлючПриемника_");
			
			лМассивСтрРеквизиты.Добавить("ВЫБОР КОГДА "+лПутьДоКлюча+" ЕСТЬ NULL ТОГДА ИСТИНА ИНАЧЕ ЛОЖЬ КОНЕЦ КАК _НовыйОбъект_");
			лМассивСтрРеквизитыОбработка.Добавить("ВЫБОР КОГДА "+лПутьДоКлюча2+" ЕСТЬ NULL ТОГДА ИСТИНА ИНАЧЕ ЛОЖЬ КОНЕЦ КАК _НовыйОбъект_");
			
			Если лИспользуютсяСоответствияКлючей Тогда 
				лМассивСтрРеквизиты.Добавить("ИсходныеДанные._КлючПриемникаНайденЧерезТаблицуСоответствий_ КАК _КлючПриемникаНайденЧерезТаблицуСоответствий_");
				лМассивСтрРеквизитыОбработка.Добавить("ИсходныеДанные._КлючПриемникаНайденЧерезТаблицуСоответствий_ КАК _КлючПриемникаНайденЧерезТаблицуСоответствий_");
			КонецЕсли;
		КонецЕсли;
		
		// ключ источника используется как при поиске, так и в алгоритме поиска ключа
		Если ЗначениеЗаполнено(лСтруктураДанные.ПравилоКонвертацииТаблицы.ТаблицаИсточник.ИмяРеквизитаПервичногоКлюча) Тогда
			лМассивСтрРеквизиты.Добавить("ИсходныеДанные._КлючИсточника_ КАК _КлючИсточника_");
			лМассивСтрРеквизитыОбработка.Добавить("ИсходныеДанные._КлючИсточника_ КАК _КлючИсточника_");
		КонецЕсли;
		
		лМассивРеквизиты=Новый Массив;
		Для Каждого лСтруктураПКР Из лСтруктураДанные.ПравилоКонвертацииТаблицы.ПравилаКонвертацииРеквизитов Цикл
			Если лСтруктураПКР.Свойство("ПравилаКонвертацииРеквизитов") Тогда Продолжить; КонецЕсли; // тч
			лИмяРеквизита=лСтруктураПКР.РеквизитПриемникИмя;
			Если Не ЗначениеЗаполнено(лИмяРеквизита) Тогда лИмяРеквизита=лСтруктураПКР.ИмяПараметра; КонецЕсли; 
			Если Не ЗначениеЗаполнено(лИмяРеквизита) Тогда лИмяРеквизита=лСтруктураПКР.РеквизитИсточникИмя; КонецЕсли;
			
			лМассивРеквизиты.Добавить(лИмяРеквизита);
			лМассивСтрРеквизиты.Добавить("ИсходныеДанные."+лИмяРеквизита+" КАК "+лИмяРеквизита);
			лМассивСтрРеквизитыОбработка.Добавить("ИсходныеДанные."+лИмяРеквизита+" КАК "+лИмяРеквизита);
			
			Если лСтруктураПКР.Составной Тогда 
				лМассивСтрРеквизиты.Добавить("ИсходныеДанные."+лИмяРеквизита+"__Тип__ КАК "+лИмяРеквизита+"__Тип__");
				лМассивСтрРеквизитыОбработка.Добавить("ИсходныеДанные."+лИмяРеквизита+"__Тип__ КАК "+лИмяРеквизита+"__Тип__");
			КонецЕсли;
			Если ТипЗнч(лСтруктураПКР.КодПравила)=Тип("Массив") Тогда
				лМассивСтрРеквизиты.Добавить("ИсходныеДанные."+лИмяРеквизита+"__КодПравила__ КАК "+лИмяРеквизита+"__КодПравила__");
				лМассивСтрРеквизитыОбработка.Добавить("ИсходныеДанные."+лИмяРеквизита+"__КодПравила__ КАК "+лИмяРеквизита+"__КодПравила__");
			КонецЕсли; 
		КонецЦикла;
		
		// Добавление ключей в таблицу поиска
		Для Каждого лСтруктураРеквизита Из лСтруктураДанные.ПравилоКонвертацииТаблицы.ТаблицаПриемник.Реквизиты Цикл
			Если лСтруктураРеквизита.ЭтоКлюч<>Истина Тогда Продолжить; КонецЕсли; // может быть типа NULL
			Если лМассивРеквизиты.Найти(лСтруктураРеквизита.Имя)<>Неопределено Тогда Продолжить; КонецЕсли; 
			лМассивСтрРеквизиты.Добавить("Таблица."+лСтруктураРеквизита.Имя+" КАК "+лСтруктураРеквизита.Имя);
			лМассивСтрРеквизитыОбработка.Добавить("ИсходныеДанные."+лСтруктураРеквизита.Имя+" КАК "+лСтруктураРеквизита.Имя);
		КонецЦикла;
		лЕстьДанныеВТаблицеПриемника=Истина;
		Если ЗначениеЗаполнено(лСтрУсловияСоединения) Тогда // если не заполнено, то мы не делаем обращение к таблице приемника а значит заполнять таблицу данных нам не надо
			Если Не пСтруктураКонтекст.СтандартныйДрайвер1с Тогда 
				лИмяТаблицыДанных="";
				Если Не лСтруктураДанные.ПравилоКонвертацииТаблицы.ТаблицаПриемник.Свойство("ИмяВТ", лИмяТаблицыДанных) Тогда // !!!!!!!!!!!!
					лСтруктураДанныеТаблицы=пДрайверПодключения.СтруктураТаблицыКонфигурацииПолучитьДанные(пПодключение, лСтруктураДанные.ПравилоКонвертацииТаблицы.ТаблицаПриемник, пСтруктураКонтекст, лСтруктураДанные.Параметры);
					
					лДанныеИсточника=?(ТипЗнч(лСтруктураДанныеТаблицы)=Тип("Структура"), лСтруктураДанныеТаблицы.Данные, лСтруктураДанныеТаблицы);
					лИмяТаблицыДанных="ВТДанныеИсточник"+лСтруктураДанные.ПравилоКонвертацииТаблицы.ТаблицаПриемник.Имя;
					лЕстьДанныеВТаблицеПриемника=ДанныеПоместитьТзВоВременнуюТаблицу(пЗапрос, лДанныеИсточника, лИмяТаблицыДанных, пСоединениеКОМ);
				КонецЕсли;
				
			Иначе // для стандартных драйверов 1с
				Если лСтруктураДанные.ПравилоКонвертацииТаблицы.ТаблицаПриемник.Тип="Перечисления" Тогда
					лИмяТаблицыДанных="ВтДанныеПеречисления"+Формат(лСтруктураДанные.КодПравила, "ЧГ=");
					// Напрямую нельзя так как там идет отбор, а помещать можно только без отбора иначе он не работает!
					лТзДанныеПеречисления=мПолучитьТзДанныеПеречисления(лСтруктураДанные.ПравилоКонвертацииТаблицы.ТаблицаПриемник, пСоединениеКОМ);
					мВыгрузитьТзПеречисленияВоВременнуюТаблицу(лТзДанныеПеречисления, лИмяТаблицыДанных, пЗапрос.МенеджерВременныхТаблиц, пСоединениеКОМ);
					
				Иначе
					лИмяТаблицыДанных=ПолучитьИмяТаблицы1с(лСтруктураДанные.ПравилоКонвертацииТаблицы.ТаблицаПриемник); //, лСтруктураДанные.ТабличнаяЧастьПриемник, это нужно если будем когда то искать по табличной части и обновлять тч
				КонецЕсли;
			КонецЕсли;
		КонецЕсли; 
		лИмяВТНовое="ВТПоискКлючей"+Формат(лСтруктураДанные.КодПравила, "ЧГ=")+пСуффиксВТ;
		
		пЗапрос.Текст=
		"ВЫБРАТЬ
		|	"+СтрСоединить(лМассивСтрРеквизиты, ","+Символы.ПС+Символы.Таб)+"
		|ПОМЕСТИТЬ "+лИмяВТНовое+"
		|ИЗ
		|	"+лСтруктураДанные.ИмяВТ+" КАК ИсходныеДанные";
		Если ЗначениеЗаполнено(лСтрУсловияСоединения) и лЕстьДанныеВТаблицеПриемника Тогда
			пЗапрос.Текст=пЗапрос.Текст+лСтрСоединение+"
			|		ЛЕВОЕ СОЕДИНЕНИЕ "+лИмяТаблицыДанных+" КАК Таблица
			|		ПО "+лСтрУсловияСоединения;
		КонецЕсли;
		пЗапрос.Выполнить(); // Для отладки: ТсПлатформаОбщий.ПолучитьВТ(пЗапрос)
		
		лСтруктураДанные.ИмяВТ=лИмяВТНовое;
		лСтруктураДанные.Этап="КлючиНайдены";
		
		пЕстьОбработанныеПравила=Истина;
		
		//Если Не ЗначениеЗаполнено(лСтруктураДанные.ПравилоКонвертацииТаблицы.ТаблицаПриемник.ИмяРеквизитаПервичногоКлюча) Тогда Продолжить; КонецЕсли;
		Если Не пСтруктураКонтекст.СтандартныйДрайвер1с Тогда Продолжить; КонецЕсли;
		
		//Если Не лИспользуютсяСоответствияКлючей Тогда Продолжить; КонецЕсли;
		//Если Не лСтруктураДанные.ЕстьСохраненныеСоответствияКлючей Тогда Продолжить; КонецЕсли; // ?????
		
		// нам необходимо заменить ключи приемника из кросс таблиц на ссылки, или заменить ключи если используется соответствие ключ в ключ, в стандартных таблицах
		Если Не лИспользуютсяСоответствияКлючей и Не лБезСоединенияСТаблицейПриемника Тогда Продолжить; КонецЕсли; 
		
		пЗапрос.Текст=
		"ВЫБРАТЬ РАЗЛИЧНЫЕ
		|	ИсходныеДанные._КлючПриемника_ КАК _КлючПриемника_
		|ИЗ
		|	"+лСтруктураДанные.ИмяВТ+" КАК ИсходныеДанные";
		Если лИспользуютсяСоответствияКлючей и Не лБезСоединенияСТаблицейПриемника Тогда
			пЗапрос.Текст=пЗапрос.Текст+"
			|ГДЕ
			|	ИсходныеДанные._КлючПриемникаНайденЧерезТаблицуСоответствий_";
		КонецЕсли; 
		лРезультатЗапроса=пЗапрос.Выполнить();
		Если лРезультатЗапроса.Пустой() Тогда Продолжить; КонецЕсли; 
		
		//лТзПервичныеКлючи=мТзПервичныеКлючиПолучить(лСтруктураДанные, "_КлючПриемника_", "_КлючПриемникаОбработанный_", пСтруктураКонтекст.СтандартныйДрайвер1с, пСоединениеКОМ);
		лТзПервичныеКлючи=лРезультатЗапроса.Выгрузить();
		мТзПервичныеКлючиДобавитьКлюч2(лСтруктураДанные, лТзПервичныеКлючи, "_КлючПриемника_", "_КлючПриемникаОбработанный_", пСтруктураКонтекст.СтандартныйДрайвер1с, пСоединениеКОМ);
		
		лЭтоПеречисление=лСтруктураДанные.ПравилоКонвертацииТаблицы.ТаблицаПриемник.Тип="Перечисления";
		Для Каждого лСтрокаТзПервичныеКлючи Из лТзПервичныеКлючи Цикл
			Если лЭтоПеречисление Тогда
				лЗначение=лСтруктураДанные.МенеджерТаблицы[лСтрокаТзПервичныеКлючи._КлючПриемника_];
			Иначе
				лЗначение=лСтруктураДанные.МенеджерКлюча.ПолучитьСсылку(НовыйОбъект1("УникальныйИдентификатор", пСоединениеКОМ, лСтрокаТзПервичныеКлючи._КлючПриемника_));
			КонецЕсли;
			лСтрокаТзПервичныеКлючи._КлючПриемникаОбработанный_=лЗначение;
		КонецЦикла;
		
		//лВыборка=лРезультатЗапроса.Выбрать();
		//Пока лВыборка.Следующий() Цикл
		//	Если ПустаяСтрока(лВыборка._КлючПриемника_) Тогда Продолжить; КонецЕсли;
		//	лСтрокаТзПервичныеКлючи=лТзПервичныеКлючи.Добавить();
		//	лСтрокаТзПервичныеКлючи._КлючПриемника_=лВыборка._КлючПриемника_;
		//	Если лЭтоПеречисление Тогда
		//		лЗначение=лСтруктураДанные.МенеджерТаблицы[лВыборка._КлючПриемника_];
		//	Иначе
		//		лЗначение=лСтруктураДанные.МенеджерКлюча.ПолучитьСсылку(НовыйОбъект1("УникальныйИдентификатор", пСоединениеКОМ, лВыборка._КлючПриемника_));
		//	КонецЕсли;
		//	лСтрокаТзПервичныеКлючи._КлючПриемникаОбработанный_=лЗначение;
		//КонецЦикла;
		
		лНовоеИмяВТПоиска=лСтруктураДанные.ИмяВТ+"_СОбработкойКлючей"+пСуффиксВТ;
		пЗапрос.УстановитьПараметр("ТзДанныеКлючиОбработанные", лТзПервичныеКлючи);
		пЗапрос.Текст=
		"ВЫБРАТЬ
		|	ИсходныеДанные._КлючПриемника_ КАК _КлючПриемника_,
		|	ИсходныеДанные._КлючПриемникаОбработанный_ КАК _КлючПриемникаОбработанный_
		|ПОМЕСТИТЬ ВТКлючиЗаменаНаСсылки
		|ИЗ
		|	&ТзДанныеКлючиОбработанные КАК ИсходныеДанные
		//|ИНДЕКСИРОВАТЬ ПО ИсходныеДанные._КлючПриемника_ // тут составной ключ, так не работает
		|;
		|////////////////////////////
		|ВЫБРАТЬ
		|	"+СтрСоединить(лМассивСтрРеквизитыОбработка, ","+Символы.ПС+Символы.Таб)+"
		|ПОМЕСТИТЬ "+лНовоеИмяВТПоиска+"
		|ИЗ
		|	"+лСтруктураДанные.ИмяВТ+" КАК ИсходныеДанные
		|		ЛЕВОЕ СОЕДИНЕНИЕ ВТКлючиЗаменаНаСсылки КАК Таблица
		|		ПО Таблица._КлючПриемника_ = ИсходныеДанные._КлючПриемника_
		|;
		|////////////////////////////
		|УНИЧТОЖИТЬ ВТКлючиЗаменаНаСсылки";
		
		пЗапрос.Выполнить(); // Для отладки: ТсПлатформаОбщий.ПолучитьВТ(пЗапрос)
		лСтруктураДанные.ИмяВТ=лНовоеИмяВТПоиска;
	КонецЦикла;
	
	мДанныеЗагрузкиПоискКлючейЧерезСобытие(пДанные, пЗапрос, пСтруктураКонтекст, пМассивПараметры, пСоединениеКОМ);
КонецФункции

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

Функция мТзПервичныеКлючиДобавитьКлюч2(пСтруктураДанные, пТзПервичныеКлючи, пИмяКлюча1, пИмяКлюча2, пСтандартныйДрайвер1с, пСоединениеКОМ)
	лТипКлюча1=пТзПервичныеКлючи.Колонки[пИмяКлюча1].ТипЗначения;
	лТипКлюча2=ТипЗнч(пСтруктураДанные.МенеджерКлюча.ПустаяСсылка()); // TODO: по поводу соединения КОМ посмотреть как типзнч // СоединениеComCon.Справочники.Контрагенты.пустаяссылка().метаданные().стандартныереквизиты.ссылка.тип.типы().получить(0);
	лОписаниеТипаКлючаПриемника=?(пСтандартныйДрайвер1с, НовыйОбъект2("ОписаниеТипов", пСоединениеКОМ, лТипКлюча1, мМассивСоздатьПоЗначениям1(лТипКлюча2)), лТипКлюча1);
	пТзПервичныеКлючи.Колонки.Добавить(пИмяКлюча2, лОписаниеТипаКлючаПриемника);
КонецФункции

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

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

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

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

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

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

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

Функция мПолучитьСоответствиеДляКонвертацииПеречисления(пИмяПеречисления, пМенеджерТаблицы, пСоединениеКОМ)
	лСоответствиеЗначений=Новый Соответствие; // тут тогда просто сделаем соответствие Имя >> Ссылка
	лМетаданные=?(пСоединениеКОМ=Неопределено, Метаданные, пСоединениеКОМ.Метаданные);
	Для Каждого лМетаЗначенияПеречисления Из лМетаданные.Перечисления[пИмяПеречисления].ЗначенияПеречисления Цикл
		лСоответствиеЗначений.Вставить(лМетаЗначенияПеречисления.Имя, пМенеджерТаблицы[лМетаЗначенияПеречисления.Имя]);
	КонецЦикла;
	Возврат лСоответствиеЗначений;
КонецФункции

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

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

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

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

Функция мЗначениеЗаполнено(пЗначение, пСоединениеКОМ)
	Если пСоединениеКОМ=Неопределено Тогда Возврат ЗначениеЗаполнено(пЗначение); КонецЕсли; 
	Возврат пСоединениеКОМ.ЗначениеЗаполнено(пЗначение);
КонецФункции

Функция ВсеПравилаКонвертацииРеквизитовПоисковые(пМассивСтруктурыПКР) Экспорт
	Для Каждого лСтруктураПКР Из пМассивСтруктурыПКР Цикл
		Если Не лСтруктураПКР.Поиск и Не лСтруктураПКР.ПравилоКонвертацииКлюча Тогда Возврат Ложь; КонецЕсли;
	КонецЦикла;
	Возврат Истина;
КонецФункции

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

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

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

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

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

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

#Область ПараметрыСервера
Функция ПолучитьПараметрыСервера(пСоединениеКОМ=Неопределено) Экспорт
	лСистемнаяИнформация=?(пСоединениеКОМ=Неопределено, Новый СистемнаяИнформация, пСоединениеКОМ.NewObject("СистемнаяИнформация"));
	лМетаданные=?(пСоединениеКОМ=Неопределено, Метаданные, пСоединениеКОМ.Метаданные);
	
	лСтруктураПараметры=Новый Структура;
	лСтруктураПараметры.Вставить("ТипИсточника", "Конфигурация 1с");
	лСтруктураПараметры.Вставить("Платформа", мЗначениеВСтроку(лСистемнаяИнформация.ТипПлатформы, пСоединениеКОМ));
	лСтруктураПараметры.Вставить("Конфигурация", лМетаданные.Представление());
	лСтруктураПараметры.Вставить("ВерсияКонфигурации", лМетаданные.Версия);
	лСтруктураПараметры.Вставить("ВерсияМодуляОбмена", Версия());
	лСтруктураПараметры.Вставить("ОперационнаяСистема", лСистемнаяИнформация.ВерсияОС);
	лСтруктураПараметры.Вставить("Память", лСистемнаяИнформация.ОперативнаяПамять);
	лСтруктураПараметры.Вставить("Процессор", лСистемнаяИнформация.Процессор);
	//лСтруктураПараметры.Вставить("ИдентификаторКлиента", мЗначениеВСтроку(лСистемнаяИнформация.ИдентификаторКлиента, пСоединениеКОМ));
	лСтруктураПараметры.Вставить("ВерсияПриложения", лСистемнаяИнформация.ВерсияПриложения);
	//лСтруктураПараметры.Вставить("ИнформацияБраузера", лСистемнаяИнформация.ИнформацияПрограммыПросмотра);
	лСтруктураПараметры.Вставить("СтрокаСоединенияИБ", ?(пСоединениеКОМ=Неопределено, СтрокаСоединенияИнформационнойБазы(), пСоединениеКОМ.СтрокаСоединенияИнформационнойБазы()));
	лСтруктураПараметры.Вставить("ИмяКомпьютера", ИмяКомпьютера());
	Возврат лСтруктураПараметры;
КонецФункции
#КонецОбласти 

#Область ПолучениеДанныхТаблицы
Функция ТаблицаДанныеОтобратьПоУсловию(пДанные, пСтруктураТаблицы, пСтруктураКонтекст=Неопределено, пМассивПараметры=Неопределено) Экспорт
	Если Не пСтруктураТаблицы.Свойство("Отбор") Тогда Возврат пДанные; КонецЕсли;
	
	// TODO: Доделать отбор по табличным частям
	лЗапрос=Новый Запрос;
	лЗапрос.УстановитьПараметр("ТзДанные", ?(ТипЗнч(пДанные)=Тип("Структура"), пДанные.Данные, пДанные));
	ПараметрыОтбораВычислитьЗначения(пСтруктураТаблицы.Отбор.ПараметрыОтбора, пСтруктураКонтекст, пМассивПараметры);
	Для Каждого лСтруктураПараметрыОтбора Из пСтруктураТаблицы.Отбор.ПараметрыОтбора Цикл
		лЗапрос.УстановитьПараметр(лСтруктураПараметрыОтбора.Имя, лСтруктураПараметрыОтбора.Значение);
	КонецЦикла; 
	лЗапрос.Текст=
	"ВЫБРАТЬ
	|	*
	|ПОМЕСТИТЬ ВтДанные
	|ИЗ
	|	&ТзДанные КАК ИсходныеДанные
	|;
	|
	|////////////////////////////////////////////////////////////////////////////////
	|ВЫБРАТЬ
	|	*
	|ИЗ
	|	ВтДанные КАК ИсходныеДанные
	|ГДЕ
	|	"+пСтруктураТаблицы.Отбор.Условие;
	лЗапрос.Текст=СтрЗаменить(лЗапрос.Текст, "#ИсходныеДанные#", "ИсходныеДанные");
	Возврат лЗапрос.Выполнить().Выгрузить();
КонецФункции

Функция мПолучитьУИД(пСсылка, пСоединениеКОМ=Неопределено, пСоответствиеЗначенияПеречислений=Неопределено)
	Попытка	Возврат мЗначениеВСтроку(пСсылка.УникальныйИдентификатор(), пСоединениеКОМ); Исключение КонецПопытки; 
	Если пСоответствиеЗначенияПеречислений=Неопределено Тогда Возврат Неопределено; КонецЕсли; // TODO: убрать, этот параметр должен быть всегда
	Возврат пСоответствиеЗначенияПеречислений.Получить(пСсылка);
	//Возврат Неопределено;
КонецФункции

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

Функция мПолучитьЗначениеПоУмолчаниюДляNULL(пСтруктураРеквизита)
	Если пСтруктураРеквизита=Неопределено Тогда Возврат """"""; КонецЕсли;
	Для Каждого лСтрокаТипы Из пСтруктураРеквизита.Типы Цикл
		Если лСтрокаТипы.Тип="Строка" Тогда Возврат """"""; КонецЕсли; // и лСтрокаТипы.Длина=0
	КонецЦикла;
	Возврат "Неопределено";
КонецФункции

Функция мСтруктураРеквизитаИмеетТипСтрокаНеограниченнойДлины(пСтруктураРеквизита)
	Если пСтруктураРеквизита.Типы.Количество()<>1 Тогда Возврат Ложь; КонецЕсли;
	Если пСтруктураРеквизита.Типы[0].Тип<>"Строка" Тогда Возврат Ложь; КонецЕсли;
	Возврат пСтруктураРеквизита.Типы[0].Длина=0; 
КонецФункции

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

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

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

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

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

Функция мПолучитьСсылкуПоКлючу(пМенеджерТаблицы, пЗначение, пСоединениеКОМ, пЭтоПеречисление)
	Попытка	
		Если пЭтоПеречисление Тогда 
			Возврат пМенеджерТаблицы[пЗначение];
		Иначе
			Возврат пМенеджерТаблицы.ПолучитьСсылку(НовыйОбъект1("УникальныйИдентификатор", пСоединениеКОМ, пЗначение));
		КонецЕсли;
	Исключение
	КонецПопытки; 
	Возврат Неопределено; 
КонецФункции 

Функция мЭтоМассив(пЗначение)
	Попытка	
		лТест=пЗначение.Количество(); 
		Возврат Истина; 
	Исключение
	КонецПопытки;
	Возврат Ложь; 
КонецФункции 

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

Функция мПолучитьДанныеТаблицыПоСтруктуреТаблицы1с(пСтруктураТаблицы, пСтруктураКонтекст, пМассивПараметры, пСоединениеКОМ=Неопределено)
	лИмяВТОсновнойТаблицы="ВТ"+пСтруктураТаблицы.Имя;
	лЭтоПроизвольныйЗапросАвтосгенерированный=Ложь;
	лПолучатьПредставление=ТсПлатформаОбщий.ПолучитьСвойство(пСтруктураКонтекст, "ПолучатьПредставление", Ложь);
	
	лЗапрос=НовыйОбъект0("Запрос", пСоединениеКОМ);
	лЗапрос.МенеджерВременныхТаблиц=НовыйОбъект0("МенеджерВременныхТаблиц", пСоединениеКОМ);
	
	мСоздатьВТПоСоставнымТипамПоСтруктуреТаблицы(пСтруктураТаблицы, лЗапрос.МенеджерВременныхТаблиц);
	
	лСтруктураПараметрыГенерацииЗапроса=Новый Структура;
	Если пСтруктураТаблицы.ПроизвольныйЗапрос Тогда
		лСтруктураПараметрыГенерацииЗапроса.Вставить("Реквизиты", Новый Массив);
		лСтруктураПараметрыГенерацииЗапроса.Вставить("ТабличныеЧасти", Новый Массив);
		лИмяВТОсновнойТаблицы=пСтруктураТаблицы.ИмяВременнойТаблицы;
		Если Не ЗначениеЗаполнено(лИмяВТОсновнойТаблицы) Тогда ВызватьИсключение "Для произвольного запроса: "+пСтруктураТаблицы.Имя+", не задана Имя ВТ (обязательно указывать если идет работа с запросом)"; КонецЕсли; 
		
		//лЭтоПроизвольныйЗапросАвтосгенерированный=СтрНайти(пСтруктураТаблицы.ТекстЗапроса, "ПОМЕСТИТЬ "+лИмяВТОсновнойТаблицы)<>0;
		//МассивПараметрыПреобразоватьПараметрыТипаДата(пСтруктураТаблицы.Параметры);
		
		лЗапрос.Текст=пСтруктураТаблицы.ТекстЗапроса;
		мЗапросУстановитьПараметрыЗапроса(лЗапрос, пСтруктураТаблицы, пМассивПараметры);
		Для Каждого лСтруктураВременныеТаблицыТабличныхЧастей Из пСтруктураТаблицы.ВременныеТаблицыТабличныхЧастей Цикл
			лСтруктураТабличнаяЧасть=Новый Структура("Имя, ИмяВТ, Заголовок", лСтруктураВременныеТаблицыТабличныхЧастей.ИмяТабличнойЧасти, лСтруктураВременныеТаблицыТабличныхЧастей.ИмяВременнойТаблицы, лСтруктураВременныеТаблицыТабличныхЧастей.НаименованиеТабличнойЧасти);
			лСтруктураПараметрыГенерацииЗапроса.ТабличныеЧасти.Добавить(лСтруктураТабличнаяЧасть);
		КонецЦикла;
		
		Если пСтруктураТаблицы.Свойство("КоличествоСтрокДляЧтения") Тогда
			лЗапрос.Текст=СтрЗаменить(лЗапрос.Текст, "//ПЕРВЫЕ", " ПЕРВЫЕ "+Формат(пСтруктураТаблицы.КоличествоСтрокДляЧтения, "ЧГ="));
		КонецЕсли;
		
		лОтборПоУсловиюОтбораДобавлен=СтрНайти(пСтруктураТаблицы.ТекстЗапроса, "ВЫБРАТЬ // ОТБОРПОУСЛОВИЮОТБОРАДОБАВЛЕН")<>0;
		Если Не лОтборПоУсловиюОтбораДобавлен и пСтруктураТаблицы.Свойство("Отбор") Тогда
			лСтрУсловие=пСтруктураТаблицы.Отбор.Условие;
			лСтрУсловие=СтрЗаменить(лСтрУсловие, "#ИсходныеДанные#.", ""); // пока без псевдонимов, если будет и там и там, то будут проблемы
			лЗапрос.Текст=СтрЗаменить(лЗапрос.Текст, "&_ОтборОсновнаяТаблица_", "("+лСтрУсловие+")");
		Иначе
			лЗапрос.Текст=СтрЗаменить(лЗапрос.Текст, "&_ОтборОсновнаяТаблица_", "ИСТИНА");
		КонецЕсли;
		лЗапрос.Текст=СтрЗаменить(лЗапрос.Текст, "&_ОтборПервичныйОсновнаяТаблица_", "ИСТИНА");
		Если лСтруктураПараметрыГенерацииЗапроса.ТабличныеЧасти.Количество()<>0 и ЗначениеЗаполнено(пСтруктураТаблицы.ИмяРеквизитаПервичногоКлюча) Тогда
			лЗапрос.Текст=СтрЗаменить(лЗапрос.Текст, "&_ОтборТабличнаяЧасть_", пСтруктураТаблицы.ИмяРеквизитаПервичногоКлюча+" В (ВЫБРАТЬ ИсходныеДанные."+пСтруктураТаблицы.ИмяРеквизитаПервичногоКлюча+" ИЗ "+лИмяВТОсновнойТаблицы+" КАК ИсходныеДанные)");
		КонецЕсли;
		
		Если лПолучатьПредставление Тогда
			лМассивПоляПредставления=Новый Массив;
			Для Каждого лСтруктураРеквизита Из пСтруктураТаблицы.Реквизиты Цикл
				Если Не лСтруктураРеквизита.ЭтоСсылка1С Тогда Продолжить; КонецЕсли;
				лСтрПеременные="ПРЕДСТАВЛЕНИЕ(ИсходныеДанные."+лСтруктураРеквизита.Имя+") КАК "+лСтруктураРеквизита.Имя+"_Представление_";
				лМассивПоляПредставления.Добавить(лСтрПеременные);
			КонецЦикла;
			Если лМассивПоляПредставления.Количество()<>0 Тогда
				лИмяВТПредставления=лИмяВТОсновнойТаблицы+"_ПРЕДСТАВЛЕНИЯ_";
				лЗапрос.Текст=лЗапрос.Текст+Символы.ПС+ // перевод строки нужен, потому как запрос может заканчиваться комментарием
				";
				|///////////////////////////////////////
				|ВЫБРАТЬ 
				|	*,
				|	"+СтрСоединить(лМассивПоляПредставления, ","+Символы.ПС+Символы.Таб)+"
				|ПОМЕСТИТЬ "+лИмяВТПредставления+"
				|ИЗ 
				|	"+лИмяВТОсновнойТаблицы+" КАК ИсходныеДанные";
				лИмяВТОсновнойТаблицы=лИмяВТПредставления;
			КонецЕсли;
		КонецЕсли;
		
	Иначе
		лЭтоРегистрБухгалтерии=пСтруктураТаблицы.Тип="РегистрыБухгалтерии";
		// TODO: для бух разобраться какие из реквизитов бух могут быть NULL и оптимизировать
		лОборачиватьВКонструкциюЕстьНУЛЛ=(пСтруктураТаблицы.Иерархический и Не пСтруктураТаблицы.ИерархияЭлементов и (пСтруктураТаблицы.Тип="Справочники" или пСтруктураТаблицы.Тип="ПланыВидовХарактеристик")) или лЭтоРегистрБухгалтерии;
		лЭтоПланСчетов=пСтруктураТаблицы.Тип="ПланыСчетов";
		
		лСтруктураПараметрыГенерацииЗапроса=мПолучитьПолучитьПараметрыГенерацииЗапроса(пСтруктураТаблицы, пСтруктураТаблицы.Реквизиты, лОборачиватьВКонструкциюЕстьНУЛЛ, лЭтоПланСчетов, лЭтоРегистрБухгалтерии,, лПолучатьПредставление);
		Если лСтруктураПараметрыГенерацииЗапроса.Реквизиты.Количество()=0 Тогда ВызватьИсключение "Не выбраны реквизиты для таблицы: "+пСтруктураТаблицы.Имя; КонецЕсли;
		лИмяТаблицы=ПолучитьИмяТаблицы1с(пСтруктураТаблицы);
		
		// Это для оптимизации при выборке из временной таблицы
		лСтрУсловие=?(пСтруктураТаблицы.Свойство("Отбор"), пСтруктураТаблицы.Отбор.Условие, "");
		Если лЭтоРегистрБухгалтерии Тогда
			Если ЗначениеЗаполнено(лСтрУсловие) Тогда лСтрУсловие=СтрЗаменить(лСтрУсловие, "#ИсходныеДанные#.", ""); КонецЕсли;
			лИмяТаблицы=лИмяТаблицы+".ДвиженияССубконто(, , "+лСтрУсловие+", , )";
			лСтрУсловие="";
			
		ИначеЕсли ЗначениеЗаполнено(лСтрУсловие) Тогда 
			лСтрУсловие=СтрЗаменить(лСтрУсловие, "#ИсходныеДанные#.", "_ИсходныеДанные_.");
		КонецЕсли;
		Для Каждого лКлючИЗначениеПараметр Из лСтруктураПараметрыГенерацииЗапроса.Параметры Цикл
			лЗапрос.УстановитьПараметр(лКлючИЗначениеПараметр.Ключ, лКлючИЗначениеПараметр.Значение);
		КонецЦикла;
		Если пСтруктураТаблицы.Дополнительная Тогда
			лТаблицаКонфигурации=ТсПлатформаМодули.Платформа().ТаблицаПолучить(пСтруктураТаблицы.Тип, пСтруктураТаблицы.Имя, пСтруктураТаблицы.Конфигурация, пСтруктураТаблицы.Дополнительная);
			лЗапрос.УстановитьПараметр("ВладелецТаблицы", лТаблицаКонфигурации);
			лСтрУсловие=?(ЗначениеЗаполнено(лСтрУсловие), лСтрУсловие+" И ", "")+"_ИсходныеДанные_.Владелец = &ВладелецТаблицы";
		КонецЕсли;
		Если пСтруктураКонтекст.ПолучениеРазмераТаблицы Тогда
			лСтруктураПараметрыГенерацииЗапроса.Реквизиты=СтрРазделить("	Сумма(1) КАК Количество", "/");
		КонецЕсли;
		
		лЗапрос.Текст=
		"ВЫБРАТЬ"+?(пСтруктураТаблицы.Свойство("КоличествоСтрокДляЧтения"), " ПЕРВЫЕ "+Формат(пСтруктураТаблицы.КоличествоСтрокДляЧтения, "ЧГ="), "")+"
		|"+СтрСоединить(лСтруктураПараметрыГенерацииЗапроса.Реквизиты, ","+Символы.ПС)+"
		|ПОМЕСТИТЬ "+лИмяВТОсновнойТаблицы+"
		|ИЗ
		|	"+лИмяТаблицы+" КАК _ИсходныеДанные_
		|"+СтрСоединить(лСтруктураПараметрыГенерацииЗапроса.Соединения, Символы.ПС);
		Если Не ПустаяСтрока(лСтрУсловие) Тогда
			лЗапрос.Текст=лЗапрос.Текст+"
			|ГДЕ
			|	"+лСтрУсловие;
		КонецЕсли;
		
		Если Не пСтруктураКонтекст.ПолучениеРазмераТаблицы Тогда // Для размера таблицы табличные части не важны
			Для Каждого лСтруктураТабличнаяЧасть Из лСтруктураПараметрыГенерацииЗапроса.ТабличныеЧасти Цикл
				Для Каждого лКлючИЗначениеПараметр Из лСтруктураТабличнаяЧасть.Параметры Цикл
					лЗапрос.УстановитьПараметр(лКлючИЗначениеПараметр.Ключ, лКлючИЗначениеПараметр.Значение);
				КонецЦикла;
				Если лСтруктураТабличнаяЧасть.Дополнительный Тогда 
					лТаблицаКонфигурации=ТсПлатформаМодули.Платформа().ТаблицаПолучить(пСтруктураТаблицы.Тип, пСтруктураТаблицы.Имя, пСтруктураТаблицы.Конфигурация, пСтруктураТаблицы.Дополнительная);
					лРеквизитТаблицы=ТсПлатформаМодули.Платформа().РеквизитПолучить(лТаблицаКонфигурации, лСтруктураТабличнаяЧасть.Имя, Истина);
					лЗапрос.УстановитьПараметр("РеквизитТч", лРеквизитТаблицы);
					лЗапрос.Текст=лЗапрос.Текст+";
					|
					|////////////////////////////////////////////////////////////////////////////////
					|ВЫБРАТЬ РАЗЛИЧНЫЕ
					|	ТсКонфигурацииЗначенияРеквизитов.Номер КАК Номер,
					|	ТсКонфигурацииЗначенияРеквизитов.Объект КАК Ссылка
					|ПОМЕСТИТЬ ВТЗначенияНомераСтрок
					|ИЗ
					|	РегистрСведений.ТсКонфигурацииЗначенияРеквизитов КАК ТсКонфигурацииЗначенияРеквизитов
					|ГДЕ
					|	ТсКонфигурацииЗначенияРеквизитов.Объект В (ВЫБРАТЬ _ИсходныеДанные_.Ссылка ИЗ "+лИмяВТОсновнойТаблицы+" КАК _ИсходныеДанные_)
					|	И ТсКонфигурацииЗначенияРеквизитов.Реквизит.Родитель = &РеквизитТч
					|	И ТсКонфигурацииЗначенияРеквизитов.Номер <> 0
					|;
					|
					|////////////////////////////////////////////////////////////////////////////////
					|ВЫБРАТЬ
					|	ТсКонфигурацииЗначенияРеквизитов.Номер КАК Номер,
					|	ТсКонфигурацииЗначенияРеквизитов.Реквизит КАК Реквизит,
					|	ТсКонфигурацииЗначенияРеквизитов.Значение КАК Значение,
					|	ТсКонфигурацииЗначенияРеквизитов.ЗначениеСтрока КАК ЗначениеСтрока
					|ПОМЕСТИТЬ ВТЗначения
					|ИЗ
					|	РегистрСведений.ТсКонфигурацииЗначенияРеквизитов КАК ТсКонфигурацииЗначенияРеквизитов
					|ГДЕ
					|	ТсКонфигурацииЗначенияРеквизитов.Объект В (ВЫБРАТЬ _ИсходныеДанные_.Ссылка ИЗ "+лИмяВТОсновнойТаблицы+" КАК _ИсходныеДанные_)
					|	И ТсКонфигурацииЗначенияРеквизитов.Номер <> 0
					|;
					|
					|////////////////////////////////////////////////////////////////////////////////
					|ВЫБРАТЬ
					|	_ИсходныеДанные_.Номер КАК НомерСтроки,
					|	_ИсходныеДанные_.Ссылка КАК Ссылка,
					|"+СтрСоединить(лСтруктураТабличнаяЧасть.Реквизиты, ","+Символы.ПС)+"
					|ПОМЕСТИТЬ "+лСтруктураТабличнаяЧасть.ИмяВТ+"
					|ИЗ
					|	ВТЗначенияНомераСтрок КАК _ИсходныеДанные_"
					+СтрСоединить(лСтруктураТабличнаяЧасть.Соединения, "");
				Иначе
					лЗапрос.Текст=лЗапрос.Текст+";
					|
					|////////////////////////////////////////////////////////////////////////////////
					|ВЫБРАТЬ
					|"+СтрСоединить(лСтруктураТабличнаяЧасть.Реквизиты, ","+Символы.ПС)+"
					|ПОМЕСТИТЬ "+лСтруктураТабличнаяЧасть.ИмяВТ+"
					|ИЗ
					|	"+ПолучитьИмяТаблицы1с(пСтруктураТаблицы)+"."+лСтруктураТабличнаяЧасть.Имя+" КАК _ИсходныеДанные_
					|"+СтрСоединить(лСтруктураТабличнаяЧасть.Соединения, Символы.ПС);
					Если пСтруктураТаблицы.Свойство("Отбор") или пСтруктураТаблицы.Свойство("КоличествоСтрокДляЧтения") Тогда
						лЗапрос.Текст=лЗапрос.Текст+"
						|ГДЕ
						|	_ИсходныеДанные_.Ссылка В (ВЫБРАТЬ _ИсходныеДанные_.Ссылка ИЗ "+лИмяВТОсновнойТаблицы+" КАК _ИсходныеДанные_)";
					КонецЕсли;
				КонецЕсли;
			КонецЦикла;
		КонецЕсли;
	КонецЕсли;
	
	Если пСтруктураТаблицы.Свойство("Отбор") Тогда
		ПараметрыОтбораВычислитьЗначения(пСтруктураТаблицы.Отбор.ПараметрыОтбора, пСтруктураКонтекст, пМассивПараметры);
		мПараметрыОтбораПреобразоватьГуидыВСсылки(пСтруктураТаблицы.Отбор.ПараметрыОтбора, пСоединениеКОМ);
		мПараметрыОтбораЗаменитьМассивыНаМассивыКОМ(пСтруктураТаблицы.Отбор.ПараметрыОтбора, пСоединениеКОМ);
		Для Каждого лСтруктураПараметрыОтбора Из пСтруктураТаблицы.Отбор.ПараметрыОтбора Цикл
			лЗапрос.УстановитьПараметр(лСтруктураПараметрыОтбора.Имя, лСтруктураПараметрыОтбора.Значение);
		КонецЦикла;
	КонецЕсли;
	лМассивСобытия=ТсПлатформаОбщий.ПолучитьСвойство(пСтруктураТаблицы, "События.ПриПолучении");
	ВызватьМассивСобытий(лМассивСобытия, "ПриПолучении", Новый Структура("Запрос, Контекст, СоединениеКОМ", лЗапрос, пСтруктураКонтекст, пСоединениеКОМ), пМассивПараметры);
	
	лРезультатЗапроса=лЗапрос.Выполнить(); // Для отладки: ТсПлатформаОбщий.ПолучитьВТ(лЗапрос) // ТсПлатформаМодули.Платформа().БуферЗапросовПоместить(лЗапрос)
	
	Если пСтруктураКонтекст.ПолучениеРазмераТаблицы Тогда 
		лВыборка=лРезультатЗапроса.Выбрать();
		Возврат ?(лВыборка.Следующий(), лВыборка.Количество, 0); 
	КонецЕсли;

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

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

Функция СтруктураТаблицыКонфигурацииПолучитьРазмер(пСтруктураТаблицы, пСтруктураКонтекст, пМассивПараметры, пСоединениеКОМ=Неопределено) Экспорт // TODO: Оптимизировать
	Если пСтруктураТаблицы.Тип="Перечисления" Тогда
		лТзДанные=мПолучитьТзДанныеПеречисления(пСтруктураТаблицы, пСоединениеКОМ); 
		лТзДанные=ТаблицаДанныеОтобратьПоУсловию(лТзДанные, пСтруктураТаблицы, пСтруктураКонтекст, пМассивПараметры);
		Возврат лТзДанные.Количество();
	КонецЕсли;
	пСтруктураКонтекст.Вставить("ПолучениеРазмераТаблицы", Истина);
	Возврат мПолучитьДанныеТаблицыПоСтруктуреТаблицы1с(пСтруктураТаблицы, пСтруктураКонтекст, пМассивПараметры, пСоединениеКОМ);
КонецФункции

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

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

#Область СервисОбмена
Функция мСервисПолучитьИнформацию(пПараметры, пТекстОшибки)
	Возврат ПолучитьПараметрыСервера();
КонецФункции

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

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

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

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

Функция мПолучитьСсылкуСправочникаПоУИД(пИмяСправочника, пУИД)
	Возврат Справочники[пИмяСправочника].ПолучитьСсылку(Новый УникальныйИдентификатор(пУИД));
КонецФункции 

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

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

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

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

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

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

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

Функция мСервисПравилаВыгрузкиОбновить(пПараметры, пТекстОшибки)
	лДанные=ТсПлатформаОбщий.КонвертироватьИзJSON(пПараметры.Данные);
	
	мКонстантаАгентаУстановить("ТсОбменДатаАктуальностиКонстант", ТекущаяДата());
	мКонстантаТекущаяКонфигурацияУстановить(пПараметры, лДанные);
	
	лСтруктураСвойства=Новый Структура("ДатаОбновления, ПодключениеИсточник, ПодключениеПриемник", ПрочитатьДатуJSON(лДанные.ДатаОбновления, ФорматДатыJSON.ISO), мПолучитьСсылкуПоСтруктуре("ТсПодключения", пПараметры.ПодключениеИсточник), мПолучитьСсылкуПоСтруктуре("ТсПодключения", пПараметры.ПодключениеПриемник));
	лСтруктураСвойства.Вставить("Входящее", лДанные.Входящее);
	лСтруктураСвойства.Вставить("Исходящее", лДанные.Исходящее);
	
	лДанные.ПравилоВыгрузкиКонфигурации.Правила=ТсПлатформаОбщий.КонвертироватьВJSON(лДанные.ПравилоВыгрузкиКонфигурации.Правила);
	лСпрПравилоВыгрузкиКонфигурацийСсылка=мПолучитьСсылкуПоСтруктуре("ТсОбменПравилаВыгрузокКонфигураций", лДанные.ПравилоВыгрузкиКонфигурации, лСтруктураСвойства);
	
	лМассивЗагруженныеПравилаВыгрузкиТаблиц=Новый Массив;
	Для Каждого лСтруктураПравилаВыгрузкиТаблиц Из лДанные.ПравилаВыгрузкиТаблиц Цикл
		лСтруктураПравилаВыгрузкиТаблиц.Вставить("Владелец", лСпрПравилоВыгрузкиКонфигурацийСсылка);
		лСтруктураПравилаВыгрузкиТаблиц.Вставить("Отборы", ?(лСтруктураПравилаВыгрузкиТаблиц.Свойство("Отбор"), ТсПлатформаОбщий.КонвертироватьВJSON(лСтруктураПравилаВыгрузкиТаблиц.Отбор), ""));
		лМассивЗагруженныеПравилаВыгрузкиТаблиц.Добавить(мПолучитьСсылкуПоСтруктуре("ТсОбменПравилаВыгрузокТаблиц", лСтруктураПравилаВыгрузкиТаблиц));
	КонецЦикла;
	
	лЗапрос=Новый Запрос;
	лЗапрос.УстановитьПараметр("Владелец", лСпрПравилоВыгрузкиКонфигурацийСсылка);
	лЗапрос.УстановитьПараметр("ЗагруженныеПравилаВыгрузкиТаблицы", лМассивЗагруженныеПравилаВыгрузкиТаблиц);
	лЗапрос.Текст=
	"ВЫБРАТЬ
	|	ТсОбменПравилаВыгрузокТаблиц.Ссылка КАК Ссылка
	|ИЗ
	|	Справочник.ТсОбменПравилаВыгрузокТаблиц КАК ТсОбменПравилаВыгрузокТаблиц
	|ГДЕ
	|	ТсОбменПравилаВыгрузокТаблиц.Владелец = &Владелец
	|	И НЕ ТсОбменПравилаВыгрузокТаблиц.Ссылка В (&ЗагруженныеПравилаВыгрузкиТаблицы)";
	лВыборка=лЗапрос.Выполнить().Выбрать();
	Пока лВыборка.Следующий() Цикл лВыборка.Ссылка.ПолучитьОбъект().Удалить(); КонецЦикла;
	ОбновитьПовторноИспользуемыеЗначения(); // Обновились константы
	Возврат Истина;
КонецФункции
#КонецОбласти 

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

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

Функция мЭтоРеквизитТипаДата(пСтруктураРеквизит)
	Если пСтруктураРеквизит.Типы=Неопределено Тогда Возврат Ложь; КонецЕсли;
	Если пСтруктураРеквизит.Типы.Количество()<>1 Тогда Возврат Ложь; КонецЕсли;
	Возврат пСтруктураРеквизит.Типы[0].Тип="Дата";
КонецФункции

Функция мДанныеТаблицыКонвертироватьПоляТипаДата(пСтруктураТаблица, пДанные, пТчПриемник="")
	Если пДанные.Количество()=0 Тогда Возврат Истина; КонецЕсли;
	лСтрокаДанныеПервая=пДанные[0];
	лМассивКолонкиТипаДата=Новый Массив;
	лРеквизитТч=Неопределено;
	Для Каждого лСтруктураРеквизиты Из пСтруктураТаблица.Реквизиты Цикл
		Если лСтруктураРеквизиты.Имя=пТчПриемник Тогда лРеквизитТч=лСтруктураРеквизиты; КонецЕсли;
		Если Не ТсПлатформаОбщий.СуществуетСвойство(лСтрокаДанныеПервая, лСтруктураРеквизиты.Имя) Тогда Продолжить; КонецЕсли; 
		Если Не мЭтоРеквизитТипаДата(лСтруктураРеквизиты) Тогда Продолжить; КонецЕсли;
		лМассивКолонкиТипаДата.Добавить(лСтруктураРеквизиты.Имя);
	КонецЦикла;
	Если ЗначениеЗаполнено(лРеквизитТч) Тогда // Это если идет в табличную часть
		Для Каждого лСтруктураРеквизиты Из лРеквизитТч.Реквизиты Цикл
			Если лСтруктураРеквизиты.Имя=пТчПриемник Тогда лРеквизитТч=лСтруктураРеквизиты; КонецЕсли;
			Если Не ТсПлатформаОбщий.СуществуетСвойство(лСтрокаДанныеПервая, лСтруктураРеквизиты.Имя) Тогда Продолжить; КонецЕсли; 
			Если Не мЭтоРеквизитТипаДата(лСтруктураРеквизиты) Тогда Продолжить; КонецЕсли;
			лМассивКолонкиТипаДата.Добавить(лСтруктураРеквизиты.Имя);
		КонецЦикла;
	КонецЕсли;
	Если лМассивКолонкиТипаДата.Количество()=0 Тогда Возврат Истина; КонецЕсли;
	Для Каждого лСтрокаДанные Из пДанные Цикл
		Для Каждого лИмяКолонки Из лМассивКолонкиТипаДата Цикл
			лЗначение=лСтрокаДанные[лИмяКолонки];
			лСтрокаДанные[лИмяКолонки]=?(ЗначениеЗаполнено(лЗначение), ПрочитатьДатуJSON(лЗначение, ФорматДатыJSON.ISO), Дата(1, 1, 1));
		КонецЦикла;
	КонецЦикла;
КонецФункции

Функция ДанныеКонвертироватьПоляТипаДата(пДанные, пПравилаКонвертацииТаблиц=Неопределено) Экспорт
	Для Каждого лСтруктураДанные Из пДанные Цикл
		Если пПравилаКонвертацииТаблиц=Неопределено Тогда // TODO: исправить!!!!!!!!!!!!!!
			лСтрокаПравилаКонвертации=лСтруктураДанные;
		Иначе
			лСтрокаПравилаКонвертации=мМассивНайтиВМассивеСтруктур(пПравилаКонвертацииТаблиц, "КодПравила", лСтруктураДанные.КодПравила);
		КонецЕсли;
		
		Если лСтрокаПравилаКонвертации.ТаблицаПриемник=Неопределено Тогда Продолжить; КонецЕсли;
		мДанныеТаблицыКонвертироватьПоляТипаДата(лСтрокаПравилаКонвертации.ТаблицаПриемник, лСтруктураДанные.Данные);
		Если Не лСтруктураДанные.Свойство("ДанныеТч") Тогда Продолжить; КонецЕсли;
		Для Каждого лСтруктураДанныеТч Из лСтруктураДанные.ДанныеТч Цикл
			Если ТипЗнч(лСтруктураДанныеТч)=Тип("Структура") Тогда 
				лИмяТч=лСтрокаПравилаКонвертации.ПравилаКонвертацииРеквизитов[лСтруктураДанныеТч.Индекс].РеквизитПриемникИмя;
				лСтруктураРеквизитыТч=мМассивНайтиВМассивеСтруктур(лСтрокаПравилаКонвертации.ТаблицаПриемник.Реквизиты, "Имя", лИмяТч);
				мДанныеТаблицыКонвертироватьПоляТипаДата(лСтруктураРеквизитыТч, лСтруктураДанныеТч.Данные);
			Иначе // это для простой загрузки таблицы
				лСтруктураРеквизитыТч=мМассивНайтиВМассивеСтруктур(лСтрокаПравилаКонвертации.ТаблицаПриемник.Реквизиты, "Имя", лСтруктураДанныеТч.Ключ);
				мДанныеТаблицыКонвертироватьПоляТипаДата(лСтруктураРеквизитыТч, лСтруктураДанныеТч.Значение);
			КонецЕсли;
		КонецЦикла;
	КонецЦикла;
КонецФункции 

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

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

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

Функция мСервисПолучитьКонфигурациюПодключения(пПараметры, пТекстОшибки="")
	лПодключение=Справочники.ТсПодключения.ПолучитьСсылку(Новый УникальныйИдентификатор(пПараметры.ПодключениеУИД));
	Если ПустаяСтрока(лПодключение.ВерсияДанных) Тогда пТекстОшибки="Подключение по УИД не найдено!"; Возврат Неопределено; КонецЕсли;
	
	лПравилоВыгрузкиКонфигурации=Неопределено;
	Если пПараметры.Свойство("ПравилоВыгрузкиКонфигурацииУИД") Тогда
		лПравилоВыгрузкиКонфигурации=Справочники.ТсОбменПравилаВыгрузокКонфигураций.ПолучитьСсылку(Новый УникальныйИдентификатор(пПараметры.ПравилоВыгрузкиКонфигурацииУИД));
		Если ПустаяСтрока(лПравилоВыгрузкиКонфигурации.ВерсияДанных) Тогда пТекстОшибки="Правило выгрузки конфигурации по УИД не найдено!"; Возврат Неопределено; КонецЕсли;
		Если лПравилоВыгрузкиКонфигурации.ДатаОбновления=ПрочитатьДатуJSON(пПараметры.ДатаОбновления, ФорматДатыJSON.ISO) Тогда Возврат Новый Массив; КонецЕсли;
	КонецЕсли;
	
	лТекущееПодключение=лПодключение;
	лМассивПодключения=Новый Массив;
	лМассивПодключения.Добавить(лТекущееПодключение);
	Пока ЗначениеЗаполнено(лТекущееПодключение.Родитель) Цикл
		лТекущееПодключение=лТекущееПодключение.Родитель;
		лМассивПодключения.Добавить(лТекущееПодключение);
	КонецЦикла; 
	
	лЗапрос=Новый Запрос;
	лЗапрос.УстановитьПараметр("Подключения", лМассивПодключения);
	лЗапрос.УстановитьПараметр("ПравилоВыгрузкиКонфигурации", лПравилоВыгрузкиКонфигурации);
	лЗапрос.Текст=
	"ВЫБРАТЬ
	|	ТсОбменПравилаВыгрузокКонфигураций.Ссылка КАК Ссылка, 
	|	ТсОбменПравилаВыгрузокКонфигураций.Входящее, 
	|	ТсОбменПравилаВыгрузокКонфигураций.Исходящее,
	|	ТсОбменПравилаВыгрузокКонфигураций.ПодключениеИсточник В (&Подключения) КАК ПодключениеЯвляетсяИсточником
	|ИЗ
	|	Справочник.ТсОбменПравилаВыгрузокКонфигураций КАК ТсОбменПравилаВыгрузокКонфигураций
	|ГДЕ
	|	(ТсОбменПравилаВыгрузокКонфигураций.ПодключениеИсточник В (&Подключения)
	|		ИЛИ ТсОбменПравилаВыгрузокКонфигураций.ПодключениеПриемник В (&Подключения))
	|	И ТсОбменПравилаВыгрузокКонфигураций.Включен
	|	И НЕ ТсОбменПравилаВыгрузокКонфигураций.ПометкаУдаления";
	Если ЗначениеЗаполнено(лПравилоВыгрузкиКонфигурации) Тогда 
		лЗапрос.Текст=лЗапрос.Текст+Символы.ПС+"	И ТсОбменПравилаВыгрузокКонфигураций.Ссылка = &ПравилоВыгрузкиКонфигурации";
	КонецЕсли;
	
	лМассивПравилаВыгрузкиСтруктуры=Новый Массив;
	лВыборка=лЗапрос.Выполнить().Выбрать();
	Пока лВыборка.Следующий() Цикл
		лСтруктураПравилаВыгрузки=ПравилаВыгрузкиПолучитьСтруктуруДляВыгрузки(лВыборка.Ссылка, лПодключение, лВыборка.ПодключениеЯвляетсяИсточником, Не лВыборка.Входящее, Не лВыборка.Исходящее);
		лМассивПравилаВыгрузкиСтруктуры.Добавить(лСтруктураПравилаВыгрузки);
	КонецЦикла;
	Возврат лМассивПравилаВыгрузкиСтруктуры;
КонецФункции 

Функция мПакетыОбменаПолучитьСохраненныеПоПравилуВыгрузки(пПравилоВыгрузкиКонфигурации, пПодключение)
	лЗапрос=Новый Запрос;
	лЗапрос.УстановитьПараметр("ПравилоВыгрузкиКонфигурации", пПравилоВыгрузкиКонфигурации);
	лЗапрос.УстановитьПараметр("Подключение", пПодключение);
	лЗапрос.Текст=
	"ВЫБРАТЬ
	|	ТсОбменПакетыСобытияСохранение.Пакет КАК Пакет
	|ИЗ
	|	РегистрСведений.ТсОбменПакетыСобытия КАК ТсОбменПакетыСобытияСохранение
	|ГДЕ
	|	ТсОбменПакетыСобытияСохранение.Событие = ЗНАЧЕНИЕ(Перечисление.ТсОбменПакетыСобытия.Сохранение)
	|	И НЕ ТсОбменПакетыСобытияСохранение.Ошибка
	|	И НЕ ТсОбменПакетыСобытияСохранение.Пакет.ПометкаУдаления
	|	И ТсОбменПакетыСобытияСохранение.Пакет.ПравилоВыгрузкиКонфигурации = &ПравилоВыгрузкиКонфигурации
	|	И ТсОбменПакетыСобытияСохранение.Пакет.ПодключениеПриемник = &Подключение
	|	И НЕ ТсОбменПакетыСобытияСохранение.Пакет В
	|				(ВЫБРАТЬ РАЗЛИЧНЫЕ
	|					ТсОбменПакетыСобытияПрочиеСобытия.Пакет
	|				ИЗ
	|					РегистрСведений.ТсОбменПакетыСобытия КАК ТсОбменПакетыСобытияПрочиеСобытия
	|				ГДЕ
	|					ТсОбменПакетыСобытияПрочиеСобытия.Событие <> ЗНАЧЕНИЕ(Перечисление.ТсОбменПакетыСобытия.Сохранение)
	|					И НЕ ТсОбменПакетыСобытияПрочиеСобытия.Ошибка)
	|
	|УПОРЯДОЧИТЬ ПО
	|	ТсОбменПакетыСобытияСохранение.Позиция,
	|	ТсОбменПакетыСобытияСохранение.Пакет.Код";
	Возврат лЗапрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Пакет");
КонецФункции

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

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

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

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

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

#Если Не МобильноеПриложениеСервер Тогда
Функция мСервисОбработатьМетодOPTIONS(пЗапрос) // Для редиректов
	лХТТПСервисОтвет=Новый HTTPСервисОтвет(200);
	лХТТПСервисОтвет.Заголовки.Вставить("Access-Control-Allow-Origin", "*");
	лХТТПСервисОтвет.Заголовки.Вставить("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization");
	лХТТПСервисОтвет.Заголовки.Вставить("Access-Control-Allow-Methods", "GET, PATCH, PUT, POST, DELETE, OPTIONS");
	Возврат лХТТПСервисОтвет;
КонецФункции

Функция мСервисПолучитьИмяФункции(пЗапрос)
	лИмяМетода=Сред(пЗапрос.ОтносительныйURL, 2); // Уберем слэш впереди
	Если лИмяМетода="Info" Тогда Возврат "мСервисПолучитьИнформацию"; КонецЕсли;
	Если лИмяМетода="Test" Тогда Возврат ""; КонецЕсли;
	Если лИмяМетода="GetStructure" Тогда Возврат "мСервисПолучитьСтруктуру"; КонецЕсли;
	Если лИмяМетода="GetStatistics" Тогда Возврат "мСервисПолучитьСтатистику"; КонецЕсли;
	
	Если лИмяМетода="GetData" Тогда Возврат "мСервисДанныеВыгрузить"; КонецЕсли;
	Если лИмяМетода="PutData" Тогда Возврат "мСервисДанныеЗагрузить"; КонецЕсли;
	Если лИмяМетода="PutResult" Тогда Возврат "мСервисЗаписатьРезультатыЗагрузки"; КонецЕсли;
	Если лИмяМетода="GetResult" Тогда Возврат "мСервисПолучитьРезультатыЗагрузки"; КонецЕсли;
	Если лИмяМетода="PutResultEvents" Тогда Возврат "мСервисЗаписатьСобытияРезультатовЗагрузки"; КонецЕсли;
	
	Если лИмяМетода="UpdateRules" Тогда Возврат "мСервисПравилаВыгрузкиОбновить"; КонецЕсли; // для загрузки правил в текущую конфигурацию
	Если лИмяМетода="GetConnectionConfig" Тогда Возврат "мСервисПолучитьКонфигурациюПодключения"; КонецЕсли; // для подключения к текущей конфигурации другой которая умеет забирать данные
	
	// доделать!!!!!!!!!!!!!!!
	Если лИмяМетода="GetRules" Тогда Возврат "мСервисПолучитьПравила"; КонецЕсли; // получает правила для конфигурации которая забирает данные
	
	Если лИмяМетода="GetDataForRules" Тогда Возврат "мСервисПолучитьДанныеПоПравилуЗагрузки"; КонецЕсли; // получает данные для конфигурации которая забирает данные
	Если лИмяМетода="GetAllDataForRule" Тогда Возврат "мСервисПолучитьВсеДанныеПоПравилуЗагрузки"; КонецЕсли;
	Если лИмяМетода="UpdatePackageState" Тогда Возврат "мСервисПакетыОбновитьСостоянияНаВыгружены"; КонецЕсли; // для обновления состояния пакетов на Выгружены данные
	
	
	Если лИмяМетода="GetTableData" Тогда Возврат "мСервисТаблицаПолучитьДанные"; КонецЕсли;
	Если лИмяМетода="GetTableSize" Тогда Возврат "мСервисТаблицаПолучитьРазмер"; КонецЕсли;
	Если лИмяМетода="PutTableData" Тогда Возврат "мСервисТаблицаЗаписатьДанные"; КонецЕсли;
	
	Если лИмяМетода="StartScript" Тогда Возврат "мСервисСценарийЗапустить"; КонецЕсли;
	Если лИмяМетода="ExecuteUserMethod" Тогда Возврат "мСервисВыполнитьПользовательскийМетод"; КонецЕсли;
	Возврат Неопределено;
КонецФункции

Функция мHTTPОтветТекст(пДанные, пКод=200)
	#Если Не МобильноеПриложениеСервер Тогда
	лХТТПСервисОтвет=Новый HTTPСервисОтвет(пКод);
	лХТТПСервисОтвет.Заголовки.Вставить("Content-Type", "application/json");
	лХТТПСервисОтвет.УстановитьТелоИзСтроки(пДанные);
	Возврат лХТТПСервисОтвет;
	#КонецЕсли
КонецФункции 

Функция мHTTPОтветДвоичныеДанные(пДанные, пКод=200)
	#Если Не МобильноеПриложениеСервер Тогда
	лХТТПСервисОтвет=Новый HTTPСервисОтвет(пКод);
	лХТТПСервисОтвет.Заголовки.Вставить("Content-Type", "application/octet-stream");
	лХТТПСервисОтвет.УстановитьТелоИзДвоичныхДанных(пДанные);
	Возврат лХТТПСервисОтвет;
	#КонецЕсли
КонецФункции

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

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

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

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

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

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

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

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

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

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

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

Функция ПравилоВыгрузкиКонфигурацииПолучитьКонтекст(пПравилоВыгрузкиКонфигурации) Экспорт // TODO: перенести в повт исп!
	лСтруктураКонтекст=Неопределено;
	лСтруктураКонтекст=ТсПлатформаОбщий.КонвертироватьИзJSON(пПравилоВыгрузкиКонфигурации.Правила);
	МассивПараметрыПреобразоватьПараметрыТипаДата(лСтруктураКонтекст.Параметры);
	МассивПараметрыПреобразоватьПараметрыТипаДата(лСтруктураКонтекст.ПодключениеИсточник.Параметры);
	МассивПараметрыПреобразоватьПараметрыТипаДата(лСтруктураКонтекст.ПодключениеПриемник.Параметры);
	МассивПараметрыПреобразоватьПараметрыТипаДата(лСтруктураКонтекст.ПравилоКонвертацииКонфигурации.Параметры);
	МассивПараметрыПреобразоватьПараметрыТипаДата(лСтруктураКонтекст.ПравилоКонвертацииКонфигурации.КонфигурацияИсточник.Параметры);
	МассивПараметрыПреобразоватьПараметрыТипаДата(лСтруктураКонтекст.ПравилоКонвертацииКонфигурации.КонфигурацияПриемник.Параметры);
	Возврат лСтруктураКонтекст;
КонецФункции

Функция мПолучитьПравилоВыгрузкиТаблицы(пПравилоВыгрузкиКонфигурации, пТип, пИмя, пРаботаВРежимеАгента)
	лЗапрос=Новый Запрос;
	лЗапрос.УстановитьПараметр("Владелец", пПравилоВыгрузкиКонфигурации);
	лЗапрос.УстановитьПараметр("Тип", пТип);
	лЗапрос.УстановитьПараметр("Имя", пИмя);
	лЗапрос.Текст=
	"ВЫБРАТЬ
	|	ТсОбменПравилаВыгрузокТаблиц.Ссылка КАК Ссылка
	|ИЗ
	|	Справочник.ТсОбменПравилаВыгрузокТаблиц КАК ТсОбменПравилаВыгрузокТаблиц
	|ГДЕ
	|	ТсОбменПравилаВыгрузокТаблиц.Владелец = &Владелец
	|	И НЕ ТсОбменПравилаВыгрузокТаблиц.ПометкаУдаления
	|	И ТсОбменПравилаВыгрузокТаблиц"+?(пРаботаВРежимеАгента, "", ".ПравилоКонвертацииТаблицы.ТаблицаИсточник")+".Тип = &Тип
	|	И ТсОбменПравилаВыгрузокТаблиц"+?(пРаботаВРежимеАгента, "", ".ПравилоКонвертацииТаблицы.ТаблицаИсточник")+".Имя = &Имя";
	лВыборка=лЗапрос.Выполнить().Выбрать();
	Возврат ?(лВыборка.Следующий(), лВыборка.Ссылка, Справочники.ТсОбменПравилаВыгрузокТаблиц.ПустаяСсылка());
КонецФункции

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

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

Функция мПакетыОбменаВыгрузить(пТолькоПоПравиламВыгрузкиКонфигураций=Ложь)
	лПодключениеТекущее=ТсПлатформаОбщий.КонстантаПолучить("ТсПлатформаПодключениеЧерезСервис");
	лНеобходимаЗагрузкаРезультатовСоСтороныИсточника=ЗначениеЗаполнено(лПодключениеТекущее) и лПодключениеТекущее.ЗабираетДанные;
	лМассивПодключенияДляЗагрузкиРезультатов=Новый Массив;
	
	лКоличество=0;
	лМассивПакетыСОшибками=Новый Массив;
	Попытка
		Пока Истина Цикл
			лЗапрос=Новый Запрос;
			лЗапрос.УстановитьПараметр("ПакетыСОшибками", лМассивПакетыСОшибками);
			лЗапрос.Текст=
			"ВЫБРАТЬ ПЕРВЫЕ 10
			|	ТсОбменПакеты.Ссылка КАК Ссылка,
			|	ТсОбменПакеты.ПодключениеИсточник КАК ПодключениеИсточник,
			|	ТсОбменПакеты.ПодключениеПриемник КАК ПодключениеПриемник
			|ИЗ
			|	Справочник.ТсОбменПакеты КАК ТсОбменПакеты
			|		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ТсОбменПакетыСобытия КАК ТсОбменПакетыСобытия
			|		ПО (ТсОбменПакетыСобытия.Пакет = ТсОбменПакеты.Ссылка)
			|			И (ТсОбменПакетыСобытия.Событие = ЗНАЧЕНИЕ(Перечисление.ТсОбменПакетыСобытия.Выгрузка))
			|ГДЕ
			|	ТсОбменПакеты.Исходящий
			|	И НЕ ТсОбменПакеты.Ссылка В (&ПакетыСОшибками)
			|	И НЕ ТсОбменПакеты.ПометкаУдаления
			|	И ТсОбменПакеты.ПодключениеПриемник <> ЗНАЧЕНИЕ(Справочник.ТсПодключения.ПустаяСсылка)
			|	И НЕ ТсОбменПакеты.ПодключениеПриемник.ЗабираетДанные
			|	И ТсОбменПакетыСобытия.Позиция ЕСТЬ NULL
			|	"+?(пТолькоПоПравиламВыгрузкиКонфигураций, "И ТсОбменПакеты.ПравилоВыгрузкиКонфигурации <> ЗНАЧЕНИЕ(Справочник.ТсОбменПравилаВыгрузокКонфигураций.ПустаяСсылка)", "")+"
			|
			|УПОРЯДОЧИТЬ ПО
			|	ТсОбменПакеты.Дата";
			лРезультатЗапроса=лЗапрос.Выполнить();
			Если лРезультатЗапроса.Пустой() Тогда Прервать; КонецЕсли;
			лВыборка=лРезультатЗапроса.Выбрать();
			Пока лВыборка.Следующий() Цикл
				Если лНеобходимаЗагрузкаРезультатовСоСтороныИсточника и лВыборка.ПодключениеИсточник=лПодключениеТекущее и лМассивПодключенияДляЗагрузкиРезультатов.Найти(лВыборка.ПодключениеПриемник)=Неопределено Тогда
					лМассивПодключенияДляЗагрузкиРезультатов.Добавить(лВыборка.ПодключениеПриемник);
				КонецЕсли;
				лДанные=ПакетОбменаПолучитьДанные(лВыборка.Ссылка);
				Попытка	
					лСтруктураДанные=ТсПлатформаОбщий.КонвертироватьИзJSON(лДанные);
					лТекстОшибки="";
					Если ПакетОбменаВыгрузить(лВыборка.Ссылка, лВыборка.ПодключениеПриемник, лСтруктураДанные, лТекстОшибки) Тогда 
						лКоличество=лКоличество+1; 
						Продолжить; 
					КонецЕсли;
				Исключение 
					лИнформацияОбОшибке=ИнформацияОбОшибке();
					лТекстОшибки=ТсПлатформаОбщий.ПолучитьПолноеОписаниеОшибки(лИнформацияОбОшибке);
				КонецПопытки;
				лМассивПакетыСОшибками.Добавить(лВыборка.Ссылка);
				Сообщить(лТекстОшибки); 
			КонецЦикла;
		КонецЦикла;
	Исключение
		лИнформацияОбОшибке=ИнформацияОбОшибке();
		Сообщить(ТсПлатформаОбщий.ПолучитьПолноеОписаниеОшибки(лИнформацияОбОшибке));
	КонецПопытки;
	
	Если лНеобходимаЗагрузкаРезультатовСоСтороныИсточника Тогда // для источников с галкой "Забирает данные"
		лПараметры=Новый Структура("Подключение", ""+лПодключениеТекущее.УникальныйИдентификатор());
		Для Каждого лПодключение Из лМассивПодключенияДляЗагрузкиРезультатов Цикл
			лТекстОшибки="";
			лСтруктураОтвета=ЗапросPOSTКСерверуОбмена("GetResult", лПодключение, лПараметры, Новый Структура("Таймаут", 10), лТекстОшибки);
			Если лСтруктураОтвета=Неопределено Тогда Сообщить("Не получилось забрать данные о результатах загрузки пакетов: "+лТекстОшибки); Продолжить; КонецЕсли;
			
			лМассивПакетыОбработанные=Новый Массив;
			Для Каждого лСтруктураДанные Из лСтруктураОтвета.Данные Цикл
				лТекстОшибки="";
				Если мСервисЗаписатьРезультатыЗагрузки(лСтруктураДанные, лТекстОшибки)=Неопределено Тогда 
					Сообщить(лТекстОшибки);
				Иначе
					лМассивПакетыОбработанные.Добавить(лСтруктураДанные.Пакет);
				КонецЕсли;
			КонецЦикла;
			
			лСтруктураОтвета=ЗапросPOSTКСерверуОбмена("PutResultEvents", лПодключение, лМассивПакетыОбработанные, Новый Структура("Таймаут", 10), лТекстОшибки);
			Если лСтруктураОтвета=Неопределено Тогда Сообщить("Не получилось записать событие передачи данных в подключение источник: "+лТекстОшибки); Продолжить; КонецЕсли;
		КонецЦикла;
	КонецЕсли;
	Возврат лКоличество;
КонецФункции

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

Функция мСервисЗаписатьРезультатыЗагрузки(пПараметры, пТекстОшибки)
	лСпрПакетыСсылка=Справочники.ТсОбменПакеты.ПолучитьСсылку(Новый УникальныйИдентификатор(пПараметры.Пакет));
	Если лСпрПакетыСсылка.ПолучитьОбъект()=Неопределено Тогда 
		//пТекстОшибки="Не найден пакет с идентификатором: "+пПараметры.Пакет; 
		//Возврат Неопределено; 
		Возврат Истина;
	КонецЕсли;
	
	лТзОбъектыПакета=Новый ТаблицаЗначений;
	лТзОбъектыПакета.Колонки.Добавить("Номер", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(10, 0, ДопустимыйЗнак.Неотрицательный)));
	лТзОбъектыПакета.Колонки.Добавить("КодПравила", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(5, 0, ДопустимыйЗнак.Неотрицательный)));
	лТзОбъектыПакета.Колонки.Добавить("КлючОбъекта", Новый ОписаниеТипов("Строка",, Новый КвалификаторыСтроки(50)));
	лТзОбъектыПакета.Колонки.Добавить("Загружен", Новый ОписаниеТипов("Булево"));
	лТзОбъектыПакета.Колонки.Добавить("Ошибка", Новый ОписаниеТипов("Булево"));
	лТзОбъектыПакета.Колонки.Добавить("ТекстСообщения", Новый ОписаниеТипов("Строка",, Новый КвалификаторыСтроки(0)));
	
	мЗаполнитьТзИзМассиваСтруктур(лТзОбъектыПакета, пПараметры.Объекты, Ложь);
	
	лЗапрос=Новый Запрос;
	лЗапрос.УстановитьПараметр("Пакет", лСпрПакетыСсылка);
	лЗапрос.УстановитьПараметр("ТзОбъектыПакета", лТзОбъектыПакета);
	лЗапрос.Текст=
	"ВЫБРАТЬ
	|	ТзОбъектыПакета.Номер КАК Номер,
	|	ТзОбъектыПакета.КодПравила КАК КодПравила,
	|	ТзОбъектыПакета.КлючОбъекта КАК КлючОбъекта,
	|	ТзОбъектыПакета.Загружен КАК Загружен,
	|	ТзОбъектыПакета.Ошибка КАК Ошибка,
	|	ТзОбъектыПакета.ТекстСообщения КАК ТекстСообщения
	|ПОМЕСТИТЬ ВТОбъектыПакета
	|ИЗ
	|	&ТзОбъектыПакета КАК ТзОбъектыПакета
	|;
	|
	|////////////////////////////////////////////////////////////////////////////////
	|ВЫБРАТЬ
	|	ТсОбменОбъектыПакетов.Пакет КАК Пакет,
	|	ТсОбменОбъектыПакетов.КодПравила КАК КодПравила,
	|	ТсОбменОбъектыПакетов.Номер КАК Номер,
	|	ЕСТЬNULL(ВТОбъектыПакета.КлючОбъекта, ТсОбменОбъектыПакетов.КлючОбъекта) КАК КлючОбъекта,
	|	ЕСТЬNULL(ВТОбъектыПакета.Загружен, ТсОбменОбъектыПакетов.Загружен) КАК Загружен,
	|	ЕСТЬNULL(ВТОбъектыПакета.Ошибка, ТсОбменОбъектыПакетов.Ошибка) КАК Ошибка,
	|	ЕСТЬNULL(ВТОбъектыПакета.ТекстСообщения, ТсОбменОбъектыПакетов.ТекстСообщения) КАК ТекстСообщения
	|ИЗ
	|	РегистрСведений.ТсОбменОбъектыПакетов КАК ТсОбменОбъектыПакетов
	|		ЛЕВОЕ СОЕДИНЕНИЕ ВТОбъектыПакета КАК ВТОбъектыПакета
	|		ПО ТсОбменОбъектыПакетов.КодПравила = ВТОбъектыПакета.КодПравила
	|			И ТсОбменОбъектыПакетов.Номер = ВТОбъектыПакета.Номер
	|ГДЕ
	|	ТсОбменОбъектыПакетов.Пакет = &Пакет";
	лВыборка=лЗапрос.Выполнить().Выбрать();
	
	лНаборЗаписей=РегистрыСведений.ТсОбменОбъектыПакетов.СоздатьНаборЗаписей();
	лНаборЗаписей.ОбменДанными.Загрузка=Истина;
	лНаборЗаписей.Отбор.Пакет.Установить(лСпрПакетыСсылка);
		
	лОшибка=Ложь;
	Попытка
		Пока лВыборка.Следующий() Цикл
			лЗапись=лНаборЗаписей.Добавить();
			ЗаполнитьЗначенияСвойств(лЗапись, лВыборка);
		КонецЦикла;
		лНаборЗаписей.Записать();
		
		//Для Каждого лСтруктураОбъекты Из пПараметры.Объекты Цикл
		//	лЗапись=РегистрыСведений.ТсОбменОбъектыПакетов.СоздатьМенеджерЗаписи();
		//	ЗаполнитьЗначенияСвойств(лЗапись, лСтруктураОбъекты, "Тип, Имя, Номер");
		//	лЗапись.Пакет=лСпрПакетыСсылка;
		//	лЗапись.Прочитать();
		//	Если лЗапись.Выбран() Тогда 
		//		ЗаполнитьЗначенияСвойств(лЗапись, лСтруктураОбъекты, "Загружен, Ошибка, ТекстСообщения");
		//		лЗапись.Записать();
		//	КонецЕсли;
		//КонецЦикла;
	Исключение 
		лИнформацияОбОшибке=ИнформацияОбОшибке();
		пТекстОшибки=ТсПлатформаОбщий.ПолучитьПолноеОписаниеОшибки(лИнформацияОбОшибке);
		лОшибка=Истина;
	КонецПопытки; 
	
	лДанныеПакета=ТсПлатформаОбщий.КонвертироватьИзJSON(ПакетОбменаПолучитьДанные(лСпрПакетыСсылка));
	лДанныеПакета.Вставить("ОбъектыПакета", лТзОбъектыПакета);
	лСобытияФиксацияРезультата=ТсПлатформаОбщий.ПолучитьСвойство(лДанныеПакета, "Контекст.События.ФиксацияРезультата");
	Если лСобытияФиксацияРезультата<>Неопределено Тогда
		ВызватьМассивСобытий(лСобытияФиксацияРезультата, "ФиксацияРезультата", лДанныеПакета,, Ложь);
	КонецЕсли;
	
	ПакетОбменаЗаписатьСобытие(лСпрПакетыСсылка, Перечисления.ТсОбменПакетыСобытия.ЗаписьРезультата, лОшибка, пТекстОшибки);
	Если лСпрПакетыСсылка.Входящий Тогда ПакетыОбменаПередатьРезультаты(Истина); КонецЕсли;
	Возврат ?(лОшибка, Неопределено, Истина); // если ошибка нужно вернуть Неопределено
КонецФункции

Функция мСервисПолучитьРезультатыЗагрузки(пПараметры, пТекстОшибки)
	лПодключение=Справочники.ТсПодключения.ПолучитьСсылку(Новый УникальныйИдентификатор(пПараметры.Подключение));
	Если лПодключение.ПолучитьОбъект()=Неопределено Тогда пТекстОшибки="Не найдено подключение с идентификатором: "+пПараметры.Подключение; Возврат Неопределено; КонецЕсли;
	
	лЗапрос=Новый Запрос;
	лЗапрос.УстановитьПараметр("Подключение", лПодключение);
	лЗапрос.Текст=
	"ВЫБРАТЬ ПЕРВЫЕ 10
	|	ТсОбменПакеты.Ссылка КАК Ссылка
	|ИЗ
	|	Справочник.ТсОбменПакеты КАК ТсОбменПакеты
	|		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ТсОбменПакетыСобытия КАК ТсОбменПакетыСобытияЗаписьРезультата
	|		ПО (ТсОбменПакетыСобытияЗаписьРезультата.Пакет = ТсОбменПакеты.Ссылка)
	|			И (ТсОбменПакетыСобытияЗаписьРезультата.Событие = ЗНАЧЕНИЕ(Перечисление.ТсОбменПакетыСобытия.ЗаписьРезультата))
	|			И (НЕ ТсОбменПакетыСобытияЗаписьРезультата.Ошибка)
	|		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ТсОбменПакетыСобытия КАК ТсОбменПакетыСобытияПередачаРезультата
	|		ПО (ТсОбменПакетыСобытияПередачаРезультата.Пакет = ТсОбменПакеты.Ссылка)
	|			И (ТсОбменПакетыСобытияПередачаРезультата.Событие = ЗНАЧЕНИЕ(Перечисление.ТсОбменПакетыСобытия.ПередачаРезультата))
	|ГДЕ
	|	ТсОбменПакеты.Входящий
	|	И НЕ ТсОбменПакеты.ПометкаУдаления
	|	И НЕ ТсОбменПакетыСобытияЗаписьРезультата.Позиция ЕСТЬ NULL
	|	И ТсОбменПакетыСобытияПередачаРезультата.Позиция ЕСТЬ NULL
	|	И ТсОбменПакеты.ПодключениеИсточник = &Подключение
	|
	|УПОРЯДОЧИТЬ ПО
	|	ТсОбменПакеты.Дата";
	лРезультатЗапроса=лЗапрос.Выполнить();
	лМассивДанные=Новый Массив;
	Если лРезультатЗапроса.Пустой() Тогда Возврат лМассивДанные; КонецЕсли;
	
	лВыборка=лРезультатЗапроса.Выбрать();
	Пока лВыборка.Следующий() Цикл
		лМассивОбъекты=мПакетОбменаПолучитьРезультаты(лВыборка.Ссылка);
		лМассивДанные.Добавить(Новый Структура("Пакет, Объекты", ""+лВыборка.Ссылка.УникальныйИдентификатор(), лМассивОбъекты));
	КонецЦикла;
	
	Возврат лМассивДанные; 
КонецФункции 

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

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

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

Функция мПакетОбменаПолучитьРезультаты(пПакет)
	лЗапрос=Новый Запрос;
	лЗапрос.УстановитьПараметр("Пакет", пПакет);
	лЗапрос.Текст=
	"ВЫБРАТЬ
	|	ТсОбменОбъектыПакетов.Номер КАК Номер,
	|	ТсОбменОбъектыПакетов.КодПравила КАК КодПравила,
	|	ТсОбменОбъектыПакетов.КлючОбъекта КАК КлючОбъекта,
	|	ТсОбменОбъектыПакетов.Загружен КАК Загружен,
	|	ТсОбменОбъектыПакетов.Ошибка КАК Ошибка,
	|	ТсОбменОбъектыПакетов.ТекстСообщения КАК ТекстСообщения
	|ИЗ
	|	РегистрСведений.ТсОбменОбъектыПакетов КАК ТсОбменОбъектыПакетов
	|ГДЕ
	|	ТсОбменОбъектыПакетов.Пакет = &Пакет";
	
	лМассивОбъекты=Новый Массив;
	лВыборка=лЗапрос.Выполнить().Выбрать();
	Пока лВыборка.Следующий() Цикл
		лСтруктураОбъекта=Новый Структура("Номер, КодПравила, КлючОбъекта, Загружен, Ошибка, ТекстСообщения");
		ЗаполнитьЗначенияСвойств(лСтруктураОбъекта, лВыборка);
		лМассивОбъекты.Добавить(лСтруктураОбъекта);
	КонецЦикла;
	Возврат лМассивОбъекты; 
КонецФункции 

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

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

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

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

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

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

Функция мПравилаВыгрузокСформироватьПакеты(пПараметры, пМассивУИДВыгруженные, пНеобходимоВыгружатьПакеты, пНеобходимоЗагружатьПакеты, лЕстьОшибки)
	лПравилоВыгрузкиКонфигурации=ТсПлатформаОбщий.ПолучитьСвойство(пПараметры, "ПравилоВыгрузкиКонфигурации");
	лПравилоВыгрузкиТаблицы=ТсПлатформаОбщий.ПолучитьСвойство(пПараметры, "ПравилоВыгрузкиТаблицы");
	лПодключение=ТсПлатформаОбщий.ПолучитьСвойство(пПараметры, "Подключение");
	лМассивОбъектыКВыгрузке=ТсПлатформаОбщий.ПолучитьСвойство(пПараметры, "МассивОбъектыКВыгрузке");
	лСтруктураПравилоВыгрузки=Неопределено;
	
	лПакетВременный=Справочники.ТсОбменПакеты.ПолучитьСсылку(Новый УникальныйИдентификатор("11111111-1111-1111-1111-111111111111")); // Для фиксации что начала обработка
	лРаботаВРежимеАгента=ТсПлатформаОбщий.РаботаВРежимеАгента();
	Если лМассивОбъектыКВыгрузке<>Неопределено Тогда
		лТзВыгружаемыеОбъекты=мПолучитьТзИзМассивСтруктур(лМассивОбъектыКВыгрузке,, Ложь); // нужно в тз, потому что после ищем через НайтиСтроки
	Иначе
		лМаксимальнаяПорцияДанных=?(лРаботаВРежимеАгента, ТсПлатформаОбщий.КонстантаПолучить("ТсОбменМаксимальнаяПорцияВыгрузки", 100), 100);
		лВыгрузкаРучныхПравил=ТсПлатформаОбщий.ПолучитьСвойство(пПараметры, "ВыгрузкаРучныхПравил", Ложь);
		
		лЗапрос=Новый Запрос;
		лЗапрос.УстановитьПараметр("ПравилоВыгрузкиКонфигурации", лПравилоВыгрузкиКонфигурации);
		лЗапрос.УстановитьПараметр("Подключение", лПодключение);
		лЗапрос.УстановитьПараметр("ПравилоВыгрузкиТаблицы", лПравилоВыгрузкиТаблицы);
		лЗапрос.УстановитьПараметр("ПакетВременный", лПакетВременный); // Для фиксации что начала обработка
		лЗапрос.УстановитьПараметр("УИДВыгруженные", пМассивУИДВыгруженные);
		лЗапрос.УстановитьПараметр("ПоПодключениямКоторыеЗабираютДанные", ТсПлатформаОбщий.ПолучитьСвойство(пПараметры, "ПоПодключениямКоторыеЗабираютДанные", Ложь));
		лЗапрос.УстановитьПараметр("ВыгрузкаРучныхПравил", лВыгрузкаРучныхПравил);
		лЗапрос.Текст=
		"ВЫБРАТЬ
		|	ТсОбменОбъектыКВыгрузке.ДатаРегистрации КАК ДатаРегистрации,
		|	ТсОбменОбъектыКВыгрузке.УИД КАК УИД,
		|	ТсОбменОбъектыКВыгрузке.ПравилоВыгрузкиТаблицы.Владелец КАК ПравилоВыгрузкиКонфигурации,
		|	ТсОбменОбъектыКВыгрузке.ПравилоВыгрузкиТаблицы КАК ПравилоВыгрузкиТаблицы,
		|	ТсОбменОбъектыКВыгрузке.Подключение КАК Подключение
		|ПОМЕСТИТЬ ВТДанные
		|ИЗ
		|	РегистрСведений.ТсОбменОбъектыКВыгрузке КАК ТсОбменОбъектыКВыгрузке
		|ГДЕ
		|	(ТсОбменОбъектыКВыгрузке.ПакетОбмена = ЗНАЧЕНИЕ(Справочник.ТсОбменПакеты.ПустаяСсылка) 
		|		ИЛИ ТсОбменОбъектыКВыгрузке.ПакетОбмена = &ПакетВременный) // Для фиксации что начала обработка
		|	И НЕ ТсОбменОбъектыКВыгрузке.УИД В (&УИДВыгруженные)
		|	И ТсОбменОбъектыКВыгрузке.Подключение.ЗабираетДанные = &ПоПодключениямКоторыеЗабираютДанные
		|	И (&ВыгрузкаРучныхПравил
		|			ИЛИ НЕ ТсОбменОбъектыКВыгрузке.ПравилоВыгрузкиТаблицы.Владелец.НеВыгружать
		|				И НЕ ТсОбменОбъектыКВыгрузке.ПравилоВыгрузкиТаблицы.НеВыгружать)
		|	И &ДополнительныеПараметрыОтбора
		|;
		|
		|////////////////////////////////////////////////////////////////////////////////
		|ВЫБРАТЬ ПЕРВЫЕ "+лМаксимальнаяПорцияДанных+"
		|	ВТДанные.ДатаРегистрации КАК ДатаРегистрации,
		|	ВТДанные.УИД КАК УИД,
		|	ВТДанные.ПравилоВыгрузкиКонфигурации КАК ПравилоВыгрузкиКонфигурации,
		|	ВТДанные.ПравилоВыгрузкиТаблицы КАК ПравилоВыгрузкиТаблицы,
		|	ВТДанные.Подключение КАК Подключение
		|ИЗ
		|	ВТДанные КАК ВТДанные
		|
		|УПОРЯДОЧИТЬ ПО
		|	ВТДанные.Подключение,
		|	ВТДанные.ПравилоВыгрузкиКонфигурации,
		|	ВТДанные.ПравилоВыгрузкиТаблицы";
		// TODO: тут если ставить по дате регистрации порядок (ВТДанные.ДатаРегистрации), то нужно вообще каждое правило отдельно выгружать потому как тогда порядок правил выгрузки таблиц тоже не будет соответствовать
		
		лМассивОтборы=Новый Массив;
		Если ЗначениеЗаполнено(лПодключение) Тогда лМассивОтборы.Добавить("ТсОбменОбъектыКВыгрузке.Подключение = &Подключение"); КонецЕсли;
		Если ЗначениеЗаполнено(лПравилоВыгрузкиКонфигурации) Тогда лМассивОтборы.Добавить("ТсОбменОбъектыКВыгрузке.ПравилоВыгрузкиТаблицы.Владелец = &ПравилоВыгрузкиКонфигурации"); КонецЕсли;
		Если ЗначениеЗаполнено(лПравилоВыгрузкиТаблицы) Тогда лМассивОтборы.Добавить("ТсОбменОбъектыКВыгрузке.ПравилоВыгрузкиТаблицы = &ПравилоВыгрузкиТаблицы"); КонецЕсли;
		
		Если лМассивОтборы.Количество()=0 Тогда лМассивОтборы.Добавить("Истина"); КонецЕсли; // чтобы ошибок не было
		лЗапрос.Текст=СтрЗаменить(лЗапрос.Текст, "&ДополнительныеПараметрыОтбора", СтрСоединить(лМассивОтборы, Символы.ПС+Символы.Таб+"И "));
		
		//НачатьТранзакцию();
		//лБлокировкаДанных=Новый БлокировкаДанных; // Для фиксации что начала обработка
		//лЭлементБлокировки=лБлокировкаДанных.Добавить("РегистрСведений.ТсОбменОбъектыКВыгрузке");
		//лЭлементБлокировки.Режим=РежимБлокировкиДанных.Исключительный;
		//лБлокировкаДанных.Заблокировать();
		
		лТзВыгружаемыеОбъекты=лЗапрос.Выполнить().Выгрузить();
	КонецЕсли;
	
	Для Каждого лСтрокаТзВыгружаемыеОбъекты Из лТзВыгружаемыеОбъекты Цикл // Для фиксации что начала обработка
		лЗапись=РегистрыСведений.ТсОбменОбъектыКВыгрузке.СоздатьМенеджерЗаписи();
		ЗаполнитьЗначенияСвойств(лЗапись, лСтрокаТзВыгружаемыеОбъекты, "ПравилоВыгрузкиТаблицы, Подключение, УИД, ДатаРегистрации");
		лЗапись.ПакетОбмена=лПакетВременный;
		лЗапись.Записать();
	КонецЦикла;
	//Если лБлокировкаДанных<>Неопределено Тогда // Для фиксации что начала обработка
	//	ЗафиксироватьТранзакцию();
	//КонецЕсли;
	
	лМассивПакеты=Новый Массив;
	Если лТзВыгружаемыеОбъекты.Количество()=0 Тогда Возврат лМассивПакеты; КонецЕсли;
	лТзВыгружаемыеОбъекты.Колонки.Добавить("Объект");
	
	лСоответствиеМассивыОбъектов=Новый Соответствие;
	лПодключение=Неопределено; лПравилоВыгрузкиКонфигурации=Неопределено; лПравилоВыгрузкиТаблицы=Неопределено;
	лКодПравила=Неопределено; лМассивОбъекты=Неопределено;
	лМенеджерТаблицы=Неопределено;
	
	Для Каждого лСтрокаТзВыгружаемыеОбъекты Из лТзВыгружаемыеОбъекты Цикл
		пМассивУИДВыгруженные.Добавить(лСтрокаТзВыгружаемыеОбъекты.УИД);
		Если лПодключение<>лСтрокаТзВыгружаемыеОбъекты.Подключение или лПравилоВыгрузкиКонфигурации<>лСтрокаТзВыгружаемыеОбъекты.ПравилоВыгрузкиКонфигурации Тогда 
			Если лПравилоВыгрузкиКонфигурации<>Неопределено Тогда
				лСоответствиеМассивыОбъектов.Вставить(лКодПравила, лМассивОбъекты);
				лТекстОшибки="";
				лПакетОбмена=мПравилоВыгрузкиКонфигурацииСформироватьПакеты(лПодключение, лПравилоВыгрузкиКонфигурации,, лСоответствиеМассивыОбъектов, лТзВыгружаемыеОбъекты, пНеобходимоВыгружатьПакеты, пНеобходимоЗагружатьПакеты, лТекстОшибки);
				Если лПакетОбмена=Неопределено Тогда 
					лМассивПакеты.Добавить(Новый Структура("КодПравилаВыгрузки, Ошибка, ТекстОшибки", лПравилоВыгрузкиКонфигурации.Код, Истина, лТекстОшибки));
					лЕстьОшибки=Истина; 
				Иначе
					лМассивПакеты.Добавить(Новый Структура("КодПравилаВыгрузки, Ошибка, ТекстОшибки, Пакет", лПравилоВыгрузкиКонфигурации.Код, Ложь, "", лПакетОбмена));
				КонецЕсли;
			КонецЕсли;
			лСоответствиеМассивыОбъектов.Очистить();
			лМассивОбъекты=Новый Массив;
			лПодключение=лСтрокаТзВыгружаемыеОбъекты.Подключение;
			лПравилоВыгрузкиКонфигурации=лСтрокаТзВыгружаемыеОбъекты.ПравилоВыгрузкиКонфигурации;
		КонецЕсли;
			
		Если лПравилоВыгрузкиТаблицы<>лСтрокаТзВыгружаемыеОбъекты.ПравилоВыгрузкиТаблицы Тогда
			Если лКодПравила<>Неопределено Тогда лСоответствиеМассивыОбъектов.Вставить(лКодПравила, лМассивОбъекты); КонецЕсли; 
			лМассивОбъекты=Новый Массив;
			лПравилоВыгрузкиТаблицы=лСтрокаТзВыгружаемыеОбъекты.ПравилоВыгрузкиТаблицы;
			лКодПравила=?(лРаботаВРежимеАгента, лСтрокаТзВыгружаемыеОбъекты.ПравилоВыгрузкиТаблицы.КодПравила, лСтрокаТзВыгружаемыеОбъекты.ПравилоВыгрузкиТаблицы.ПравилоКонвертацииТаблицы.Код);
			
			лСтруктураТаблицы=?(лРаботаВРежимеАгента, лСтрокаТзВыгружаемыеОбъекты.ПравилоВыгрузкиТаблицы, лСтрокаТзВыгружаемыеОбъекты.ПравилоВыгрузкиТаблицы.ПравилоКонвертацииТаблицы.ТаблицаИсточник);
			
			Если СтрНачинаетсяС(лСтруктураТаблицы.Тип, "Регистры") Тогда 
				лСтруктураПКК=ТсПлатформаОбщий.КонвертироватьИзJSON(лПравилоВыгрузкиКонфигурации.Правила);
				лИмяТаблицы=мПравилаКонвертацииПолучитьИмяТаблицыУстановленногоПервичногоКлючаРегистра(лСтруктураПКК, лПравилоВыгрузкиТаблицы.КодПравила, лПравилоВыгрузкиТаблицы.ИмяРеквизитаРегистрации);
				лМенеджерТаблицы=?(лИмяТаблицы=Неопределено, Неопределено, Вычислить(лИмяТаблицы));
			Иначе
				лТекстОшибки="";
				лМенеджерТаблицы=МенеджерТаблицыПолучить(лСтруктураТаблицы);
				Если лМенеджерТаблицы=Неопределено Тогда ВызватьИсключение "Ошибка при получении менеджера таблицы: "+лСтруктураТаблицы.Имя+", ошибка: "+лТекстОшибки; КонецЕсли;
			КонецЕсли;
		КонецЕсли;
		
		Если лМенеджерТаблицы<>Неопределено Тогда лСтрокаТзВыгружаемыеОбъекты.Объект=лМенеджерТаблицы.ПолучитьСсылку(лСтрокаТзВыгружаемыеОбъекты.УИД); КонецЕсли;
		лМассивОбъекты.Добавить(лСтрокаТзВыгружаемыеОбъекты.Объект);
	КонецЦикла;
	
	Если лПравилоВыгрузкиКонфигурации<>Неопределено Тогда
		лСоответствиеМассивыОбъектов.Вставить(лКодПравила, лМассивОбъекты);
		лТекстОшибки="";
		лПакетОбмена=мПравилоВыгрузкиКонфигурацииСформироватьПакеты(лПодключение, лПравилоВыгрузкиКонфигурации,, лСоответствиеМассивыОбъектов, лТзВыгружаемыеОбъекты, пНеобходимоВыгружатьПакеты, пНеобходимоЗагружатьПакеты, лТекстОшибки);
		Если лПакетОбмена=Неопределено Тогда
			лМассивПакеты.Добавить(Новый Структура("КодПравилаВыгрузки, Ошибка, ТекстОшибки", лПравилоВыгрузкиКонфигурации.Код, Истина, лТекстОшибки));
			лЕстьОшибки=Истина; 
		Иначе
			лМассивПакеты.Добавить(Новый Структура("КодПравилаВыгрузки, Ошибка, ТекстОшибки, Пакет", лПравилоВыгрузкиКонфигурации.Код, Ложь, "", лПакетОбмена));
		КонецЕсли;
	КонецЕсли;
	Возврат лМассивПакеты;
КонецФункции

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

Функция мЭтоМобильноеПриложение()
	#Если МобильноеПриложениеСервер Тогда
		Возврат Истина; 
	#КонецЕсли
	Возврат Ложь;
КонецФункции

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

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

Функция РегламентныеЗаданияПравилаВыгрузокВыполнитьОбмен() Экспорт
	Возврат ПравилаВыгрузокВыполнитьОбмен(Новый Структура("ВыгрузкаРучныхПравил", Истина),, Истина); // Выполняем в фоне чтобы если обмен уже идет не запускать его
КонецФункции
#КонецОбласти 

#Область Отборы
Функция мРеквизитСтрокаТипаПолучитьПустоеЗначениеТипа(пСтрокаТипы, пСоединениеКОМ)
	Если ЗначениеЗаполнено(пСтрокаТипы.ИмяТаблицы) Тогда Возврат "00000000-0000-0000-0000-000000000000"; КонецЕсли; // после преобразуем при формировании запроса
	лОписаниеТипов=Новый ОписаниеТипов(""+пСтрокаТипы.Тип);
	Возврат лОписаниеТипов.ПривестиЗначение();
КонецФункции

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

Функция мПолучитьСтрУсловияОтбора(пДеревоОтборов, пМассивПараметрыОтбора, пМассивРеквизитыОтбораПоТипу, пТипГруппы, пСоединениеКОМ, пСуффикс="", пРеквизитТч=Неопределено, пМассивДеревоУсловия)
	лМассивУсловия=Новый Массив;
	лНомерСтроки=0;
	Для Каждого лСтрокаДеревоОтборов Из пДеревоОтборов.Строки Цикл
		Если Не лСтрокаДеревоОтборов.Включен Тогда Продолжить; КонецЕсли;
		
		лНомерСтроки=лНомерСтроки+1;
		лСуффикс=пСуффикс+"_"+Формат(лНомерСтроки, "ЧГ=0");
		Если лСтрокаДеревоОтборов.ЭтоГруппа Тогда
			лМассивДеревоОтборовГруппы=Новый Массив;
			лУзелДеревоОтборов=Новый Структура("ТипГруппы, Строки", ТсПлатформаОбщий.ПеречислениеИмя(лСтрокаДеревоОтборов.ТипГруппы), лМассивДеревоОтборовГруппы);
			пМассивДеревоУсловия.Добавить(лУзелДеревоОтборов);
			
			лМассивУсловия.Добавить("("+мПолучитьСтрУсловияОтбора(лСтрокаДеревоОтборов, пМассивПараметрыОтбора, пМассивРеквизитыОтбораПоТипу, лСтрокаДеревоОтборов.ТипГруппы, пСоединениеКОМ, лСуффикс, пРеквизитТч, лМассивДеревоОтборовГруппы)+")");
			Продолжить;
		КонецЕсли;
		
		лУзелДеревоОтборов=Новый Структура("Имя");
		лУзелДеревоОтборов.Имя=лСтрокаДеревоОтборов.ИмяРеквизита;
		лУзелДеревоОтборов.Вставить("ВидСравнения", ТсПлатформаОбщий.ПеречислениеИмя(лСтрокаДеревоОтборов.ВидСравнения));
		
		пМассивДеревоУсловия.Добавить(лУзелДеревоОтборов);
		
		Если Не ЗначениеЗаполнено(лСтрокаДеревоОтборов.ВидЗначения) Тогда 
			ВызватьИсключение "Заполните вид значения для всех элементов отбора!";
		КонецЕсли;
		лИмяПараметра="ЗначениеОтбора"+лСуффикс;
		
		лЗначение=?(лСтрокаДеревоОтборов.ВидСравнения=Перечисления.ТсПлатформаВидыСравнений.ВСписке или лСтрокаДеревоОтборов.ВидСравнения=Перечисления.ТсПлатформаВидыСравнений.НеВСписке, лСтрокаДеревоОтборов.Значения.ВыгрузитьКолонку("Значение"), лСтрокаДеревоОтборов.Значение);
		лСтрУсловие="#ИсходныеДанные#.";
		Если ЗначениеЗаполнено(пРеквизитТч) Тогда // Если задан реквизит тч, то это отбор в рамках фильтрации табличной части
			Если лСтрокаДеревоОтборов.ИмяРеквизитаРодителя<>NULL Тогда 
				Если пРеквизитТч.Имя<>лСтрокаДеревоОтборов.ИмяРеквизитаРодителя Тогда 
					ВызватьИсключение "Нельзя делать отбор в тч для другой тч!";
				КонецЕсли;
			Иначе
				лСтрУсловие=лСтрУсловие+"Ссылка."; // Добавляем путь до основной таблицы
			КонецЕсли;
			
		ИначеЕсли лСтрокаДеревоОтборов.ИмяРеквизитаРодителя<>NULL Тогда
			лСтрУсловие=лСтрУсловие+лСтрокаДеревоОтборов.ИмяРеквизитаРодителя+".";
		КонецЕсли;
		лСтрУсловие=лСтрУсловие+лСтрокаДеревоОтборов.ИмяРеквизита;
		
		лИмяМенеджераТаблицы="";
		Если ЗначениеЗаполнено(лСтрокаДеревоОтборов.ТаблицаЗначения) Тогда 
			лДополнительная=ТсПлатформаОбщий.ПолучитьСвойство(лСтрокаДеревоОтборов, "ТаблицаЗначения.Дополнительная");
			Если лДополнительная Тогда
				лИмяМенеджераТаблицы="Справочники.ТсКонфигурацииСтрокиТаблиц";
			Иначе
				лИмяМенеджераТаблицы=?(ЗначениеЗаполнено(лСтрокаДеревоОтборов.ТаблицаЗначения), лСтрокаДеревоОтборов.ТаблицаЗначения.Тип+"."+лСтрокаДеревоОтборов.ТаблицаЗначения.Имя, Неопределено);
			КонецЕсли;
		КонецЕсли; 
		
		лСтруктураПараметрыОтбора=Неопределено;
		Если лСтрокаДеревоОтборов.ВидСравнения=Перечисления.ТсПлатформаВидыСравнений.Тип Тогда 
			Если лСтрокаДеревоОтборов.ВидЗначения<>Перечисления.ТсОбменВидыЗначенийОтбора.Значение Тогда
				ВызватьИсключение "Для сравнения по типу значения реализован только отбора по виду значения - значение!";
			КонецЕсли;
			Если ТипЗнч(лЗначение)=Тип("СправочникСсылка.ТсКонфигурацииТаблицы") Тогда
				Если лЗначение.Дополнительная Тогда
					пМассивРеквизитыОтбораПоТипу.Добавить(лСтрокаДеревоОтборов.ИмяРеквизита); // это только для дополнительных таблиц
					Если ЗначениеЗаполнено(лСтрокаДеревоОтборов.ИмяРеквизитаРодителя) Тогда 
						ВызватьИсключение "Не реализован отбор по типу в табличных полях дополнительных таблиц!";
					КонецЕсли;
					лСтрУсловие="ИсходныеДанные.__Ссылка__"+лСтрокаДеревоОтборов.ИмяРеквизита+".Владелец.Код = &"+лИмяПараметра;
					лСтруктураПараметрыОтбора=Новый Структура("Имя, ВидЗначения, Тип, Значение", лИмяПараметра, "Значение", "Строка", лЗначение.Код);
				Иначе
					лСтрУсловие=лСтрУсловие+" ССЫЛКА "+ТсПлатформаМодули.Платформа().ТаблицаПолучитьПолноеИмя(лЗначение);
				КонецЕсли;
			Иначе
				лСтрУсловие="ТИПЗНАЧЕНИЯ("+лСтрУсловие+") = ТИП("+ТсПлатформаОбщий.ПеречислениеИмя(лЗначение)+")";
			КонецЕсли;
			
		ИначеЕсли лСтрокаДеревоОтборов.ВидСравнения=Перечисления.ТсПлатформаВидыСравнений.Заполнено
			или лСтрокаДеревоОтборов.ВидСравнения=Перечисления.ТсПлатформаВидыСравнений.НеЗаполнено
		Тогда
			лЗначение=мРеквизитПолучитьПустыеЗначения(лСтрокаДеревоОтборов.Реквизит, пСоединениеКОМ);
			лЭтоМассив=ТипЗнч(лЗначение)=Тип("Массив");
			лОбернутьПараметрВСкобки=лЭтоМассив;
			лДобавитьОтрицание=лСтрокаДеревоОтборов.ВидСравнения=Перечисления.ТсПлатформаВидыСравнений.Заполнено;
			лСтрВидСравнения=?(лЭтоМассив, " В ", " = ");
			
			лСтрУсловие=лСтрУсловие+лСтрВидСравнения+?(лОбернутьПараметрВСкобки, "(&"+лИмяПараметра+")", "&"+лИмяПараметра);
			Если лДобавитьОтрицание Тогда лСтрУсловие="НЕ ("+лСтрУсловие+")"; КонецЕсли;
			лСтруктураПараметрыОтбора=Новый Структура("Имя, Тип, ВидЗначения, Значение, ИмяМенеджераТаблицы", лИмяПараметра, ""+ТипЗнч(лЗначение), "Значение", лЗначение, лИмяМенеджераТаблицы);
			
		Иначе
			лДобавитьОтрицание=Ложь; лОбернутьПараметрВСкобки=Ложь;
			лСтрВидСравнения=ТсПлатформаМодули.Платформа().ПолучитьСтрВидСравнения(лСтрокаДеревоОтборов.ВидСравнения, лДобавитьОтрицание, лОбернутьПараметрВСкобки, лЗначение);
			лСтрУсловие=лСтрУсловие+лСтрВидСравнения+?(лОбернутьПараметрВСкобки, "(&"+лИмяПараметра+")", "&"+лИмяПараметра);
			Если лДобавитьОтрицание Тогда лСтрУсловие="НЕ ("+лСтрУсловие+")"; КонецЕсли;
			
			лСтруктураПараметрыОтбора=Новый Структура("Имя, Тип, ВидЗначения, ИмяМенеджераТаблицы", лИмяПараметра, ""+ТипЗнч(лЗначение), ТсПлатформаОбщий.ПеречислениеИмя(лСтрокаДеревоОтборов.ВидЗначения), лИмяМенеджераТаблицы);
			Если лСтрокаДеревоОтборов.ВидЗначения=Перечисления.ТсОбменВидыЗначенийОтбора.Значение Тогда
				лСтруктураПараметрыОтбора.Вставить("Значение", лЗначение);
			ИначеЕсли лСтрокаДеревоОтборов.ВидЗначения=Перечисления.ТсОбменВидыЗначенийОтбора.Параметр Тогда
				лСтруктураПараметрыОтбора.Вставить("Параметр", лСтрокаДеревоОтборов.Параметр.Имя);
			ИначеЕсли лСтрокаДеревоОтборов.ВидЗначения=Перечисления.ТсОбменВидыЗначенийОтбора.Алгоритм Тогда
				лСтруктураПараметрыОтбора.Вставить("Алгоритм", АлгоритмПолучитьСтруктуру(лСтрокаДеревоОтборов.Алгоритм));
			КонецЕсли;
		КонецЕсли;
		Если лСтруктураПараметрыОтбора<>Неопределено Тогда 
			пМассивПараметрыОтбора.Добавить(лСтруктураПараметрыОтбора);
			лУзелДеревоОтборов.Вставить("ИмяПараметра", лСтруктураПараметрыОтбора.Имя);
		КонецЕсли;
		
		лМассивУсловия.Добавить(лСтрУсловие);
	КонецЦикла;
	Если лМассивУсловия.Количество()=0 Тогда Возврат Неопределено; КонецЕсли; 
	лСтрУсловияОтбора=СтрСоединить(лМассивУсловия, ?(пТипГруппы=Перечисления.ТсОбменТипыГруппОтбора.Или, " ИЛИ ", " И "));
	Если пТипГруппы=Перечисления.ТсОбменТипыГруппОтбора.Не Тогда лСтрУсловияОтбора="НЕ ("+лСтрУсловияОтбора+")"; КонецЕсли;
	Возврат лСтрУсловияОтбора;
КонецФункции

Функция ОтборыПолучить(пВладельцы, пМассивПараметрыОтбора, пМассивРеквизитыОтбораПоТипу, пСоединениеКОМ=Неопределено, пСуффикс="", пРеквизитТч=Неопределено, пМассивДеревоУсловия=Неопределено, пТипПрименения=Неопределено) Экспорт
	Если ТипЗнч(пМассивПараметрыОтбора)<>Тип("Массив") Тогда пМассивПараметрыОтбора=Новый Массив; КонецЕсли;
	Если ТипЗнч(пМассивРеквизитыОтбораПоТипу)<>Тип("Массив") Тогда пМассивРеквизитыОтбораПоТипу=Новый Массив; КонецЕсли;
	
	лЭтоОтборПоСсылке=ТипЗнч(пВладельцы)=Тип("СправочникСсылка.ТсКонфигурацииОтборыТаблиц")
		или (ТипЗнч(пВладельцы)=Тип("Массив") и пВладельцы.Количество()<>0 и ТипЗнч(пВладельцы[0])=Тип("СправочникСсылка.ТсКонфигурацииОтборыТаблиц"));
	
	лЗапрос=Новый Запрос;
	лЗапрос.УстановитьПараметр("Владельцы", пВладельцы);
	лЗапрос.УстановитьПараметр("ТипПрименения", ?(ЗначениеЗаполнено(пТипПрименения), пТипПрименения, Перечисления.ТсКонфигурацииТипыПримененияОтбора.ПустаяСсылка()));
	лЗапрос.Текст=
	"ВЫБРАТЬ
	|	ТсКонфигурацииОтборыТаблицЭлементы.Ссылка КАК Ссылка,
	|	ТсКонфигурацииОтборыТаблицЭлементы.Порядок КАК Порядок,
	|	ТсКонфигурацииОтборыТаблицЭлементы.Включен КАК Включен,
	|	ТсКонфигурацииОтборыТаблицЭлементы.ЭтоГруппа КАК ЭтоГруппа,
	|	ТсКонфигурацииОтборыТаблицЭлементы.ТипГруппы КАК ТипГруппы,
	|	ТсКонфигурацииОтборыТаблицЭлементы.Реквизит.Родитель.Имя КАК ИмяРеквизитаРодителя,
	|	ТсКонфигурацииОтборыТаблицЭлементы.Реквизит КАК Реквизит,
	|	ТсКонфигурацииОтборыТаблицЭлементы.Реквизит.Имя КАК ИмяРеквизита,
	|	ТсКонфигурацииОтборыТаблицЭлементы.Реквизит.ЭтоСсылка1С КАК ЭтоСсылка1С,
	|	ТсКонфигурацииОтборыТаблицЭлементы.ВидСравнения КАК ВидСравнения,
	|	ТсКонфигурацииОтборыТаблицЭлементы.ВидЗначения КАК ВидЗначения,
	|	ТсКонфигурацииОтборыТаблицЭлементы.Значение КАК Значение,
	|	ТсКонфигурацииОтборыТаблицЭлементы.Значения.(
	|		Значение КАК Значение
	|	) КАК Значения,
	|	ТсКонфигурацииОтборыТаблицЭлементы.Параметр КАК Параметр,
	|	ТсКонфигурацииОтборыТаблицЭлементы.Алгоритм КАК Алгоритм,
	|	ТсКонфигурацииОтборыТаблицЭлементы.ТаблицаЗначения КАК ТаблицаЗначения
	|ИЗ
	|	Справочник.ТсКонфигурацииОтборыТаблицЭлементы КАК ТсКонфигурацииОтборыТаблицЭлементы
	|ГДЕ
	|	ТсКонфигурацииОтборыТаблицЭлементы.Владелец В ";
	
	Если лЭтоОтборПоСсылке Тогда
		лЗапрос.Текст=лЗапрос.Текст+"(&Владельцы)";
	Иначе
		лЗапрос.Текст=лЗапрос.Текст+"
		|			(ВЫБРАТЬ
		|				ТсКонфигурацииПрименяемыеОтборыТаблиц.ОтборТаблицыКонфигурации
		|			ИЗ
		|				РегистрСведений.ТсКонфигурацииПрименяемыеОтборыТаблиц КАК ТсКонфигурацииПрименяемыеОтборыТаблиц
		|			ГДЕ
		|				ТсКонфигурацииПрименяемыеОтборыТаблиц.Владелец В (&Владельцы)
		|				И ТсКонфигурацииПрименяемыеОтборыТаблиц.Включен
		|				И ТсКонфигурацииПрименяемыеОтборыТаблиц.ТипПрименения = &ТипПрименения)";
	КонецЕсли;
	
	лЗапрос.Текст=лЗапрос.Текст+"
	|
	|УПОРЯДОЧИТЬ ПО
	|	Ссылка ИЕРАРХИЯ";
	лДеревоОтборов=лЗапрос.Выполнить().Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией);
	лДеревоОтборов.Строки.Сортировать("Порядок");
	Если ТипЗнч(пМассивДеревоУсловия)<>Тип("Массив") Тогда пМассивДеревоУсловия=Новый Массив; КонецЕсли;
	Возврат мПолучитьСтрУсловияОтбора(лДеревоОтборов, пМассивПараметрыОтбора, пМассивРеквизитыОтбораПоТипу, Перечисления.ТсОбменТипыГруппОтбора.И, пСоединениеКОМ, пСуффикс, пРеквизитТч, пМассивДеревоУсловия);
КонецФункции
#КонецОбласти 

Функция мСоответствиеКлючейВПравилеВыгрузкиТаблицы(пПравилоВыгрузкиКонфигураций, пПКТ)
	Если Не ЗначениеЗаполнено(пПКТ) Тогда Возврат Неопределено; КонецЕсли; 
	лЗапрос=Новый Запрос;
	лЗапрос.УстановитьПараметр("Владелец", пПравилоВыгрузкиКонфигураций);
	лЗапрос.УстановитьПараметр("ПравилоКонвертацииТаблицы", пПКТ);
	лЗапрос.Текст=
	"ВЫБРАТЬ
	|	ТсОбменПравилаВыгрузокТаблиц.СоответствиеКлючей.Имя КАК СоответствиеКлючейИмя
	|ИЗ
	|	Справочник.ТсОбменПравилаВыгрузокТаблиц КАК ТсОбменПравилаВыгрузокТаблиц
	|ГДЕ
	|	ТсОбменПравилаВыгрузокТаблиц.Владелец = &Владелец
	|	И ТсОбменПравилаВыгрузокТаблиц.ПравилоКонвертацииТаблицы = &ПравилоКонвертацииТаблицы
	|	И НЕ ТсОбменПравилаВыгрузокТаблиц.ПометкаУдаления
	|
	|УПОРЯДОЧИТЬ ПО
	|	ТсОбменПравилаВыгрузокТаблиц.Включен УБЫВ";
	лВыборка=лЗапрос.Выполнить().Выбрать();
	Возврат ?(лВыборка.Следующий() и ЗначениеЗаполнено(лВыборка.СоответствиеКлючейИмя), лВыборка.СоответствиеКлючейИмя, Неопределено); 
КонецФункции

Функция мПравилаВыгрузкиПолучитьСтруктуруДляВыгрузкиДанных(пПравилоВыгрузкиКонфигураций, пВходящее, пИсходящее)
	лРаботаВРежимеАгента=ТсПлатформаОбщий.РаботаВРежимеАгента();
	
	Если лРаботаВРежимеАгента Тогда 
		лПравилаКонвертацииКонфигурации=ТсПлатформаОбщий.КонвертироватьИзJSON(пПравилоВыгрузкиКонфигураций.Правила);
		
	Иначе
		Если Не ЗначениеЗаполнено(пПравилоВыгрузкиКонфигураций.ДатаОбновления) Тогда
			Сообщить("Сначала необходимо обновить правила конвертации внутри правил выгрузки (нажать кнопку Обновить правила)"); 
			Возврат Неопределено;
		КонецЕсли; 
		лПравилаКонвертацииКонфигурации=ТсПлатформаМодули.Обмен().ПравилоВыгрузкиКонфигурацииПолучитьКонтекстИзИсточника(пПравилоВыгрузкиКонфигураций.ПравилоКонвертацииКонфигурации, пПравилоВыгрузкиКонфигураций.ПодключениеИсточник, пПравилоВыгрузкиКонфигураций.ПодключениеПриемник);
		Если лПравилаКонвертацииКонфигурации=Неопределено Тогда Возврат Неопределено; КонецЕсли;
		
		Если пПравилоВыгрузкиКонфигураций.ПрямойОбмен Тогда
			// Если группа то определяется подключение уже в конфигурации
			Если (Не пПравилоВыгрузкиКонфигураций.ПодключениеПриемник.ЭтоГруппа и пПравилоВыгрузкиКонфигураций.ПодключениеПриемник.Драйвер.Имя<>"ТсДрайвер1сHttpСервис") 
				или (Не пПравилоВыгрузкиКонфигураций.ПодключениеИсточник.ЭтоГруппа и пПравилоВыгрузкиКонфигураций.ПодключениеИсточник.Драйвер.Имя<>"ТсДрайвер1сHttpСервис") 
			Тогда
				Сообщить("Прямой обмен возможен только между конфигурациями через драйвер 1с http сервис!");
				Возврат Неопределено;
			КонецЕсли;
		КонецЕсли; 
		
		// подменим соответствия ключей
		Для Каждого лСтруктураПКТ Из лПравилаКонвертацииКонфигурации.ПравилаКонвертацииТаблиц Цикл
			лПКТ=Справочники.ТсОбменПравилаКонвертацииТаблиц.НайтиПоКоду(лСтруктураПКТ.КодПравила,,, пПравилоВыгрузкиКонфигураций.ПравилоКонвертацииКонфигурации);
			лСоответствиеКлючейПравилоВыгрузкиТаблицы=мСоответствиеКлючейВПравилеВыгрузкиТаблицы(пПравилоВыгрузкиКонфигураций, лПКТ);
			Если лСоответствиеКлючейПравилоВыгрузкиТаблицы=Неопределено Тогда Продолжить; КонецЕсли; 
			лСтруктураПКТ.СоответствиеКлючей=лСоответствиеКлючейПравилоВыгрузкиТаблицы;
		КонецЦикла;
	КонецЕсли; 
	
	лСтруктураПравилоВыгрузкиКонфигурации=Новый Структура("Ссылка, Наименование, Код, ПрефиксПакетов, Имя, Включен, Правила, Параметры, Комментарий");
	ЗаполнитьЗначенияСвойств(лСтруктураПравилоВыгрузкиКонфигурации, пПравилоВыгрузкиКонфигураций);
	лСтруктураПравилоВыгрузкиКонфигурации.Ссылка=""+лСтруктураПравилоВыгрузкиКонфигурации.Ссылка.УникальныйИдентификатор();
	лСтруктураПравилоВыгрузкиКонфигурации.Правила=лПравилаКонвертацииКонфигурации;
	лСтруктураПравилоВыгрузкиКонфигурации.Параметры=?(лРаботаВРежимеАгента, мТзВМассивСтруктур(пПравилоВыгрузкиКонфигураций.Параметры.Выгрузить()), ТсПлатформаМодули.Платформа().ПараметрыТаблицПолучить(пПравилоВыгрузкиКонфигураций, Истина));
	
	лЗапрос=Новый Запрос;
	лЗапрос.УстановитьПараметр("Владелец", пПравилоВыгрузкиКонфигураций);
	лЗапрос.Текст=
	"ВЫБРАТЬ
	|	ТсОбменПравилаВыгрузокТаблиц.Ссылка КАК Ссылка,
	|	ТсОбменПравилаВыгрузокТаблиц.Родитель КАК Родитель,
	|	ТсОбменПравилаВыгрузокТаблиц.ЭтоГруппа КАК ЭтоГруппа,
	|	ТсОбменПравилаВыгрузокТаблиц.Код КАК Код,
	|	ТсОбменПравилаВыгрузокТаблиц.Наименование КАК Наименование,
	|	ЕСТЬNULL(ТсОбменПравилаВыгрузокТаблиц.Включен, ЛОЖЬ) КАК Включен,
	|	ЕСТЬNULL(ТсОбменПравилаВыгрузокТаблиц.КодПравила, """") КАК КодПравила,
	|	ЕСТЬNULL(ТсОбменПравилаВыгрузокТаблиц.СоответствиеКлючейИмя, """") КАК СоответствиеКлючей,
	|	ЕСТЬNULL(ТсОбменПравилаВыгрузокТаблиц.Тип, """") КАК Тип,
	|	ЕСТЬNULL(ТсОбменПравилаВыгрузокТаблиц.Имя, """") КАК Имя,
	|	ЕСТЬNULL(ТсОбменПравилаВыгрузокТаблиц.ИмяРеквизитаРегистрации, """") КАК ИмяРеквизитаРегистрации,
	|	ТсОбменПравилаВыгрузокТаблиц.ОтборЗапросаПоПодключениям КАК ОтборЗапросаПоПодключениям,
	|	ТсОбменПравилаВыгрузокТаблиц.Комментарий КАК Комментарий
	|ИЗ
	|	Справочник.ТсОбменПравилаВыгрузокТаблиц КАК ТсОбменПравилаВыгрузокТаблиц
	|ГДЕ
	|	НЕ ТсОбменПравилаВыгрузокТаблиц.ПометкаУдаления
	|	И ТсОбменПравилаВыгрузокТаблиц.Владелец = &Владелец";
	лМассивПравилаВыгрузкиТаблиц=Новый Массив;
	лВыборка=лЗапрос.Выполнить().Выбрать();
	лЕстьОшибки=Ложь;
	Пока лВыборка.Следующий() Цикл
		Если Не ЗначениеЗаполнено(лВыборка.Тип) или Не ЗначениеЗаполнено(лВыборка.Имя) Тогда 
			Сообщить("Для правила выгрузки таблицы: "+лВыборка.Ссылка+", не заполнено имя и/или тип, вероятно нужно обновить правила"); 
			лЕстьОшибки=Истина;
			Продолжить;
		КонецЕсли;
		лСтруктураПравилоВыгрузкиТаблицы=Новый Структура("Ссылка, Родитель, ЭтоГруппа, Наименование, Код, Включен, Тип, Имя, ИмяРеквизитаРегистрации, КодПравила, СоответствиеКлючей, Параметры, ОтборЗапросаПоПодключениям, Комментарий");
		ЗаполнитьЗначенияСвойств(лСтруктураПравилоВыгрузкиТаблицы, лВыборка);
		лСтруктураПравилоВыгрузкиТаблицы.Ссылка=""+лСтруктураПравилоВыгрузкиТаблицы.Ссылка.УникальныйИдентификатор();
		лСтруктураПравилоВыгрузкиТаблицы.Родитель=""+лСтруктураПравилоВыгрузкиТаблицы.Родитель.УникальныйИдентификатор();
		лСтруктураПравилоВыгрузкиТаблицы.Тип=лСтруктураПравилоВыгрузкиТаблицы.Тип;
		лСтруктураПравилоВыгрузкиТаблицы.СоответствиеКлючей=лВыборка.СоответствиеКлючей;
		лСтруктураПравилоВыгрузкиТаблицы.Параметры=?(лРаботаВРежимеАгента, мТзВМассивСтруктур(лВыборка.Ссылка.Параметры.Выгрузить()), ТсПлатформаМодули.Платформа().ПараметрыТаблицПолучить(лВыборка.Ссылка, Истина));
		
		Если ЗначениеЗаполнено(лВыборка.Ссылка.Отборы) Тогда 
			лСтруктураПравилоВыгрузкиТаблицы.Вставить("Отбор", ТсПлатформаОбщий.КонвертироватьИзJSON(лВыборка.Ссылка.Отборы));
		КонецЕсли;
		лМассивПравилаВыгрузкиТаблиц.Добавить(лСтруктураПравилоВыгрузкиТаблицы);
	КонецЦикла;
	Если лЕстьОшибки Тогда Возврат Неопределено; КонецЕсли;
	
	лДанные=Новый Структура("ПравилоВыгрузкиКонфигурации, Входящее, Исходящее, ПравилаВыгрузкиТаблиц, ДатаОбновления", лСтруктураПравилоВыгрузкиКонфигурации, пВходящее, пИсходящее, лМассивПравилаВыгрузкиТаблиц, пПравилоВыгрузкиКонфигураций.ДатаОбновления);
	Возврат ТсПлатформаОбщий.КонвертироватьВJSON(лДанные);
КонецФункции 

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

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

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

#Область ПодключениеКУдаленнойБазеОбмена
Функция мПодключитьКБазеОбменаПоПараметрам(пСтрокаПодключения, пЛогин, пПароль, пУИДПодключения, пУИДПравилаВыгрузокКонфигураций=Неопределено, пДатаОбновления=Неопределено, пТекстОшибки="")
	лСтруктураСсылки=ВебСсылкаРазобрать(пСтрокаПодключения, пТекстОшибки);
	Если лСтруктураСсылки=Неопределено Тогда Возврат Ложь; КонецЕсли;
	
	лПараметрыЗапроса=Новый Структура("Таймаут, Логировать", 5, ТсПлатформаОбщий.КонстантаПолучить("ТсОбменЛогироватьHttpСервисы", Ложь)); // TODO: исправить таймаут
	лСтруктураДанные=Новый Структура("ПодключениеУИД", пУИДПодключения);
	
	Если пУИДПравилаВыгрузокКонфигураций<>Неопределено Тогда 
		лСтруктураДанные.Вставить("ПравилоВыгрузкиКонфигурацииУИД", пУИДПравилаВыгрузокКонфигураций);
		лСтруктураДанные.Вставить("ДатаОбновления", пДатаОбновления);
	КонецЕсли;
	лТекстОтвета=ЗапросPOST(лСтруктураСсылки.ИмяСервера, лСтруктураСсылки.Порт, "/"+лСтруктураСсылки.Путь+"/hs/TsExchange/GetConnectionConfig", пЛогин, пПароль, ТсПлатформаОбщий.КонвертироватьВJSON(лСтруктураДанные), лСтруктураСсылки.ИспользоватьЗащищеннуюАвторизацию, лПараметрыЗапроса, пТекстОшибки);
	Если ЗначениеЗаполнено(пТекстОшибки) Тогда пТекстОшибки="При подключении возникла ошибка: "+пТекстОшибки; Возврат Ложь; КонецЕсли;
	Если ТипЗнч(лТекстОтвета)=Тип("ДвоичныеДанные") Тогда лТекстОтвета=ДанныеРазрахивировать(лТекстОтвета); КонецЕсли;
	
	лСтруктураОтвета=ТсПлатформаОбщий.КонвертироватьИзJSON(лТекстОтвета);
	Если лСтруктураОтвета.Ошибка Тогда пТекстОшибки="При подключении возникла ошибка: "+лСтруктураОтвета.ТекстОшибки; Возврат Ложь; КонецЕсли;
	
	Для Каждого лСтруктураПравилоВыгрузкиКонфигурации Из лСтруктураОтвета.Данные Цикл // Если пустой массив значит обновлять нечего
		Если Не мСервисПравилаВыгрузкиОбновить(лСтруктураПравилоВыгрузкиКонфигурации, пТекстОшибки) Тогда пТекстОшибки="При загрузке правил возникла ошибка: "+пТекстОшибки; Возврат Ложь; КонецЕсли; 
	КонецЦикла;
	Возврат Истина;
КонецФункции

Функция ПодключитьКБазеОбмена(пСтрокаНастройки) Экспорт
	лМассивНастройки=СтрРазделить(пСтрокаНастройки, "?");
	Если лМассивНастройки.Количество()<>2 Тогда Сообщить("Неверный формат настройки"); Возврат Ложь; КонецЕсли;
	лСтрокаПодключения=лМассивНастройки[0];
	лСтруктураНастройки=Новый Структура;
	Для Каждого лДанныеПараметра Из СтрРазделить(лМассивНастройки[1], "&") Цикл
		лМассивПараметры=СтрРазделить(лДанныеПараметра, "=");
		Если лМассивПараметры.Количество()<>2 Тогда Сообщить("Неверный формат настройки"); Возврат Ложь; КонецЕсли;
		Попытка лСтруктураНастройки.Вставить(лМассивПараметры[0], лМассивПараметры[1]); Исключение Сообщить("Неверный формат настройки"); Возврат Ложь; КонецПопытки; 
	КонецЦикла;
	Если Не лСтруктураНастройки.Свойство("uid") или Не лСтруктураНастройки.Свойство("user") или Не лСтруктураНастройки.Свойство("pass") Тогда Сообщить("Неверный формат настройки"); Возврат Ложь; КонецЕсли;
	лТекстОшибки="";
	Если Не мПодключитьКБазеОбменаПоПараметрам(лСтрокаПодключения, лСтруктураНастройки.user, лСтруктураНастройки.pass, лСтруктураНастройки.uid,,, лТекстОшибки) Тогда 
		Сообщить(лТекстОшибки);
		Возврат Ложь;
	КонецЕсли;
	ОбновитьПовторноИспользуемыеЗначения();
	Сообщить("Настройки успешно загружены!"); 
	Возврат Истина; 
КонецФункции
#КонецОбласти

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

Функция ЗагрузитьОбъекты() Экспорт // для подключений которые забирают данные
	лДатаЗагрузки=ТекущаяДата();
	лПодключениеТекущее=ТсПлатформаОбщий.КонстантаПолучить("ТсПлатформаПодключениеЧерезСервис");
	
	//мОбновитьПравилаПередЗагрузкойОбъектов(лПодключениеТекущее); // доделать!!!!!!!!!!!!!
	
	лЗапрос=Новый Запрос;
	лЗапрос.УстановитьПараметр("ПодключениеПриемник", лПодключениеТекущее);
	лЗапрос.Текст=
	"ВЫБРАТЬ
	|	ТсОбменПравилаВыгрузокКонфигураций.Ссылка КАК Ссылка,
	|	ТсОбменПравилаВыгрузокКонфигураций.ПодключениеИсточник КАК ПодключениеИсточник,
	|	ТсОбменПравилаВыгрузокКонфигураций.ДатаОбновления КАК ДатаОбновления
	|ИЗ
	|	Справочник.ТсОбменПравилаВыгрузокКонфигураций КАК ТсОбменПравилаВыгрузокКонфигураций
	|ГДЕ
	|	ТсОбменПравилаВыгрузокКонфигураций.ПодключениеПриемник = &ПодключениеПриемник
	|	И ТсОбменПравилаВыгрузокКонфигураций.Включен
	|	И НЕ ТсОбменПравилаВыгрузокКонфигураций.ПометкаУдаления";
	лЕстьЗагруженныеПакеты=Ложь;
	лВыборка=лЗапрос.Выполнить().Выбрать();
	Пока лВыборка.Следующий() Цикл
		лТекстОшибки="";
		лСтруктураОтвета=ЗапросPOSTКСерверуОбмена("GetDataForRules", лВыборка.ПодключениеИсточник, Новый Структура("ПравилоВыгрузкиКонфигурации, ДатаОбновления, Подключение", ""+лВыборка.Ссылка.УникальныйИдентификатор(), лВыборка.ДатаОбновления, ""+лПодключениеТекущее.УникальныйИдентификатор()), Новый Структура("Таймаут", 30), лТекстОшибки);
		Если Не ЗначениеЗаполнено(лТекстОшибки) и лСтруктураОтвета.Ошибка Тогда лТекстОшибки=лСтруктураОтвета.ТекстОшибки; КонецЕсли;
		Если ЗначениеЗаполнено(лТекстОшибки) Тогда Сообщить("При загрузке по правилу: "+лВыборка.Ссылка+", возникла ошибка: "+лТекстОшибки); Продолжить; КонецЕсли;
		
		Если лСтруктураОтвета.Данные.ПравилоВыгрузкиКонфигурации<>Неопределено Тогда // правила выгрузки изменились, надо загрузить их
			Если Не мСервисПравилаВыгрузкиОбновить(лСтруктураОтвета.Данные.ПравилоВыгрузкиКонфигурации, лТекстОшибки) Тогда 
				Сообщить("При загрузке правил возникла ошибка: "+лТекстОшибки);
				Продолжить;
			КонецЕсли; 
		КонецЕсли;
		
		лМассивДляПередачиСостояния=Новый Массив;
		Для Каждого лСтруктураДанные Из лСтруктураОтвета.Данные.Пакеты Цикл
			Если лСтруктураДанные.Ошибка Тогда Сообщить("При формировании данных по правилу: "+лВыборка.Ссылка+", возникла ошибка: "+лСтруктураДанные.ТекстОшибки); Продолжить; КонецЕсли; 
			
			лТекстОшибки="";
			лСтруктураПакета=ТсПлатформаОбщий.КонвертироватьИзJSON(лСтруктураДанные.Пакет);
			лПакет=ПакетОбменаСохранить(лСтруктураПакета, Истина, Ложь, лВыборка.ПодключениеИсточник, лПодключениеТекущее, лТекстОшибки, Ложь, лВыборка.Ссылка); // тут не будем записывать объекты пакета, сохраним их сразу после загрузки
			Если лПакет<>Неопределено Тогда лЕстьЗагруженныеПакеты=Истина; КонецЕсли;
			лМассивДляПередачиСостояния.Добавить(Новый Структура("ПакетУИД, Ошибка, ТекстОшибки", ""+лПакет.УникальныйИдентификатор(), лПакет=Неопределено, лТекстОшибки));
			Если ЗначениеЗаполнено(лТекстОшибки) Тогда Сообщить(лТекстОшибки); Продолжить; КонецЕсли;
			
			Попытка
				Если Не ПакетОбменаЗагрузить(лПакет,,, лТекстОшибки, Истина) Тогда Сообщить(лТекстОшибки); КонецЕсли;
			Исключение
				лИнформацияОбОшибке=ИнформацияОбОшибке();
				Сообщить(ТсПлатформаОбщий.ПолучитьПолноеОписаниеОшибки(лИнформацияОбОшибке));
			КонецПопытки; 
		КонецЦикла;
		
		Если лМассивДляПередачиСостояния.Количество()<>0 Тогда
			лСтруктураОтвета=ЗапросPOSTКСерверуОбмена("UpdatePackageState", лВыборка.ПодключениеИсточник, лМассивДляПередачиСостояния, Новый Структура("Таймаут", 10), лТекстОшибки);
			Если Не ЗначениеЗаполнено(лТекстОшибки) и лСтруктураОтвета.Ошибка Тогда лТекстОшибки=лСтруктураОтвета.ТекстОшибки; Сообщить(лТекстОшибки); КонецЕсли;
		КонецЕсли;
	КонецЦикла;
	ТсПлатформаОбщий.КонстантаУстановить("ТсМПДатаПоследнегоОбмена", лДатаЗагрузки); // Есть в МП, в остальных просто не установится
	Если лЕстьЗагруженныеПакеты Тогда ПакетыОбменаПередатьРезультаты(); КонецЕсли;
КонецФункции

Функция ПравилоВыгрузкиКонфигурацииЗагрузитьВсеДанные(пПравилоВыгрузкиКонфигурации) Экспорт
	лДатаНачала=ТекущаяДата();
	лПодключениеТекущее=ТсПлатформаОбщий.КонстантаПолучить("ТсПлатформаПодключениеЧерезСервис");
	лТекстОшибки="";
	лСтруктураОтвета=ЗапросPOSTКСерверуОбмена("GetAllDataForRule", пПравилоВыгрузкиКонфигурации.ПодключениеИсточник, Новый Структура("ПравилоВыгрузкиКонфигурации, Подключение", ""+пПравилоВыгрузкиКонфигурации.УникальныйИдентификатор(), ""+лПодключениеТекущее.УникальныйИдентификатор()), Новый Структура("Таймаут", 2000), лТекстОшибки);
	Если Не ЗначениеЗаполнено(лТекстОшибки) и лСтруктураОтвета.Ошибка Тогда лТекстОшибки=лСтруктураОтвета.ТекстОшибки; КонецЕсли;
	Если ЗначениеЗаполнено(лТекстОшибки) Тогда Сообщить("При загрузке по правилу: "+пПравилоВыгрузкиКонфигурации+", возникла ошибка: "+лТекстОшибки); Возврат Ложь; КонецЕсли;
	
	Для Каждого лСтруктураДанные Из лСтруктураОтвета.Данные Цикл
		Попытка	
			лТекстОшибки="";
			лПакет=ПакетОбменаСохранить(лСтруктураДанные, Истина, Ложь, пПравилоВыгрузкиКонфигурации.ПодключениеИсточник, лПодключениеТекущее, лТекстОшибки, Ложь);
			Если ЗначениеЗаполнено(лТекстОшибки) Тогда Сообщить(лТекстОшибки); Возврат Ложь; КонецЕсли; 
		Исключение
			лИнформацияОбОшибке=ИнформацияОбОшибке();
			Сообщить(ТсПлатформаОбщий.ПолучитьПолноеОписаниеОшибки(лИнформацияОбОшибке));
			Возврат Ложь;
		КонецПопытки; 
	КонецЦикла;
	
	ПакетыОбменаЗагрузить(,, Истина);
	
	лКоличествоМинут=Цел((ТекущаяДата()-лДатаНачала)/60);
	Сообщить("Все данные по правилу: "+пПравилоВыгрузкиКонфигурации+" успешно загружены за "+лКоличествоМинут+" минут!");
	Возврат Истина; 
КонецФункции

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

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

Функция мДляХраненияПакетаИспользуетсяХранилище() // для перехода на хранилища
	Возврат Метаданные.Справочники.ТсОбменПакеты.Реквизиты.Найти("ДанныеХранилище")<>Неопределено;
КонецФункции

Функция ПакетОбменаПолучитьДанные(пПакетСсылка, пДанныеВозврата=Ложь) Экспорт
	лИмяРеквизита=?(пДанныеВозврата, "ДанныеВозврата", "Данные");
	Если мДляХраненияПакетаИспользуетсяХранилище() Тогда // для перехода на хранилища
		лДанные=пПакетСсылка[лИмяРеквизита+"Хранилище"].Получить();
		Если лДанные<>Неопределено Тогда Возврат лДанные; КонецЕсли;
	КонецЕсли;
	Возврат ?(пДанныеВозврата, пПакетСсылка.ДанныеВозврата, пПакетСсылка.Данные);
КонецФункции

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

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

Функция ЭлементПриПолученииДанныхНаСервере(пИмяФормы, пИмяЭлемента, пНастройки, пСтроки) Экспорт
	Если пИмяФормы="Справочник.ТсОбменПакеты.Форма.ФормаСписка" Тогда
		лЗапрос=Новый Запрос;
		лЗапрос.УстановитьПараметр("Пакеты", пСтроки.ПолучитьКлючи());
		лЗапрос.Текст=
		"ВЫБРАТЬ
		|	ТсОбменПакетыСобытия.Пакет КАК Пакет,
		|	МАКСИМУМ(ТсОбменПакетыСобытия.Позиция) КАК Позиция
		|ПОМЕСТИТЬ ВТПозицииПоследние
		|ИЗ
		|	РегистрСведений.ТсОбменПакетыСобытия КАК ТсОбменПакетыСобытия
		|ГДЕ
		|	ТсОбменПакетыСобытия.Пакет В(&Пакеты)
		|
		|СГРУППИРОВАТЬ ПО
		|	ТсОбменПакетыСобытия.Пакет
		|;
		|
		|////////////////////////////////////////////////////////////////////////////////
		|ВЫБРАТЬ
		|	ТсОбменПакетыСобытия.Пакет КАК Пакет,
		|	ТсОбменПакетыСобытия.Событие КАК Событие,
		|	ТсОбменПакетыСобытия.Дата КАК ДатаСобытия,
		|	ТсОбменПакетыСобытия.Ошибка КАК Ошибка
		|ИЗ
		|	РегистрСведений.ТсОбменПакетыСобытия КАК ТсОбменПакетыСобытия
		|		ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТПозицииПоследние КАК ВТПозицииПоследние
		|		ПО ТсОбменПакетыСобытия.Пакет = ВТПозицииПоследние.Пакет
		|			И ТсОбменПакетыСобытия.Позиция = ВТПозицииПоследние.Позиция
		|ГДЕ
		|	ТсОбменПакетыСобытия.Пакет В(&Пакеты)";
		лВыборка=лЗапрос.Выполнить().Выбрать();
		Пока лВыборка.Следующий() Цикл
			лСтрока=пСтроки[лВыборка.Пакет];
			ЗаполнитьЗначенияСвойств(лСтрока.Данные, лВыборка);
		КонецЦикла;
		
	ИначеЕсли пИмяФормы="Справочник.ТсОбменПравилаВыгрузокКонфигураций.Форма.ФормаСписка" Тогда
		Если пИмяЭлемента="СписокОбъектыКВыгрузке" Тогда
			Если мСоответствиеИмяТаблицыМенеджер=Неопределено Тогда мСоответствиеИмяТаблицыМенеджер=Новый Соответствие; КонецЕсли;
			Для Каждого лСтрока Из пСтроки Цикл
				лИмяТаблицы=лСтрока.Значение.Данные.ИмяТаблицы;
				Если Не ЗначениеЗаполнено(лИмяТаблицы) Тогда Продолжить; КонецЕсли; 
				лМенеджер=мСоответствиеИмяТаблицыМенеджер.Получить(лИмяТаблицы);
				Если лМенеджер=Неопределено Тогда
					Если СтрНачинаетсяС(лИмяТаблицы, "Регистры") Тогда
						лПравилоВыгрузкиТаблицы=лСтрока.Значение.Данные.ПравилоВыгрузкиТаблицы;
						лСтруктураПКК=ТсПлатформаОбщий.КонвертироватьИзJSON(лПравилоВыгрузкиТаблицы.Владелец.Правила);
						лИмяТаблицы=мПравилаКонвертацииПолучитьИмяТаблицыУстановленногоПервичногоКлючаРегистра(лСтруктураПКК, лПравилоВыгрузкиТаблицы.КодПравила, лПравилоВыгрузкиТаблицы.ИмяРеквизитаРегистрации);
					КонецЕсли;
					лМенеджер=?(лИмяТаблицы=Неопределено, Неопределено, Вычислить(лИмяТаблицы));
					мСоответствиеИмяТаблицыМенеджер.Вставить(лИмяТаблицы, лМенеджер);
				КонецЕсли;
				Если лМенеджер=Неопределено Тогда лСтрока.Значение.Данные.Объект=""; Продолжить; КонецЕсли;
				Попытка лСтрока.Значение.Данные.Объект=""+лМенеджер.ПолучитьСсылку(лСтрока.Значение.Данные.УИД); Исключение КонецПопытки; 
			КонецЦикла;
		КонецЕсли;
		
	ИначеЕсли пИмяФормы="РегистрСведений.ТсОбменОбъектыКВыгрузке.Форма.ФормаСписка" Тогда
		Если пИмяЭлемента="Список" Тогда
			Для Каждого лСтрока Из пСтроки Цикл
				Если Не ЗначениеЗаполнено(лСтрока.Значение.Данные.ИмяТаблицы) Тогда Продолжить; КонецЕсли;
				Попытка лСтрока.Значение.Данные.Объект=""+Вычислить(лСтрока.Значение.Данные.ИмяТаблицы).ПолучитьСсылку(лСтрока.Значение.Данные.УИД); Исключение КонецПопытки; // TODO: переделать для регистра
			КонецЦикла;
		КонецЕсли;
	КонецЕсли;
КонецФункции
#КонецОбласти 

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

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

Функция Инициализировать() Экспорт

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