//Признак использования настроек
Перем мИспользоватьНастройки Экспорт;
Перем мНастройка;
Перем мСоединениеСУБД;

////////////////////////////////////////////////////////////////////////////////
// ВСПОМОГАТЕЛЬНЫЕ ПРОЦЕДУРЫ И ФУНКЦИИ

// Сохраняет значения реквизитов формы.
//
// Параметры:
//  Нет.
//
Процедура вСохранитьНастройку() Экспорт

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

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

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

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

// Восстанавливает сохраненные значения реквизитов формы.
//
// Параметры:
//  Нет.
//
Процедура вЗагрузитьНастройку() Экспорт

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

	Для каждого РеквизитНастройки из мНастройка Цикл
        Значение = мНастройка[РеквизитНастройки.Ключ];
		Выполнить(Строка(РеквизитНастройки.Ключ) + " = Значение;");
	КонецЦикла;

КонецПроцедуры //вЗагрузитьНастройку()

// Устанавливает значение реквизита "ТекущаяНастройка" по имени настройки или произвольно.
//
// Параметры:
//  ИмяНастройки   - произвольное имя настройки, которое необходимо установить.
//
Процедура вУстановитьИмяНастройки(ИмяНастройки = "") Экспорт

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

КонецПроцедуры // вУстановитьИмяНастройки()

////////////////////////////////////////////////////////////////////////////////
// ОБРАБОТЧИКИ СОБЫТИЙ ФОРМЫ

// Процедура - обработчик события "ПередОткрытием" формы.
//
Процедура ПередОткрытием(Отказ, СтандартнаяОбработка)

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

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

////////////////////////////////////////////////////////////////////////////////
// ОБРАБОТЧИКИ СОБЫТИЙ, ВЫЗЫВАЕМЫЕ ИЗ ЭЛЕМЕНТОВ ФОРМЫ

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

	Элемент.СписокВыбора.Очистить();

	Если ТекущаяНастройка.Родитель = Неопределено Тогда
		КоллекцияСтрок = ТекущаяНастройка.Строки;
	Иначе
		КоллекцияСтрок = ТекущаяНастройка.Родитель.Строки;
	КонецЕсли;

	Для каждого Строка из КоллекцияСтрок Цикл
		Элемент.СписокВыбора.Добавить(Строка, Строка.Обработка);
	КонецЦикла;

КонецПроцедуры // ТекущаяНастройкаНачалоВыбораИзСписка()

// Обработчик действия "ОбработкаВыбора" реквизита "ТекущаяНастройка".
//
Процедура ТекущаяНастройкаОбработкаВыбора(Элемент, ВыбранноеЗначение, СтандартнаяОбработка)

	СтандартнаяОбработка = Ложь;

	Если Истина
		И НЕ ТекущаяНастройка = ВыбранноеЗначение
		И Элемент.СписокВыбора.НайтиПоЗначению(ВыбранноеЗначение) <> Неопределено
	Тогда

		Если ЭтаФорма.Модифицированность Тогда
			Если Вопрос("Сохранить текущую настройку?", РежимДиалогаВопрос.ДаНет,, КодВозвратаДиалога.Да) = КодВозвратаДиалога.Да Тогда
				вСохранитьНастройку();
			КонецЕсли;
		КонецЕсли;

		ТекущаяНастройка = ВыбранноеЗначение;
		вУстановитьИмяНастройки();

		вЗагрузитьНастройку();

	КонецЕсли;

КонецПроцедуры // ТекущаяНастройкаОбработкаВыбора()

// Обработчик действия "Выполнить" командной панели "ОсновныеДействияФормы".
//
Процедура ОсновныеДействияФормыВыполнить(Кнопка)

	вВыполнитьОбработку(Кнопка);

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

Процедура вВыполнитьОбработку(Кнопка = Неопределено) Экспорт 
	
	ВыполнитьЗаданиеГрупповойОбработки(ЭтаФорма, Кнопка);

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

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

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

// Обработчик действия "СохранитьНастройку" командной панели "ОсновныеДействияФормы".
//
Процедура ОсновныеДействияФормыСохранитьНастройку(Кнопка)

	вСохранитьНастройку();

КонецПроцедуры // ОсновныеДействияФормыСохранитьНастройку()

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

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

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

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

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

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

// СУБД

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

