////////////////////////////////////////////////////////////////////////////////
// ПЕРЕМЕННЫЕ МОДУЛЯ

Перем мМетаданныеОбъекта Экспорт;
Перем мКорневойТипОбъекта Экспорт;
Перем мТекущаяГруппа;
Перем мЗависимыеМетаданные;
Перем мПостроительЗапросаОтбора;
Перем мМассивОтложеннойЗагрузкиРеквизитов;
Перем мОтборТекущемуПоПравилу;
Перем мИмяСтарогоОбъектаМД;
Перем мТекущаяСтрокаУровняЦенности;
Перем мСхемаКомпоновкиОбщая;
Перем мСхемаКомпоновкиПар;
Перем мПсевдонимТаблицы;
Перем мОбработкаПоискаСсылок;
Перем мТекущееПравило;
Перем мПроизвольныйЗапрос;
Перем мПолеТекстаПрограммы;
Перем мШаблонПравилЗависимых;
Перем мПолучатьПредставленияСсылокВНайденныхСсылках;
Перем СтарыйОтборНайденных;
Перем мСсылкиНаЭлементыГрупп;
Перем мСвязанныйРедакторОбъектаБД;

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

// @@@.КЛАСС.ПолеТекстаПрограммы
// Транслятор обработки событий нажатия на кнопки командной панели в компоненту.
//
// Параметры:
//  Кнопка       - КнопкаКоманднойПанели.
//
Процедура КлсПолеТекстаПрограммыНажатие(Кнопка)
	
	#Если Сервер И Не Сервер Тогда
	    мПолеТекстаПрограммы = Обработки.ирКлсПолеТекстаПрограммы.Создать();
	#КонецЕсли
	КлсПолеТекстаПрограммыОбновитьКонтекст(, Кнопка);
	мПолеТекстаПрограммы.Нажатие(Кнопка);
	
КонецПроцедуры

// @@@.КЛАСС.ПолеТекстаПрограммы
Процедура ВнешнееСобытие(Источник, Событие, Данные) Экспорт
	
	Если мПолеТекстаПрограммы = Неопределено Тогда
		Возврат;
	КонецЕсли; 
	#Если Сервер И Не Сервер Тогда
	    мПолеТекстаПрограммы = Обработки.ирКлсПолеТекстаПрограммы.Создать();
	#КонецЕсли
	мПолеТекстаПрограммы.ВнешнееСобытиеОбъекта(Источник, Событие, Данные);
	
КонецПроцедуры

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

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

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

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

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

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

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

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

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

Функция ПолучитьЗначениеНастройки(ИмяНастройки) 
	
	Возврат Неопределено;
	
КонецФункции

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

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

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

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

Функция НоваяТаблицаПравилЗависимых()
	
	Возврат мШаблонПравилЗависимых.СкопироватьКолонки();

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

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

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

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

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

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

КонецФункции
	
Функция ДобавитьВыражениеЦенности(ЗапросПоиска)

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

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

Функция ПолучитьСтрокуПорядкаЦенности()

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

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

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

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

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

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

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

Процедура СброситьДоступность()
	
	ЭлементыФормы.Панель.Страницы.ЗависимыеЭлементы.Доступность = Ложь;
	//ЭлементыФормы.Панель.Страницы.ПравилаЗаменыСсылок.Доступность = Ложь;
	ЗависимыеОбъекты.Строки.Очистить();
	ЭлементыФормы.КоманднаяПанельЗависимыеОбъекты.Кнопки.ВыполнитьЗамену.Доступность = Ложь;
	
КонецПроцедуры // () 

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

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

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

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

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

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

Процедура ПередОткрытием(Отказ, СтандартнаяОбработка)
	
	ДопустимоеРазличиеСлов = 30;
	ПриУстановкеПолногоИмениОбъекта();
		
КонецПроцедуры

Функция ПриУстановкеПолногоИмениОбъекта(НастройкиТаблицыБД = Неопределено)

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

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

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

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

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

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

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

Процедура УстановитьПроизвольныйЗапросПоУмолчанию()
	
	мПроизвольныйЗапрос = Новый Запрос;
	мПроизвольныйЗапрос.Текст = "ВЫБРАТЬ Т.* ИЗ " + ПолноеИмяОбъекта + " КАК Т";

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

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

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

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

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

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

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

Функция СохранитьНастройкиПоискаПоТаблице()

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

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

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

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

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

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

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

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

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

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

