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

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

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	
	УстановитьУсловноеОформление();
	
	Если Параметры.ЖурналДоступаКДанным Тогда
		Заголовок = НСтр("ru = 'Журнал доступа к данным'");
		СобытиеЖурналаРегистрации = Новый Массив;
		СобытиеЖурналаРегистрации.Добавить("_$Access$_.Access");
		СобытиеЖурналаРегистрации.Добавить("_$Access$_.AccessDenied");
		СобытиеЖурналаРегистрации.Добавить("_$Session$_.Authentication");
		СобытиеЖурналаРегистрации.Добавить("_$Session$_.AuthenticationError");
		СобытиеЖурналаРегистрации.Добавить("_$Session$_.Start");
		СобытиеЖурналаРегистрации.Добавить("_$Session$_.Finish");
		Элементы.Журнал.Видимость = Ложь;
		Элементы.Журнал2.Видимость = Истина;
		АвтоНавигационнаяСсылка = Ложь;
		НавигационнаяСсылка = "e1cib/command/Обработка.ЖурналРегистрации.Команда.ЖурналДоступаКДанным";
	Иначе
		Элементы.Журнал.Видимость = Истина;
		Элементы.Журнал2.Видимость = Ложь;
		СобытиеЖурналаРегистрации = Параметры.СобытиеЖурналаРегистрации;
	КонецЕсли;
	
	ОтборЖурналаРегистрации = Новый Структура;
	ОтборЖурналаРегистрацииПоУмолчанию = Новый Структура;
	ЗначенияОтбора = ПолучитьЗначенияОтбораЖурналаРегистрации("Событие").Событие;
	
	ОтборПоПользователю = ОтборПоПользователюИзПараметра(Параметры.Пользователь);
	Если ЗначениеЗаполнено(ОтборПоПользователю) Тогда
		ОтборЖурналаРегистрации.Вставить("Пользователь", ОтборПоПользователю);
	КонецЕсли;
	
	Если ЗначениеЗаполнено(СобытиеЖурналаРегистрации) Тогда
		ОтборПоСобытию = Новый СписокЗначений;
		Если ТипЗнч(СобытиеЖурналаРегистрации) = Тип("Массив") Тогда
			Для Каждого Событие Из СобытиеЖурналаРегистрации Цикл
				ОтборПоСобытию.Добавить(Событие, ПредставлениеСобытия(Событие, ЗначенияОтбора));
			КонецЦикла;
		Иначе
			Событие = СобытиеЖурналаРегистрации;
			ОтборПоСобытию.Добавить(Событие, ПредставлениеСобытия(Событие, ЗначенияОтбора));
		КонецЕсли;
		ОтборЖурналаРегистрации.Вставить("Событие", ОтборПоСобытию);
	КонецЕсли;
	
	ОтборЖурналаРегистрации.Вставить("ДатаНачала", 
		?(ЗначениеЗаполнено(Параметры.ДатаНачала), Параметры.ДатаНачала, НачалоДня(ТекущаяДатаСеанса())));
	ОтборЖурналаРегистрации.Вставить("ДатаОкончания", 
		?(ЗначениеЗаполнено(Параметры.ДатаОкончания), Параметры.ДатаОкончания, КонецДня(ТекущаяДатаСеанса())));
	
	Если Параметры.Данные <> Неопределено Тогда
		Если ТипЗнч(Параметры.Данные) = Тип("Массив") Тогда
			ОтборЖурналаРегистрации.Вставить("Данные", Новый СписокЗначений);
			ОтборЖурналаРегистрации.Данные.ЗагрузитьЗначения(Параметры.Данные);
		Иначе
			ОтборЖурналаРегистрации.Вставить("Данные", Параметры.Данные);
		КонецЕсли;
	КонецЕсли;
	
	Если Параметры.Сеанс <> Неопределено Тогда
		ОтборЖурналаРегистрации.Вставить("Сеанс", Параметры.Сеанс);
	КонецЕсли;
	
	// Уровень - список значений.
	Если Параметры.Уровень <> Неопределено Тогда
		ОтборПоУровню = Новый СписокЗначений;
		Если ТипЗнч(Параметры.Уровень) = Тип("Массив") Тогда
			Для Каждого ПредставлениеУровня Из Параметры.Уровень Цикл
				ОтборПоУровню.Добавить(ПредставлениеУровня, ПредставлениеУровня);
			КонецЦикла;
		ИначеЕсли ТипЗнч(Параметры.Уровень) = Тип("Строка") Тогда
			ОтборПоУровню.Добавить(Параметры.Уровень, Параметры.Уровень);
		Иначе
			ОтборПоУровню = Параметры.Уровень;
		КонецЕсли;
		ОтборЖурналаРегистрации.Вставить("Уровень", ОтборПоУровню);
	КонецЕсли;
	
	// ИмяПриложения - список значений.
	Если Параметры.ИмяПриложения <> Неопределено Тогда
		СписокПриложений = Новый СписокЗначений;
		Для Каждого Приложение Из Параметры.ИмяПриложения Цикл
			СписокПриложений.Добавить(Приложение, ПредставлениеПриложения(Приложение));
		КонецЦикла;
		ОтборЖурналаРегистрации.Вставить("ИмяПриложения", СписокПриложений);
	КонецЕсли;
	
	КоличествоПоказываемыхСобытий = 200;
	
	Если ОбщегоНазначения.ЭтоВебКлиент() Или ОбщегоНазначения.ЭтоМобильныйКлиент() Тогда
		УдаляемыйЭлемент = Элементы.КоличествоПоказываемыхСобытий.СписокВыбора.НайтиПоЗначению(10000);
		Элементы.КоличествоПоказываемыхСобытий.СписокВыбора.Удалить(УдаляемыйЭлемент);
		Элементы.КоличествоПоказываемыхСобытий.МаксимальноеЗначение = 1000;
	КонецЕсли;
	
	ОтборПоУмолчанию = ОтборПоУмолчанию(ЗначенияОтбора);
	Если Не ОтборЖурналаРегистрации.Свойство("Событие") Тогда
		ОтборЖурналаРегистрации.Вставить("Событие", ОтборПоУмолчанию);
	КонецЕсли;
	ОтборЖурналаРегистрацииПоУмолчанию.Вставить("Событие", ОтборПоУмолчанию);
	
	ТолькоСтандартныеРазделители = ЖурналРегистрации.ТолькоСтандартныеРазделители();
	УстановитьВидимостьРазделения(ЭтотОбъект,
		Не ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных());
	
	Критичность = "ВсеСобытия";
	
	// Взводится в значение Истина, если нужно, чтобы формирование журнала регистрации проходило не в фоне.
	ЗапускатьНеВФоне = Параметры.ЗапускатьНеВФоне;
	
	Если ОбщегоНазначения.ЭтоМобильныйКлиент() Тогда
		
		ОбщегоНазначенияКлиентСервер.УстановитьСвойствоЭлементаФормы(Элементы, "Критичность",	"ПоложениеЗаголовка",		ПоложениеЗаголовкаЭлементаФормы.Нет);
		ОбщегоНазначенияКлиентСервер.УстановитьСвойствоЭлементаФормы(Элементы, "Критичность",	"КнопкаВыбора",				Истина);
		ОбщегоНазначенияКлиентСервер.УстановитьСвойствоЭлементаФормы(Элементы, "Журнал", 		"ПоложениеКоманднойПанели", ПоложениеКоманднойПанелиЭлементаФормы.Нет);
		
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ПриОткрытии(Отказ)
	
	ПодключитьОбработчикОжидания("ОбновитьТекущийСписок", 0.1, Истина);
	
