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

Перем мАлгоритмПередВыгрузкойПараметры Экспорт;

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

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

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

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

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

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

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

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

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

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

Функция ВыгрузитьЖурналРегистрацииЛкс(Параметры) Экспорт 
	Фильтр = Параметры.Фильтр;
	Если Фильтр.Свойство("Данные") Тогда
		// Антибаг платформы 8.3.8-14 https://partners.v8.1c.ru/forum/t/1807905/m/1807905
		МаксимальныйРазмерВыгрузкиТекущий = 0;
	Иначе
		МаксимальныйРазмерВыгрузкиТекущий = МаксимальныйРазмерВыгрузки;
	КонецЕсли; 
	Если Фильтр.Свойство("Метаданные") И ТипЗнч(Фильтр.Метаданные) = Тип("Массив") Тогда
		// Антибаг платформы 8.3.8-14 https://partners.v8.1c.ru/forum/topic/1988645, https://www.hostedredmine.com/issues/925192
		Для Индекс = 0 По Фильтр.Метаданные.ВГраница() Цикл
			ЗначениеОтбора = Фильтр.Метаданные[Индекс];
			Если Истина
				И ТипЗнч(ЗначениеОтбора) = Тип("Строка") 
				И ирОбщий.ЛиКорневойТипВнешнегоИсточникаДанныхЛкс(ирОбщий.ПервыйФрагментЛкс(ЗначениеОтбора))
			Тогда
				ОбъектМД = ирОбщий.ОбъектМДПоПолномуИмениЛкс(ЗначениеОтбора);
				Если ОбъектМД <> Неопределено Тогда
					Фильтр.Метаданные[Индекс] = ОбъектМД;
				КонецЕсли; 
			КонецЕсли; 
		КонецЦикла;
	КонецЕсли; 
	Если АнализироватьТранзакцииСУчастиемОбъекта Тогда
		#Если Клиент Тогда
		Состояние("Анализ транзакций журнала...");
		#КонецЕсли
		ЭтотОбъект.ТаблицаЗначенийЖурнала = Новый ТаблицаЗначений;
		ТаблицаТранзакций = Новый ТаблицаЗначений;
		ВыгрузитьЖурналРегистрации(ТаблицаТранзакций, Фильтр,, ИмяФайла, МаксимальныйРазмерВыгрузкиТекущий);
		ирОбщий.ПеревестиКолонкиСистемнойТаблицыЛкс(ТаблицаТранзакций);
		ТаблицаТранзакций.Свернуть("Транзакция");
		ТаблицаТранзакций.Сортировать("Транзакция");
		Транзакции = ТаблицаТранзакций.ВыгрузитьКолонку("Транзакция");
		Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(Транзакции.Количество(), "Выгрузка журнала по транзакциям");
		ФильтрТранзакции = ирОбщий.СкопироватьКоллекциюЛкс(Фильтр);
		Для Каждого Транзакция Из Транзакции Цикл
			ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
			//ФильтрТранзакции.Вставить("Транзакция", ирОбщий.ТекстМеждуМаркерамиЛкс(Транзакция, "(",")"));
			ФильтрТранзакции.Вставить("Транзакция", Транзакция);
			Если Транзакция <> "" Тогда
				ФильтрТранзакции.Удалить("Данные");
			КонецЕсли; 
			ТаблицаТранзакции = Новый ТаблицаЗначений;
			Если МаксимальныйРазмерВыгрузкиТекущий > 0 Тогда
				МаксимальныйРазмерВыгрузкиТекущий = МаксимальныйРазмерВыгрузкиТекущий - ТаблицаЗначенийЖурнала.Количество();
			КонецЕсли; 
			ВыгрузитьЖурналРегистрации(ТаблицаТранзакции, ФильтрТранзакции,, ИмяФайла, МаксимальныйРазмерВыгрузкиТекущий);
			Если Транзакция = "" Тогда
				ТаблицаТранзакции = ТаблицаТранзакции.Скопировать(Новый Структура("Транзакция", ""));
			КонецЕсли; 
			ТаблицаТранзакции.Колонки.Добавить("ПорядокСтроки", Новый ОписаниеТипов("Число"));
			Для Счетчик = 1 По ТаблицаТранзакции.Количество() Цикл
				ТаблицаТранзакции[Счетчик - 1].ПорядокСтроки = ТаблицаЗначенийЖурнала.Количество() + Счетчик;
			КонецЦикла;
			Если ТаблицаЗначенийЖурнала.Колонки.Количество() = 0 Тогда
				ТаблицаЗначенийЖурнала = ТаблицаТранзакции;
				ТаблицаЗначенийЖурнала.Колонки.Добавить("ДлительностьТранзакции", Новый ОписаниеТипов("Число"));
			Иначе
				СвойстваТранзакции = Новый Структура("ДлительностьТранзакции", ТаблицаТранзакции[ТаблицаТранзакции.Количество() - 1].Дата - ТаблицаТранзакции[0].Дата);
				ирОбщий.ЗагрузитьВТаблицуЗначенийЛкс(ТаблицаТранзакции, ТаблицаЗначенийЖурнала, СвойстваТранзакции);
			КонецЕсли; 
			Если МаксимальныйРазмерВыгрузкиТекущий > 0 И ТаблицаЗначенийЖурнала.Количество() >= МаксимальныйРазмерВыгрузкиТекущий Тогда
				Прервать;
			КонецЕсли; 
		КонецЦикла;
		ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
	Иначе
		ТаблицаЗначенийЖурнала = Новый ТаблицаЗначений;
		ирОбщий.СостояниеЛкс("Выгрузка журнала регистрации");
		ВыгрузитьЖурналРегистрации(ТаблицаЗначенийЖурнала, Фильтр,, ИмяФайла, МаксимальныйРазмерВыгрузкиТекущий);
		ирОбщий.СостояниеЛкс("");
	КонецЕсли; 
	#Если Сервер И Не Сервер Тогда
		ТаблицаЗначенийЖурнала = Новый ТаблицаЗначений;
	#КонецЕсли
	Если ТаблицаЗначенийЖурнала.Колонки.Найти("ПорядокСтроки") = Неопределено Тогда
		ТаблицаЗначенийЖурнала.Колонки.Добавить("ПорядокСтроки", Новый ОписаниеТипов("Число"));
		Для Счетчик = 1 По ТаблицаЗначенийЖурнала.Количество() Цикл
			ТаблицаЗначенийЖурнала[Счетчик - 1].ПорядокСтроки = Счетчик;
		КонецЦикла;
	КонецЕсли; 
	ТаблицаЗначенийЖурнала.Индексы.Добавить("ПорядокСтроки");
	ТаблицаЗначенийЖурнала.Сортировать("ПорядокСтроки");
	ирОбщий.ПеревестиКолонкиСистемнойТаблицыЛкс(ТаблицаЗначенийЖурнала);
	РеквизитыДляРезультата = "АнализироватьТранзакцииСУчастиемОбъекта";
	ПараметрыДляРезультата = "ПредставлениеОтбора";
	Результат = Новый Структура(РеквизитыДляРезультата + ", " + ПараметрыДляРезультата);
	ЗаполнитьЗначенияСвойств(Результат, ЭтотОбъект, РеквизитыДляРезультата); 
	ЗаполнитьЗначенияСвойств(Результат, Параметры, ПараметрыДляРезультата); 
	Результат.Вставить("ТаблицаЗначенийЖурнала", ТаблицаЗначенийЖурнала);
	Возврат Результат;
КонецФункции

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

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

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

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

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

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

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

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

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

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

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

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

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

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

#КонецЕсли

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

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