Функция УстановитьПредставленияСлужебныхПолей()

	мПредставления.Вставить(мИмяПоляИдентификатор, "<Идентификатор>");
	мПредставления.Вставить(мИмяПоляКоличествоЭлементов, "<Количество элементов>");
	мПредставления.Вставить(мИмяПоляКоличествоСсылок, "<Ссылки>");
	мПредставления.Вставить(мИмяПоляНеправильныеСсылки, "<Неправильные ссылки>");
	мПредставления.Вставить(мИмяПоляНомерГруппы, "<Номер группы>");
	мПредставления.Вставить(мИмяПоляЦенность, "<Ценность данных>");
	мПредставления.Вставить(мИмяПоляПравильныйЭлемент, "<Правильный элемент>");
	мПредставления.Вставить(мИмяПоляНеправильныйЭлемент, "<Неправильный элемент>");
	мПредставления.Вставить(мИмяПоляПравильныеДанные, "<Правильные данные>");
	мПредставления.Вставить(мИмяФлагаПравильныйЭлемент, "<Правильный элемент>");
	мПредставления.Вставить(мИмяФлагаПравильныеДанные, "<Правильные данные>");
	Возврат Неопределено;

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

////////////////////////////////////////////////////////////////////////////////
// ПРОЦЕДУРЫ - ДЕЙСТВИЯ КОМАНДНОЙ ПАНЕЛЕЙ ФОРМЫ "ЭлементыТекущейГруппы"

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

Процедура КоманднаяПанельЭлементыТекущейГруппыПоискСсылок(Кнопка)
	
	СохранитьТекущуюГруппуРезультатовПоиска();
	УспехПоиска = ЗаполнитьПравилаЗаменыСсылокПоТекущейГруппе();
	//ЭлементыФормы.Панель.Страницы.ПравилаЗаменыСсылок.Доступность = УспехПоиска;
	Если УспехПоиска Тогда
		ЭлементыФормы.Панель.ТекущаяСтраница = ЭлементыФормы.Панель.Страницы.ПравилаЗаменыСсылок;
	КонецЕсли;
	
КонецПроцедуры

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

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

	ЗагрузитьГруппуРезультатовПоиска();
	
КонецПроцедуры

////////////////////////////////////////////////////////////////////////////////
// ПРОЦЕДУРЫ - ОБРАБОТЧИКИ СОБЫТИЙ ТАБЛИЧНОГО ПОЛЯ "ЭлементыТекущейГруппы"

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

Процедура ОтложенноЗагрузитьРеквизиты() Экспорт
	
	СохранитьТекущуюГруппуРезультатовПоиска();
	Если ЭлементыФормы.ЭлементыТекущейГруппы.Значение.Количество() = 0 Тогда
		Возврат;
	КонецЕсли; 
	ПоследняяСтрока = ЭлементыФормы.ЭлементыТекущейГруппы.Значение[ЭлементыФормы.ЭлементыТекущейГруппы.Значение.Количество() - 1];
	ЭлементыФормы.ЭлементыТекущейГруппы.ТекущаяСтрока = ПоследняяСтрока;
	КопияМассива = ирОбщий.СкопироватьКоллекциюЛкс(мМассивОтложеннойЗагрузкиРеквизитов);
	мМассивОтложеннойЗагрузкиРеквизитов.Очистить();
	ЗагрузитьРеквизитыЭлементовТекущейГруппы(КопияМассива);
	
КонецПроцедуры

Процедура ЭлементыТекущейГруппыПослеУдаления(Элемент)
	
	СохранитьТекущуюГруппуРезультатовПоиска();
	
КонецПроцедуры

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

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

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

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

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

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

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

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

Функция УдалитьНеправильнуюСсылкуВФорме(УдаляемаяСсылка, НепосредственноеУдаление, СтрокаНеправильного = Неопределено, СтрокаГруппы = Неопределено,
	Знач СсылкаДляЗаменыДанных = Неопределено)

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

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

Процедура НайденныеСсылкиПередНачаломИзменения(Элемент, Отказ)
	
	Если Элемент.ТекущаяКолонка = Неопределено Тогда
		Возврат;
	КонецЕсли; 
	Если Элемент.ТекущаяКолонка <> Элемент.Колонки.Пометка Тогда
		Отказ = Истина;
	КонецЕсли; 

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

Процедура КоманднаяПанельЗависимыеОбъектыПоискСсылок(Кнопка)
	ПоискЗависимыхСсылок();
	ЭлементыФормы.КоманднаяПанельЗависимыеОбъекты.Кнопки.ВыполнитьЗамену.Доступность = Истина;
КонецПроцедуры

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

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

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

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

Процедура ЗависимыеОбъектыПриВыводеСтроки(Элемент, ОформлениеСтроки, ДанныеСтроки) Экспорт
	ОформлениеСтроки.Ячейки.ВключатьВПоиск.ОтображатьТекст = Ложь;
	Если ДанныеСтроки.Уровень() = 1  Тогда
		ОформлениеСтроки.ЦветФона   = ЦветаСтиля.ЦветФонаФормы;
		ОформлениеСтроки.ЦветТекста = WebЦвета.ТемноСиний;
		ОформлениеСтроки.Ячейки.ВключатьВПоиск.ОтображатьФлажок = Ложь;
	ИначеЕсли ДанныеСтроки.Уровень() = 0  Тогда
		ОформлениеСтроки.ЦветФона   = ЦветаСтиля.ЦветФонаФормы;
		ОформлениеСтроки.ЦветТекста = WebЦвета.ТемноСиний;
		ОформлениеСтроки.Шрифт = Новый Шрифт(,,Истина);
		ОформлениеСтроки.Ячейки.ВключатьВПоиск.ОтображатьФлажок = Ложь;
	Иначе
