#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда
#Область ПрограммныйИнтерфейс
#Область ДляВызоваИзДругихПодсистем
Процедура ПередДобавлениемКомандОтчетов(КомандыОтчетов, Параметры, СтандартнаяОбработка) Экспорт
Если Не ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ВариантыОтчетов") Тогда
Возврат;
КонецЕсли;
Если Не ПравоДоступа("Просмотр", Метаданные.Отчеты.АнализЖурналаРегистрации)
Или СтандартныеПодсистемыСервер.ЭтоБазоваяВерсияКонфигурации() Тогда
Возврат;
КонецЕсли;
ДобавитьКоманду = Ложь;
Если Параметры.ИмяФормы = "Справочник.Пользователи.Форма.ФормаСписка" Тогда
Команда = КомандыОтчетов.Добавить();
Команда.Представление = НСтр("ru = 'Анализ активности пользователей'");
Команда.КлючВарианта = "АнализАктивностиПользователей";
Команда.МножественныйВыбор = Истина;
Команда.Менеджер = "Отчет.АнализЖурналаРегистрации";
Команда.ТолькоВоВсехДействиях = Истина;
Команда.Важность = "СмТакже";
Если Пользователи.ПодразделениеИспользуется() Тогда
Команда = КомандыОтчетов.Добавить();
Команда.Представление = НСтр("ru = 'Анализ активности подразделений'");
Команда.КлючВарианта = "АнализАктивностиПодразделений";
Команда.МножественныйВыбор = Истина;
Команда.Менеджер = "Отчет.АнализЖурналаРегистрации";
Команда.ТолькоВоВсехДействиях = Истина;
Команда.Важность = "СмТакже";
КонецЕсли;
ДобавитьКоманду = Истина;
ИначеЕсли Параметры.ИмяФормы = "Справочник.Пользователи.Форма.ФормаЭлемента" Тогда
ДобавитьКоманду = Истина;
КонецЕсли;
Если Не ДобавитьКоманду Тогда
Возврат;
КонецЕсли;
Команда = КомандыОтчетов.Добавить();
Команда.Представление = НСтр("ru = 'Анализ активности пользователя'");
Команда.КлючВарианта = "АктивностьПользователя";
Команда.МножественныйВыбор = Ложь;
Команда.Менеджер = "Отчет.АнализЖурналаРегистрации";
Команда.ТолькоВоВсехДействиях = Истина;
Команда.Важность = "СмТакже";
КонецПроцедуры
Процедура НастроитьВариантыОтчета(Настройки, НастройкиОтчета) Экспорт
НастройкиОтчета.ОпределитьНастройкиФормы = Истина;
МодульВариантыОтчетов = ОбщегоНазначения.ОбщийМодуль("ВариантыОтчетов");
МодульВариантыОтчетов.УстановитьРежимВыводаВПанеляхОтчетов(Настройки, НастройкиОтчета, Ложь);
ПодсистемаАдминистрирования = Метаданные.Подсистемы.Найти("Администрирование");
ПодсистемаКонтроля = ?(ПодсистемаАдминистрирования = Неопределено, Неопределено,
ПодсистемаАдминистрирования.Подсистемы.Найти("КонтрольРаботыПользователей"));
НастройкиВарианта = МодульВариантыОтчетов.ОписаниеВарианта(Настройки, НастройкиОтчета, "АнализАктивностиПользователей");
Если ПодсистемаКонтроля <> Неопределено Тогда
НастройкиВарианта.Размещение.Вставить(ПодсистемаКонтроля, "");
КонецЕсли;
НастройкиВарианта.Описание =
НСтр("ru = 'Позволяет выполнять мониторинг активности пользователей в приложении (насколько интенсивно и с какими объектами работают пользователи).'");
НастройкиВарианта = МодульВариантыОтчетов.ОписаниеВарианта(Настройки, НастройкиОтчета, "АнализАктивностиПодразделений");
НастройкиВарианта.Включен = Пользователи.ПодразделениеИспользуется();
Если ПодсистемаКонтроля <> Неопределено Тогда
НастройкиВарианта.Размещение.Вставить(ПодсистемаКонтроля, "");
КонецЕсли;
НастройкиВарианта.Описание =
НСтр("ru = 'Позволяет выполнять мониторинг активности подразделений в приложении (насколько интенсивно и с какими объектами работают пользователи подразделений).'");
НастройкиВарианта = МодульВариантыОтчетов.ОписаниеВарианта(Настройки, НастройкиОтчета, "АктивностьПользователя");
Если ПодсистемаКонтроля <> Неопределено Тогда
НастройкиВарианта.Размещение.Вставить(ПодсистемаКонтроля, "");
КонецЕсли;
НастройкиВарианта.Описание =
НСтр("ru = 'Подробная информация о том, с какими объектами работал пользователь в приложении.'");
НастройкиВарианта = МодульВариантыОтчетов.ОписаниеВарианта(Настройки, НастройкиОтчета, "КонтрольЖурналаРегистрации");
НастройкиВарианта.НастройкиДляПоиска.ИменаМакетов = "МакетОтчетаПоОшибкамВЖурналеРегистрации";
Если ПодсистемаАдминистрирования <> Неопределено Тогда
НастройкиВарианта.Размещение.Вставить(ПодсистемаАдминистрирования, "");
КонецЕсли;
НастройкиВарианта.Описание = НСтр("ru = 'Список критичных записей журнала регистрации.'");
НастройкиВарианта = МодульВариантыОтчетов.ОписаниеВарианта(Настройки, НастройкиОтчета, "ПродолжительностьРаботыРегламентныхЗаданий");
НастройкиВарианта.НастройкиДляПоиска.ИменаМакетов = "ПродолжительностьРаботыРегламентныхЗаданий, РасшифровкаРегламентныхЗаданий";
НастройкиВарианта.Включен = Не ОбщегоНазначения.РазделениеВключено();
Если ПодсистемаАдминистрирования <> Неопределено Тогда
НастройкиВарианта.Размещение.Вставить(ПодсистемаАдминистрирования, "");
КонецЕсли;
НастройкиВарианта.Описание = НСтр("ru = 'Выводит график выполнения регламентных заданий в приложении.'");
КонецПроцедуры
#КонецОбласти
#КонецОбласти
#Область СлужебныеПроцедурыИФункции
Функция ДанныеИзЖурналаРегистрации(ПараметрыОтчета) Экспорт
ДатаНачала = ПараметрыОтчета.ДатаНачала;
ДатаОкончания = ПараметрыОтчета.ДатаОкончания;
Пользователь = ПараметрыОтчета.Пользователь;
ПользователиИГруппы = ПараметрыОтчета.ПользователиИГруппы;
Подразделение = ПараметрыОтчета.Подразделение;
ВариантОтчета = ПараметрыОтчета.ВариантОтчета;
Если ВариантОтчета = "АктивностьПользователя" Тогда
ВыводитьСлужебныхПользователей = Истина;
ВыводитьБизнесПроцессы = ПараметрыОтчета.ВыводитьБизнесПроцессы;
ВыводитьЗадачи = ПараметрыОтчета.ВыводитьЗадачи;
ВыводитьСправочники = ПараметрыОтчета.ВыводитьСправочники;
ВыводитьДокументы = ПараметрыОтчета.ВыводитьДокументы;
Иначе
ВыводитьСлужебныхПользователей = ПараметрыОтчета.ВыводитьСлужебныхПользователей;
ВыводитьСправочники = Истина;
ВыводитьДокументы = Истина;
ВыводитьБизнесПроцессы = Ложь;
ВыводитьЗадачи = Ложь;
КонецЕсли;
ИсходныеДанные = Новый ТаблицаЗначений();
ИсходныеДанные.Колонки.Добавить("Дата", Новый ОписаниеТипов("Дата", , , Новый КвалификаторыДаты(ЧастиДаты.Дата)));
ИсходныеДанные.Колонки.Добавить("Неделя", Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(10)));
ИсходныеДанные.Колонки.Добавить("Пользователь");
ИсходныеДанные.Колонки.Добавить("Подразделение");
ИсходныеДанные.Колонки.Добавить("ПодразделениеПредставление");
ИсходныеДанные.Колонки.Добавить("ЧасовРаботы", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15,4)));
ИсходныеДанные.Колонки.Добавить("КоличествоЗапусков", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(10)));
ИсходныеДанные.Колонки.Добавить("СозданоДокументов", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(10)));
ИсходныеДанные.Колонки.Добавить("СозданоСправочников", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(10)));
ИсходныеДанные.Колонки.Добавить("ИзмененоДокументов", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(10)));
ИсходныеДанные.Колонки.Добавить("СозданоБизнесПроцессов", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(10)));
ИсходныеДанные.Колонки.Добавить("СозданоЗадач", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(10)));
ИсходныеДанные.Колонки.Добавить("ИзмененоБизнесПроцессов", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(10)));
ИсходныеДанные.Колонки.Добавить("ИзмененоЗадач", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(10)));
ИсходныеДанные.Колонки.Добавить("ИзмененоСправочников", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(10)));
ИсходныеДанные.Колонки.Добавить("Ошибок", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(10)));
ИсходныеДанные.Колонки.Добавить("Предупреждений", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(10)));
ИсходныеДанные.Колонки.Добавить("ВидОбъекта", Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(50)));
ИсходныеДанные.Колонки.Добавить("ОбъектСправочникДокумент");
ОдновременноСессий = Новый ТаблицаЗначений();
ОдновременноСессий.Колонки.Добавить("ДатаОдновременноРаботавшихПользователей",
Новый ОписаниеТипов("Дата", , , Новый КвалификаторыДаты(ЧастиДаты.Дата)));
ОдновременноСессий.Колонки.Добавить("ОдновременноРаботавшихПользователей",
Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(10)));
ОдновременноСессий.Колонки.Добавить("СписокОдновременноРаботавшихПользователей");
ДанныеЖурналаРегистрации = Новый ТаблицаЗначений;
Уровни = Новый Массив;
Уровни.Добавить(УровеньЖурналаРегистрации.Информация);
События = Новый Массив;
События.Добавить("_$Session$_.Start");
События.Добавить("_$Session$_.Finish");
События.Добавить("_$Data$_.New");
События.Добавить("_$Data$_.Update");
ИмяПриложения = Новый Массив;
ИмяПриложения.Добавить("1CV8C");
ИмяПриложения.Добавить("WebClient");
ИмяПриложения.Добавить("1CV8");
ИмяПриложения.Добавить("BackgroundJob");
ИмяПриложения.Добавить("MobileClient");
ИмяПриложения.Добавить("HTTPServiceConnection");
ИмяПриложения.Добавить("WSConnection");
ИмяПриложения.Добавить("ODataConnection");
ИмяПриложения.Добавить("COMConnection");
ДатыВЧасовомПоясеСервера = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(ПараметрыОтчета,
"ДатыВЧасовомПоясеСервера", Ложь);
Если ДатыВЧасовомПоясеСервера Тогда
СмещениеВремениСервера = 0;
Иначе
СмещениеВремениСервера = ЖурналРегистрации.СмещениеВремениСервера();
КонецЕсли;
ПользовательФильтр = Новый Массив;
ВыбранныеПодразделения = Неопределено;
ПодразделенияПользователей = Неопределено;
Если ВариантОтчета = "АктивностьПользователя" Тогда
ПользовательФильтр.Добавить(ПользовательДляОтбора(Пользователь));
ИначеЕсли ВариантОтчета = "АнализАктивностиПодразделений" Тогда
ВыбранныеПодразделения = ВыбранныеПодразделения(Подразделение);
ПодразделенияПользователей = ПодразделенияПользователей(ДатаНачала,
СмещениеВремениСервера, ВыбранныеПодразделения);
ЗаполнитьПользователейДляАнализаИзПодразделения(ПользовательФильтр,
ВыбранныеПодразделения, ПодразделенияПользователей);
Иначе
ЗаполнитьПользователейДляАнализа(ПользовательФильтр, ПользователиИГруппы);
КонецЕсли;
Если ПользовательФильтр.Количество() = 0 Тогда
Возврат Новый Структура("АнализАктивностиПользователей, ОдновременноСессий, ОтчетПустой",
ИсходныеДанные, ОдновременноСессий, Истина);
КонецЕсли;
ОтборЖурналаРегистрации = Новый Структура;
ОтборЖурналаРегистрации.Вставить("ДатаНачала", ДатаНачала + СмещениеВремениСервера);
ОтборЖурналаРегистрации.Вставить("ДатаОкончания", ДатаОкончания + СмещениеВремениСервера);
ОтборЖурналаРегистрации.Вставить("ИмяПриложения", ИмяПриложения);
ОтборЖурналаРегистрации.Вставить("Уровень", Уровни);
ОтборЖурналаРегистрации.Вставить("Событие", События);
Если ПользовательФильтр.Найти("ВсеПользователи") = Неопределено Тогда
ОтборЖурналаРегистрации.Вставить("Пользователь", ПользовательФильтр);
Иначе
ПользовательФильтр = Неопределено;
КонецЕсли;
УстановитьПривилегированныйРежим(Истина);
ВыгрузитьЖурналРегистрации(ДанныеЖурналаРегистрации, ОтборЖурналаРегистрации);
УстановитьПривилегированныйРежим(Ложь);
ОтчетПустой = (ДанныеЖурналаРегистрации.Количество() = 0);
СоответствиеИдентификаторыПользователей = УникальныеИдентификаторыПользователей(ДанныеЖурналаРегистрации,
ВыводитьСлужебныхПользователей);
Сеансы = Новый ТаблицаЗначений;
Сеансы.Колонки.Добавить("НомерСеанса");
Сеансы.Колонки.Добавить("СобытиеНачала");
Сеансы.Колонки.Добавить("СобытиеЗавершения");
Сеансы.Колонки.Добавить("Пользователь");
Сеансы.Колонки.Добавить("Подразделение");
Сеансы.Колонки.Добавить("ПодразделениеПредставление");
Сеансы.Колонки.Добавить("ДатаПервогоСобытияСеанса");
Сеансы.Колонки.Добавить("ДатаПоследнегоСобытияСеанса");
Сеансы.Индексы.Добавить("НомерСеанса");
Для Каждого СтрокаДанныхЖурналаРегистрации Из ДанныеЖурналаРегистрации Цикл
СтрокаДанныхЖурналаРегистрации.Дата = СтрокаДанныхЖурналаРегистрации.Дата - СмещениеВремениСервера;
Если Не ЗначениеЗаполнено(СтрокаДанныхЖурналаРегистрации.Сеанс)
Или Не ЗначениеЗаполнено(СтрокаДанныхЖурналаРегистрации.Дата) Тогда
Продолжить;
КонецЕсли;
ИмяПользователяСсылка = СоответствиеИдентификаторыПользователей[СтрокаДанныхЖурналаРегистрации.Пользователь];
Если ИмяПользователяСсылка = Неопределено Тогда
Продолжить;
КонецЕсли;
ПодразделениеПользователяИБ = Новый Структура("Подразделение, ПодразделениеПредставление");
Если ПодразделенияПользователей <> Неопределено Тогда
ЗаполнитьПодразделениеПользователяИБ(ПодразделениеПользователяИБ, СтрокаДанныхЖурналаРегистрации.Дата,
СтрокаДанныхЖурналаРегистрации.Пользователь, ПодразделенияПользователей);
Если ВыбранныеПодразделения <> Неопределено
И ВыбранныеПодразделения.Найти(ПодразделениеПользователяИБ.Подразделение) = Неопределено Тогда
Продолжить;
КонецЕсли;
КонецЕсли;
Сеанс = Сеансы.Найти(СтрокаДанныхЖурналаРегистрации.Сеанс, "НомерСеанса");
СеансДобавлен = Ложь;
Если СтрокаДанныхЖурналаРегистрации.Событие = "_$Session$_.Start" Тогда
Если Сеанс <> Неопределено Тогда
Сеанс.НомерСеанса = Неопределено;
КонецЕсли;
Сеанс = Сеансы.Добавить();
Сеанс.НомерСеанса = СтрокаДанныхЖурналаРегистрации.Сеанс;
Сеанс.СобытиеНачала = СтрокаДанныхЖурналаРегистрации;
СеансДобавлен = Истина;
ИначеЕсли СтрокаДанныхЖурналаРегистрации.Событие = "_$Session$_.Finish" Тогда
Если Сеанс = Неопределено Тогда
Сеанс = Сеансы.Добавить();
СеансДобавлен = Истина;
КонецЕсли;
Сеанс.НомерСеанса = Неопределено;
Сеанс.СобытиеЗавершения = СтрокаДанныхЖурналаРегистрации;
Иначе
Если Сеанс = Неопределено Тогда
Сеанс = Сеансы.Добавить();
Сеанс.ДатаПервогоСобытияСеанса = СтрокаДанныхЖурналаРегистрации.Дата;
СеансДобавлен = Истина;
КонецЕсли;
Сеанс.ДатаПоследнегоСобытияСеанса = СтрокаДанныхЖурналаРегистрации.Дата;
КонецЕсли;
Если СеансДобавлен Тогда
Сеанс.Пользователь = ИмяПользователяСсылка;
ЗаполнитьЗначенияСвойств(Сеанс, ПодразделениеПользователяИБ);
КонецЕсли;
СобытиеМетаданные = СтрокаДанныхЖурналаРегистрации.Метаданные;
СтрокаИсходныхДанных = Неопределено;
Если СтрокаДанныхЖурналаРегистрации.Событие = "_$Data$_.New" Тогда
Если СтрНайти(СобытиеМетаданные, "Документ.") > 0 И ВыводитьДокументы Тогда
СтрокаИсходныхДанных = ИсходныеДанные.Добавить();
СтрокаИсходныхДанных.СозданоДокументов = 1;
КонецЕсли;
Если СтрНайти(СобытиеМетаданные, "Справочник.") > 0 И ВыводитьСправочники Тогда
СтрокаИсходныхДанных = ИсходныеДанные.Добавить();
СтрокаИсходныхДанных.СозданоСправочников = 1;
КонецЕсли;
КонецЕсли;
Если СтрокаДанныхЖурналаРегистрации.Событие = "_$Data$_.Update" Тогда
Если СтрНайти(СобытиеМетаданные, "Документ.") > 0 И ВыводитьДокументы Тогда
СтрокаИсходныхДанных = ИсходныеДанные.Добавить();
СтрокаИсходныхДанных.ИзмененоДокументов = 1;
КонецЕсли;
Если СтрНайти(СобытиеМетаданные, "Справочник.") > 0 И ВыводитьСправочники Тогда
СтрокаИсходныхДанных = ИсходныеДанные.Добавить();
СтрокаИсходныхДанных.ИзмененоСправочников = 1;
КонецЕсли;
КонецЕсли;
Если СтрокаДанныхЖурналаРегистрации.Событие = "_$Data$_.New" Тогда
Если СтрНайти(СобытиеМетаданные, "БизнесПроцесс.") > 0 И ВыводитьБизнесПроцессы Тогда
СтрокаИсходныхДанных = ИсходныеДанные.Добавить();
СтрокаИсходныхДанных.СозданоБизнесПроцессов = 1;
КонецЕсли;
Если СтрНайти(СобытиеМетаданные, "Задача.") > 0 И ВыводитьЗадачи Тогда
СтрокаИсходныхДанных = ИсходныеДанные.Добавить();
СтрокаИсходныхДанных.СозданоЗадач = 1;
КонецЕсли;
КонецЕсли;
Если СтрокаДанныхЖурналаРегистрации.Событие = "_$Data$_.Update" Тогда
Если СтрНайти(СобытиеМетаданные, "БизнесПроцесс.") > 0 И ВыводитьБизнесПроцессы Тогда
СтрокаИсходныхДанных = ИсходныеДанные.Добавить();
СтрокаИсходныхДанных.ИзмененоБизнесПроцессов = 1;
КонецЕсли;
Если СтрНайти(СобытиеМетаданные, "Задача.") > 0 И ВыводитьЗадачи Тогда
СтрокаИсходныхДанных = ИсходныеДанные.Добавить();
СтрокаИсходныхДанных.ИзмененоЗадач = 1;
КонецЕсли;
КонецЕсли;
Если СтрокаИсходныхДанных <> Неопределено Тогда
СтрокаИсходныхДанных.Дата = СтрокаДанныхЖурналаРегистрации.Дата;
СтрокаИсходныхДанных.Неделя = СтрокаНеделяГода(СтрокаДанныхЖурналаРегистрации.Дата);
СтрокаИсходныхДанных.ВидОбъекта = СтрокаДанныхЖурналаРегистрации.ПредставлениеМетаданных;
СтрокаИсходныхДанных.ОбъектСправочникДокумент = СтрокаДанныхЖурналаРегистрации.Данные;
СтрокаИсходныхДанных.Пользователь = ИмяПользователяСсылка;
ЗаполнитьЗначенияСвойств(СтрокаИсходныхДанных, ПодразделениеПользователяИБ);
КонецЕсли;
КонецЦикла;
Для Каждого Сеанс Из Сеансы Цикл
Если Сеанс.СобытиеНачала <> Неопределено Тогда
Начало = Сеанс.СобытиеНачала.Дата;
ИначеЕсли ЗначениеЗаполнено(Сеанс.ДатаПервогоСобытияСеанса) Тогда
Начало = Сеанс.ДатаПервогоСобытияСеанса;
Иначе
Начало = Сеанс.СобытиеЗавершения.Дата;
КонецЕсли;
Если Сеанс.СобытиеЗавершения <> Неопределено Тогда
Завершение = Сеанс.СобытиеЗавершения.Дата;
ИначеЕсли ЗначениеЗаполнено(Сеанс.ДатаПоследнегоСобытияСеанса) Тогда
Завершение = Сеанс.ДатаПоследнегоСобытияСеанса;
Иначе
Завершение = Начало;
КонецЕсли;
КоличествоЗапусков = 1;
Продолжать = Истина;
Пока Продолжать Цикл
Дата = Начало;
Если НачалоДня(Начало) < НачалоДня(Завершение) Тогда
Начало = НачалоДня(Начало) + 86400;
ЧасовРаботы = (Начало - Дата) / 3600;
Иначе
Продолжать = Ложь;
ЧасовРаботы = (Завершение - Начало) / 3600;
КонецЕсли;
СтрокаИсходныхДанных = ИсходныеДанные.Добавить();
СтрокаИсходныхДанных.Дата = Дата;
СтрокаИсходныхДанных.Неделя = СтрокаНеделяГода(Дата);
СтрокаИсходныхДанных.Пользователь = Сеанс.Пользователь;
СтрокаИсходныхДанных.Подразделение = Сеанс.Подразделение;
СтрокаИсходныхДанных.ПодразделениеПредставление = Сеанс.ПодразделениеПредставление;
СтрокаИсходныхДанных.КоличествоЗапусков = КоличествоЗапусков;
СтрокаИсходныхДанных.ЧасовРаботы = ?(ЧасовРаботы = 0, 0.0001, ЧасовРаботы);
КоличествоЗапусков = 0;
КонецЦикла;
КонецЦикла;
Если ВариантОтчета = "АнализАктивностиПользователей" Тогда
МассивПользователей = Новый Массив;
МаксМассивПользователей = Новый Массив;
ОдновременноРаботавшихПользователей = 0;
Счетчик = 0;
ТекущаяДата = Неопределено;
Для Каждого СтрокаДанныхЖурналаРегистрации Из ДанныеЖурналаРегистрации Цикл
Если Не ЗначениеЗаполнено(СтрокаДанныхЖурналаРегистрации.Дата) Тогда
Продолжить;
КонецЕсли;
ИмяПользователяСсылка = СоответствиеИдентификаторыПользователей[СтрокаДанныхЖурналаРегистрации.Пользователь];
Если ИмяПользователяСсылка = Неопределено Тогда
Продолжить;
КонецЕсли;
ДатаОдновременноРаботавшихПользователей = НачалоДня(СтрокаДанныхЖурналаРегистрации.Дата);
Если ТекущаяДата <> ДатаОдновременноРаботавшихПользователей Тогда
Если ОдновременноРаботавшихПользователей <> 0 Тогда
СформироватьСтрокуОдновременноСессий(ОдновременноСессий, МаксМассивПользователей,
ОдновременноРаботавшихПользователей, ТекущаяДата);
КонецЕсли;
ОдновременноРаботавшихПользователей = 0;
Счетчик = 0;
МассивПользователей.Очистить();
ТекущаяДата = ДатаОдновременноРаботавшихПользователей;
КонецЕсли;
Если СтрокаДанныхЖурналаРегистрации.Событие = "_$Session$_.Start" Тогда
Счетчик = Счетчик + 1;
МассивПользователей.Добавить(ИмяПользователяСсылка);
ИначеЕсли СтрокаДанныхЖурналаРегистрации.Событие = "_$Session$_.Finish" Тогда
ИндексПользователя = МассивПользователей.Найти(ИмяПользователяСсылка);
Если Не ИндексПользователя = Неопределено Тогда
МассивПользователей.Удалить(ИндексПользователя);
Счетчик = Счетчик - 1;
КонецЕсли;
КонецЕсли;
Счетчик = Макс(Счетчик, 0);
Если Счетчик > ОдновременноРаботавшихПользователей Тогда
МаксМассивПользователей = Новый Массив;
Для Каждого Элемент Из МассивПользователей Цикл
МаксМассивПользователей.Добавить(Элемент);
КонецЦикла;
КонецЕсли;
ОдновременноРаботавшихПользователей = Макс(ОдновременноРаботавшихПользователей, Счетчик);
КонецЦикла;
Если ОдновременноРаботавшихПользователей <> 0 Тогда
СформироватьСтрокуОдновременноСессий(ОдновременноСессий, МаксМассивПользователей,
ОдновременноРаботавшихПользователей, ТекущаяДата);
КонецЕсли;
ДанныеЖурналаРегистрации = ИнформацияПоОшибкамЖурналаРегистрации(ДатаНачала,
ДатаОкончания, СмещениеВремениСервера, ПользовательФильтр);
ОтчетПустой = ОтчетПустой Или (ДанныеЖурналаРегистрации.Количество() = 0);
Для Каждого СтрокаДанныхЖурналаРегистрации Из ДанныеЖурналаРегистрации Цикл
ИмяПользователяСсылка = СоответствиеИдентификаторыПользователей[СтрокаДанныхЖурналаРегистрации.Пользователь];
Если ИмяПользователяСсылка = Неопределено Тогда
Продолжить;
КонецЕсли;
Если СтрокаДанныхЖурналаРегистрации.Уровень = УровеньЖурналаРегистрации.Ошибка Тогда
СтрокаИсходныхДанных = ИсходныеДанные.Добавить();
СтрокаИсходныхДанных.Ошибок = 1;
КонецЕсли;
Если СтрокаДанныхЖурналаРегистрации.Уровень = УровеньЖурналаРегистрации.Предупреждение Тогда
СтрокаИсходныхДанных = ИсходныеДанные.Добавить();
СтрокаИсходныхДанных.Предупреждений = 1;
КонецЕсли;
Если СтрокаИсходныхДанных <> Неопределено Тогда
СтрокаИсходныхДанных.Дата = СтрокаДанныхЖурналаРегистрации.Дата;
СтрокаИсходныхДанных.Неделя = СтрокаНеделяГода(СтрокаДанныхЖурналаРегистрации.Дата);
СтрокаИсходныхДанных.Пользователь = ИмяПользователяСсылка;
Если ПодразделенияПользователей <> Неопределено Тогда
ЗаполнитьПодразделениеПользователяИБ(СтрокаИсходныхДанных, СтрокаДанныхЖурналаРегистрации.Дата,
СтрокаДанныхЖурналаРегистрации.Пользователь, ПодразделенияПользователей);
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Возврат Новый Структура("АнализАктивностиПользователей, ОдновременноСессий, ОтчетПустой",
ИсходныеДанные, ОдновременноСессий, ОтчетПустой);
КонецФункции
#Область АнализАктивностиПользователей
Процедура ЗаполнитьПользователейДляАнализа(ПользовательФильтр, ЗначениеОтбора)
Если ТипЗнч(ЗначениеОтбора) = Тип("СписокЗначений") Тогда
ПользователиИГруппы = ЗначениеОтбора.ВыгрузитьЗначения();
Иначе
ПользователиИГруппы = ОбщегоНазначенияКлиентСервер.ЗначениеВМассиве(ЗначениеОтбора);
КонецЕсли;
ГруппыДляПолученияПользователей = Новый Массив;
ГруппаВсеПользователи = Пользователи.ГруппаВсеПользователи();
Для Каждого ПользовательИлиГруппа Из ПользователиИГруппы Цикл
Если ТипЗнч(ПользовательИлиГруппа) = Тип("СправочникСсылка.Пользователи") Тогда
ПользовательДляОтбора = ПользовательДляОтбора(ПользовательИлиГруппа);
Если ПользовательДляОтбора <> Неопределено Тогда
ПользовательФильтр.Добавить(ПользовательДляОтбора);
КонецЕсли;
ИначеЕсли ПользовательИлиГруппа = ГруппаВсеПользователи Тогда
ПользовательФильтр = Новый Массив;
ПользовательФильтр.Добавить("ВсеПользователи");
Возврат;
ИначеЕсли ТипЗнч(ПользовательИлиГруппа) = Тип("СправочникСсылка.ГруппыПользователей") Тогда
ГруппыДляПолученияПользователей.Добавить(ПользовательИлиГруппа);
КонецЕсли;
КонецЦикла;
Если ГруппыДляПолученияПользователей.Количество() > 0 Тогда
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("Группа", ГруппыДляПолученияПользователей);
Запрос.Текст =
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| СоставыГруппПользователей.Пользователь КАК Пользователь
|ИЗ
| РегистрСведений.СоставыГруппПользователей КАК СоставыГруппПользователей
|ГДЕ
| СоставыГруппПользователей.ГруппаПользователей В
| (ВЫБРАТЬ
| ГруппыПользователей.Ссылка КАК Ссылка
| ИЗ
| Справочник.ГруппыПользователей КАК ГруппыПользователей
| ГДЕ
| ГруппыПользователей.Ссылка В ИЕРАРХИИ (&Группа))";
Результат = Запрос.Выполнить().Выгрузить();
Для Каждого Строка Из Результат Цикл
ПользовательДляОтбора = ПользовательДляОтбора(Строка.Пользователь);
Если ПользовательДляОтбора <> Неопределено Тогда
ПользовательФильтр.Добавить(ПользовательДляОтбора);
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Функция ПодразделенияПользователей(ДатаНачала, СмещениеВремениСервера, Знач ВыбранныеПодразделения)
ОтборЖурнала = Новый Структура;
ОтборЖурнала.Вставить("ДатаНачала", ДатаНачала + СмещениеВремениСервера);
ОтборЖурнала.Вставить("Событие", ПользователиСлужебный.ИмяСобытияИзменениеДополнительноДляЖурналаРегистрации());
ДанныеЖурнала = Новый ТаблицаЗначений;
ВыгрузитьЖурналРегистрации(ДанныеЖурнала, ОтборЖурнала, "Дата, Данные");
ИзмененияПодразделений = Новый Соответствие;
ПользователиВыбранныхПодразделений = Новый Соответствие;
Если ВыбранныеПодразделения = Неопределено Тогда
ВыбранныеПодразделения = Новый Массив;
КонецЕсли;
Для Каждого СтрокаТаблицы Из ДанныеЖурнала Цикл
ДанныеСобытия = СтрокаТаблицы.Данные;
Если Не ЗначениеЗаполнено(ДанныеСобытия) Тогда
Продолжить;
КонецЕсли;
СтрокаТаблицы.Дата = СтрокаТаблицы.Дата - СмещениеВремениСервера;
Попытка
Данные = ОбщегоНазначения.ЗначениеИзСтрокиXML(ДанныеСобытия);
Исключение
Продолжить;
КонецПопытки;
Если ТипЗнч(Данные) <> Тип("Структура") Тогда
Продолжить;
КонецЕсли;
ХранениеВерсии = Новый Структура;
ХранениеВерсии.Вставить("ВерсияСтруктурыДанных");
ЗаполнитьЗначенияСвойств(ХранениеВерсии, Данные);
Если ХранениеВерсии.ВерсияСтруктурыДанных <> 2 Тогда
Продолжить;
КонецЕсли;
ОписаниеСтарогоПодразделения = Неопределено;
СтарыйИдентификаторПользователяИБ = Неопределено;
Попытка
ИдентификаторПользователяИБ = Новый УникальныйИдентификатор(
Данные.ИдентификаторПользователяИБ);
ОписаниеПодразделения = ОписаниеПодразделения(Данные);
Если Данные.СтарыеЗначенияСвойств.Свойство("Подразделение") Тогда
ОписаниеСтарогоПодразделения = ОписаниеПодразделения(Данные.СтарыеЗначенияСвойств);
Если Данные.СтарыеЗначенияСвойств.Свойство("ИдентификаторПользователяИБ") Тогда
СтарыйИдентификаторПользователяИБ = Новый УникальныйИдентификатор(
Данные.СтарыеЗначенияСвойств.ИдентификаторПользователяИБ);
КонецЕсли;
Если Не ЗначениеЗаполнено(СтарыйИдентификаторПользователяИБ) Тогда
СтарыйИдентификаторПользователяИБ = ИдентификаторПользователяИБ;
КонецЕсли;
КонецЕсли;
Исключение
Продолжить;
КонецПопытки;
Если Не ЗначениеЗаполнено(ИдентификаторПользователяИБ) Тогда
Продолжить;
КонецЕсли;
ТекущиеИзменения = ИзмененияПодразделений.Получить(ИдентификаторПользователяИБ);
Если ТекущиеИзменения = Неопределено Тогда
ТекущиеИзменения = Новый Массив;
ИзмененияПодразделений.Вставить(ИдентификаторПользователяИБ, ТекущиеИзменения);
КонецЕсли;
ОписаниеИзменения = ОписаниеИзмененияПодразделения(СтрокаТаблицы.Дата, ОписаниеПодразделения);
ТекущиеИзменения.Добавить(ОписаниеИзменения);
Если ВыбранныеПодразделения.Найти(ОписаниеПодразделения.Подразделение) <> Неопределено
И (ОписаниеПодразделения.Подразделение <> Неопределено
Или Не ЗначениеЗаполнено(ОписаниеПодразделения.ПодразделениеСтрока)) Тогда
ПользователиВыбранныхПодразделений.Вставить(ИдентификаторПользователяИБ);
КонецЕсли;
Если ОписаниеСтарогоПодразделения = Неопределено Тогда
Продолжить;
КонецЕсли;
Если ВыбранныеПодразделения.Найти(ОписаниеСтарогоПодразделения.Подразделение) <> Неопределено
И (ОписаниеСтарогоПодразделения.Подразделение <> Неопределено
Или Не ЗначениеЗаполнено(ОписаниеСтарогоПодразделения.ПодразделениеСтрока)) Тогда
ПользователиВыбранныхПодразделений.Вставить(СтарыйИдентификаторПользователяИБ);
КонецЕсли;
Если ИдентификаторПользователяИБ = СтарыйИдентификаторПользователяИБ Тогда
ОписаниеИзменения.Старое = ОписаниеСтарогоПодразделения;
Продолжить;
КонецЕсли;
ТекущиеИзменения = ИзмененияПодразделений.Получить(СтарыйИдентификаторПользователяИБ);
Если ТекущиеИзменения = Неопределено Тогда
ТекущиеИзменения = Новый Массив;
ИзмененияПодразделений.Вставить(СтарыйИдентификаторПользователяИБ, ТекущиеИзменения);
КонецЕсли;
ОписаниеИзменения = ОписаниеИзмененияПодразделения(СтрокаТаблицы.Дата,, ОписаниеСтарогоПодразделения);
ТекущиеИзменения.Добавить(ОписаниеИзменения);
КонецЦикла;
Результат = Новый Структура;
Результат.Вставить("Текущие", Новый Соответствие);
Результат.Вставить("Изменения", ИзмененияПодразделений);
Результат.Вставить("ПользователиВыбранныхПодразделений", ПользователиВыбранныхПодразделений);
Возврат Результат;
КонецФункции
Функция ОписаниеПодразделения(Данные)
Подразделение = ?(ТипЗнч(Данные.Подразделение) = Тип("Строка"),
Данные.Подразделение, Неопределено);
Результат = Новый Структура;
Результат.Вставить("Подразделение", ?(ЗначениеЗаполнено(Подразделение),
ЗначениеИзСтрокиВнутр(Подразделение), Неопределено));
Результат.Вставить("ПодразделениеСтрока", Подразделение);
Результат.Вставить("ПодразделениеПредставление", Данные.ПодразделениеПредставление);
Возврат Результат;
КонецФункции
Функция ОписаниеИзмененияПодразделения(Дата, Новое = Неопределено, Старое = Неопределено)
Возврат Новый Структура("Дата, Новое, Старое", Дата, Новое, Старое);
КонецФункции
Процедура ЗаполнитьПользователейДляАнализаИзПодразделения(ПользовательФильтр,
ВыбранныеПодразделения, ПодразделенияПользователей)
Если ВыбранныеПодразделения = Неопределено Тогда
ПользовательФильтр.Добавить("ВсеПользователи");
ДобавитьТекущиеПодразделенияПользователей(ПодразделенияПользователей);
Возврат;
КонецЕсли;
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("Подразделение", ВыбранныеПодразделения);
Запрос.УстановитьПараметр("ПустойУникальныйИдентификатор",
ОбщегоНазначенияКлиентСервер.ПустойУникальныйИдентификатор());
Запрос.Текст =
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| Пользователи.ИдентификаторПользователяИБ КАК ИдентификаторПользователяИБ
|ИЗ
| Справочник.Пользователи КАК Пользователи
|ГДЕ
| Пользователи.Подразделение В(&Подразделение)
| И Пользователи.ИдентификаторПользователяИБ <> &ПустойУникальныйИдентификатор";
Выгрузка = Запрос.Выполнить().Выгрузить();
Выгрузка.Индексы.Добавить("ИдентификаторПользователяИБ");
Для Каждого КлючИЗначение Из ПодразделенияПользователей.ПользователиВыбранныхПодразделений Цикл
Если Выгрузка.Найти(КлючИЗначение.Ключ, "ИдентификаторПользователяИБ") = Неопределено Тогда
Выгрузка.Добавить().ИдентификаторПользователяИБ = КлючИЗначение.Ключ;
КонецЕсли;
КонецЦикла;
УстановитьПривилегированныйРежим(Истина);
Для Каждого СтрокаТаблицы Из Выгрузка Цикл
ПользовательФильтр.Добавить(ПользовательДляОтбора(,
СтрокаТаблицы.ИдентификаторПользователяИБ));
КонецЦикла;
КонецПроцедуры
Функция ВыбранныеПодразделения(ЗначениеОтбора)
Если ЗначениеОтбора = Неопределено Тогда
Возврат Неопределено;
ИначеЕсли ТипЗнч(ЗначениеОтбора) = Тип("СписокЗначений") Тогда
Результат = ЗначениеОтбора.ВыгрузитьЗначения();
Иначе
Результат = ОбщегоНазначенияКлиентСервер.ЗначениеВМассиве(ЗначениеОтбора);
КонецЕсли;
ПустыеЗначения = Новый Массив;
ПустыеЗначения.Добавить(Неопределено);
Для Каждого Тип Из Метаданные.Справочники.Пользователи.Реквизиты.Подразделение.Тип.Типы() Цикл
ОписаниеТипа = Новый ОписаниеТипов(ОбщегоНазначенияКлиентСервер.ЗначениеВМассиве(Тип));
ПустыеЗначения.Добавить(ОписаниеТипа.ПривестиЗначение(Неопределено));
КонецЦикла;
ЕстьПустоеЗначение = Ложь;
Для Каждого ПустоеЗначение Из ПустыеЗначения Цикл
Если Результат.Найти(ПустоеЗначение) <> Неопределено Тогда
ЕстьПустоеЗначение = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
Если Не ЕстьПустоеЗначение Тогда
Возврат Результат;
КонецЕсли;
Для Каждого ПустоеЗначение Из ПустыеЗначения Цикл
Если Результат.Найти(ПустоеЗначение) = Неопределено Тогда
Результат.Добавить(ПустоеЗначение);
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
Процедура ДобавитьТекущиеПодразделенияПользователей(ПодразделенияПользователей, ИдентификаторыПользователейИБ = Неопределено)
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("ИдентификаторыПользователейИБ", ИдентификаторыПользователейИБ);
Запрос.УстановитьПараметр("ПустойУникальныйИдентификатор",
ОбщегоНазначенияКлиентСервер.ПустойУникальныйИдентификатор());
Запрос.Текст =
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| Пользователи.ИдентификаторПользователяИБ КАК ИдентификаторПользователяИБ,
| Пользователи.Подразделение КАК Подразделение
|ИЗ
| Справочник.Пользователи КАК Пользователи
|ГДЕ
| Пользователи.ИдентификаторПользователяИБ В(&ИдентификаторыПользователейИБ)";
Если ИдентификаторыПользователейИБ = Неопределено Тогда
Запрос.Текст = СтрЗаменить(Запрос.Текст,
"Пользователи.ИдентификаторПользователяИБ В(&ИдентификаторыПользователейИБ)",
"Пользователи.ИдентификаторПользователяИБ <> &ПустойУникальныйИдентификатор");
КонецЕсли;
Выборка = Запрос.Выполнить().Выбрать();
ИзмененияПодразделений = ПодразделенияПользователей.Изменения;
Пока Выборка.Следующий() Цикл
ОписаниеПодразделения = Новый Структура;
ОписаниеПодразделения.Вставить("Подразделение", Выборка.Подразделение);
ОписаниеПодразделения.Вставить("ПодразделениеСтрока", "");
ОписаниеПодразделения.Вставить("ПодразделениеПредставление", Строка(Выборка.Подразделение));
ТекущиеИзменения = ИзмененияПодразделений.Получить(Выборка.ИдентификаторПользователяИБ);
Если ТекущиеИзменения = Неопределено Тогда
ТекущиеИзменения = Новый Массив;
ИзмененияПодразделений.Вставить(Выборка.ИдентификаторПользователяИБ, ТекущиеИзменения);
КонецЕсли;
ОписаниеИзменения = ОписаниеИзмененияПодразделения('39991231',, ОписаниеПодразделения);
ТекущиеИзменения.Добавить(ОписаниеИзменения);
КонецЦикла;
КонецПроцедуры
Процедура ЗаполнитьПодразделениеПользователяИБ(СтрокаИсходныхДанных, Дата, ИдентификаторПользователяИБ,
ПодразделенияПользователей)
ОписаниеПодразделения = ПодразделенияПользователей.Текущие.Получить(ИдентификаторПользователяИБ);
ТекущиеИзменения = ПодразделенияПользователей.Изменения.Получить(ИдентификаторПользователяИБ);
Обновить = Ложь;
Если ТекущиеИзменения.Количество() > 0 Тогда
Пока ЗначениеЗаполнено(ТекущиеИзменения) И Дата >= ТекущиеИзменения[0].Дата Цикл
ПредыдущееОписаниеИзменения = ТекущиеИзменения[0];
ТекущиеИзменения.Удалить(0);
Обновить = Истина;
КонецЦикла;
Если Обновить Тогда
Если ПредыдущееОписаниеИзменения.Новое <> Неопределено
Или Не ЗначениеЗаполнено(ТекущиеИзменения) Тогда
ОписаниеПодразделения = ПредыдущееОписаниеИзменения.Новое;
Иначе
ОписаниеПодразделения = ТекущиеИзменения[0].Старое;
КонецЕсли;
ИначеЕсли ОписаниеПодразделения = Неопределено Тогда
ОписаниеПодразделения = ТекущиеИзменения[0].Старое;
Обновить = Истина;
КонецЕсли;
КонецЕсли;
Если Обновить Тогда
ПодразделенияПользователей.Текущие.Вставить(ИдентификаторПользователяИБ, ОписаниеПодразделения);
КонецЕсли;
Если ОписаниеПодразделения = Неопределено
Или Не ЗначениеЗаполнено(ОписаниеПодразделения.Подразделение)
И Не ЗначениеЗаполнено(ОписаниеПодразделения.ПодразделениеПредставление) Тогда
СтрокаИсходныхДанных.ПодразделениеПредставление = "<" + НСтр("ru = 'Не указано'") + ">";
Возврат;
КонецЕсли;
Если ОписаниеПодразделения.Подразделение <> Неопределено Тогда
СтрокаИсходныхДанных.Подразделение = ОписаниеПодразделения.Подразделение;
СтрокаИсходныхДанных.ПодразделениеПредставление = ОписаниеПодразделения.ПодразделениеПредставление;
Иначе
СтрокаИсходныхДанных.Подразделение = ОписаниеПодразделения.ПодразделениеСтрока;
СтрокаИсходныхДанных.ПодразделениеПредставление = ОписаниеПодразделения.ПодразделениеПредставление;
КонецЕсли;
КонецПроцедуры
Функция УникальныеИдентификаторыПользователей(ДанныеЖурналаРегистрации, ВыводитьСлужебныхПользователей)
ТаблицаПользователей = ДанныеЖурналаРегистрации.Скопировать(, "Пользователь, ИмяПользователя");
ТаблицаПользователей.Индексы.Добавить("Пользователь, ИмяПользователя");
ТаблицаПользователей.Свернуть("Пользователь, ИмяПользователя");
СоответствиеУИД = Новый Соответствие;
Отбор = Новый Структура("Пользователь", ОбщегоНазначенияКлиентСервер.ПустойУникальныйИдентификатор());
НайденныеСтроки = ТаблицаПользователей.НайтиСтроки(Отбор);
Для Каждого НайденнаяСтрока Из НайденныеСтроки Цикл
Если Не ЗначениеЗаполнено(НайденнаяСтрока.ИмяПользователя) И ВыводитьСлужебныхПользователей Тогда
СоответствиеУИД.Вставить(НайденныеСтроки[0].Пользователь,
Пользователи.СсылкаНеуказанногоПользователя());
КонецЕсли;
ТаблицаПользователей.Удалить(НайденныеСтроки[0]);
КонецЦикла;
ИдентификаторыПользователейИБ = ТаблицаПользователей.ВыгрузитьКолонку("Пользователь");
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("ИдентификаторыПользователейИБ", ИдентификаторыПользователейИБ);
Запрос.Текст =
"ВЫБРАТЬ
| Пользователи.Ссылка КАК Ссылка,
| Пользователи.Служебный КАК Служебный,
| Пользователи.ИдентификаторПользователяИБ КАК ИдентификаторПользователяИБ
|ИЗ
| Справочник.Пользователи КАК Пользователи
|ГДЕ
| Пользователи.ИдентификаторПользователяИБ В(&ИдентификаторыПользователейИБ)
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
| Пользователи.Ссылка,
| ЛОЖЬ,
| Пользователи.ИдентификаторПользователяИБ
|ИЗ
| Справочник.ВнешниеПользователи КАК Пользователи
|ГДЕ
| Пользователи.ИдентификаторПользователяИБ В(&ИдентификаторыПользователейИБ)";
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
Если Не Выборка.Служебный Или ВыводитьСлужебныхПользователей Тогда
СоответствиеУИД.Вставить(Выборка.ИдентификаторПользователяИБ, Выборка.Ссылка);
КонецЕсли;
Строка = ТаблицаПользователей.Найти(Выборка.ИдентификаторПользователяИБ, "Пользователь");
ТаблицаПользователей.Удалить(Строка);
КонецЦикла;
Если Не ВыводитьСлужебныхПользователей Тогда
Возврат СоответствиеУИД;
КонецЕсли;
Для Каждого Строка Из ТаблицаПользователей Цикл
Если ЗначениеЗаполнено(Строка.ИмяПользователя) Тогда
СоответствиеУИД.Вставить(Строка.Пользователь, Строка.ИмяПользователя);
Иначе
СоответствиеУИД.Вставить(Строка.Пользователь, Строка(Строка.Пользователь));
КонецЕсли;
КонецЦикла;
Возврат СоответствиеУИД;
КонецФункции
Функция ПользовательДляОтбора(ПользовательСсылка = "", ИдентификаторПользователяИБ = Неопределено) Экспорт
УстановитьПривилегированныйРежим(Истина);
Если ПользовательСсылка <> "" Тогда
ИдентификаторПользователяИБ = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(ПользовательСсылка,
"ИдентификаторПользователяИБ");
КонецЕсли;
Если ЗначениеЗаполнено(ИдентификаторПользователяИБ) Тогда
Возврат ЖурналРегистрации.ПользовательИБДляОтбора(ИдентификаторПользователяИБ);
КонецЕсли;
Если ПользовательСсылка = Пользователи.СсылкаНеуказанногоПользователя() Тогда
Возврат ПользователиИнформационнойБазы.НайтиПоИмени("");
КонецЕсли;
Возврат Неопределено;
КонецФункции
Функция СтрокаНеделяГода(ДатаГода)
Возврат СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = 'Неделя %1'"), НеделяГода(ДатаГода));
КонецФункции
Процедура СформироватьСтрокуОдновременноСессий(ОдновременноСессий, МаксМассивПользователей,
ОдновременноРаботавшихПользователей, ТекущаяДата)
ВременныйМассив = Новый Массив;
Индекс = 0;
Для Каждого Элемент Из МаксМассивПользователей Цикл
ВременныйМассив.Вставить(Индекс, Элемент);
СчетчикКоличестваСеансовПользователя = 0;
Для Каждого ТекущийПользователь Из ВременныйМассив Цикл
Если ТекущийПользователь = Элемент Тогда
СчетчикКоличестваСеансовПользователя = СчетчикКоличестваСеансовПользователя + 1;
ПользовательИНомер = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = '%1 (%2)'"),
Элемент,
СчетчикКоличестваСеансовПользователя);
КонецЕсли;
КонецЦикла;
СтрокаТаблицы = ОдновременноСессий.Добавить();
СтрокаТаблицы.ДатаОдновременноРаботавшихПользователей = ТекущаяДата;
СтрокаТаблицы.ОдновременноРаботавшихПользователей = ОдновременноРаботавшихПользователей;
СтрокаТаблицы.СписокОдновременноРаботавшихПользователей = ПользовательИНомер;
Индекс = Индекс + 1;
КонецЦикла;
КонецПроцедуры
#КонецОбласти
#Область ПродолжительностьРаботыРегламентныхЗаданий
Функция СформироватьОтчетПоПродолжительностиРаботыРегламентныхЗаданий(ПараметрыЗаполнения) Экспорт
ДатаНачала = ПараметрыЗаполнения.ДатаНачала;
ДатаОкончания = ПараметрыЗаполнения.ДатаОкончания;
МинимальнаяПродолжительностьСеансовРегламентныхЗаданий =
ПараметрыЗаполнения.МинимальнаяПродолжительностьСеансовРегламентныхЗаданий;
ВыводитьЗаголовок = ПараметрыЗаполнения.ВыводитьЗаголовок;
ВыводитьОтбор = ПараметрыЗаполнения.ВыводитьОтбор;
Результат = Новый Структура;
Отчет = Новый ТабличныйДокумент;
ПолучитьДанные = ДанныеДляОтчетаПоПродолжительностиРаботыРегламентныхЗаданий(ПараметрыЗаполнения);
ТаблицаСеансыРегламентныхЗаданий = ПолучитьДанные.ТаблицаСеансыРегламентныхЗаданий;
ОдновременноСессий = ПолучитьДанные.ИтогоОдновременноРегламентныхЗаданий;
КоличествоЗапусков = ПолучитьДанные.КоличествоЗапусков;
ОтчетПустой = ПолучитьДанные.ОтчетПустой;
Макет = ПолучитьМакет("ПродолжительностьРаботыРегламентныхЗаданий");
ЦветаФона = Новый Массив;
ЦветаФона.Добавить(WebЦвета.Белый);
ЦветаФона.Добавить(WebЦвета.СветлоЖелтый);
ЦветаФона.Добавить(WebЦвета.Лимонный);
ЦветаФона.Добавить(WebЦвета.НавахоБелый);
Если ВыводитьЗаголовок.Значение = ТипВыводаТекстаКомпоновкиДанных.Выводить
И ВыводитьЗаголовок.Использование
ИЛИ Не ВыводитьЗаголовок.Использование Тогда
Отчет.Вывести(ОписаниеОбластиМакета(Макет, "ШапкаОтчета"));
КонецЕсли;
Если ВыводитьОтбор.Значение = ТипВыводаТекстаКомпоновкиДанных.Выводить
И ВыводитьОтбор.Использование
Или Не ВыводитьОтбор.Использование Тогда
Область = ОписаниеОбластиМакета(Макет, "Отбор");
Если МинимальнаяПродолжительностьСеансовРегламентныхЗаданий > 0 Тогда
РежимОтображенияИнтервалов = НСтр("ru = 'Отключено отображение интервалов с нулевой продолжительностью'");
Иначе
РежимОтображенияИнтервалов = НСтр("ru = 'Включено отображение интервалов с нулевой продолжительностью'");
КонецЕсли;
Область.Параметры.ДатаНачала = ДатаНачала;
Область.Параметры.ДатаОкончания = ДатаОкончания;
Область.Параметры.РежимОтображенияИнтервалов = РежимОтображенияИнтервалов;
Отчет.Вывести(Область);
КонецЕсли;
Если ЗначениеЗаполнено(ОдновременноСессий) Тогда
Отчет.Вывести(ОписаниеОбластиМакета(Макет, "ШапкаТаблицы"));
ТекущееКоличествоСессий = 0;
ИндексЦвета = 3;
Для Каждого СтрокаОдновременноСессий Из ОдновременноСессий Цикл
Область = ОписаниеОбластиМакета(Макет, "Таблица");
Если ТекущееКоличествоСессий <> 0
И ТекущееКоличествоСессий <> СтрокаОдновременноСессий.ОдновременноРегламентныхЗаданий
И ИндексЦвета <> 0 Тогда
ИндексЦвета = ИндексЦвета - 1;
КонецЕсли;
Если СтрокаОдновременноСессий.ОдновременноРегламентныхЗаданий = 1 Тогда
ИндексЦвета = 0;
КонецЕсли;
Область.Параметры.Заполнить(СтрокаОдновременноСессий);
ЦветФонаТаблицы = ЦветаФона.Получить(ИндексЦвета);
ОбластьТаблицы = Область.Области.Таблица;
ОбластьТаблицы.ЦветФона = ЦветФонаТаблицы;
Отчет.Вывести(Область);
ТекущееКоличествоСессий = СтрокаОдновременноСессий.ОдновременноРегламентныхЗаданий;
МассивРегламентныхЗаданий = СтрокаОдновременноСессий.СписокРегламентныхЗаданий;
ИндексРегламентногоЗадания = 0;
Отчет.НачатьГруппуСтрок(, Ложь);
Для Каждого Элемент Из МассивРегламентныхЗаданий Цикл
Если Не ТипЗнч(Элемент) = Тип("Число")
И Не ТипЗнч(Элемент) = Тип("Дата") Тогда
Область = ОписаниеОбластиМакета(Макет, "СписокРегламентныхЗаданий");
Область.Параметры.СписокРегламентныхЗаданий = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = '%1 (сеанс %2)'"),
Элемент,
МассивРегламентныхЗаданий[ИндексРегламентногоЗадания+1]);
ИначеЕсли Не ТипЗнч(Элемент) = Тип("Дата")
И Не ТипЗнч(Элемент) = Тип("Строка") Тогда
Область.Параметры.РасшифровкаЗадания = Новый Массив;
Область.Параметры.РасшифровкаЗадания.Добавить("РасшифровкаРегламентногоЗадания");
Область.Параметры.РасшифровкаЗадания.Добавить(Элемент);
ИмяРегламентногоЗадания = МассивРегламентныхЗаданий.Получить(ИндексРегламентногоЗадания-1);
Область.Параметры.РасшифровкаЗадания.Добавить(ИмяРегламентногоЗадания);
Область.Параметры.РасшифровкаЗадания.Добавить(ДатаНачала);
Область.Параметры.РасшифровкаЗадания.Добавить(ДатаОкончания);
Отчет.Вывести(Область);
КонецЕсли;
ИндексРегламентногоЗадания = ИндексРегламентногоЗадания + 1;
КонецЦикла;
Отчет.ЗакончитьГруппуСтрок();
КонецЦикла;
КонецЕсли;
Отчет.Вывести(ОписаниеОбластиМакета(Макет, "ПустаяСтрока"));
Область = ОписаниеОбластиМакета(Макет, "Диаграмма");
ДиаграммаГанта = Область.Рисунки.ДиаграммаГанта.Объект;
ДиаграммаГанта.Обновление = Ложь;
Серия = ДиаграммаГанта.Серии.Добавить();
ТекущееСобытие = Неопределено;
ОбщаяПродолжительностьРЗ = 0;
Точка = Неопределено;
СтрокаКоличествоЗапусков = Неопределено;
ЗапусковРегламентногоЗадания = 0;
ПризнакСменыТочки = Ложь;
Для Каждого СтрокаРегламентныеЗадания Из ТаблицаСеансыРегламентныхЗаданий Цикл
ДлительностьИнтервалаРегламентногоЗадания =
СтрокаРегламентныеЗадания.ДатаОкончанияЗадания - СтрокаРегламентныеЗадания.ДатаЗапускаЗадания;
Если ДлительностьИнтервалаРегламентногоЗадания >= МинимальнаяПродолжительностьСеансовРегламентныхЗаданий Тогда
Если ТекущееСобытие <> СтрокаРегламентныеЗадания.НазваниеСобытия Тогда
Если ТекущееСобытие <> Неопределено
И ПризнакСменыТочки Тогда
РасшифровкаТочки = Точка.Расшифровка;
РасшифровкаТочки.Добавить(ЗапусковРегламентногоЗадания);
РасшифровкаТочки.Добавить(ОбщаяПродолжительностьРЗ);
РасшифровкаТочки.Добавить(ДатаНачала);
РасшифровкаТочки.Добавить(ДатаОкончания);
ТочкаНазвание = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = '%1 (%2 из %3)'"),
Точка.Значение,
ЗапусковРегламентногоЗадания,
Строка(СтрокаКоличествоЗапусков.Запусков));
Точка.Значение = ТочкаНазвание;
КонецЕсли;
СтрокаКоличествоЗапусков = КоличествоЗапусков.Найти(
СтрокаРегламентныеЗадания.НазваниеСобытия, "НазваниеСобытия");
Если СтрокаРегламентныеЗадания.СобытиеМетаданные <> "" Тогда
ТочкаНазвание = СтрокаРегламентныеЗадания.НазваниеСобытия;
Точка = ДиаграммаГанта.УстановитьТочку(ТочкаНазвание);
РасшифровкаТочки = Новый Массив;
ИнтервалНачало = Новый Массив;
ИнтервалКонец = Новый Массив;
СеансРегламентногоЗадания = Новый Массив;
РасшифровкаТочки.Добавить("РасшифровкаТочки");
РасшифровкаТочки.Добавить(СтрокаРегламентныеЗадания.СобытиеМетаданные);
РасшифровкаТочки.Добавить(СтрокаРегламентныеЗадания.НазваниеСобытия);
РасшифровкаТочки.Добавить(СтрокаКоличествоЗапусков.Отменено);
РасшифровкаТочки.Добавить(СтрокаКоличествоЗапусков.ОшибкаВыполнения);
РасшифровкаТочки.Добавить(ИнтервалНачало);
РасшифровкаТочки.Добавить(ИнтервалКонец);
РасшифровкаТочки.Добавить(СеансРегламентногоЗадания);
РасшифровкаТочки.Добавить(МинимальнаяПродолжительностьСеансовРегламентныхЗаданий);
Точка.Расшифровка = РасшифровкаТочки;
ТекущееСобытие = СтрокаРегламентныеЗадания.НазваниеСобытия;
ОбщаяПродолжительностьРЗ = 0;
ЗапусковРегламентногоЗадания = 0;
Точка.Картинка = БиблиотекаКартинок.РегламентноеЗадание;
ИначеЕсли Не ЗначениеЗаполнено(СтрокаРегламентныеЗадания.СобытиеМетаданные) Тогда
ТочкаНазвание = НСтр("ru = 'Фоновые задания'");
Точка = ДиаграммаГанта.УстановитьТочку(ТочкаНазвание);
ОбщаяПродолжительностьРЗ = 0;
КонецЕсли;
КонецЕсли;
Значение = ДиаграммаГанта.ПолучитьЗначение(Точка, Серия);
Интервал = Значение.Добавить();
Интервал.Начало = СтрокаРегламентныеЗадания.ДатаЗапускаЗадания;
Интервал.Конец = СтрокаРегламентныеЗадания.ДатаОкончанияЗадания;
Интервал.Текст = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = '%1 - %2'"),
Формат(Интервал.Начало, "ДЛФ=T"),
Формат(Интервал.Конец, "ДЛФ=T"));
ПризнакСменыТочки = Ложь;
Если СтрокаРегламентныеЗадания.СобытиеМетаданные <> "" Тогда
ИнтервалНачало.Добавить(СтрокаРегламентныеЗадания.ДатаЗапускаЗадания);
ИнтервалКонец.Добавить(СтрокаРегламентныеЗадания.ДатаОкончанияЗадания);
СеансРегламентногоЗадания.Добавить(СтрокаРегламентныеЗадания.Сеанс);
ОбщаяПродолжительностьРЗ = ДлительностьИнтервалаРегламентногоЗадания + ОбщаяПродолжительностьРЗ;
ЗапусковРегламентногоЗадания = ЗапусковРегламентногоЗадания + 1;
ПризнакСменыТочки = Истина;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если ЗапусковРегламентногоЗадания <> 0
И ЗначениеЗаполнено(Точка.Расшифровка) Тогда
РасшифровкаТочки = Точка.Расшифровка;
РасшифровкаТочки.Добавить(ЗапусковРегламентногоЗадания);
РасшифровкаТочки.Добавить(ОбщаяПродолжительностьРЗ);
РасшифровкаТочки.Добавить(ДатаНачала);
РасшифровкаТочки.Добавить(ДатаОкончания);
ТочкаНазвание = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = '%1 (%2 из %3)'"),
Точка.Значение,
ЗапусковРегламентногоЗадания,
Строка(СтрокаКоличествоЗапусков.Запусков));
Точка.Значение = ТочкаНазвание;
КонецЕсли;
ЦветаДиаграммыГанта(ДатаНачала, ДиаграммаГанта, ОдновременноСессий, ЦветаФона);
ПериодАнализа = ДатаОкончания - ДатаНачала;
ШкалаВремениДиаграммыГанта(ДиаграммаГанта, ПериодАнализа);
КоличествоКолонок = ДиаграммаГанта.Точки.Количество();
Область.Рисунки.ДиаграммаГанта.Высота = 15 + 10 * КоличествоКолонок;
Область.Рисунки.ДиаграммаГанта.Ширина = 450;
ДиаграммаГанта.АвтоОпределениеПолногоИнтервала = Ложь;
ДиаграммаГанта.ОтображениеИнтервала = ОтображениеИнтервалаДиаграммыГанта.Плоский;
ДиаграммаГанта.ОбластьЛегенды.Расположение = РасположениеЛегендыДиаграммы.Нет;
ДиаграммаГанта.РастягиваниеПоВертикали = РастягиваниеПоВертикалиДиаграммыГанта.РастягиватьСтрокиИДанные;
ДиаграммаГанта.УстановитьПолныйИнтервал(ДатаНачала, ДатаОкончания);
ДиаграммаГанта.Обновление = Истина;
Отчет.Вывести(Область);
Результат.Вставить("Отчет", Отчет);
Результат.Вставить("ОтчетПустой", ОтчетПустой);
Возврат Результат;
КонецФункции
Функция ДанныеДляОтчетаПоПродолжительностиРаботыРегламентныхЗаданий(ПараметрыЗаполнения)
ДатаНачала = ПараметрыЗаполнения.ДатаНачала;
ДатаОкончания = ПараметрыЗаполнения.ДатаОкончания;
РазмерОдновременноСессий = ПараметрыЗаполнения.РазмерОдновременноСессий;
ОтображатьФоновыеЗадания = ПараметрыЗаполнения.ОтображатьФоновыеЗадания;
МинимальнаяПродолжительностьСеансовРегламентныхЗаданий =
ПараметрыЗаполнения.МинимальнаяПродолжительностьСеансовРегламентныхЗаданий;
СкрытьРегламентныеЗадания = ПараметрыЗаполнения.СкрытьРегламентныеЗадания;
СмещениеВремениСервера = ПараметрыЗаполнения.СмещениеВремениСервера;
Уровни = Новый Массив;
Уровни.Добавить(УровеньЖурналаРегистрации.Информация);
Уровни.Добавить(УровеньЖурналаРегистрации.Предупреждение);
Уровни.Добавить(УровеньЖурналаРегистрации.Ошибка);
СобытияРЗ = Новый Массив;
СобытияРЗ.Добавить("_$Job$_.Start");
СобытияРЗ.Добавить("_$Job$_.Cancel");
СобытияРЗ.Добавить("_$Job$_.Fail");
СобытияРЗ.Добавить("_$Job$_.Succeed");
СобытияРЗ.Добавить("_$Job$_.Finish");
СобытияРЗ.Добавить("_$Job$_.Error");
УстановитьПривилегированныйРежим(Истина);
ОтборЖурнала = Новый Структура;
ОтборЖурнала.Вставить("Уровень", Уровни);
ОтборЖурнала.Вставить("ДатаНачала", ДатаНачала + СмещениеВремениСервера);
ОтборЖурнала.Вставить("ДатаОкончания", ДатаОкончания + СмещениеВремениСервера);
ОтборЖурнала.Вставить("Событие", СобытияРЗ);
ДанныеЖурналаРегистрации = Новый ТаблицаЗначений;
ВыгрузитьЖурналРегистрации(ДанныеЖурналаРегистрации, ОтборЖурнала);
ОтчетПустой = (ДанныеЖурналаРегистрации.Количество() = 0);
Если СмещениеВремениСервера <> 0 Тогда
Для Каждого СтрокаТаблицы Из ДанныеЖурналаРегистрации Цикл
СтрокаТаблицы.Дата = СтрокаТаблицы.Дата - СмещениеВремениСервера;
КонецЦикла;
КонецЕсли;
СписокВсехРегламентныхЗаданий = РегламентныеЗаданияСервер.НайтиЗадания(Новый Структура);
СоответствиеМетаданныеИдентификатор = Новый Соответствие;
СоответствиеМетаданныеНазвание = Новый Соответствие;
СоответствиеНаименованиеИдентификатор = Новый Соответствие;
УстановитьПривилегированныйРежим(Ложь);
Для Каждого РегЗадание Из СписокВсехРегламентныхЗаданий Цикл
СоответствиеМетаданныеИдентификатор.Вставить(РегЗадание.Метаданные, Строка(РегЗадание.УникальныйИдентификатор));
СоответствиеНаименованиеИдентификатор.Вставить(РегЗадание.Наименование, Строка(РегЗадание.УникальныйИдентификатор));
Если РегЗадание.Наименование <> "" Тогда
СоответствиеМетаданныеНазвание.Вставить(РегЗадание.Метаданные, РегЗадание.Наименование);
Иначе
СоответствиеМетаданныеНазвание.Вставить(РегЗадание.Метаданные, РегЗадание.Метаданные.Синоним);
КонецЕсли;
КонецЦикла;
ПараметрыОдновременноСессий = Новый Структура;
ПараметрыОдновременноСессий.Вставить("ДанныеЖурналаРегистрации", ДанныеЖурналаРегистрации);
ПараметрыОдновременноСессий.Вставить("СоответствиеНаименованиеИдентификатор", СоответствиеНаименованиеИдентификатор);
ПараметрыОдновременноСессий.Вставить("СоответствиеМетаданныеИдентификатор", СоответствиеМетаданныеИдентификатор);
ПараметрыОдновременноСессий.Вставить("СоответствиеМетаданныеНазвание", СоответствиеМетаданныеНазвание);
ПараметрыОдновременноСессий.Вставить("СкрытьРегламентныеЗадания", СкрытьРегламентныеЗадания);
ПараметрыОдновременноСессий.Вставить("МинимальнаяПродолжительностьСеансовРегламентныхЗаданий",
МинимальнаяПродолжительностьСеансовРегламентныхЗаданий);
ОдновременноСессий = ОдновременноРегламентныхЗаданий(ПараметрыОдновременноСессий);
ОдновременноСессий.Сортировать("ОдновременноРегламентныхЗаданий Убыв");
СтрокаИтогоОдновременноРегламентныхЗаданий = Неопределено;
ИтогоОдновременноРегламентныхЗаданий = Новый ТаблицаЗначений();
ИтогоОдновременноРегламентныхЗаданий.Колонки.Добавить("ДатаОдновременноРегламентныхЗаданий",
Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(50)));
ИтогоОдновременноРегламентныхЗаданий.Колонки.Добавить("ОдновременноРегламентныхЗаданий",
Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(10)));
ИтогоОдновременноРегламентныхЗаданий.Колонки.Добавить("СписокРегламентныхЗаданий");
Для Каждого СтрокаОдновременноСессий Из ОдновременноСессий Цикл
Если СтрокаОдновременноСессий.ОдновременноРегламентныхЗаданий >= РазмерОдновременноСессий
И СтрокаОдновременноСессий.ОдновременноРегламентныхЗаданий >= 2 Тогда
СтрокаИтогоОдновременноРегламентныхЗаданий = ИтогоОдновременноРегламентныхЗаданий.Добавить();
СтрокаИтогоОдновременноРегламентныхЗаданий.ДатаОдновременноРегламентныхЗаданий =
СтрокаОдновременноСессий.ДатаОдновременноРегламентныхЗаданий;
СтрокаИтогоОдновременноРегламентныхЗаданий.ОдновременноРегламентныхЗаданий =
СтрокаОдновременноСессий.ОдновременноРегламентныхЗаданий;
СтрокаИтогоОдновременноРегламентныхЗаданий.СписокРегламентныхЗаданий =
СтрокаОдновременноСессий.СписокРегламентныхЗаданий;
КонецЕсли;
КонецЦикла;
ДанныеЖурналаРегистрации.Сортировать("Метаданные, Данные, Дата, Сеанс");
ПараметрыСеансыРегламентныхЗаданий = Новый Структура;
ПараметрыСеансыРегламентныхЗаданий.Вставить("ДанныеЖурналаРегистрации", ДанныеЖурналаРегистрации);
ПараметрыСеансыРегламентныхЗаданий.Вставить("СоответствиеНаименованиеИдентификатор", СоответствиеНаименованиеИдентификатор);
ПараметрыСеансыРегламентныхЗаданий.Вставить("СоответствиеМетаданныеИдентификатор", СоответствиеМетаданныеИдентификатор);
ПараметрыСеансыРегламентныхЗаданий.Вставить("СоответствиеМетаданныеНазвание", СоответствиеМетаданныеНазвание);
ПараметрыСеансыРегламентныхЗаданий.Вставить("ОтображатьФоновыеЗадания", ОтображатьФоновыеЗадания);
ПараметрыСеансыРегламентныхЗаданий.Вставить("СкрытьРегламентныеЗадания", СкрытьРегламентныеЗадания);
ТаблицаСеансыРегламентныхЗаданий =
СеансыРегламентныхЗаданий(ПараметрыСеансыРегламентныхЗаданий).ТаблицаСеансыРегламентныхЗаданий;
КоличествоЗапусков = СеансыРегламентныхЗаданий(ПараметрыСеансыРегламентныхЗаданий).КоличествоЗапусков;
Результат = Новый Структура;
Результат.Вставить("ТаблицаСеансыРегламентныхЗаданий", ТаблицаСеансыРегламентныхЗаданий);
Результат.Вставить("ИтогоОдновременноРегламентныхЗаданий", ИтогоОдновременноРегламентныхЗаданий);
Результат.Вставить("КоличествоЗапусков", КоличествоЗапусков);
Результат.Вставить("ОтчетПустой", ОтчетПустой);
Возврат Результат;
КонецФункции
Функция ОдновременноРегламентныхЗаданий(ПараметрыОдновременноСессий)
ДанныеЖурналаРегистрации = ПараметрыОдновременноСессий.ДанныеЖурналаРегистрации;
СоответствиеНаименованиеИдентификатор = ПараметрыОдновременноСессий.СоответствиеНаименованиеИдентификатор;
СоответствиеМетаданныеИдентификатор = ПараметрыОдновременноСессий.СоответствиеМетаданныеИдентификатор;
СоответствиеМетаданныеНазвание = ПараметрыОдновременноСессий.СоответствиеМетаданныеНазвание;
СкрытьРегламентныеЗадания = ПараметрыОдновременноСессий.СкрытьРегламентныеЗадания;
МинимальнаяПродолжительностьСеансовРегламентныхЗаданий = ПараметрыОдновременноСессий.
МинимальнаяПродолжительностьСеансовРегламентныхЗаданий;
ОдновременноСессий = Новый ТаблицаЗначений();
ОдновременноСессий.Колонки.Добавить("ДатаОдновременноРегламентныхЗаданий",
Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(50)));
ОдновременноСессий.Колонки.Добавить("ОдновременноРегламентныхЗаданий",
Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(10)));
ОдновременноСессий.Колонки.Добавить("СписокРегламентныхЗаданий");
МассивРегламентныхЗаданий = Новый Массив;
ОдновременноРегламентныхЗаданий = 0;
Счетчик = 0;
ТекущаяДата = Неопределено;
СтрокаТаблицы = Неопределено;
МаксМассивРегламентныхЗаданий = Неопределено;
Для Каждого СтрокаДанныхЖурналаРегистрации Из ДанныеЖурналаРегистрации Цикл
Если Не ЗначениеЗаполнено(СтрокаДанныхЖурналаРегистрации.Дата)
Или Не ЗначениеЗаполнено(СтрокаДанныхЖурналаРегистрации.Метаданные) Тогда
Продолжить;
КонецЕсли;
НазваниеИУникальныйИдентификатор = НазваниеИУникальныйИдентификаторСеансаРегламентногоЗадания(
СтрокаДанныхЖурналаРегистрации, СоответствиеНаименованиеИдентификатор,
СоответствиеМетаданныеИдентификатор, СоответствиеМетаданныеНазвание);
НазваниеРегламентногоЗадания = НазваниеИУникальныйИдентификатор.НазваниеСеанса;
УникальныйИдентификаторРегламентногоЗадания =
НазваниеИУникальныйИдентификатор.УникальныйИдентификаторРегламентногоЗадания;
Если Не СкрытьРегламентныеЗадания = Неопределено
И Не ТипЗнч(СкрытьРегламентныеЗадания) = Тип("Строка") Тогда
ФильтрРегламентныхЗаданий = СкрытьРегламентныеЗадания.НайтиПоЗначению(
УникальныйИдентификаторРегламентногоЗадания);
Если Не ФильтрРегламентныхЗаданий = Неопределено Тогда
Продолжить;
КонецЕсли;
ИначеЕсли Не СкрытьРегламентныеЗадания = Неопределено
И ТипЗнч(СкрытьРегламентныеЗадания) = Тип("Строка") Тогда
Если УникальныйИдентификаторРегламентногоЗадания = СкрытьРегламентныеЗадания Тогда
Продолжить;
КонецЕсли;
КонецЕсли;
ДатаОдновременноРегламентныхЗаданий = НачалоЧаса(СтрокаДанныхЖурналаРегистрации.Дата);
Если ТекущаяДата <> ДатаОдновременноРегламентныхЗаданий Тогда
Если СтрокаТаблицы <> Неопределено Тогда
СтрокаТаблицы.ОдновременноРегламентныхЗаданий = ОдновременноРегламентныхЗаданий;
СтрокаТаблицы.ДатаОдновременноРегламентныхЗаданий = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = '%1 - %2'"),
Формат(ТекущаяДата, "ДЛФ=T"),
Формат(КонецЧаса(ТекущаяДата), "ДЛФ=T"));
СтрокаТаблицы.СписокРегламентныхЗаданий = МаксМассивРегламентныхЗаданий;
КонецЕсли;
СтрокаТаблицы = ОдновременноСессий.Добавить();
ОдновременноРегламентныхЗаданий = 0;
Счетчик = 0;
МассивРегламентныхЗаданий.Очистить();
ТекущаяДата = ДатаОдновременноРегламентныхЗаданий;
КонецЕсли;
Если СтрокаДанныхЖурналаРегистрации.Событие = "_$Job$_.Start" Тогда
Счетчик = Счетчик + 1;
МассивРегламентныхЗаданий.Добавить(НазваниеРегламентногоЗадания);
МассивРегламентныхЗаданий.Добавить(СтрокаДанныхЖурналаРегистрации.Сеанс);
МассивРегламентныхЗаданий.Добавить(СтрокаДанныхЖурналаРегистрации.Дата);
Иначе
ИндексРегламентногоЗадания = МассивРегламентныхЗаданий.Найти(НазваниеРегламентногоЗадания);
Если ИндексРегламентногоЗадания = Неопределено Тогда
Продолжить;
КонецЕсли;
Если ЗначениеЗаполнено(МаксМассивРегламентныхЗаданий) Тогда
ИндексСтрокиМассива = МаксМассивРегламентныхЗаданий.Найти(НазваниеРегламентногоЗадания);
Если ИндексСтрокиМассива <> Неопределено
И МаксМассивРегламентныхЗаданий[ИндексСтрокиМассива+1] = МассивРегламентныхЗаданий[ИндексРегламентногоЗадания+1]
И СтрокаДанныхЖурналаРегистрации.Дата - МаксМассивРегламентныхЗаданий[ИндексСтрокиМассива+2] <
МинимальнаяПродолжительностьСеансовРегламентныхЗаданий Тогда
МаксМассивРегламентныхЗаданий.Удалить(ИндексСтрокиМассива);
МаксМассивРегламентныхЗаданий.Удалить(ИндексСтрокиМассива);
МаксМассивРегламентныхЗаданий.Удалить(ИндексСтрокиМассива);
ОдновременноРегламентныхЗаданий = ОдновременноРегламентныхЗаданий - 1;
КонецЕсли;
КонецЕсли;
МассивРегламентныхЗаданий.Удалить(ИндексРегламентногоЗадания);
МассивРегламентныхЗаданий.Удалить(ИндексРегламентногоЗадания);
МассивРегламентныхЗаданий.Удалить(ИндексРегламентногоЗадания);
Счетчик = Счетчик - 1;
КонецЕсли;
Счетчик = Макс(Счетчик, 0);
Если Счетчик > ОдновременноРегламентныхЗаданий Тогда
МаксМассивРегламентныхЗаданий = Новый Массив;
Для Каждого Элемент Из МассивРегламентныхЗаданий Цикл
МаксМассивРегламентныхЗаданий.Добавить(Элемент);
КонецЦикла;
КонецЕсли;
ОдновременноРегламентныхЗаданий = Макс(ОдновременноРегламентныхЗаданий, Счетчик);
КонецЦикла;
Если ОдновременноРегламентныхЗаданий <> 0 Тогда
СтрокаТаблицы.ОдновременноРегламентныхЗаданий = ОдновременноРегламентныхЗаданий;
СтрокаТаблицы.ДатаОдновременноРегламентныхЗаданий = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = '%1 - %2'"),
Формат(ТекущаяДата, "ДЛФ=T"),
Формат(КонецЧаса(ТекущаяДата), "ДЛФ=T"));
СтрокаТаблицы.СписокРегламентныхЗаданий = МаксМассивРегламентныхЗаданий;
КонецЕсли;
Возврат ОдновременноСессий;
КонецФункции
Функция СеансыРегламентныхЗаданий(ПараметрыСеансыРегламентныхЗаданий)
ДанныеЖурналаРегистрации = ПараметрыСеансыРегламентныхЗаданий.ДанныеЖурналаРегистрации;
СоответствиеНаименованиеИдентификатор = ПараметрыСеансыРегламентныхЗаданий.СоответствиеНаименованиеИдентификатор;
СоответствиеМетаданныеИдентификатор = ПараметрыСеансыРегламентныхЗаданий.СоответствиеМетаданныеИдентификатор;
СоответствиеМетаданныеНазвание = ПараметрыСеансыРегламентныхЗаданий.СоответствиеМетаданныеНазвание;
СкрытьРегламентныеЗадания = ПараметрыСеансыРегламентныхЗаданий.СкрытьРегламентныеЗадания;
ОтображатьФоновыеЗадания = ПараметрыСеансыРегламентныхЗаданий.ОтображатьФоновыеЗадания;
ТаблицаСеансыРегламентныхЗаданий = Новый ТаблицаЗначений();
ТаблицаСеансыРегламентныхЗаданий.Колонки.Добавить("ДатаЗапускаЗадания",Новый ОписаниеТипов("Дата", , , Новый КвалификаторыДаты(ЧастиДаты.ДатаВремя)));
ТаблицаСеансыРегламентныхЗаданий.Колонки.Добавить("ДатаОкончанияЗадания",Новый ОписаниеТипов("Дата", , , Новый КвалификаторыДаты(ЧастиДаты.ДатаВремя)));
ТаблицаСеансыРегламентныхЗаданий.Колонки.Добавить("НазваниеСобытия",Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(100)));
ТаблицаСеансыРегламентныхЗаданий.Колонки.Добавить("СобытиеМетаданные",Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(100)));
ТаблицаСеансыРегламентныхЗаданий.Колонки.Добавить("Сеанс",Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(10)));
КоличествоЗапусков = Новый ТаблицаЗначений();
КоличествоЗапусков.Колонки.Добавить("НазваниеСобытия",Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(100)));
КоличествоЗапусков.Колонки.Добавить("Запусков",Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(10)));
КоличествоЗапусков.Колонки.Добавить("Отменено",Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(10)));
КоличествоЗапусков.Колонки.Добавить("ОшибкаВыполнения",Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(10)));
СтрокаРегламентныеЗадания = Неопределено;
НазваниеСобытия = Неопределено;
ДатаОкончанияЗадания = Неопределено;
ДатаЗапускаЗадания = Неопределено;
СобытиеМетаданные = Неопределено;
Запусков = 0;
ТекущееСобытие = Неопределено;
СтрокаКоличествоЗапусков = Неопределено;
ТекущийСеанс = 0;
Отменено = 0;
ОшибкаВыполнения = 0;
Для Каждого СтрокаДанныхЖурналаРегистрации Из ДанныеЖурналаРегистрации Цикл
Если Не ЗначениеЗаполнено(СтрокаДанныхЖурналаРегистрации.Метаданные)
И ОтображатьФоновыеЗадания = Ложь Тогда
Продолжить;
КонецЕсли;
НазваниеИУникальныйИдентификатор = НазваниеИУникальныйИдентификаторСеансаРегламентногоЗадания(
СтрокаДанныхЖурналаРегистрации, СоответствиеНаименованиеИдентификатор,
СоответствиеМетаданныеИдентификатор, СоответствиеМетаданныеНазвание);
НазваниеСобытия = НазваниеИУникальныйИдентификатор.НазваниеСеанса;
УникальныйИдентификаторРегламентногоЗадания = НазваниеИУникальныйИдентификатор.
УникальныйИдентификаторРегламентногоЗадания;
Если Не СкрытьРегламентныеЗадания = Неопределено
И Не ТипЗнч(СкрытьРегламентныеЗадания) = Тип("Строка") Тогда
ФильтрРегламентныхЗаданий = СкрытьРегламентныеЗадания.НайтиПоЗначению(
УникальныйИдентификаторРегламентногоЗадания);
Если Не ФильтрРегламентныхЗаданий = Неопределено Тогда
Продолжить;
КонецЕсли;
ИначеЕсли Не СкрытьРегламентныеЗадания = Неопределено
И ТипЗнч(СкрытьРегламентныеЗадания) = Тип("Строка") Тогда
Если УникальныйИдентификаторРегламентногоЗадания = СкрытьРегламентныеЗадания Тогда
Продолжить;
КонецЕсли;
КонецЕсли;
Сеанс = СтрокаДанныхЖурналаРегистрации.Сеанс;
Если ТекущееСобытие = Неопределено Тогда
ТекущееСобытие = НазваниеСобытия;
Запусков = 0;
ИначеЕсли ТекущееСобытие <> НазваниеСобытия Тогда
СтрокаКоличествоЗапусков = КоличествоЗапусков.Добавить();
СтрокаКоличествоЗапусков.НазваниеСобытия = ТекущееСобытие;
СтрокаКоличествоЗапусков.Запусков = Запусков;
СтрокаКоличествоЗапусков.Отменено = Отменено;
СтрокаКоличествоЗапусков.ОшибкаВыполнения = ОшибкаВыполнения;
Запусков = 0;
Отменено = 0;
ОшибкаВыполнения = 0;
ТекущееСобытие = НазваниеСобытия;
КонецЕсли;
Если ТекущийСеанс <> Сеанс Тогда
СтрокаРегламентныеЗадания = ТаблицаСеансыРегламентныхЗаданий.Добавить();
ДатаЗапускаЗадания = СтрокаДанныхЖурналаРегистрации.Дата;
СтрокаРегламентныеЗадания.ДатаЗапускаЗадания = ДатаЗапускаЗадания;
КонецЕсли;
Если ТекущийСеанс = Сеанс Тогда
ДатаОкончанияЗадания = СтрокаДанныхЖурналаРегистрации.Дата;
СобытиеМетаданные = СтрокаДанныхЖурналаРегистрации.Метаданные;
СтрокаРегламентныеЗадания.НазваниеСобытия = НазваниеСобытия;
СтрокаРегламентныеЗадания.СобытиеМетаданные = СобытиеМетаданные;
СтрокаРегламентныеЗадания.ДатаОкончанияЗадания = ДатаОкончанияЗадания;
СтрокаРегламентныеЗадания.Сеанс = ТекущийСеанс;
КонецЕсли;
ТекущийСеанс = Сеанс;
Если СтрокаДанныхЖурналаРегистрации.Событие = "_$Job$_.Cancel" Тогда
Отменено = Отменено + 1;
ИначеЕсли СтрокаДанныхЖурналаРегистрации.Событие = "_$Job$_.Fail" Тогда
ОшибкаВыполнения = ОшибкаВыполнения + 1;
ИначеЕсли СтрокаДанныхЖурналаРегистрации.Событие = "_$Job$_.Start" Тогда
Запусков = Запусков + 1
КонецЕсли;
КонецЦикла;
СтрокаКоличествоЗапусков = КоличествоЗапусков.Добавить();
СтрокаКоличествоЗапусков.НазваниеСобытия = ТекущееСобытие;
СтрокаКоличествоЗапусков.Запусков = Запусков;
СтрокаКоличествоЗапусков.Отменено = Отменено;
СтрокаКоличествоЗапусков.ОшибкаВыполнения = ОшибкаВыполнения;
ТаблицаСеансыРегламентныхЗаданий.Сортировать("СобытиеМетаданные, НазваниеСобытия, ДатаЗапускаЗадания");
Возврат Новый Структура("ТаблицаСеансыРегламентныхЗаданий, КоличествоЗапусков",
ТаблицаСеансыРегламентныхЗаданий, КоличествоЗапусков);
КонецФункции
Функция РасшифровкаРегламентногоЗадания(Расшифровка) Экспорт
Результат = Новый Структура;
Отчет = Новый ТабличныйДокумент;
ОтмененоЗаданий = 0;
ОшибкаВыполнения = 0;
ДатаЗапускаЗадания = Расшифровка.Получить(5);
ДатаОкончанияЗадания = Расшифровка.Получить(6);
СписокСеансов = Расшифровка.Получить(7);
Макет = ПолучитьМакет("РасшифровкаРегламентныхЗаданий");
Область = ОписаниеОбластиМакета(Макет, "Заголовок");
ДатаНачала = Расшифровка.Получить(11);
ДатаОкончания = Расшифровка.Получить(12);
Область.Параметры.ДатаНачала = ДатаНачала;
Область.Параметры.ДатаОкончания = ДатаОкончания;
Если Расшифровка.Получить(8) = 0 Тогда
РежимОтображенияИнтервалов = НСтр("ru = 'Включено отображение интервалов с нулевой продолжительностью'");
Иначе
РежимОтображенияИнтервалов = НСтр("ru = 'Отключено отображение интервалов с нулевой продолжительностью'");
КонецЕсли;
Область.Параметры.РежимОтображенияСеансов = РежимОтображенияИнтервалов;
Отчет.Вывести(Область);
Отчет.Вывести(Макет.ПолучитьОбласть("ПустаяСтрока"));
Область = ОписаниеОбластиМакета(Макет, "Таблица");
Область.Параметры.ТипЗадания = НСтр("ru = 'Регламентное'");
Область.Параметры.НазваниеСобытия = Расшифровка.Получить(2);
Область.Параметры.Запусков = Расшифровка.Получить(9);
ОтмененоЗаданий = Расшифровка.Получить(3);
ОшибкаВыполнения = Расшифровка.Получить(4);
Если ОтмененоЗаданий = 0 Тогда
Область.Параметры.Отменено = "0";
Иначе
Область.Параметры.Отменено = ОтмененоЗаданий;
КонецЕсли;
Если ОшибкаВыполнения = 0 Тогда
Область.Параметры.ОшибкаВыполнения = "0";
Иначе
Область.Параметры.ОшибкаВыполнения = ОшибкаВыполнения;
КонецЕсли;
ОбщаяПродолжительностьРЗ = Расшифровка.Получить(10);
ОбщаяПродолжительностьРЗИтог = ПродолжительностьРегламентногоЗадания(ОбщаяПродолжительностьРЗ);
Область.Параметры.ОбщаяПродолжительностьРЗ = ОбщаяПродолжительностьРЗИтог;
Отчет.Вывести(Область);
Отчет.Вывести(Макет.ПолучитьОбласть("ПустаяСтрока"));
Отчет.Вывести(Макет.ПолучитьОбласть("ЗаголовокИнтервалов"));
Отчет.Вывести(Макет.ПолучитьОбласть("ПустаяСтрока"));
Отчет.Вывести(Макет.ПолучитьОбласть("ШапкаТаблицы"));
РазмерМассива = ДатаЗапускаЗадания.Количество();
НомерИнтервала = 1;
Отчет.НачатьГруппуСтрок(, Ложь);
Для Индекс = 0 По РазмерМассива-1 Цикл
Область = ОписаниеОбластиМакета(Макет, "ТаблицаИнтервалов");
НачалоИнтервала = ДатаЗапускаЗадания.Получить(Индекс);
КонецИнтервала = ДатаОкончанияЗадания.Получить(Индекс);
ПродолжительностьРЗ = ПродолжительностьРегламентногоЗадания(КонецИнтервала - НачалоИнтервала);
Область.Параметры.НомерИнтервала = НомерИнтервала;
Область.Параметры.НачалоИнтервала = Формат(НачалоИнтервала, "ДЛФ=T");
Область.Параметры.КонецИнтервала = Формат(КонецИнтервала, "ДЛФ=T");
Область.Параметры.ПродолжительностьРЗ = ПродолжительностьРЗ;
Область.Параметры.Сеанс = СписокСеансов.Получить(Индекс);
Область.Параметры.РасшифровкаИнтервала = Новый Массив;
Область.Параметры.РасшифровкаИнтервала.Добавить(НачалоИнтервала);
Область.Параметры.РасшифровкаИнтервала.Добавить(КонецИнтервала);
Область.Параметры.РасшифровкаИнтервала.Добавить(СписокСеансов.Получить(Индекс));
Отчет.Вывести(Область);
НомерИнтервала = НомерИнтервала + 1;
КонецЦикла;
Отчет.ЗакончитьГруппуСтрок();
Результат.Вставить("Отчет", Отчет);
Возврат Результат;
КонецФункции
Процедура ЦветаДиаграммыГанта(ДатаНачала, ДиаграммаГанта, ОдновременноСессий, ЦветаФона)
ТекущееКоличествоСессий = 0;
ИндексЦвета = 3;
Для Каждого СтрокаОдновременноСессий Из ОдновременноСессий Цикл
Если СтрокаОдновременноСессий.ОдновременноРегламентныхЗаданий = 1 Тогда
Продолжить
КонецЕсли;
СтрокаДаты = Лев(СтрокаОдновременноСессий.ДатаОдновременноРегламентныхЗаданий, 8);
ДатаНачалоИФ = Дата(Формат(ДатаНачала,"ДЛФ=D") + " " + СтрокаДаты);
ДатаКонецИФ = КонецЧаса(ДатаНачалоИФ);
ИнтервалДГ = ДиаграммаГанта.ИнтервалыФона.Добавить(ДатаНачалоИФ, ДатаКонецИФ);
Если ТекущееКоличествоСессий <> 0
И ТекущееКоличествоСессий <> СтрокаОдновременноСессий.ОдновременноРегламентныхЗаданий
И ИндексЦвета <> 0 Тогда
ИндексЦвета = ИндексЦвета - 1;
КонецЕсли;
ЦветФона = ЦветаФона.Получить(ИндексЦвета);
ИнтервалДГ.Цвет = ЦветФона;
ТекущееКоличествоСессий = СтрокаОдновременноСессий.ОдновременноРегламентныхЗаданий;
КонецЦикла;
КонецПроцедуры
Процедура ШкалаВремениДиаграммыГанта(ДиаграммаГанта, ПериодАнализа)
ЭлементыШкалыВремени = ДиаграммаГанта.ОбластьПостроения.ШкалаВремени.Элементы;
ПервыйЭлемент = ЭлементыШкалыВремени[0];
Для Индекс = 1 По ЭлементыШкалыВремени.Количество()-1 Цикл
ЭлементыШкалыВремени.Удалить(ЭлементыШкалыВремени[1]);
КонецЦикла;
ПервыйЭлемент.Единица = ТипЕдиницыШкалыВремени.День;
ПервыйЭлемент.ЛинииДелений = Новый Линия(ТипЛинииДиаграммы.Сплошная, 1);
ПервыйЭлемент.ФорматДня = ФорматДняШкалыВремени.ДеньМесяца;
Элемент = ЭлементыШкалыВремени.Добавить();
Элемент.Единица = ТипЕдиницыШкалыВремени.Час;
Элемент.ЛинииДелений = Новый Линия(ТипЛинииДиаграммы.Точечная, 1);
Если ПериодАнализа <= 3600 Тогда
Элемент = ЭлементыШкалыВремени.Добавить();
Элемент.Единица = ТипЕдиницыШкалыВремени.Минута;
Элемент.ЛинииДелений = Новый Линия(ТипЛинииДиаграммы.Точечная, 1);
КонецЕсли;
КонецПроцедуры
Функция ПродолжительностьРегламентногоЗадания(ПродолжительностьРЗ)
Если ПродолжительностьРЗ = 0 Тогда
ОбщаяПродолжительностьРЗ = "0";
ИначеЕсли ПродолжительностьРЗ <= 60 Тогда
ОбщаяПродолжительностьРЗ = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = '%1 сек'"), ПродолжительностьРЗ);
ИначеЕсли 60 < ПродолжительностьРЗ <= 3600 Тогда
ПродолжительностьМинуты = Формат(ПродолжительностьРЗ/60, "ЧДЦ=0");
ПродолжительностьСекунды = Формат((Формат(ПродолжительностьРЗ/60, "ЧДЦ=2")
- Цел(ПродолжительностьРЗ/60)) * 60, "ЧДЦ=0");
ОбщаяПродолжительностьРЗ = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = '%1 мин %2 сек'"), ПродолжительностьМинуты, ПродолжительностьСекунды);
ИначеЕсли ПродолжительностьРЗ > 3600 Тогда
ПродолжительностьЧасы = Формат(ПродолжительностьРЗ/60/60, "ЧДЦ=0");
ПродолжительностьМинуты = (Формат(ПродолжительностьРЗ/60/60, "ЧДЦ=2") - Цел(ПродолжительностьРЗ/60/60))*60;
ПродолжительностьМинуты = Формат(ПродолжительностьМинуты, "ЧДЦ=0");
ОбщаяПродолжительностьРЗ = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = '%1 ч %2 мин'"), ПродолжительностьЧасы, ПродолжительностьМинуты);
КонецЕсли;
Возврат ОбщаяПродолжительностьРЗ;
КонецФункции
Функция МетаданныеРегламентногоЗадания(ДанныеРегламентногоЗадания)
Если ДанныеРегламентногоЗадания <> "" Тогда
Возврат Метаданные.РегламентныеЗадания.Найти(
СтрЗаменить(ДанныеРегламентногоЗадания, "РегламентноеЗадание." , ""));
КонецЕсли;
КонецФункции
Функция НазваниеИУникальныйИдентификаторСеансаРегламентногоЗадания(СтрокаДанныхЖурналаРегистрации,
СоответствиеНаименованиеИдентификатор, СоответствиеМетаданныеИдентификатор, СоответствиеМетаданныеНазвание)
Если Не СтрокаДанныхЖурналаРегистрации.Данные = "" Тогда
УникальныйИдентификаторРегламентногоЗадания = СоответствиеНаименованиеИдентификатор[
СтрокаДанныхЖурналаРегистрации.Данные];
НазваниеСеанса = СтрокаДанныхЖурналаРегистрации.Данные;
Иначе
УникальныйИдентификаторРегламентногоЗадания = СоответствиеМетаданныеИдентификатор[
МетаданныеРегламентногоЗадания(СтрокаДанныхЖурналаРегистрации.Метаданные)];
НазваниеСеанса = СоответствиеМетаданныеНазвание[МетаданныеРегламентногоЗадания(
СтрокаДанныхЖурналаРегистрации.Метаданные)];
КонецЕсли;
Возврат Новый Структура("НазваниеСеанса, УникальныйИдентификаторРегламентногоЗадания",
НазваниеСеанса, УникальныйИдентификаторРегламентногоЗадания)
КонецФункции
Функция ОписаниеОбластиМакета(Макет, ИмяОбласти)
Возврат Макет.ПолучитьОбласть(ИмяОбласти);
КонецФункции
#КонецОбласти
#Область КонтрольЖурналаРегистрации
Функция СформироватьОтчетКонтрольЖурналаРегистрации(ДатаНачала, ДатаОкончания, СмещениеВремениСервера) Экспорт
Результат = Новый Структура;
Отчет = Новый ТабличныйДокумент;
Макет = ПолучитьМакет("МакетОтчетаПоОшибкамВЖурналеРегистрации");
ДанныеЖурналаРегистрации = ИнформацияПоОшибкамЖурналаРегистрации(ДатаНачала, ДатаОкончания, СмещениеВремениСервера);
КоличествоЗаписейЖурналаРегистрации = ДанныеЖурналаРегистрации.Количество();
ОтчетПустой = (КоличествоЗаписейЖурналаРегистрации = 0);
СверткаПоКомментариям = ДанныеЖурналаРегистрации.Скопировать();
СверткаПоКомментариям.Колонки.Добавить("ИтогПоКомментарию");
СверткаПоКомментариям.ЗаполнитьЗначения(1, "ИтогПоКомментарию");
СверткаПоКомментариям.Свернуть("Уровень, Комментарий, Событие, ПредставлениеСобытия", "ИтогПоКомментарию");
МассивСтрок_УровеньОшибка = СверткаПоКомментариям.НайтиСтроки(
Новый Структура("Уровень", УровеньЖурналаРегистрации.Ошибка));
МассивСтрок_УровеньПредупреждение = СверткаПоКомментариям.НайтиСтроки(
Новый Структура("Уровень", УровеньЖурналаРегистрации.Предупреждение));
Свертка_Ошибки = СверткаПоКомментариям.Скопировать(МассивСтрок_УровеньОшибка);
Свертка_Ошибки.Сортировать("ИтогПоКомментарию Убыв");
Свертка_Предупреждения = СверткаПоКомментариям.Скопировать(МассивСтрок_УровеньПредупреждение);
Свертка_Предупреждения.Сортировать("ИтогПоКомментарию Убыв");
Область = Макет.ПолучитьОбласть("ШапкаОтчета");
Область.Параметры.ПериодВыборкиНачало = ДатаНачала;
Область.Параметры.ПериодВыборкиОкончание = ДатаОкончания;
Область.Параметры.ПредставлениеИнформационнойБазы = ПредставлениеИнформационнойБазы();
Отчет.Вывести(Область);
РезультатКомпоновкиТЧ = СформироватьТабличнуюЧасть(Макет, ДанныеЖурналаРегистрации, Свертка_Ошибки);
Отчет.Вывести(Макет.ПолучитьОбласть("ПустаяСтрока"));
Область = Макет.ПолучитьОбласть("ЗаголовокБлокаОшибки");
Область.Параметры.ЧислоОшибок = Строка(РезультатКомпоновкиТЧ.Итог);
Отчет.Вывести(Область);
Если РезультатКомпоновкиТЧ.Итог > 0 Тогда
Отчет.Вывести(РезультатКомпоновкиТЧ.ТабличнаяЧасть);
КонецЕсли;
Результат.Вставить("ИтогПоОшибкам", РезультатКомпоновкиТЧ.Итог);
РезультатКомпоновкиТЧ = СформироватьТабличнуюЧасть(Макет, ДанныеЖурналаРегистрации, Свертка_Предупреждения);
Отчет.Вывести(Макет.ПолучитьОбласть("ПустаяСтрока"));
Область = Макет.ПолучитьОбласть("ЗаголовокБлокаПредупреждения");
Область.Параметры.ЧислоПредупреждений = РезультатКомпоновкиТЧ.Итог;
Отчет.Вывести(Область);
Если РезультатКомпоновкиТЧ.Итог > 0 Тогда
Отчет.Вывести(РезультатКомпоновкиТЧ.ТабличнаяЧасть);
КонецЕсли;
Результат.Вставить("ИтогПоПредупреждениям", РезультатКомпоновкиТЧ.Итог);
Отчет.ОтображатьСетку = Ложь;
Результат.Вставить("Отчет", Отчет);
Результат.Вставить("ОтчетПустой", ОтчетПустой);
Возврат Результат;
КонецФункции
Функция ПредставлениеИнформационнойБазы()
СтрокаСоединенияСБД = СтрокаСоединенияИнформационнойБазы();
Если ОбщегоНазначения.ИнформационнаяБазаФайловая(СтрокаСоединенияСБД) Тогда
Возврат Сред(СтрокаСоединенияСБД, 6, СтрДлина(СтрокаСоединенияСБД) - 6);
КонецЕсли;
ПозицияПоиска = СтрНайти(ВРег(СтрокаСоединенияСБД), "SRVR=");
Если ПозицияПоиска <> 1 Тогда
Возврат Неопределено;
КонецЕсли;
ПозицияТочкиСЗапятой = СтрНайти(СтрокаСоединенияСБД, ";");
НачальнаяПозицияКопирования = 6 + 1;
КонечнаяПозицияКопирования = ПозицияТочкиСЗапятой - 2;
ИмяСервера = Сред(СтрокаСоединенияСБД, НачальнаяПозицияКопирования, КонечнаяПозицияКопирования - НачальнаяПозицияКопирования + 1);
СтрокаСоединенияСБД = Сред(СтрокаСоединенияСБД, ПозицияТочкиСЗапятой + 1);
ПозицияПоиска = СтрНайти(ВРег(СтрокаСоединенияСБД), "REF=");
Если ПозицияПоиска <> 1 Тогда
Возврат Неопределено;
КонецЕсли;
НачальнаяПозицияКопирования = 6;
ПозицияТочкиСЗапятой = СтрНайти(СтрокаСоединенияСБД, ";");
КонечнаяПозицияКопирования = ПозицияТочкиСЗапятой - 2;
ИмяИБНаСервере = Сред(СтрокаСоединенияСБД, НачальнаяПозицияКопирования, КонечнаяПозицияКопирования - НачальнаяПозицияКопирования + 1);
ПутьКБД = ИмяСервера + "/ " + ИмяИБНаСервере;
Возврат ПутьКБД;
КонецФункции
Функция ИнформацияПоОшибкамЖурналаРегистрации(ДатаНачала, ДатаОкончания,
СмещениеВремениСервера, ПользовательФильтр = Неопределено)
ДанныеЖурналаРегистрации = Новый ТаблицаЗначений;
УровниРегистрацииОшибок = Новый Массив;
УровниРегистрацииОшибок.Добавить(УровеньЖурналаРегистрации.Ошибка);
УровниРегистрацииОшибок.Добавить(УровеньЖурналаРегистрации.Предупреждение);
Отбор = Новый Структура;
Отбор.Вставить("Уровень", УровниРегистрацииОшибок);
Отбор.Вставить("ДатаНачала", ДатаНачала + СмещениеВремениСервера);
Отбор.Вставить("ДатаОкончания", ДатаОкончания + СмещениеВремениСервера);
Если ПользовательФильтр <> Неопределено Тогда
Отбор.Вставить("Пользователь", ПользовательФильтр);
КонецЕсли;
УстановитьПривилегированныйРежим(Истина);
ВыгрузитьЖурналРегистрации(ДанныеЖурналаРегистрации, Отбор);
УстановитьПривилегированныйРежим(Ложь);
Если СмещениеВремениСервера <> 0 Тогда
Для Каждого СтрокаТаблицы Из ДанныеЖурналаРегистрации Цикл
СтрокаТаблицы.Дата = СтрокаТаблицы.Дата - СмещениеВремениСервера;
КонецЦикла;
КонецЕсли;
Возврат ДанныеЖурналаРегистрации;
КонецФункции
Функция СформироватьТабличнуюЧасть(Макет, ДанныеЖурналаРегистрации, СвернутыеДанные)
Отчет = Новый ТабличныйДокумент;
Итог = 0;
Если СвернутыеДанные.Количество() > 0 Тогда
Отчет.Вывести(Макет.ПолучитьОбласть("ПустаяСтрока"));
Для Каждого Запись Из СвернутыеДанные Цикл
Итог = Итог + Запись.ИтогПоКомментарию;
МассивСтрок = ДанныеЖурналаРегистрации.НайтиСтроки(
Новый Структура("Уровень, Комментарий",
УровеньЖурналаРегистрации.Ошибка,
Запись.Комментарий));
Область = Макет.ПолучитьОбласть("ТелоТабличнойЧастиШапка");
Область.Параметры.Заполнить(Запись);
Отчет.Вывести(Область);
Отчет.НачатьГруппуСтрок(, Ложь);
Для Каждого Строка Из МассивСтрок Цикл
Область = Макет.ПолучитьОбласть("ТелоТабличнойЧастиДетализация");
Область.Параметры.Заполнить(Строка);
Отчет.Вывести(Область);
КонецЦикла;
Отчет.ЗакончитьГруппуСтрок();
Отчет.Вывести(Макет.ПолучитьОбласть("ПустаяСтрока"));
КонецЦикла;
КонецЕсли;
Результат = Новый Структура("ТабличнаяЧасть, Итог", Отчет, Итог);
Возврат Результат;
КонецФункции
#КонецОбласти
#КонецОбласти
#КонецЕсли