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

// Структура примитивных типов (Булево, Дата, Строка, Число)
Перем ПримитивныеТипы;
Перем мИмяКолонкиНомерСтроки Экспорт;
Перем мИмяКолонкиРезультатПоиска Экспорт;
Перем мИмяКолонкиРезультатЗаписи Экспорт;
Перем мИмяКолонкиСообщенияОбработки Экспорт;
Перем мАлгоритмКонвертацииЗначенияПараметры Экспорт;
Перем мЭтоСсылочныйОбъект Экспорт;
Перем мПлатформа Экспорт;
Перем мКоличествоУспешно Экспорт;
Перем мКоличествоНеуспешно Экспорт;
Перем мТекущееПолноеИмяТаблицы Экспорт;
Перем мКонсольЗапросов Экспорт;
Перем мДополнениеЗапросом Экспорт;
Перем мСуффиксСырыхДанных Экспорт;
Перем мКэшОбластейТД Экспорт;
Перем _РежимОтладки;

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

	НачалоСлужебногоСообщения    = Найти(ТекстСообщения, "{");
	ОкончаниеСлужебногоСообщения = Найти(ТекстСообщения, "}:");
	Если ОкончаниеСлужебногоСообщения > 0 И НачалоСлужебногоСообщения > 0 Тогда
		ТекстСообщения = Лев(ТекстСообщения, (НачалоСлужебногоСообщения - 1)) +
		                 Сред(ТекстСообщения, (ОкончаниеСлужебногоСообщения + 2));
	КонецЕсли;
	Отказ = Истина;
	Возврат ТекстСообщения;
	
КонецФункции

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

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

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

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

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

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

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

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

// Функция считывает в табличный документ данные из файла в формате Excel
//
// Параметры:
//  ТабличныйДокумент  - ТабличныйДокумент, в который необходимо прочитать данные
//  ИмяФайла           - имя файла в формате Excel, из которого необходимо прочитать данные
//  НомерЛистаExcel    - номер листа книги Excel, из которого необходимо прочитать данные
//
// Возвращаемое значение:
//  Истина, если файл прочитан, Ложь - иначе
//
Функция _мПрочитатьТабличныйДокументИзExcel(ТабличныйДокумент, ИмяФайла, НомерЛистаExcel = 1) Экспорт
	
	#Если Сервер И Не Сервер Тогда
	    ТабличныйДокумент = Новый ТабличныйДокумент;
	#КонецЕсли
	xlLastCell = 11;
	ВыбФайл = Новый Файл(ИмяФайла);
	Если НЕ ВыбФайл.Существует() Тогда
		ирОбщий.СообщитьЛкс("Файл не существует!");
		Возврат Ложь;
	КонецЕсли;
	Попытка
		Excel = Новый COMОбъект("Excel.Application");
		Excel.WorkBooks.Open(ИмяФайла);
		Состояние("Обработка файла Microsoft Excel...");
		ExcelЛист = Excel.Sheets(НомерЛистаExcel);
	Исключение
		ирОбщий.СообщитьЛкс("Ошибка. Возможно неверно указан номер листа книги Excel.");
		Возврат ложь;
	КонецПопытки;
	ТабличныйДокумент.Очистить();
	ActiveCell = Excel.ActiveCell.SpecialCells(xlLastCell);
	RowCount = ActiveCell.Row;
	ColumnCount = ActiveCell.Column;
	Для Column = 1 По ColumnCount Цикл
		ТабличныйДокумент.Область("C" + Формат(Column, "ЧГ=")).ШиринаКолонки = ExcelЛист.Columns(Column).ColumnWidth;
	КонецЦикла;
	Для Row = 1 По RowCount Цикл
		Для Column = 1 По ColumnCount Цикл
			ТабличныйДокумент.Область("R" + Формат(Row, "ЧГ=") +"C" + Формат(Column, "ЧГ=")).Текст = ExcelЛист.Cells(Row,Column).Text;
		КонецЦикла;
	КонецЦикла;
	Excel.WorkBooks.Close();
	Excel = 0;
	Возврат Истина;
	
КонецФункции // ()

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

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

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

#КонецЕсли

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

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

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

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

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

// Функция возвращает метаданные источника данных
//
// Параметры:
//  нет
//
// Возвращаемое значение:
//  Объект метаданных
//
Функция МетаданныеТаблицыБД() Экспорт
	
	Результат = ирОбщий.ОбъектМДПоПолномуИмениТаблицыБДЛкс(ПолноеИмяТаблицы);
	Возврат Результат;
	
КонецФункции

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

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

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

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

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

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

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

Функция ПолучитьКолонкиТабличногоДокумента(СтруктураПозицийТД = Неопределено, ТолькоВыделенныеСтрокиТД = Ложь) Экспорт 

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

Функция ИмяКолонкиТабличногоДокумента(Знач НомерКолонки)
	
	СтрокаНомераКолонки = Формат(НомерКолонки, "ЧЦ=3; ЧВН=");
	Возврат СтрокаНомераКолонки;

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

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

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

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

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

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

