Сопоставление объектов информационных баз / Форма / Модуль формы

файл
///////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2025, ООО 1С-Софт
// Все права защищены. Эта программа и сопроводительные материалы предоставляются 
// в соответствии с условиями лицензии Attribution 4.0 International (CC BY 4.0)
// Текст лицензии доступен по ссылке:
// https://creativecommons.org/licenses/by/4.0/legalcode
///////////////////////////////////////////////////////////////////////////////////////////////////////

#Область ОбработчикиСобытийФормы

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

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

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

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

&НаКлиенте
Процедура ПередЗакрытиемЗавершение(Знач РезультатВопроса = Неопределено, Знач ДополнительныеПараметры = Неопределено) Экспорт
	// Процедура вызывается при положительном ответе на вопрос.
	// Закрываем форму с сохранением данных.
	ЗаписатьИЗакрыть(Неопределено);
КонецПроцедуры

&НаКлиенте
Процедура ПередЗакрытиемПродолжение()
	ЗаписатьИЗакрыть = Истина;
	ВыдаватьПредупреждениеПриЗакрытииФормы = Истина;
	ОбновитьТаблицуСопоставления();
КонецПроцедуры

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

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

#КонецОбласти

#Область ОбработчикиСобытийЭлементовШапкиФормы

&НаКлиенте
Процедура ОтборПоСтатусуСопоставленияПриИзменении(Элемент)
	
	УстановитьОтборТабличныхЧастей();
	
КонецПроцедуры

#КонецОбласти

#Область ОбработчикиСобытийЭлементовТаблицыФормыТаблицаСопоставления

&НаКлиенте
Процедура ТаблицаСопоставленияВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
	
	УстановитьСвязьИнтерактивно();
	СтандартнаяОбработка = Ложь;
	
КонецПроцедуры

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

#КонецОбласти

#Область ОбработчикиКомандФормы

&НаКлиенте
Процедура Обновить(Команда)
	
	ОбновитьТаблицуСопоставления();
	
КонецПроцедуры

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

&НаКлиенте
Процедура ВыполнитьЗагрузкуДанных(Команда)
	НСтрока = НСтр("ru = 'Получить данные в информационную базу?'");
	Оповещение = Новый ОписаниеОповещения("ВыполнитьЗагрузкуДанныхПослеВопросаОПодтвержденииПолученияДанных", ЭтотОбъект);
	
	ПоказатьВопрос(Оповещение, НСтрока, РежимДиалогаВопрос.ДаНет, ,КодВозвратаДиалога.Да);
КонецПроцедуры

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

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

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

&НаКлиенте
Процедура ДобавитьСопоставление(Команда)
	
	УстановитьСвязьИнтерактивно();
	
КонецПроцедуры

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

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

&НаКлиенте
Процедура ОтменитьСопоставлениеЗавершение(Результат, ДополнительныеПараметры) Экспорт
	
	Если Результат = КодВозвратаДиалога.Да Тогда
		ОтменитьСопоставлениеНаКлиенте()
	КонецЕсли;

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

&НаКлиенте
Процедура ОтменитьСопоставлениеНаКлиенте()

	ВыделенныеСтроки = Элементы.ТаблицаСопоставления.ВыделенныеСтроки;
	
	ОтменитьСопоставлениеНаСервере(ВыделенныеСтроки);
	
	// Обновляем отбор в табличных частях.
	УстановитьОтборТабличныхЧастей();
	
КонецПроцедуры



&НаКлиенте
Процедура ЗаписатьОбновить(Команда)
	
	ПрименитьТаблицуНеутвержденныхЗаписей = Истина;
	
	ОбновитьТаблицуСопоставления();
	
КонецПроцедуры

&НаКлиенте
Процедура ЗаписатьИЗакрыть(Команда)
	
	ПрименитьТаблицуНеутвержденныхЗаписей = Истина;
	ЗаписатьИЗакрыть = Истина;
	
	ОбновитьТаблицуСопоставления();
КонецПроцедуры

////////////////////////////////////////////////////////////////////////////////
// СЛУЖЕБНЫЕ ПРОЦЕДУРЫ И ФУНКЦИИ (Поставляемая часть).

&НаКлиенте
Процедура ИзменитьПорядковыйНомерПерехода(Итератор)
	
	ОчиститьСообщения();
	
	УстановитьПорядковыйНомерПерехода(ПорядковыйНомерПерехода + Итератор);
	