//		ОформлениеСтроки.Ячейки.ВключатьВПоиск.ОтображатьФлажок = Истина;
	КонецЕсли; 
КонецПроцедуры

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

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

Процедура КоманднаяПанельНайденныеГруппыАвтоопределениеПравильныхДанных(Кнопка)
	
	СохранитьТекущуюГруппуРезультатовПоиска();
	ЗаполнитьПризнакПравильногоПоЦенности(мИмяФлагаПравильныеДанные, мИмяПоляПравильныеДанные);
	ЗагрузитьГруппуРезультатовПоиска();
	
КонецПроцедуры

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

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

Процедура ПолноеИмяОбъектаОчистка(Элемент, СтандартнаяОбработка)
	
	Элемент.Значение = "";
	ПриУстановкеПолногоИмениОбъекта();
	
КонецПроцедуры

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

Процедура НайденныеГруппыВыбор(Элемент, ВыбраннаяСтрока, Колонка, СтандартнаяОбработка)
	
	//Если ВыбраннаяСтрока <> Неопределено Тогда
		ЗначениеЯчейки = ВыбраннаяСтрока[Колонка.Имя];
		КорневойТипЗначения = ирОбщий.КорневойТипКонфигурацииЛкс(ЗначениеЯчейки);
		Если КорневойТипЗначения <> Неопределено Тогда
			ирКлиент.ОткрытьЗначениеЛкс(ЗначениеЯчейки);
		КонецЕсли;
	//КонецЕсли;
	
КонецПроцедуры

Процедура НайденныеГруппыПриВыводеСтроки(Элемент, ОформлениеСтроки, ДанныеСтроки) Экспорт
	
	ирКлиент.ТабличноеПолеПриВыводеСтрокиЛкс(ЭтаФорма, Элемент, ОформлениеСтроки, ДанныеСтроки);
	
КонецПроцедуры

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

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

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

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

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

Процедура КоманднаяПанельНайденныеГруппыАвтоопределениеПравильныхЭлементов(Кнопка)

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

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

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

Процедура КоманднаяПанельЭлементыТекущейГруппыАвтоопределениеПравильных(Кнопка)
	// Вставить содержимое обработчика.
КонецПроцедуры

Процедура НайденныеГруппыПередУдалением(Элемент, Отказ)
	
	Если Элемент.ТекущаяСтрока = Неопределено Тогда
		Возврат;
	КонецЕсли;
	СоставТекущейГруппы = мРезультатыПоиска.НайтиСтроки(Новый Структура(мИмяПоляНомерГруппы, Элемент.ТекущаяСтрока[мИмяПоляНомерГруппы]));
	Для Каждого СтрокаВнутриТекущейГруппы Из СоставТекущейГруппы Цикл
		мРезультатыПоиска.Удалить(СтрокаВнутриТекущейГруппы);
	КонецЦикла;
	Если Элемент.ТекущаяСтрока = мТекущаяГруппа Тогда
		мТекущаяГруппа = Неопределено;
	КонецЕсли;
	
КонецПроцедуры

Процедура НайденныеГруппыПередНачаломДобавления(Элемент, Отказ, Копирование)
	
	Если Копирование Тогда
		Отказ = Истина;
	КонецЕсли;
	
КонецПроцедуры

Процедура ОбновитьРамкуГруппыНайденныеГруппы()

	ирОбщий.ОбновитьТекстПослеМаркераЛкс(ЭлементыФормы.РамкаГруппыНайденныеГруппы.Заголовок, ,
		Строка(НайденныеГруппы.Количество()) + ")", "(");

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

Процедура ПриДобавленииНовойГруппы()
	
	КопияТаблицы = НайденныеГруппы.Скопировать(, мИмяПоляНомерГруппы);
	КопияТаблицы.Сортировать(мИмяПоляНомерГруппы + " Убыв");
	Если КопияТаблицы.Количество() > 1 Тогда
		ПоследнийНомер = КопияТаблицы[0][мИмяПоляНомерГруппы];
	Иначе
		ПоследнийНомер = 0;
	КонецЕсли;
	ЭлементыФормы.НайденныеГруппы.ТекущаяСтрока[мИмяПоляНомерГруппы] = ПоследнийНомер + 1;
	ОбновитьРамкуГруппыНайденныеГруппы();
	
КонецПроцедуры

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

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