// Обработать элементы объекта
//
// Параметры:
//  ПараметрыОбработкиОбъекта - Структура - 
// 
// Возвращаемое значение:
//   - 
//
Функция ОбработатьЭлементыОбъекта(ПараметрыОбработкиОбъекта) Экспорт 

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

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

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

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

Процедура ОбновитьКоличествоУспешноДляОтображения()
	
	ЭтотОбъект.КоличествоУспешно = мКоличествоУспешно;
	ЭтотОбъект.КоличествоНеуспешно = мКоличествоНеуспешно;

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

Функция ОбработатьСобытиеЛкс(ТаблицаСобытий, ИмяСобытия, выхОписаниеОшибки, П1 = null, П2 = null, П3 = null, П4 = null, П5 = null, П6 = null, П7 = null, П8 = null) Экспорт 
	
	Алгоритм = СобытияОбработкиОбъектов.Найти(ИмяСобытия).Алгоритм;
	Попытка
		Выполнить(Алгоритм);
	Исключение
		выхОписаниеОшибки = ПолучитьПричинуОшибки(ОписаниеОшибки());
		Возврат Ложь;
	КонецПопытки;
	Возврат Истина;
	
КонецФункции

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Процедура ЗаполнитьСопоставлениеКолонокБД(Знач РазрешитьИзменятьРежим = Истина) Экспорт 
	
	КопияСопоставления = СопоставлениеКолонокБД.Скопировать();
	СопоставлениеКолонокБД.Очистить();
	Если Не ЗначениеЗаполнено(ПолноеИмяТаблицы) Тогда
		Возврат;
	КонецЕсли; 
	МетаданныеИсточника = МетаданныеТаблицыБД();
	ПоляТаблицы = ирОбщий.ПоляТаблицыМДЛкс(ПолноеИмяТаблицы);
	СтруктураКлючаОбъекта = ирОбщий.СтруктураКлючаТаблицыБДЛкс(ПолноеИмяТаблицы, Ложь);
	МассивВозможныхПолейПоиска = Новый Массив;
	МассивВозможныхПолейПоиска.Добавить("Код");
	МассивВозможныхПолейПоиска.Добавить("Наименование");
	МассивВозможныхПолейПоиска.Добавить("Период");
	МассивВозможныхПолейПоиска.Добавить("Регистратор");
	МассивВозможныхПолейПоиска.Добавить("НомерСтроки");
	МассивВозможныхПолейПоиска.Добавить("Ссылка");
	МассивВозможныхПолейПоиска.Добавить("Номер");
	МассивВозможныхПолейПоиска.Добавить("Владелец");
	МассивВозможныхПолейПоиска.Добавить("Дата");
	МассивВозможныхПолейПоиска.Добавить("Родитель");
	МассивВозможныхПолейПоиска.Добавить("ЭтоГруппа");
	ТипТаблицыБД = ирОбщий.ТипТаблицыБДЛкс(ПолноеИмяТаблицы);
	Если ирОбщий.ЛиКорневойТипРегистраБДЛкс(ТипТаблицыБД) Тогда
		Для каждого МетаИзмерение Из МетаданныеИсточника.Измерения Цикл
			МассивВозможныхПолейПоиска.Добавить(МетаИзмерение.Имя);
		КонецЦикла;
	КонецЕсли; 
	Для Каждого ПолеТаблицы Из ПоляТаблицы Цикл
		Если Ложь
			Или ПолеТаблицы.ТипЗначения.СодержитТип(Тип("ТаблицаЗначений"))
			//Или ПолеТаблицы.ТипЗначения.СодержитТип(Тип("ХранилищеЗначения"))
			//Или (Истина
			//	И ПолеТаблицы.Метаданные = Неопределено
			//	И (Ложь
			//		Или ПолеТаблицы.Имя = "ВерсияДанных"
			//		Или ПолеТаблицы.Имя = "Предопределенный"))
		Тогда
			Продолжить;
		КонецЕсли; 
		ЗагружаемыйРеквизит = СопоставлениеКолонокБД.Добавить();
		ЗагружаемыйРеквизит.ИмяКолонкиПриемника = ПолеТаблицы.Имя;
		ЗагружаемыйРеквизит.СинонимКолонкиПриемника = ПолеТаблицы.Заголовок;
		ЗагружаемыйРеквизит.ОписаниеТиповПриемника = ПолеТаблицы.ТипЗначения;
		ЗагружаемыйРеквизит.ДоступноИзменение = Истина
			И Не (Истина
				И ирОбщий.ЛиТипВложеннойТаблицыБДЛкс(ТипТаблицыБД)
				И (Ложь
					Или ПолеТаблицы.Имя = "Ссылка"
					Или ПолеТаблицы.Имя = "НомерСтроки"))
			И (Ложь
				Или Не мЭтоСсылочныйОбъект 
				Или Не ирОбщий.НедоступноИзменениеПоляСсылочногоОбъектаЛкс(ПолеТаблицы.Имя));
		Если ирОбщий.ЛиМетаданныеОбъектаСГруппамиЛкс(МетаданныеИсточника) Тогда 
			Если Истина
				И ТипЗнч(ПолеТаблицы.Метаданные) = Тип("ОбъектМетаданных")
				И (Ложь
					Или ирКэш.НомерВерсииПлатформыЛкс() < 802014 
					Или Метаданные.ОбщиеРеквизиты.Найти(ПолеТаблицы.Метаданные.Имя) = Неопределено) 
			Тогда 
				ЗагружаемыйРеквизит.Принадлежность = ПолеТаблицы.Метаданные.Использование;
			Иначе
				ЗагружаемыйРеквизит.Принадлежность = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляГруппыИЭлемента;
			КонецЕсли; 
		КонецЕсли; 
		Если СтруктураКлючаОбъекта.Свойство(ПолеТаблицы.Имя) Тогда
			ЗагружаемыйРеквизит.Ключевое = Истина;
			ЗагружаемыйРеквизит.ПолеПоиска = Не мЭтоСсылочныйОбъект;
		КонецЕсли; 
		Если ПолеТаблицы.Метаданные <> Неопределено Тогда
			ЗагружаемыйРеквизит.Подсказка = ПолеТаблицы.Метаданные.Подсказка;
			ЗагружаемыйРеквизит.Обязательное = ПолеТаблицы.Метаданные.ПроверкаЗаполнения = ПроверкаЗаполнения.ВыдаватьОшибку; 
		КонецЕсли; 
		ЗагружаемыйРеквизит.Значение = ЗагружаемыйРеквизит.ОписаниеТиповПриемника.ПривестиЗначение(Неопределено);
		ВосстановитьИзменяемыеСвойстваСтрокиСопоставленияБД(ЗагружаемыйРеквизит, КопияСопоставления);
		Если СтруктураКлючаОбъекта.Свойство(ПолеТаблицы.Имя) Тогда
			ЗагружаемыйРеквизит.Пометка = Не мЭтоСсылочныйОбъект;
			//ЗагружаемыйРеквизит.ПолеПоиска = Не мЭтоСсылочныйОбъект;
		КонецЕсли; 
	КонецЦикла;
	Если ирОбщий.ЛиКорневойТипСсылочногоОбъектаБДЛкс(ТипТаблицыБД) Тогда
		ТипСсылки = Тип(ирОбщий.ИмяТипаИзПолногоИмениМДЛкс(МетаданныеИсточника));
		СписокСвойств = ирОбщий.ДопРеквизитыБСПОбъектаЛкс(Новый(ТипСсылки));
		Для Каждого Свойство Из СписокСвойств Цикл
			#Если Сервер И Не Сервер Тогда
				Свойство = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.ПустаяСсылка(); //@skip-check unknown-method-property
			#КонецЕсли
			ЗагружаемыйРеквизит = СопоставлениеКолонокБД.Добавить();
			ЗагружаемыйРеквизит.ОписаниеТиповПриемника = Свойство.ТипЗначения;
			ЗагружаемыйРеквизит.ИмяКолонкиПриемника = Свойство.Имя;
			ЗагружаемыйРеквизит.СинонимКолонкиПриемника = Свойство.Наименование;
			ЗагружаемыйРеквизит.Принадлежность = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляГруппыИЭлемента;
			ЗагружаемыйРеквизит.ДопРеквизит = Свойство;
			ЗагружаемыйРеквизит.Подсказка = Свойство.Подсказка;
			ЗагружаемыйРеквизит.ДоступноИзменение = Истина;
			ВосстановитьИзменяемыеСвойстваСтрокиСопоставленияБД(ЗагружаемыйРеквизит, КопияСопоставления);
		КонецЦикла;
	КонецЕсли; 
	СопоставлениеКолонокБД.Сортировать("СинонимКолонкиПриемника");
	СопоставлениеКолонокБДЗаполнитьПоИменамСинонимам(Ложь,, РазрешитьИзменятьРежим);
	//ВыявитьНеуникальныеКлючи(); // Тут нельзя, т.к. ТаблицаЗначенийОтобранное может быть неактуальной
	
КонецПроцедуры

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

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

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

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

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

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

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

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

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

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

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

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

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

Процедура ОчиститьСопоставлениеКолонокБД() Экспорт

	Для Каждого СтрокаКолонкиБД Из СопоставлениеКолонокБД Цикл
		СопоставитьКолонкуБД(СтрокаКолонкиБД);
	КонецЦикла;
	ОбновитьСопоставлениеКолонокБД();

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

Процедура ОчиститьСопоставлениеКолонокТЗ() Экспорт

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

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

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

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

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

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

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

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

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

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

Функция РезультатПоискаНеНайдено() Экспорт 
	
	Возврат "Не найдено";

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

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

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