КонецПроцедуры

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

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

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

&НаКлиенте
Процедура КоличествоПоказываемыхСобытийПриИзменении(Элемент)
	
#Если ВебКлиент ИЛИ МобильныйКлиент Тогда
	КоличествоПоказываемыхСобытий = ?(КоличествоПоказываемыхСобытий > 1000, 1000, КоличествоПоказываемыхСобытий);
#КонецЕсли
	
	ОбновитьТекущийСписок();
	
КонецПроцедуры

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

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

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

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

&НаКлиенте
Процедура ЖурналПриАктивизацииПоля(Элемент)
	
	ДоступенОтборПоЗначениюВТекущейКолонке =
		Элемент.ТекущийЭлемент <> Элементы.Дата
		И Элемент.ТекущийЭлемент <> Элементы.Дата2;
	
	Элементы.УстановитьОтборПоЗначению.Доступность
		= ДоступенОтборПоЗначениюВТекущейКолонке;
	
	Элементы.УстановитьОтборПоЗначениюВТекущейКолонке2.Доступность
		= ДоступенОтборПоЗначениюВТекущейКолонке;
	
	Элементы.УстановитьОтборПоЗначениюВТекущейКолонкеКонтекст.Доступность
		= ДоступенОтборПоЗначениюВТекущейКолонке;
	
	Элементы.УстановитьОтборПоЗначениюВТекущейКолонкеКонтекст2.Доступность
		= ДоступенОтборПоЗначениюВТекущейКолонке;
	