Процедура ЗависимыеОбъектыПриАктивизацииСтроки(Элемент)
	
	Элемент.Колонки.Правильный.ЭлементУправления.КнопкаВыбора = (Элемент.ТекущаяСтрока.Уровень() = 2);
	Элемент.Колонки.Правильный.ТолькоПросмотр   = (Элемент.ТекущаяСтрока.Уровень() = 0);
	Элемент.Колонки.НеПравильный.ТолькоПросмотр = (Элемент.ТекущаяСтрока.Уровень() = 0);
	
КонецПроцедуры

Процедура КоманднаяПанельЭлементыТекущейГруппыДобавитьПустуюСсылку(Кнопка = Неопределено)

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

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

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

Процедура ОбновлениеОтображения()
	
	ирКлиент.Форма_ОбновлениеОтображенияЛкс(ЭтаФорма);
	ЭлементыФормы.ОтборУровняЦенности.Доступность = мТекущаяСтрокаУровняЦенности <> Неопределено;
	СохранитьОтборТекущегоУровняЦенности();
	НастроитьЭлементыФормы();
	
КонецПроцедуры

Процедура ОбновитьСчетчикиПравилЗамены()

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

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

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

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

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

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

// Предопределеный метод
Процедура ПроверкаЗавершенияФоновыхЗаданий() Экспорт 
	
	ирКлиент.ПроверитьЗавершениеФоновыхЗаданийФормыЛкс(ЭтаФорма);
	
КонецПроцедуры

Процедура ВыполнитьПоискЗаменяемыхСсылок(ЗадаватьВопрос = Истина, РазрешитьАсинхронно = Истина, Перезапустить = Истина)

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

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

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

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

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

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

Процедура КоманднаяПанельЗаменаСсылокПоискСсылок(Кнопка)
	
	ВыполнитьПоискЗаменяемыхСсылок(Ложь,, Ложь);

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

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

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

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

Процедура ЗаменыСсылокПриНачалеРедактирования(Элемент, НоваяСтрока, Копирование)

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

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

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

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

Функция ЛиПравилоЗаменяМожноВключить(Знач ДанныеСтроки)
	
	Возврат Истина
		И ДанныеСтроки.ЧтоЗаменять <> Неопределено
		И ТипЗнч(ДанныеСтроки.ЧтоЗаменять) <> Тип("Строка");

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

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

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

Процедура ЗаменыСсылокЧтоЗаменятьОкончаниеВводаТекста(Элемент, Текст, Значение, СтандартнаяОбработка)
	
	ирКлиент.ПолеВвода_ОкончаниеВводаТекстаЛкс(Элемент, Текст, Значение, СтандартнаяОбработка, , Истина);
	
КонецПроцедуры

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

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

Процедура КоманднаяПанельНайденныеСсылкиОтобратьПоТипам(Кнопка)
	
	ирКлиент.ИзменитьОтборКлиентаПоМетаданнымЛкс(ЭлементыФормы.НайденныеСсылки);
	ОбновитьСчетчикиПравилЗамены();
	
КонецПроцедуры

Процедура КоманднаяПанельНайденныеСсылкиВключитьПоПериоду(Кнопка)
	
	НачалоПериода = НачалоГода(ТекущаяДата());
	КонецПериода = КонецГода(ТекущаяДата());
	НастройкаПериода = Новый НастройкаПериода;
	НастройкаПериода.УстановитьПериод(НачалоПериода, ?(КонецПериода='0001-01-01', КонецПериода, КонецДня(КонецПериода)));
	НастройкаПериода.РедактироватьКакИнтервал = Истина;
	НастройкаПериода.РедактироватьКакПериод = Истина;
	НастройкаПериода.ВариантНастройки = ВариантНастройкиПериода.Период;
	Если НастройкаПериода.Редактировать() Тогда
		НачалоПериода = НастройкаПериода.ПолучитьДатуНачала();
		КонецПериода = НастройкаПериода.ПолучитьДатуОкончания();
		КонецПериода = ?(КонецПериода = Дата(1,1,1), КонецГода(ТекущаяДата()), КонецПериода);
		Для Каждого СтрокаОбъекта Из ЭтотОбъект.НайденныеСсылки Цикл
			Если Истина
				И СтрокаОбъекта.Дата >= НачалоПериода
				И СтрокаОбъекта.Дата <= КонецПериода
			Тогда
				СтрокаОбъекта.Пометка = Истина;
			КонецЕсли; 
		КонецЦикла; 
	КонецЕсли; 
	ОбновитьСчетчикиПравилЗамены();
	
КонецПроцедуры

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

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

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

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

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

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

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

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

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

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

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

Процедура ОбновитьСписокВыбораПутиКДаннымВлияющего()

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

Процедура ОбновитьОтборПоТекущемуПравилу()

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

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