КонецПроцедуры

&НаКлиенте
Процедура УстановитьПорядковыйНомерПерехода(Знач Значение)
	
	ЭтоПереходДалее = (Значение > ПорядковыйНомерПерехода);
	
	ПорядковыйНомерПерехода = Значение;
	
	Если ПорядковыйНомерПерехода < 0 Тогда
		
		ПорядковыйНомерПерехода = 0;
		
	КонецЕсли;
	
	ПорядковыйНомерПереходаПриИзменении(ЭтоПереходДалее);
	
КонецПроцедуры

&НаКлиенте
Процедура ПорядковыйНомерПереходаПриИзменении(Знач ЭтоПереходДалее)
	
	// Выполняем обработчики событий перехода.
	ВыполнитьОбработчикиСобытийПерехода(ЭтоПереходДалее);
	
	// Устанавливаем отображение страниц.
	СтрокиПереходаТекущие = ТаблицаПереходов.НайтиСтроки(Новый Структура("ПорядковыйНомерПерехода", ПорядковыйНомерПерехода));
	
	Если СтрокиПереходаТекущие.Количество() = 0 Тогда
		ВызватьИсключение НСтр("ru = 'Не определена страница для отображения.'");
	КонецЕсли;
	
	СтрокаПереходаТекущая = СтрокиПереходаТекущие[0];
	
	Элементы.ПанельОсновная.ТекущаяСтраница = Элементы[СтрокаПереходаТекущая.ИмяОсновнойСтраницы];
	
	Если ЭтоПереходДалее И СтрокаПереходаТекущая.ДлительнаяОперация Тогда
		
		ПодключитьОбработчикОжидания("ВыполнитьОбработчикДлительнойОперации", 0.1, Истина);
		
	КонецЕсли;
	
КонецПроцедуры

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

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

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

#КонецОбласти

#Область СлужебныеПроцедурыИФункции

&НаСервере
Процедура УстановитьУсловноеОформление()

	УсловноеОформление.Элементы.Очистить();

	//

	Элемент = УсловноеОформление.Элементы.Добавить();

	ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
	ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.ТаблицаСопоставленияПриемникПоле1.Имя);

	ОтборЭлемента = Элемент.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ТаблицаСопоставления.СтатусСопоставления");
	ОтборЭлемента.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
	ОтборЭлемента.ПравоеЗначение = -1;

	Элемент.Оформление.УстановитьЗначениеПараметра("ЦветТекста", ЦветаСтиля.ТекстЗапрещеннойЯчейкиЦвет);
	Элемент.Оформление.УстановитьЗначениеПараметра("Текст", НСтр("ru = 'Нет соответствия, объект будет скопирован'"));

	//

	Элемент = УсловноеОформление.Элементы.Добавить();

	ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
	ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.ТаблицаСопоставленияИсточникПоле1.Имя);

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

	Элемент.Оформление.УстановитьЗначениеПараметра("ЦветТекста", ЦветаСтиля.ТекстЗапрещеннойЯчейкиЦвет);
	Элемент.Оформление.УстановитьЗначениеПараметра("Текст", НСтр("ru = 'Нет соответствия'"));

	//
	
	Элемент = УсловноеОформление.Элементы.Добавить();

	ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
	ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.ТаблицаСопоставленияСопоставлениеПоСсылкеКартинка.Имя);

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

	Элемент.Оформление.УстановитьЗначениеПараметра("Отображать", Ложь);

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

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

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