КонецПроцедуры

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

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

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

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

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

&НаКлиенте
Процедура ОтключитьОтбор()
	
	ОтборЖурналаРегистрации = ОтборЖурналаРегистрацииПоУмолчанию;
	Критичность = "ВсеСобытия";
	ОбновитьТекущийСписок();
	
КонецПроцедуры

&НаКлиенте
Процедура ОткрытьДанныеДляПросмотра()
	
	ЖурналРегистрацииКлиент.ОткрытьДанныеДляПросмотра(ЭлементЖурнал().ТекущиеДанные);
	
КонецПроцедуры

&НаКлиенте
Процедура ПросмотрТекущегоСобытияВОтдельномОкне()
	
	ЖурналРегистрацииКлиент.ПросмотрТекущегоСобытияВОтдельномОкне(ЭлементЖурнал().ТекущиеДанные);
	
КонецПроцедуры

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

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

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

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

&НаКлиенте
Процедура ВыгрузитьЖурналДляПередачиВТехподдержку(Команда)
	
	ПараметрыСохраненияФайла = ФайловаяСистемаКлиент.ПараметрыСохраненияФайла();
	ПараметрыСохраненияФайла.Диалог.Фильтр = НСтр("ru = 'Данные журнала регистрации'") + "(*.xml)|*.xml";
	ФайловаяСистемаКлиент.СохранитьФайл(Неопределено, ВыгрузкаЖурналаРегистрации(), "EventLog.xml", ПараметрыСохраненияФайла);
	
КонецПроцедуры

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

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

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

&НаКлиенте
Функция ЭлементЖурнал()
	Возврат ?(Элементы.Журнал.Видимость, Элементы.Журнал, Элементы.Журнал2);
КонецФункции

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

// Параметры:
//  Событие - Строка
//
// Возвращаемое значение:
//  Строка, Неопределено
//
&НаСервере
Функция ПредставлениеСобытия(Событие, ЗначенияОтбора)
	
	ПредставлениеСобытия = ПредставлениеСобытияЖурналаРегистрации(Событие);
	
	Если ЗначениеЗаполнено(ПредставлениеСобытия) Тогда
		Возврат ПредставлениеСобытия;
	КонецЕсли;
	
	ПредставлениеСобытия = ЗначенияОтбора[Событие];
	
	Если ЗначениеЗаполнено(ПредставлениеСобытия) Тогда
		Возврат ПредставлениеСобытия;
	КонецЕсли;
	
	Возврат Неопределено;
	
КонецФункции

&НаСервере
Функция ОтборПоУмолчанию(СписокСобытий)
	
	ОтборПоУмолчанию = Новый СписокЗначений;
	
	Для Каждого СобытиеЖурнала Из СписокСобытий Цикл
		
		Если СобытиеЖурнала.Ключ = "_$Transaction$_.Commit"
			Или СобытиеЖурнала.Ключ = "_$Transaction$_.Begin"
			Или СобытиеЖурнала.Ключ = "_$Transaction$_.Rollback" Тогда
			Продолжить;
		КонецЕсли;
		
		ОтборПоУмолчанию.Добавить(СобытиеЖурнала.Ключ, СобытиеЖурнала.Значение);
		
	КонецЦикла;
	
	Возврат ОтборПоУмолчанию;
КонецФункции

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

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

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

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

	Возврат ПараметрыОтчета;
КонецФункции

&НаСервере
Процедура ЗагрузитьПодготовленныеДанные(АдресРезультата)
	Результат      = ПолучитьИзВременногоХранилища(АдресРезультата);
	СобытияЖурнала = Результат.СобытияЖурнала;
	
	ЗначениеВДанныеФормы(СобытияЖурнала, Журнал);
КонецПроцедуры