Процедура НайденныеСсылкиПриИзмененииФлажка(Элемент, Колонка)
	
	ирКлиент.ТабличноеПолеПриИзмененииФлажкаЛкс(ЭтаФорма, Элемент, Колонка);

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

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

Процедура ПолноеИмяОбъектаПриИзменении(Элемент)
	
	Если ПриУстановкеПолногоИмениОбъекта() Тогда 
		ирКлиент.ПолеВводаСИсториейВыбора_ПриИзмененииЛкс(Элемент, ЭтаФорма);
	КонецЕсли; 
	
КонецПроцедуры

Функция ПараметрыВыбораОбъектаМетаданных()
	Возврат ирКлиент.ПараметрыВыбораОбъектаМетаданныхЛкс(Истина,,,,,,, Истина,,, Истина);
КонецФункции

Процедура ПолноеИмяОбъектаНачалоВыбора(Элемент, СтандартнаяОбработка)
	
	ирКлиент.ОбъектМетаданныхНачалоВыбораЛкс(Элемент, ПараметрыВыбораОбъектаМетаданных(), СтандартнаяОбработка);

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

Процедура ПолноеИмяОбъектаОкончаниеВводаТекста(Элемент, Текст, Значение, СтандартнаяОбработка)
	
	ирКлиент.ОбъектМетаданныхОкончаниеВводаТекстаЛкс(Элемент, ПараметрыВыбораОбъектаМетаданных(), Текст, Значение, СтандартнаяОбработка);
	
КонецПроцедуры

Процедура ПолноеИмяОбъектаНачалоВыбораИзСписка(Элемент, СтандартнаяОбработка)
	
	ирОбщий.ПолеВводаСИсториейВыбора_ОбновитьСписокЛкс(Элемент, ЭтаФорма);

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

Процедура ПолеКомпоновкиОкончаниеВводаТекста(Элемент, Текст, Значение, СтандартнаяОбработка)
	ирКлиент.ПолеВвода_ОкончаниеВводаТекстаЛкс(Элемент, Текст, Значение, СтандартнаяОбработка, , Истина, ЭтаФорма);
КонецПроцедуры

Процедура ПолеКомпоновкиАвтоПодборТекста(Элемент, Текст, ТекстАвтоПодбора, СтандартнаяОбработка)
	ирКлиент.ПолеВвода_ОкончаниеВводаТекстаЛкс(Элемент, Текст,, СтандартнаяОбработка, , Истина, ЭтаФорма,, ТекстАвтоПодбора);
КонецПроцедуры

Процедура ОтборЗначениеНачалоВыбора(Элемент, СтандартнаяОбработка)
	ирКлиент.ПолеВводаКолонкиРасширенногоЗначения_НачалоВыбораЛкс(ЭтаФорма, ТекущийЭлемент, СтандартнаяОбработка,, Истина,, "ПравоеЗначение");
КонецПроцедуры

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

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

Процедура НайденныеГруппыПриАктивизацииСтроки(Элемент)
	
	ирКлиент.ТабличноеПолеПриАктивизацииСтрокиЛкс(ЭтаФорма, Элемент);
	СохранитьТекущуюГруппуРезультатовПоиска();
	ЗагрузитьГруппуРезультатовПоиска(Элемент.ТекущаяСтрока);
	НастроитьЭлементыФормы();

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

Процедура КоманднаяПанельЭлементыТекущейГруппыВыборПравильныхДанных(Кнопка)
	
	ТекущаяСтрока = ЭлементыФормы.ЭлементыТекущейГруппы.ТекущаяСтрока;
	Если ТекущаяСтрока = Неопределено Тогда
		Возврат;
	КонецЕсли;
	СтрокаТаблицы = ЭлементыТекущейГруппы.Найти(Истина, мИмяФлагаПравильныеДанные);
	Если Истина
		И СтрокаТаблицы <> Неопределено
		И СтрокаТаблицы <> ТекущаяСтрока
	Тогда
		СтрокаТаблицы[мИмяФлагаПравильныеДанные] = СтрокаТаблицы = ТекущаяСтрока;
	КонецЕсли;
	ТекущаяСтрока[мИмяФлагаПравильныеДанные] = Не ТекущаяСтрока[мИмяФлагаПравильныеДанные];
	СброситьДоступность();
	СохранитьТекущуюГруппуРезультатовПоиска();

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

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

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

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

Процедура СохранитьОтборТекущегоУровняЦенности()

	Если мТекущаяСтрокаУровняЦенности <> Неопределено Тогда
		Если ШкалаЦенности.Индекс(мТекущаяСтрокаУровняЦенности) = -1 Тогда
			Возврат;
		КонецЕсли; 
		СохраняемаяНастройкаКомпоновки = ирОбщий.СкопироватьНастройкиКомпоновкиЛкс(КомпоновщикЦенности.Настройки, , Истина); 
		мТекущаяСтрокаУровняЦенности.НастройкаКомпоновкиXML = ирОбщий.ОбъектВСтрокуXMLЛкс(СохраняемаяНастройкаКомпоновки);
		мТекущаяСтрокаУровняЦенности.Уровень = СохраняемаяНастройкаКомпоновки.Отбор;
		Если мТекущаяСтрокаУровняЦенности.Уровень = "" Тогда
			мТекущаяСтрокаУровняЦенности.Уровень = "<Отбор не задан>"
		КонецЕсли; 
	КонецЕсли;

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

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

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