Процедура УдалитьОбъектыЧерезСУБД(Знач Запрос, Знач ИмяГлавнойТаблицы, Знач ИмяГлавнойВременнойТаблицы = "", Знач ИмяТаблицыКлючей = "", Знач ТекстСУБД = "", выхОтключенныеИтоги)
	
	#Если Сервер И Не Сервер Тогда
		Запрос = Новый Запрос;
	#КонецЕсли
	СтруктураХраненияТаблицы = ирОбщий.СтруктураХраненияТаблицыБДЛкс(ИмяГлавнойТаблицы);
	ИмяГлавнойТаблицыХранения = СтруктураХраненияТаблицы[0].ИмяТаблицыХранения;
	Если Не ЗначениеЗаполнено(ИмяТаблицыКлючей) Тогда
		ИмяТаблицыКлючей = "КлючиСтрок" + ИмяГлавнойТаблицыХранения;
	КонецЕсли;
	ТипТаблицы = ирОбщий.ТипТаблицыБДЛкс(ИмяГлавнойТаблицы);
	УдалятьСЗависимыми = Истина
		И Не ирОбщий.ЛиКорневойТипРегистраСведенийЛкс(ТипТаблицы) 
		И Не ирКэш.ПараметрыЗаписиОбъектовЛкс().ОтключатьКонтрольЗаписи;
	Если Не ЗначениеЗаполнено(ТекстСУБД) Тогда
		ТекстСУБД = СоздатьВременнуюТаблицуИНайтиТекстСУБД(Запрос, ИмяГлавнойТаблицыХранения, ИмяТаблицыКлючей, ИмяГлавнойВременнойТаблицы);
	КонецЕсли;
	Если ЗначениеЗаполнено(ИмяГлавнойВременнойТаблицы) Тогда
		ВыражениеЗамена = "JOIN " + ИмяГлавнойВременнойТаблицы;
		Если ирОбщий.СтрНайтиЛкс(ТекстСУБД, ВыражениеЗамена,,,, Ложь) = 0 Тогда // Возможно никогда сработает. С подчиненным справочником предположительно всегда Ложь
			ТекстСУБД = ирОбщий.ЗаменитьРегВыражениеЛкс(ТекстСУБД, "JOIN\s+#\w+", ВыражениеЗамена);
		КонецЕсли;
		ЧислоОбъектов = 1;
	Иначе
		Запрос.Текст = "ВЫБРАТЬ Количество(*) ИЗ " + ИмяТаблицыКлючей; 
		ЧислоОбъектов = Запрос.Выполнить().Выгрузить()[0][0];
		ирОбщий.СообщитьЛкс(ирОбщий.СтрШаблонЛкс("Выбрано %1 объектов. " + ВладелецФормы.ПредставлениеОтбора(), ЧислоОбъектов));
	КонецЕсли;
	
	РезультатПоиска = ирОбщий.НайтиРегВыражениеЛкс(ТекстСУБД, "INSERT\s+INTO\s+(#\w+)\s+with\(tablock\)\s+\(((?:\w+,\s*)*\w+)\)",, Ложь)[0];
	ИменаПолейТаблицыКлючей = ирОбщий.СтрРазделитьЛкс(РезультатПоиска.Группа1, ",", Истина);
	ИмяТаблицыКлючейСУБД = РезультатПоиска.Группа0;
	//ИмяТаблицыКлючейСУБД = "#TempIR" + ИмяГлавнойТаблицыХранения;
	//ТекстСУБД = ирОбщий.ЗаменитьРегВыражениеЛкс(ТекстСУБД, "INSERT\s+INTO\s+#\w+", "INSERT INTO " + ИмяТаблицыКлючейСУБД);
	ТекстПоискаИмениВТ = 
	"SELECT
	|	c.name AS ИмяКолонки,
	|	c.column_id AS НомерКолонки,
	|	c.system_type_id AS НомерТипа,
	|	tb.name AS ИмяТаблицы
	|FROM
	|	tempdb.sys.columns AS c
	|	INNER JOIN tempdb.sys.tables AS tb
	|	ON tb.object_id = c.object_id
	|WHERE tb.name like '" + ИмяТаблицыКлючейСУБД + "_%'
	|ORDER BY НомерКолонки
	|";
	КолонкиКандидатов = ирОбщий.ВыполнитьЗапросЭтойСУБДЛкс(ТекстПоискаИмениВТ,,,,,, мСоединениеСУБД);
	#Если Сервер И Не Сервер Тогда
		КолонкиКандидатов = Новый ТаблицаЗначений;
		КолонкиКандидатов.Колонки.Добавить("ИмяТаблицы");
		КолонкиКандидатов.Колонки.Добавить("ИмяКолонки");
		ИменаПолейТаблицыКлючей = Новый Массив;
	#КонецЕсли 
	КандидатыИмениВТ = КолонкиКандидатов.Скопировать(, "ИмяТаблицы");
	КандидатыИмениВТ.Свернуть("ИмяТаблицы");
	ГлобальноеИмяВременнойТаблицы = Неопределено;
	Для Каждого ИмяКандидата Из КандидатыИмениВТ.ВыгрузитьКолонку(0) Цикл
		СтрокиКолонок = КолонкиКандидатов.НайтиСтроки(Новый Структура("ИмяТаблицы", ИмяКандидата));
		МассивыРавны = СтрокиКолонок.Количество() = ИменаПолейТаблицыКлючей.Количество();
		Если МассивыРавны Тогда
			Для Индекс = 0 По СтрокиКолонок.ВГраница() Цикл
				Если СтрокиКолонок[Индекс].ИмяКолонки <> ИменаПолейТаблицыКлючей[Индекс] Тогда
					МассивыРавны = Ложь;
					Прервать;
				КонецЕсли;
			КонецЦикла;
		КонецЕсли;
		Если МассивыРавны Тогда
			ГлобальноеИмяВременнойТаблицы = ИмяКандидата;
			Прервать;
		КонецЕсли;
	КонецЦикла;
	Если Не ЗначениеЗаполнено(ГлобальноеИмяВременнойТаблицы) Тогда
		ВызватьИсключение "Не удалось найти временную таблицу в СУБД";
	КонецЕсли; 
	ТекстЗапросаСозданияВТ = ПолучитьМакет("ГенераторСкриптаСозданияВТ").ПолучитьТекст();
	ТекстЗапросаСозданияВТ = ирОбщий.СтрЗаменитьЛкс(ТекстЗапросаСозданияВТ, "%ГлобальноеИмяВременнойТаблицы%", "'" + ГлобальноеИмяВременнойТаблицы + "'");
	ТекстЗапросаСозданияВТ = ирОбщий.СтрЗаменитьЛкс(ТекстЗапросаСозданияВТ, "%ИмяНовойВременнойТаблицы%", "'" + ИмяТаблицыКлючейСУБД + "'");
	ТекстЗапросаСозданияВТ = ирОбщий.ВыполнитьЗапросЭтойСУБДЛкс(ТекстЗапросаСозданияВТ,,,,,, мСоединениеСУБД,, Ложь)[0][0];
	
	ТекстСУБД = ТекстЗапросаСозданияВТ + ";" + Символы.ПС + ТекстСУБД;
	ирОбщий.ВыполнитьЗапросЭтойСУБДЛкс(ТекстСУБД,,,,,, мСоединениеСУБД);
	//Рез = ирОбщий.ВыполнитьЗапросЭтойСУБДЛкс("SELECT * FROM " + ИмяТаблицыКлючейСУБД,,,,,, мСоединениеСУБД); // Проверка выборки
	ГлавныйОбъектМД = Метаданные.НайтиПоПолномуИмени(ИмяГлавнойТаблицы);
	Если УдалятьСЗависимыми Тогда
		ТипСсылки = Тип(ирОбщий.ИмяТипаИзПолногоИмениМДЛкс(ИмяГлавнойТаблицы));
		ИндикаторПодчиненных = ирОбщий.ПолучитьИндикаторПроцессаЛкс(Метаданные.Справочники.Количество(), "Подчиненные справочники");
		Для Каждого МетаСправочник Из Метаданные.Справочники Цикл
			ирОбщий.ОбработатьИндикаторЛкс(ИндикаторПодчиненных);
			#Если Сервер И Не Сервер Тогда
				МетаСправочник = Метаданные.Справочники.Валюты;
			#КонецЕсли
			Если МетаСправочник.Владельцы.Содержит(ГлавныйОбъектМД) Тогда 
				Запрос.Текст = "ВЫБРАТЬ Т.Ссылка 
				|ИЗ " + МетаСправочник.ПолноеИмя() + " КАК Т
				|ВНУТРЕННЕЕ СОЕДИНЕНИЕ " + ИмяТаблицыКлючей + " КАК КлючиСтрокТ
				|ПО Т.Владелец = КлючиСтрокТ.Ссылка";
				УдалитьОбъектыЧерезСУБД(Запрос, МетаСправочник.ПолноеИмя(), ИмяТаблицыКлючейСУБД,,, выхОтключенныеИтоги);
			КонецЕсли;
		КонецЦикла;
		ирОбщий.ОсвободитьИндикаторПроцессаЛкс(); 
		Если ирОбщий.ЛиКорневойТипДокументаЛкс(ИмяГлавнойТаблицы) Тогда
			ПодчиненныеРегистры = ирОбщий.МетаданныеНаборовЗаписейПоРегистраторуЛкс(ГлавныйОбъектМД, Истина, Истина);
			ИндикаторДвижений = ирОбщий.ПолучитьИндикаторПроцессаЛкс(ПодчиненныеРегистры.Количество(), "Подчиненные регистры");
			Для Каждого РегистрМД Из ПодчиненныеРегистры Цикл
				#Если Сервер И Не Сервер Тогда
					РегистрМД = Метаданные.РегистрыСведений.КурсыВалют;
				#КонецЕсли
				ирОбщий.ОбработатьИндикаторЛкс(ИндикаторДвижений);
				УдалитьСтрокиТаблицыСУБДПорциями(Запрос, ирКэш.ИмяТаблицыИзМетаданныхЛкс(РегистрМД.ПолноеИмя(),, Ложь), ИмяТаблицыКлючей, ИмяТаблицыКлючейСУБД, "Регистратор", выхОтключенныеИтоги);
			КонецЦикла;
			ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
		КонецЕсли;
		ИндикаторВедомых = ирОбщий.ПолучитьИндикаторПроцессаЛкс(Метаданные.РегистрыСведений.Количество(), "Ведомые регистры");
		Для Каждого МетаРегистр Из Метаданные.РегистрыСведений Цикл
			ирОбщий.ОбработатьИндикаторЛкс(ИндикаторВедомых);
			#Если Сервер И Не Сервер Тогда
				МетаРегистр = Метаданные.РегистрыСведений.КурсыВалют;
			#КонецЕсли
			Для Каждого МетаИзмерение Из МетаРегистр.Измерения Цикл
				#Если Сервер И Не Сервер Тогда
					МетаИзмерение = Метаданные.РегистрыСведений.КурсыВалют.Измерения.Валюта;
				#КонецЕсли
				Если МетаИзмерение.Ведущее И МетаИзмерение.Тип.СодержитТип(ТипСсылки) Тогда
					УдалитьСтрокиТаблицыСУБДПорциями(Запрос, МетаРегистр.ПолноеИмя(), ИмяТаблицыКлючей, ИмяТаблицыКлючейСУБД, МетаИзмерение.Имя, выхОтключенныеИтоги);
				КонецЕсли;
			КонецЦикла;
		КонецЦикла;
		ирОбщий.ОсвободитьИндикаторПроцессаЛкс(); 
	КонецЕсли;
	Если ирОбщий.ЛиКорневойТипДокументаЛкс(ИмяГлавнойТаблицы) Тогда
		ИндикаторЖурналов = ирОбщий.ПолучитьИндикаторПроцессаЛкс(Метаданные.ЖурналыДокументов.Количество(), "Журналы");
		Для Каждого МетаЖурнал Из Метаданные.ЖурналыДокументов Цикл
			ирОбщий.ОбработатьИндикаторЛкс(ИндикаторЖурналов);
			#Если Сервер И Не Сервер Тогда
				МетаЖурнал = Метаданные.ЖурналыДокументов.ВнутренниеЗаказы;
			#КонецЕсли
			Если Не МетаЖурнал.РегистрируемыеДокументы.Содержит(ГлавныйОбъектМД) Тогда
				Продолжить;
			КонецЕсли;
			УдалитьСтрокиТаблицыСУБДПорциями(Запрос, МетаЖурнал.ПолноеИмя(), ИмяТаблицыКлючей, ИмяТаблицыКлючейСУБД, "Ссылка");
		КонецЦикла;
		ирОбщий.ОсвободитьИндикаторПроцессаЛкс(); 
	КонецЕсли;
	Если ирОбщий.ЛиКорневойТипСсылочногоОбъектаБДЛкс(ИмяГлавнойТаблицы) Тогда
		ТабличныеЧасти = ирОбщий.ТабличныеЧастиОбъектаЛкс(ГлавныйОбъектМД);
		ИндикаторТЧ = ирОбщий.ПолучитьИндикаторПроцессаЛкс(ТабличныеЧасти.Количество(), "Табличные части");
		Для Каждого КлючИЗначение Из ТабличныеЧасти Цикл
			ирОбщий.ОбработатьИндикаторЛкс(ИндикаторТЧ);
			УдалитьСтрокиТаблицыСУБДПорциями(Запрос, ИмяГлавнойТаблицы + "." + КлючИЗначение.Ключ, ИмяТаблицыКлючей, ИмяТаблицыКлючейСУБД);
		КонецЦикла;
		ирОбщий.ОсвободитьИндикаторПроцессаЛкс(); 
	КонецЕсли;
	УдалитьСтрокиТаблицыСУБДПорциями(Запрос, ИмяГлавнойТаблицы, ИмяТаблицыКлючей, ИмяТаблицыКлючейСУБД,, выхОтключенныеИтоги);
	ирОбщий.ВыполнитьЗапросЭтойСУБДЛкс("DROP TABLE " + ИмяТаблицыКлючейСУБД,,,,,, мСоединениеСУБД);

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