&НаКлиенте
Процедура ПролистатьВКонецСписка()
	Если Журнал.Количество() > 0 Тогда
		ЭлементЖурнал().ТекущаяСтрока = Журнал[Журнал.Количество() - 1].ПолучитьИдентификатор();
	КонецЕсли;
КонецПроцедуры 

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

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

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

&НаСервере
Процедура УстановитьУсловноеОформление()
	
	УсловноеОформление.Элементы.Очистить();
	
	// Важность
	Элемент = УсловноеОформление.Элементы.Добавить();
	
	ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
	Если Параметры.ЖурналДоступаКДанным Тогда
		ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.Важность2.Имя);
	Иначе
		ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.Важность.Имя);
	КонецЕсли;
	
	ОтборЭлемента = Элемент.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Журнал.Уровень");
	ОтборЭлемента.ВидСравнения = ВидСравненияКомпоновкиДанных.Заполнено;
	
	Элемент.Оформление.УстановитьЗначениеПараметра("Видимость", Ложь);
	
	// Данные
	Элемент = УсловноеОформление.Элементы.Добавить();
	
	ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
	Если Параметры.ЖурналДоступаКДанным Тогда
		ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.Данные2.Имя);
	Иначе
		ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.Данные.Имя);
	КонецЕсли;
	
	ДобавитьУсловиеСкрытияКолонкиДанные(Элемент.Отбор.Элементы);
	
	Элемент.Оформление.УстановитьЗначениеПараметра("Видимость", Ложь);
	
	Элементы.Данные.Формат  = НСтр("ru = 'ЧН=0; ДП=''01.01.0001 00:00:00'''");
	Элементы.Данные2.Формат = Элементы.Данные.Формат;
	
	// ПредставлениеДанных
	Элемент = УсловноеОформление.Элементы.Добавить();
	
	ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
	Если Параметры.ЖурналДоступаКДанным Тогда
		ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.ПредставлениеДанных2.Имя);
	Иначе
		ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.ПредставлениеДанных.Имя);
	КонецЕсли;
	
	ДобавитьУсловиеСкрытияКолонкиПредставлениеДанных(Элемент.Отбор.Элементы);
	
	Элемент.Оформление.УстановитьЗначениеПараметра("Видимость", Ложь);
	
	// ПредставлениеМетаданных
	Элемент = УсловноеОформление.Элементы.Добавить();
	
	ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
	Если Параметры.ЖурналДоступаКДанным Тогда
		ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.ПредставлениеМетаданных2.Имя);
	Иначе
		ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.ПредставлениеМетаданных.Имя);
	КонецЕсли;
	
	ОтборЭлемента = Элемент.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Журнал.ПредставлениеМетаданных");
	ОтборЭлемента.ВидСравнения = ВидСравненияКомпоновкиДанных.НеЗаполнено;
	Элемент.Оформление.УстановитьЗначениеПараметра("Видимость", Ложь);
	
	// Комментарий
	Элемент = УсловноеОформление.Элементы.Добавить();
	
	ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
	Если Параметры.ЖурналДоступаКДанным Тогда
		ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.Комментарий2.Имя);
	Иначе
		ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.Комментарий.Имя);
	КонецЕсли;
	
	ОтборЭлемента = Элемент.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Журнал.Комментарий");
	ОтборЭлемента.ВидСравнения = ВидСравненияКомпоновкиДанных.НеЗаполнено;
	
	Группа = Элемент.Отбор.Элементы.Добавить(Тип("ГруппаЭлементовОтбораКомпоновкиДанных"));
	Группа.ТипГруппы = ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаИли;
	
	Подгруппа = Группа.Элементы.Добавить(Тип("ГруппаЭлементовОтбораКомпоновкиДанных"));
	Подгруппа.ТипГруппы = ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаНе;
	ДобавитьУсловиеСкрытияКолонкиДанные(Подгруппа.Элементы);
	
	Подгруппа = Группа.Элементы.Добавить(Тип("ГруппаЭлементовОтбораКомпоновкиДанных"));
	Подгруппа.ТипГруппы = ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаНе;
	ДобавитьУсловиеСкрытияКолонкиПредставлениеДанных(Подгруппа.Элементы);
	
	ОтборЭлемента = Группа.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Журнал.ПредставлениеДанных");
	ОтборЭлемента.ВидСравнения = ВидСравненияКомпоновкиДанных.Заполнено;
	
	Элемент.Оформление.УстановитьЗначениеПараметра("Видимость", Ложь);
	
КонецПроцедуры

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

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

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