Процедура ДополнительныеПоляПрочитатьПоля(Кнопка)
	
	ПрочитатьДополнительныеПоляСсылающихсяОбъектов();

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

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

Процедура ТабличноеПолеПриИзмененииФлажка(Элемент, Колонка)
	ирКлиент.ТабличноеПолеПриИзмененииФлажкаЛкс(ЭтаФорма, Элемент, Колонка);
КонецПроцедуры

Процедура ТабличноеПолеПриАктивизацииСтроки(Элемент)
	ирКлиент.ТабличноеПолеПриАктивизацииСтрокиЛкс(ЭтаФорма, Элемент);
КонецПроцедуры

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

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

Процедура ПравилаЗаменыСсылокПриИзмененииФлажка(Элемент, Колонка)
	
	ирКлиент.ТабличноеПолеПриИзмененииФлажкаЛкс(ЭтаФорма, Элемент, Колонка);
	
КонецПроцедуры

Процедура ОбновитьКоличествоПомеченныхПравил()
	
	ЭтаФорма.КоличествоПомеченныхПравил = ПравилаЗаменыСсылок.НайтиСтроки(Новый Структура("Пометка", Истина)).Количество();

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

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

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

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

Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник) Экспорт
	
	ирКлиент.Форма_ОбработкаОповещенияЛкс(ЭтаФорма, ИмяСобытия, Параметр, Источник); 

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

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

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

Процедура КоманднаяПанельНайденныеГруппыЗаполнитьПравилаЗамены(Кнопка)
	
	СохранитьТекущуюГруппуРезультатовПоиска();
	УспехПоиска = ЗаполнитьПравилаЗаменыСсылокПоВсемГруппам();
	Если УспехПоиска Тогда
		ЭлементыФормы.Панель.ТекущаяСтраница = ЭлементыФормы.Панель.Страницы.ПравилаЗаменыСсылок;
	КонецЕсли;

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

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

Процедура КлсКомандаНажатие(Кнопка) Экспорт 
	
	ирКлиент.УниверсальнаяКомандаФормыЛкс(ЭтаФорма, Кнопка);
	
КонецПроцедуры

Процедура ОбработчикОжиданияСПараметрамиЛкс() Экспорт 
	
	ирКлиент.ОбработчикОжиданияСПараметрамиЛкс();

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

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

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

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

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

Процедура ШкалаЦенностиПриВыводеСтроки(Элемент, ОформлениеСтроки, ДанныеСтроки) Экспорт
	
	ОформлениеСтроки.Ячейки.ЗначениеЦенности.УстановитьТекст(Элемент.Значение.Индекс(ДанныеСтроки) + 1);
	
КонецПроцедуры

Процедура ЗависимыеЗначенияТипЗначенияПриИзменении(Элемент)
	
	ОбновитьСписокВыбораЗависимоеВлияющее();
	
КонецПроцедуры

Процедура ОбновитьСписокВыбораЗависимоеВлияющее()

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

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

Функция ПравилоЗависимогоЗаполнено(ДанныеСтроки)
	
	Возврат Истина
		И ЗначениеЗаполнено(ДанныеСтроки.ПутьКДаннымВлияющего)
		И ЗначениеЗаполнено(ДанныеСтроки.ЗависимоеВлияющее)
		И ДанныеСтроки.ТипЗначения <> Неопределено;

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

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

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

Процедура ЗависимыеЗначенияПутьКДаннымВлияющегоПриИзменении(Элемент)
	
	ОбновитьВлияющееЗависимогоЗначения();
	
КонецПроцедуры

Процедура ПравилаЗависимыхПриАктивизацииСтроки(Элемент)
	
	ирКлиент.ТабличноеПолеПриАктивизацииСтрокиЛкс(ЭтаФорма, Элемент);
	ОбновитьСписокВыбораЗависимоеВлияющее();
	
КонецПроцедуры

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

Процедура ПравилаЗависимыхВыбор(Элемент, ВыбраннаяСтрока, Колонка, СтандартнаяОбработка)
	
	Если Колонка.ТолькоПросмотр Тогда
		ирКлиент.ЯчейкаТабличногоПоляРасширенногоЗначения_ВыборЛкс(ЭтаФорма, Элемент, СтандартнаяОбработка);
	КонецЕсли; 
	
КонецПроцедуры

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

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

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