&НаКлиенте
Процедура ВыполнитьЗагрузкуДанныхПослеПодтвержденияПолученияДанных()
	
	// Выполняем загрузку данных на сервере.
	Отказ = Ложь;
	ВыполнитьЗагрузкуДанныхНаСервере(Отказ);
	
	Если Отказ Тогда
		НСтрока = НСтр("ru = 'При получении данных возникли ошибки.
		                     |Перейти в журнал регистрации?'");
		
		Оповещение = Новый ОписаниеОповещения("ВыполнитьЗагрузкуДанныхПослеВопросаОПереходеВЖурналРегистрации", ЭтотОбъект);
		ПоказатьВопрос(Оповещение, НСтрока, РежимДиалогаВопрос.ДаНет, ,КодВозвратаДиалога.Нет);
		
		Возврат;
	КонецЕсли;
	
	// Обновляем данные в таблице сопоставления.
	ОбновитьТаблицуСопоставления();
КонецПроцедуры

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

&НаКлиенте
Процедура ПерейтиДалее()
	
	ИзменитьПорядковыйНомерПерехода(+1);
	
КонецПроцедуры

&НаКлиенте
Процедура ПерейтиНазад()
	
	ИзменитьПорядковыйНомерПерехода(-1);
	
КонецПроцедуры

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

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

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

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

&НаСервере
Функция ПоместитьТаблицуНеутвержденныхСвязейВоВременноеХранилище()
	
	Возврат ПоместитьВоВременноеХранилище(Объект.ТаблицаНеутвержденныхСвязей.Выгрузить(), УникальныйИдентификатор);
	
КонецФункции

&НаСервере
Функция ПолучитьАдресВременногоХранилищаТаблицыВыбораСвязи(ПараметрыОтбора)
	
	Колонки = "НомерПоПорядку, ПолеСортировки1, ПолеСортировки2, ПолеСортировки3, ПолеСортировки4, ПолеСортировки5, ИндексКартинки";
	
	Возврат ПоместитьВоВременноеХранилище(ТаблицаСопоставления.Выгрузить(ПараметрыОтбора, Колонки));
	
КонецФункции

&НаКлиенте
Процедура УстановитьМодифицированностьФормы()
	
	Модифицированность = (Объект.ТаблицаНеутвержденныхСвязей.Количество() > 0);
	
КонецПроцедуры

&НаКлиенте
Процедура ОбновитьТаблицуСопоставления()
	
	Элементы.КнопкиТаблицы.Доступность = Ложь;
	Элементы.ГруппаЗаголовкаТаблицы.Доступность = Ложь;
	
	ПорядковыйНомерПерехода = 0;
	
	// Позиционируемся на втором шаге помощника.
	УстановитьПорядковыйНомерПерехода(2);
	
КонецПроцедуры

////////////////////////////////////////////////////////////////////////////////
// Прикладные

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

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

&НаКлиенте
Процедура УстановитьОтборТабличныхЧастей()
	
	Элементы.ТаблицаСопоставления.ОтборСтрок = ВариантыОтбораСтатусаСопоставления[ОтборПоСтатусуСопоставления];
	
КонецПроцедуры

&НаКлиенте
Процедура ЗаполнитьПоляПоиска()

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

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

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

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

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

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

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

&НаКлиенте
Процедура ДобавитьНеутвержденноеСопоставлениеНаКлиенте(Знач ИдентификаторСтрокиНачала, Знач ИдентификаторСтрокиОкончания)
	
	// Получаем две сопоставленные строки таблицы по указанным идентификаторам.
	// Добавляем строку в таблицу неутверженных связей.
	// Добавляем строку в таблицу сопоставления.
	// Удаляем две сопоставленные строки из таблицы сопоставления.
	
	СтрокаНачала    = ТаблицаСопоставления.НайтиПоИдентификатору(ИдентификаторСтрокиНачала);
	СтрокаОкончания = ТаблицаСопоставления.НайтиПоИдентификатору(ИдентификаторСтрокиОкончания);
	
	Если СтрокаНачала = Неопределено Или СтрокаОкончания = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	Если СтрокаНачала.СтатусСопоставления=-1 И СтрокаОкончания.СтатусСопоставления=+1 Тогда
		СтрокаИсточника = СтрокаНачала;
		СтрокаПриемника = СтрокаОкончания;
	ИначеЕсли СтрокаНачала.СтатусСопоставления=+1 И СтрокаОкончания.СтатусСопоставления=-1 Тогда
		СтрокаИсточника = СтрокаОкончания;
		СтрокаПриемника = СтрокаНачала;
	Иначе
		Возврат;
	КонецЕсли;
	
	// Добавляем строку в таблицу неутвержденных связей.
	НоваяСтрока = Объект.ТаблицаНеутвержденныхСвязей.Добавить();
	
	НоваяСтрока.УникальныйИдентификаторИсточника = СтрокаПриемника.УникальныйИдентификаторПриемника;
	НоваяСтрока.ТипИсточника                     = СтрокаПриемника.ТипПриемника;
	НоваяСтрока.УникальныйИдентификаторПриемника = СтрокаИсточника.УникальныйИдентификаторИсточника;
	НоваяСтрока.ТипПриемника                     = СтрокаИсточника.ТипИсточника;
	
	// Добавляем строку в таблицу сопоставления как неутвержденную.
	НоваяСтрокаНеутвержденные = ТаблицаСопоставления.Добавить();
	
	// Поля сортировки берем из строки приемника.
	ЗаполнитьЗначенияСвойств(НоваяСтрокаНеутвержденные, СтрокаИсточника, "ИсточникИндексКартинки, ИсточникПоле1, ИсточникПоле2, ИсточникПоле3, ИсточникПоле4, ИсточникПоле5, УникальныйИдентификаторИсточника, ТипИсточника");
	ЗаполнитьЗначенияСвойств(НоваяСтрокаНеутвержденные, СтрокаПриемника, "ПриемникИндексКартинки, ПриемникПоле1, ПриемникПоле2, ПриемникПоле3, ПриемникПоле4, ПриемникПоле5, УникальныйИдентификаторПриемника, ТипПриемника, ПолеСортировки1, ПолеСортировки2, ПолеСортировки3, ПолеСортировки4, ПолеСортировки5, ИндексКартинки");
	
	НоваяСтрокаНеутвержденные.СтатусСопоставления               = 3; // неутверженная связь
	НоваяСтрокаНеутвержденные.СтатусСопоставленияДополнительный = 0;
	
	// Удаляем сопоставленные строки.
	ТаблицаСопоставления.Удалить(СтрокаНачала);
	ТаблицаСопоставления.Удалить(СтрокаОкончания);
	
	// И обновляем номера
	НоваяСтрокаНеутвержденные.НомерПоПорядку = СледующийНомерПоПорядкуСопоставления();
	
	НоваяСтрокаНеутвержденные.СопоставлениеПоСсылке = ОбъектыСопоставленыПоСсылке(НоваяСтрокаНеутвержденные);
	
	// Устанавливаем отбор и обновляем данные в таблице сопоставления.
	УстановитьОтборТабличныхЧастей();
КонецПроцедуры

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

&НаКлиенте
Процедура ВыполнитьСортировкуТаблицы()
	
	ПоляСортировки = ПолучитьПоляСортировки();
	Если Не ПустаяСтрока(ПоляСортировки) Тогда
		ТаблицаСопоставления.Сортировать(ПоляСортировки);
	КонецЕсли;
	
КонецПроцедуры

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

////////////////////////////////////////////////////////////////////////////////
// Свойства

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

////////////////////////////////////////////////////////////////////////////////
// Обработчики событий переходов.

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

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

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

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

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

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

// Страница 3: Сопоставление объектов.
//
&НаСервере
Процедура ВыполнитьСопоставлениеОбъектовОкончание(Отказ)
	
	Попытка
		ПослеСопоставленияОбъектов();
	Исключение
		Отказ = Истина;
		ЗафиксироватьОшибку(ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
		Возврат;
	КонецПопытки;
	
КонецПроцедуры

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

&НаСервере
Процедура ЗафиксироватьОшибку(ПодробноеПредставлениеОшибки)
	
	ЗаписьЖурналаРегистрации(
		НСтр("ru = 'Помощник сопоставления объектов.Анализ данных'", ОбщегоНазначения.КодОсновногоЯзыка()),
		УровеньЖурналаРегистрации.Ошибка,
		,
		, ПодробноеПредставлениеОшибки);
	
КонецПроцедуры

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

////////////////////////////////////////////////////////////////////////////////
// Инициализация переходов помощника.

&НаСервере
Процедура СценарийВыполненияСопоставленияОбъектов()
	
	ТаблицаПереходов.Очистить();
	ТаблицаПереходовНоваяСтрока(1, "ОшибкаСопоставленияОбъектов", "Подключаемый_ОшибкаСопоставленияОбъектов_ПриОткрытии");
	
	// Ожидание сопоставления объектов.
	ТаблицаПереходовНоваяСтрока(2, "ОжиданиеСопоставленияОбъектов",, Истина, "Подключаемый_ОжиданиеСопоставленияОбъектов_ОбработкаДлительнойОперации");
	ТаблицаПереходовНоваяСтрока(3, "ОжиданиеСопоставленияОбъектов",, Истина, "Подключаемый_ОжиданиеСопоставленияОбъектовДлительнаяОперацияОкончание_ОбработкаДлительнойОперации");
	
	// Работа с таблицей сопоставления объектов.
	ТаблицаПереходовНоваяСтрока(4, "СопоставлениеОбъектов");
	
КонецПроцедуры

#КонецОбласти

Связанные материалы