Функция СоздатьВременнуюТаблицуИНайтиТекстСУБД(Знач Запрос, Знач ИмяГлавнойТаблицыХранения, Знач ИмяТаблицыКлючей, Знач ИмяГлавнойВременнойТаблицы = "")
	
	Запрос.Текст = ирОбщий.ЗаменитьРегВыражениеЛкс(Запрос.Текст, "^(ВЫБРАТЬ\s[\s\S]*?)(\sИЗ\s)", "$1" + Символы.ПС + "ПОМЕСТИТЬ " + ИмяТаблицыКлючей + " $2");
	ТекстСУБД = ирОбщий.ВыполнитьЗапросИНайтиТекстСУБДЛкс(Запрос, ИмяГлавнойТаблицыХранения, Не ЗначениеЗаполнено(ИмяГлавнойВременнойТаблицы));
	Возврат ТекстСУБД;

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

Процедура УдалитьСтрокиТаблицыСУБДПорциями(Знач Запрос, Знач ИмяТаблицы, Знач ИмяТаблицыКлючей, Знач ИмяТаблицыКлючейСУБД, Знач ИмяПоляОтбора = "", Знач ОтключенныеИтоги = Неопределено)
	
	#Если Сервер И Не Сервер Тогда
		Запрос = Новый Запрос;
	#КонецЕсли
	ТипТаблицы = ирОбщий.ТипТаблицыБДЛкс(ИмяТаблицы);
	Если Не ЗначениеЗаполнено(ИмяПоляОтбора) Тогда 
		СтруктураКлюча = ирОбщий.СтруктураКлючаТаблицыБДЛкс(ИмяТаблицы, Ложь,,, Ложь);
		#Если Сервер И Не Сервер Тогда
			СтруктураКлюча = Новый Структура;
		#КонецЕсли
	Иначе
		СтруктураКлюча = Новый Структура("Ссылка", ИмяПоляОтбора);
	КонецЕсли;
	СловоПериод = ирОбщий.ПеревестиСтроку("Период");
	Выражения = Новый Массив;
	Для Каждого КлючИЗначение Из СтруктураКлюча Цикл
		ИмяПоляТаблицы = КлючИЗначение.Ключ;
		ИмяПоляГлавнойТаблицы = КлючИЗначение.Значение;
		Если Не ЗначениеЗаполнено(ИмяПоляГлавнойТаблицы) Тогда
			ИмяПоляГлавнойТаблицы = ИмяПоляТаблицы;
		КонецЕсли;
		Выражения.Добавить("
		|	И Т." + ИмяПоляГлавнойТаблицы + " = КлючиСтрокТ." + ИмяПоляТаблицы);
	КонецЦикла;
	Выражения = ирОбщий.СтрСоединитьЛкс(Выражения, "");
	ТекстЗапроса = "ИЗ " + ИмяТаблицы + " КАК Т
		|ВНУТРЕННЕЕ СОЕДИНЕНИЕ " + ИмяТаблицыКлючей + " КАК КлючиСтрокТ
		|ПО ИСТИНА " + Выражения;
	Если ирОбщий.ЛиКорневойТипРегистраБДЛкс(ТипТаблицы) Тогда
		МенеджерРегистра = ирОбщий.ПолучитьМенеджерЛкс(ИмяТаблицы);
		#Если Сервер И Не Сервер Тогда
			МенеджерРегистра = РегистрыНакопления.РозничнаяВыручка;
		#КонецЕсли
		Если Не ирОбщий.МетодРеализованЛкс(МенеджерРегистра, "УстановитьИспользованиеИтогов") Тогда
			МенеджерРегистра = Неопределено;
		КонецЕсли;
	КонецЕсли;
	Если МенеджерРегистра <> Неопределено Тогда
		#Если Сервер И Не Сервер Тогда
			МенеджерРегистра = РегистрыНакопления.РозничнаяВыручка;
		#КонецЕсли 
		ОтключенныеИтоги[ИмяТаблицы] = 1; 
		ПоляТаблицы = ирКэш.ПоляТаблицыБДЛкс(ИмяТаблицы, Истина);
		Если ПоляТаблицы.Найти(СловоПериод, "Имя") <> Неопределено Тогда 
			Попытка
				МаксПериодИтогов = МенеджерРегистра.ПолучитьМаксимальныйПериодРассчитанныхИтогов();
			Исключение
				МаксПериодИтогов = Неопределено;
			КонецПопытки;
			Запрос.Текст = "ВЫБРАТЬ МИНИМУМ(Т.Период) " + ТекстЗапроса;
			МинПериод = Запрос.Выполнить().Выгрузить()[0][0];
			Если МинПериод <> Null Тогда
				Если МаксПериодИтогов <> Неопределено Тогда 
					Если МаксПериодИтогов >= МинПериод Тогда
						Если МенеджерРегистра.ПолучитьМинимальныйПериодРассчитанныхИтогов() < МинПериод Тогда
							МенеджерРегистра.УстановитьМаксимальныйПериодРассчитанныхИтогов(МинПериод - 1);
						Иначе
							МенеджерРегистра.УстановитьИспользованиеИтогов(Ложь);
						КонецЕсли;
					КонецЕсли;
				Иначе
					МенеджерРегистра.УстановитьИспользованиеИтогов(Ложь);
				КонецЕсли;
				Попытка
					МенеджерРегистра.УстановитьИспользованиеТекущихИтогов(Ложь);
					ЕстьТекущиеИтоги = Истина;
				Исключение
					ЕстьТекущиеИтоги = Ложь
				КонецПопытки; 
				Попытка
					РежимАгрегатов = МенеджерРегистра.ПолучитьРежимАгрегатов();
				Исключение
					РежимАгрегатов = Ложь;
				КонецПопытки; 
				Если ЗначениеЗаполнено(МинПериод) И РежимАгрегатов Тогда
					МенеджерРегистра.УстановитьРежимАгрегатов(Ложь);
					ирОбщий.СообщитьЛкс(ирОбщий.СтрШаблонЛкс("У регистра %1 выполнено отключение агрегатов. При необходимости их нужно включить вручную", СтатусСообщения.Важное));
				КонецЕсли;
				//Если ЕстьТекущиеИтоги Тогда  
				//	// Этот способ слишком капризный, т.к. вызываются обработчики записи
				//	// Установим внутренний указатель актуальности итогов на минимальный период, подлежащий удалению, путем записи и удаления нейтральной строки на этот период
				//	СтрукутраНабораЗаписей = ирОбщий.СоздатьНаборЗаписейПоИмениТаблицыБДЛкс(ИмяТаблицы);
				//	НаборЗаписей = СтрукутраНабораЗаписей.Методы;
				//	#Если Сервер И Не Сервер Тогда
				//		НаборЗаписей = МенеджерРегистра.СоздатьНаборЗаписей();
				//	#КонецЕсли
				//	НаборЗаписей.Отбор.Регистратор.Установить(ирОбщий.ПолучитьМенеджерЛкс(НаборЗаписей.Отбор.Регистратор.ТипЗначения.Типы()[0]).ПолучитьСсылку());
				//	НаборЗаписей.ОбменДанными.Загрузка = Истина;
				//	НаборЗаписей.ОбменДанными.Получатели.АвтоЗаполнение = Ложь;
				//	СтрокаРегистра = НаборЗаписей.Добавить();
				//	СтрокаРегистра.Период = МинПериод; 
				//	НачатьТранзакцию();
				//	НаборЗаписей.Записать();
				//	НаборЗаписей.Очистить();
				//	НаборЗаписей.Записать();
				//	ЗафиксироватьТранзакцию();
				//КонецЕсли;
			КонецЕсли;
		КонецЕсли;
	КонецЕсли;
	Запрос.Текст = "ВЫБРАТЬ 1 " + ТекстЗапроса;
	МассивТаблиц = Новый Массив;
	Если ирОбщий.ЛиКорневойТипРегистраБухгалтерииЛкс(ИмяТаблицы) Тогда
		ИмяТаблицыСубконто = ИмяТаблицы + ".Субконто";
		Если ирОбщий.ЛиТаблицаБДСуществуетЛкс(ИмяТаблицыСубконто) Тогда
			МассивТаблиц.Добавить(ИмяТаблицыСубконто);
		КонецЕсли;
	КонецЕсли;
	МассивТаблиц.Добавить(ИмяТаблицы);
	НачальныйТекст = Запрос.Текст;
	Для Каждого ИмяЧастиТаблицы Из МассивТаблиц Цикл
		// TODO Если выбирается вся таблица, то применять TRUNCATE TABLE
		Запрос.Текст = ирОбщий.СтрЗаменитьЛкс(НачальныйТекст, ИмяТаблицы, ИмяЧастиТаблицы);
		Если Истина
			И ирОбщий.ЛиКорневойТипРегистраРасчетаЛкс(ИмяТаблицы)
			И СтрЧислоВхождений(ИмяЧастиТаблицы, ".") = 2 
		Тогда
			// Перерасчет
			Запрос.Текст = ирОбщий.СтрЗаменитьЛкс(НачальныйТекст, "Т.Регистратор", "Т.ОбъектПерерасчета");
		КонецЕсли;
		СтруктураХраненияТаблицы = ирОбщий.СтруктураХраненияТаблицыБДЛкс(ИмяЧастиТаблицы);
		ИмяТаблицыХранения = СтруктураХраненияТаблицы[0].ИмяТаблицыХранения;
		ТекстСУБД = ирОбщий.ВыполнитьЗапросИНайтиТекстСУБДЛкс(Запрос, ИмяТаблицыХранения, Ложь);
		//ТекстСУБД = ирОбщий.ЗаменитьРегВыражениеЛкс(ТекстСУБД, "#\w+", ИмяТаблицыКлючейСУБД); 
		ТекстСУБД = ирОбщий.ЗаменитьРегВыражениеЛкс(ТекстСУБД, "(FROM\s+[\w\.]+\s+(?:AS\s+)?\w+)(?:\s+WITH\s*\(\w+\))?", "$1 WITH (tablockx)");
		ТекстСУБД = ирОбщий.ЗаменитьРегВыражениеЛкс(ТекстСУБД, "SELECT\s.*(?=\sFROM\s)", "DELETE TOP (100000) " + ИмяТаблицыХранения)
			+ Символы.ПС + ";SELECT @@ROWCOUNT";
		УдаленоВПорции = 1;
		УдаленоВсего = 0;
		ИндикаторПорций = ирОбщий.ПолучитьИндикаторПроцессаЛкс(, ИмяЧастиТаблицы);
		Пока УдаленоВПорции > 0 Цикл 
			ирОбщий.ОбработатьИндикаторЛкс(ИндикаторПорций, УдаленоВсего);
			УдаленоВПорции = ирОбщий.ВыполнитьЗапросЭтойСУБДЛкс(ТекстСУБД,,,,,, мСоединениеСУБД,, Ложь)[0][0];
			УдаленоВсего = УдаленоВсего + УдаленоВПорции;
		КонецЦикла;
		ирОбщий.ОсвободитьИндикаторПроцессаЛкс(, УдаленоВсего > 0);
	КонецЦикла;

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

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

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

//Реквизиты настройки и значения по умолчанию.
мНастройка = Новый Структура("");

//мНастройка.<Имя реквизита> = <Значение реквизита>;
//! ВладелецФормы = 0 // см. ПолучитьФорму()