Процедура ПравилаЗависимыхПриОкончанииРедактирования(Элемент, НоваяСтрока, ОтменаРедактирования)
	
	Если Не ПравилоЗависимогоЗаполнено(Элемент.ТекущаяСтрока) Тогда
		Элемент.ТекущаяСтрока.Пометка = Ложь;
	КонецЕсли; 

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

Процедура КоманднаяПанельЗаменаСсылокВключитьВсе(Кнопка)
	
	ирКлиент.ИзменитьПометкиВыделенныхИлиОтобранныхСтрокЛкс(ЭтаФорма, ЭлементыФормы.ПравилаЗаменыСсылок, , Истина);
	//ОбновитьКоличествоПомеченныхПравил();

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

Процедура КоманднаяПанельЗаменаСсылокВыключитьВсе(Кнопка)
	
	ирКлиент.ИзменитьПометкиВыделенныхИлиОтобранныхСтрокЛкс(ЭтаФорма, ЭлементыФормы.ПравилаЗаменыСсылок, , Ложь);
	//ОбновитьКоличествоПомеченныхПравил();
	
КонецПроцедуры

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

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

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

Процедура ОбработкаВыбора(ЗначениеВыбора, Источник)
	
	УстановитьПроизвольныйЗапросИзСтруктуры(ЗначениеВыбора);

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

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

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

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

Процедура ПравилаЗаменыСсылокНаЧтоЗаменятьНачалоВыбора(Элемент, СтандартнаяОбработка)
	
	ирКлиент.ПолеВводаКолонкиРасширенногоЗначения_НачалоВыбораЛкс(ЭтаФорма, ЭлементыФормы.ПравилаЗаменыСсылок, СтандартнаяОбработка,, Истина);
	
КонецПроцедуры

Процедура ПравилаЗаменыСсылокЧтоЗаменятьНачалоВыбора(Элемент, СтандартнаяОбработка)

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

Процедура ПолноеИмяОбъектаОткрытие(Элемент, СтандартнаяОбработка)
	
	СтандартнаяОбработка = Ложь;
	ирКлиент.ОткрытьОбъектМетаданныхЛкс(ПолноеИмяОбъекта);
	
КонецПроцедуры

Процедура КоманднаяПанельПараметрыЗаписи(Кнопка)
	
	ирКлиент.ОткрытьОбщиеПараметрыЗаписиЛкс();
	
КонецПроцедуры

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

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

Процедура КоманднаяПанельНайденныеСсылкиПодбор(Кнопка)
	
	ирКлиент.ОткрытьПодборСВыборомТипаЛкс(ЭлементыФормы.НайденныеСсылки);
	
КонецПроцедуры

Процедура КоманднаяПанельНайденныеСсылкиОчистить(Кнопка)
	
	НайденныеСсылки.Очистить();
	
КонецПроцедуры

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

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

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

Процедура ОбновитьОбщееКоличествоНайденныхСсылок()
	
	ЭтаФорма.КоличествоНайденныхСсылок = НайденныеСсылки.Количество();

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

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

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

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

Процедура ОтборПарПеретаскивание(Элемент, ПараметрыПеретаскивания, СтандартнаяОбработка, Строка, Колонка)
	
	ирКлиент.ТабличноеПолеОтбораКомпоновкиПеретаскиваниеЛкс(ЭтаФорма, Элемент, ПараметрыПеретаскивания, СтандартнаяОбработка, Строка, Колонка);

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

Процедура ОтборПеретаскивание(Элемент, ПараметрыПеретаскивания, СтандартнаяОбработка, Строка, Колонка)
	
	ирКлиент.ТабличноеПолеОтбораКомпоновкиПеретаскиваниеЛкс(ЭтаФорма, Элемент, ПараметрыПеретаскивания, СтандартнаяОбработка, Строка, Колонка);

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

Процедура КоманднаяПанельОтборПарУстановитьПолеВПравомЗначении(Кнопка)
	
	ирКлиент.УстановитьПолеВПравомЗначенииТабличПоляОтбораЛкс(ЭлементыФормы.ОтборПар, ЭлементыФормы.ДоступныеПоляПар);

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

Процедура КоманднаяПанельОтборУстановитьПолеВПравомЗначении(Кнопка)
	
	ирКлиент.УстановитьПолеВПравомЗначенииТабличПоляОтбораЛкс(ЭлементыФормы.Отбор, ЭлементыФормы.ДоступныеПоля);
	
КонецПроцедуры

Процедура ПравилаЗависимыхПриИзмененииФлажка(Элемент, Колонка)
	
	ирКлиент.ТабличноеПолеПриИзмененииФлажкаЛкс(ЭтаФорма, Элемент, Колонка);

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

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

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

Процедура НайденныеСсылкиПометкаПриИзменении(Элемент)
	
	ОбновитьСчетчикиПравилЗамены();

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

Процедура НастройкаСравненияПриАктивизацииСтроки(Элемент)
	
	ирКлиент.ТабличноеПолеПриАктивизацииСтрокиЛкс(ЭтаФорма, Элемент);

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

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

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

Процедура НайденныеСсылкиПриАктивизацииСтроки(Элемент)
	
	ирКлиент.ТабличноеПолеПриАктивизацииСтрокиЛкс(ЭтаФорма, Элемент);

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

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

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

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

Процедура КП_ДоступныеПоляКолонкаБД(Кнопка)
	
	ирКлиент.ОткрытьКолонкуБДДоступногоПоляКомпоновкиЛкс(ТекущийЭлемент, ПолноеИмяОбъекта);
	
КонецПроцедуры

Процедура ПорядокЦенностиВыбор(Элемент, ВыбраннаяСтрока, Колонка, СтандартнаяОбработка)
	ирКлиент.ТабличноеПолеПорядкаКомпоновкиВыборЛкс(Элемент, ВыбраннаяСтрока, Колонка, СтандартнаяОбработка);
КонецПроцедуры

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

Процедура ДоступныеПоляВыбор(Элемент, ВыбраннаяСтрока, Колонка, СтандартнаяОбработка)
	ирОбщий.НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ЭлементыФормы.НастройкаСравнения, ВыбраннаяСтрока.Поле,,, СтандартнаяОбработка); 
КонецПроцедуры

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

Процедура ПорядокЦенностиПеретаскивание(Элемент, ПараметрыПеретаскивания, СтандартнаяОбработка, Строка, Колонка)
	ирКлиент.ТабличноеПолеЭлементовКомпоновкиПеретаскиваниеЛкс(Элемент, ПараметрыПеретаскивания, СтандартнаяОбработка, Строка, Колонка);
КонецПроцедуры

Процедура ТабличноеПолеПриПолученииДанных(Элемент, ОформленияСтрок) Экспорт 
	
	ирКлиент.ТабличноеПолеПриПолученииДанныхЛкс(ЭтаФорма, Элемент, ОформленияСтрок);

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

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

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

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

Процедура ОбновитьПодменюПоследнихОтборовНайденных()
	
	ирКлиент.ОбновитьПодменюПоследнихОтборовЛкс(ЭтаФорма, ЭлементыФормы.КоманднаяПанельНайденныеСсылки, ЭлементыФормы.НайденныеСсылки);

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

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

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

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

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

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

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

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

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

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

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

Процедура ПравилаЗаменыСсылокПриОкончанииРедактирования(Элемент, НоваяСтрока, ОтменаРедактирования)
	ОбновитьСчетчикиПравилЗамены();
КонецПроцедуры

Процедура ЭлементыТекущейГруппыПриАктивизацииКолонки(Элемент)
	ирКлиент.ТабличноеПолеПриАктивацииКолонкиЛкс(ЭтаФорма, Элемент);
КонецПроцедуры

Процедура НайденныеГруппыПриАктивизацииКолонки(Элемент)
	ирКлиент.ТабличноеПолеПриАктивацииКолонкиЛкс(ЭтаФорма, Элемент);
КонецПроцедуры

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

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

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

Процедура ПанельПриСменеСтраницы(Элемент, ТекущаяСтраница)
	
	НастроитьЭлементыФормы();
	
КонецПроцедуры

Процедура ПравилаЗаменыСсылокЧтоЗаменятьОткрытие(Элемент, СтандартнаяОбработка)
	ирКлиент.ОткрытьЗначениеЛкс(ЭлементыФормы.ПравилаЗаменыСсылок.ТекущаяСтрока.ЧтоЗаменять,, СтандартнаяОбработка);
КонецПроцедуры

Процедура ПравилаЗаменыСсылокНаЧтоЗаменятьОткрытие(Элемент, СтандартнаяОбработка)
	ирКлиент.ОткрытьЗначениеЛкс(ЭлементыФормы.ПравилаЗаменыСсылок.ТекущаяСтрока.НаЧтоЗаменять,, СтандартнаяОбработка);
КонецПроцедуры

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

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

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

Процедура ВпередНажатие(Элемент)
	
	ирКлиент.СледующееВхождениеСтрокиПоискаВТабличномПолеЛкс(ЭтаФорма, ЭлементыФормы.ДоступныеПоля);
	
КонецПроцедуры

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

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

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

Процедура ОбновитьКнопкуПараметровПоискаСсылок()
	
	Кнопка = ЭлементыФормы.КоманднаяПанель.Кнопки.ПараметрыПоиска;
	ирКлиент.ОбновитьКнопкуПараметровПоискаСсылокЛкс(Кнопка);

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


ирКлиент.ИнициироватьФормуЛкс(ЭтаФорма, "Обработка.ирПоискДублейИЗаменаСсылок.Форма.Форма");

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