diff --git a/КМ-5.lersreport b/КМ-5.lersreport
index 1757572..5dfea2f 100644
--- a/КМ-5.lersreport
+++ b/КМ-5.lersreport
@@ -16,7 +16,7 @@
0
-<XtraReportsLayoutSerializer SerializerVersion="16.2.3.0" Ref="1" ControlType="DevExpress.XtraReports.UI.XtraReport, DevExpress.XtraReports.v16.2, Version=16.2.3.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" Name="BaseReport" ScriptsSource="// Типы архивов
string[] archiveType = new string[28];

// Код периода отключения питания
double period_U = 0;
int[] codes_U = {122};

// Код периода t1-t2 < min
double period_D = 0;
int[] codes_D = {96};

// Коды функционального отказа
double period_E = 0;
int[] codes_E = {14, 16, 18, 61, 64, 65, 66, 67, 68, 69, 71, 73, 74, 76, 79, 81, 88, 90, 91, 93, 94, 106, 114, 119, 120, 121};

// Коды периода G > max
double period_G = 0;
int[] codes_G = {82, 85};

// Коды периода G < min
double period_g = 0;
int[] codes_g = {84, 87};

// Коды прочие
double period_other = 0;

private void BaseReport_DataSourceDemanded(object sender, System.EventArgs e) 
{
	// Расшифровка типов архивов
	archiveType[0] = "Общий (системный)";
	archiveType[1] = "По тепловому вводу";	
	archiveType[2] = "По каналу";
	archiveType[3] = "По дискретным входам";
	archiveType[4] = "По дискретным выходам";
	archiveType[5] = "Смена режима работы";
	archiveType[6] = "Действия пользователя";
	archiveType[7] = "Архив времени перерыов в электропитании";
	archiveType[8] = "Архив изменений параметров настройки";
	archiveType[9] = "Диагностические сообщения";
	archiveType[10] = "Нештатные ситуации";
	archiveType[11] = "Архив перерывов в электропитании за месяц";
	archiveType[12] = "Архив перерывов в электропитании за день";
	archiveType[13] = "Диагностические сообщения, не влияющие на коммерческий учёт";
	archiveType[14] = "Нештатные ситуации, влияющие на коммерческий учёт";
	archiveType[15] = "Архив суточный обобщённых сообщений о НС";
	archiveType[16] = "Архив часовой обобщённых сообщений о НС";
	archiveType[17] = "Общие события";
	archiveType[18] = "Индивидуальные события ПП";
	archiveType[19] = "";
	archiveType[20] = "";
	archiveType[21] = "";
	archiveType[22] = "Архив НС за предыдущий и текущий месяцы";
	archiveType[23] = "НС периферийных устройств";
	archiveType[24] = "Отказы";
	archiveType[25] = "Ошибки";
	archiveType[26] = "Предупреждения";
	archiveType[27] = "Сообщения";
}

// Формируем текст для колонки 'Классификатор ошибок'
// Эта колонка связана с полем DeviceEventCodes, в котором события записаны в виде строки:
// архив1|ввод1|канал1|код1; архив2|ввод2|канал2|код2; ... архивN|вводN|каналN|кодN
private void EventGroups_BeforePrint(object sender, System.Drawing.Printing.PrintEventArgs e) 
{
	// Строка с информацией о событиях. 
	// Формат строки: архив1|ввод1|канал1|код1; архив2|ввод2|канал2|код2; ... архивN|вводN|каналN|кодN.
	string eventCodesString = ((XRTableCell)sender).Text;

	if (String.IsNullOrEmpty(eventCodesString))
		return;
	
	// Получаем массив типов архива и кодов событий:
	// eventCodesString - строка с форматом: архив1|ввод1|канал1|код1; архив2|ввод2|канал2|код2; ... архивN|вводN|каналN|кодN
	string[] eventCodes = eventCodesString.Split(new string[]{";"}, StringSplitOptions.RemoveEmptyEntries);

	// Формируем обозначения для групп событий и типов архивов
	string eventCodesSymbol = String.Empty;
	foreach (string eventCodeInfo in eventCodes)
	{
		// Получаем информация по событию в виде строки: архив|ввод|канал|код
		string[] eventInfo = (eventCodeInfo.Trim()).Split(new string[]{"|"}, StringSplitOptions.RemoveEmptyEntries);

		// Код типа архива 
		int archiveType = -1;
		if (!String.IsNullOrEmpty(eventInfo[0].Trim()))
			archiveType = Convert.ToInt32(eventInfo[0]);

		// Номер теплового ввода 
		int heatLeadIn = -1;
		if (!String.IsNullOrEmpty(eventInfo[1].Trim()))
			heatLeadIn = Convert.ToInt32(eventInfo[1]);

		// Номер канала 
		int channelNumber = -1;
		if (!String.IsNullOrEmpty(eventInfo[2].Trim()))
			channelNumber = Convert.ToInt32(eventInfo[2]);

		// Код события
		int code = -1;
		if (!String.IsNullOrEmpty(eventInfo[3].Trim()))
			code = Convert.ToInt32(eventInfo[3]);

		// Формируем символьное отображение событий 

		// Период отключения питания
		if (Array.Exists(codes_U, delegate(int c) { return (c == code); }) && eventCodesSymbol.IndexOf("U") == -1)
			eventCodesSymbol += "U";

		// Период t1-t2 < min
		else if (Array.Exists(codes_D, delegate(int c) { return (c == code); }) && eventCodesSymbol.IndexOf("D") == -1)
			eventCodesSymbol += "D";

		// Период функционального отказа
		else if (Array.Exists(codes_E, delegate(int c) { return (c == code); }) && eventCodesSymbol.IndexOf("E") == -1)
			eventCodesSymbol += "E";

		// Период G > max
		else if (Array.Exists(codes_G, delegate(int c) { return (c == code); }) && eventCodesSymbol.IndexOf("G") == -1)
			eventCodesSymbol += "G";

		// Период G < min
		else if (Array.Exists(codes_g, delegate(int c) { return (c == code); }) && eventCodesSymbol.IndexOf("g") == -1)
			eventCodesSymbol += "g";

		// Период прочих кодов
		else if (eventCodesSymbol.IndexOf("*") == -1)
			eventCodesSymbol += "*";
	}

	((XRTableCell)sender).Text = eventCodesSymbol;
}

// Формируем суммарные времена для групп событий
// Ячейка EventsDuration связана с полем DeviceEventDuration, в котором события записаны в виде строки:
// архив1|ввод1|канал1|код1|длительность1; архив2|ввод2|канал2|код2|длительность2; ... архивN|вводN|каналN|кодN|длительностьN
// Ячейка EventsDuration нужна только для расчета суммарных длительностей, поэтому ее можно сделать невидимой установив свойство Видимость = Нет
private void EventsDuration_BeforePrint(object sender, System.Drawing.Printing.PrintEventArgs e) 
{
	// Получаем содержимое ячейки.
	string eventDurationString = ((XRLabel)sender).Text;

	if (String.IsNullOrEmpty(eventDurationString))
		return;
	
	// Получаем массив кодов и длительностей событий
	// Каждый элемент мвссива - это строка формата: архив|ввод|канал|код|длительность
	string[] eventDurations = eventDurationString.Split(new string[]{";"}, StringSplitOptions.RemoveEmptyEntries);

	// Перебираем события и формируем суммарные длительности 	
	foreach (string eventDuration in eventDurations)
	{
		// eventDuration - строка c форматом: архив|ввод|канал|код|длительность
		string[] codeDuration = (eventDuration.Trim()).Split(new string[]{"|"}, StringSplitOptions.RemoveEmptyEntries);
		
		// Код типа архива 
		int archiveType = -1;
		if (!String.IsNullOrEmpty(codeDuration[0].Trim()))
			archiveType = Convert.ToInt32(codeDuration[0]);

		// Номер теплового ввода 
		int heatLeadIn = -1;
		if (!String.IsNullOrEmpty(codeDuration[1].Trim()))
			heatLeadIn = Convert.ToInt32(codeDuration[1]);

		// Номер канала 
		int channelNumber = -1;
		if (!String.IsNullOrEmpty(codeDuration[2].Trim()))
			channelNumber = Convert.ToInt32(codeDuration[2]);

		// Код события
		int code = -1;
		if (!String.IsNullOrEmpty(codeDuration[3].Trim()))
			code = Convert.ToInt32(codeDuration[3]);

		// Длительность события в секундах
		double duration = 0;
		if (!String.IsNullOrEmpty(codeDuration[4].Trim()))
			duration = Convert.ToDouble(codeDuration[4]);

		// Переводим длительность события из секунд в доли часа
		duration = duration / 3600D;

		// Период отключения питания
		if (Array.Exists(codes_U, delegate(int c) { return (c == code); }))
			period_U += duration;

		// Период t1-t2 < min
		else if (Array.Exists(codes_D, delegate(int c) { return (c == code); }))
			period_D += duration;

		// Период функционального отказа
		else if (Array.Exists(codes_E, delegate(int c) { return (c == code); }))
			period_E += duration;

		// Период G > max
		else if (Array.Exists(codes_G, delegate(int c) { return (c == code); }))
			period_G += duration;

		// Период G < min
		else if (Array.Exists(codes_g, delegate(int c) { return (c == code); }))
			period_g += duration;

		// Период прочих кодов
		else 
			period_other += duration;
	}
}
// Отображаем суммарные периоды событий
private void Period_BeforePrint(object sender, System.Drawing.Printing.PrintEventArgs e) 
{
	XRLabel label = (XRLabel)sender;

	double period = 0;
	switch (label.Name)
	{
		case "lblPeriod_U":	// Период отключения питания
			period = period_U;
			break;

		case "lblPeriod_D":	// Период t1-t2 < min
			period = period_D;
			break;

		case "lblPeriod_E":	// Период функционального отказа
			period = period_E;
			break;

		case "lblPeriod_Gmax":	// Период G > max
			period = period_G;
			break;

		case "lblPeriod_Gmin":	// Период G < min
			period = period_g;
			break;

		case "lblPeriod_Other":	// Период прочие
			period = period_other;
			break;
	}

	label.Text = String.Format("{0:F3}", period);
}


" SnapGridSize="31.75" ReportUnit="TenthsOfAMillimeter" Margins="249, 98, 99, 55" PaperKind="A4" PageWidth="2100" PageHeight="2970" Version="16.2" RequestParameters="false" DataMember="Архив суточный" DataSource="#Ref-0" Dpi="254" Tag_type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" Tag="1|321">
+<XtraReportsLayoutSerializer SerializerVersion="16.2.3.0" Ref="1" ControlType="DevExpress.XtraReports.UI.XtraReport, DevExpress.XtraReports.v16.2, Version=16.2.3.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" Name="BaseReport" ScriptsSource="// Типы архивов
string[] archiveType = new string[28];

// Код периода отключения питания
double period_U = 0;
int[] codes_U = {122};

// Код периода t1-t2 < min
double period_D = 0;
int[] codes_D = {96};

// Коды функционального отказа
double period_E = 0;
int[] codes_E = {61, 64, 65, 66, 67, 68, 69, 71, 73, 74, 76, 79, 81, 88, 90, 91, 93, 94, 106, 114, 119, 120, 121};

// Коды периода G > max
double period_G = 0;
int[] codes_G = {82, 85};

// Коды периода G < min
double period_g = 0;
int[] codes_g = {84, 87};

// Коды прочие
double period_other = 0;

private void BaseReport_DataSourceDemanded(object sender, System.EventArgs e) 
{
	// Расшифровка типов архивов
	archiveType[0] = "Общий (системный)";
	archiveType[1] = "По тепловому вводу";	
	archiveType[2] = "По каналу";
	archiveType[3] = "По дискретным входам";
	archiveType[4] = "По дискретным выходам";
	archiveType[5] = "Смена режима работы";
	archiveType[6] = "Действия пользователя";
	archiveType[7] = "Архив времени перерыов в электропитании";
	archiveType[8] = "Архив изменений параметров настройки";
	archiveType[9] = "Диагностические сообщения";
	archiveType[10] = "Нештатные ситуации";
	archiveType[11] = "Архив перерывов в электропитании за месяц";
	archiveType[12] = "Архив перерывов в электропитании за день";
	archiveType[13] = "Диагностические сообщения, не влияющие на коммерческий учёт";
	archiveType[14] = "Нештатные ситуации, влияющие на коммерческий учёт";
	archiveType[15] = "Архив суточный обобщённых сообщений о НС";
	archiveType[16] = "Архив часовой обобщённых сообщений о НС";
	archiveType[17] = "Общие события";
	archiveType[18] = "Индивидуальные события ПП";
	archiveType[19] = "";
	archiveType[20] = "";
	archiveType[21] = "";
	archiveType[22] = "Архив НС за предыдущий и текущий месяцы";
	archiveType[23] = "НС периферийных устройств";
	archiveType[24] = "Отказы";
	archiveType[25] = "Ошибки";
	archiveType[26] = "Предупреждения";
	archiveType[27] = "Сообщения";
}

// Формируем текст для колонки 'Классификатор ошибок'
// Эта колонка связана с полем DeviceEventCodes, в котором события записаны в виде строки:
// архив1|ввод1|канал1|код1; архив2|ввод2|канал2|код2; ... архивN|вводN|каналN|кодN
private void EventGroups_BeforePrint(object sender, System.Drawing.Printing.PrintEventArgs e) 
{
	// Строка с информацией о событиях. 
	// Формат строки: архив1|ввод1|канал1|код1; архив2|ввод2|канал2|код2; ... архивN|вводN|каналN|кодN.
	string eventCodesString = ((XRTableCell)sender).Text;

	if (String.IsNullOrEmpty(eventCodesString))
		return;
	
	// Получаем массив типов архива и кодов событий:
	// eventCodesString - строка с форматом: архив1|ввод1|канал1|код1; архив2|ввод2|канал2|код2; ... архивN|вводN|каналN|кодN
	string[] eventCodes = eventCodesString.Split(new string[]{";"}, StringSplitOptions.RemoveEmptyEntries);

	// Формируем обозначения для групп событий и типов архивов
	string eventCodesSymbol = String.Empty;
	foreach (string eventCodeInfo in eventCodes)
	{
		// Получаем информация по событию в виде строки: архив|ввод|канал|код
		string[] eventInfo = (eventCodeInfo.Trim()).Split(new string[]{"|"}, StringSplitOptions.RemoveEmptyEntries);

		// Код типа архива 
		int archiveType = -1;
		if (!String.IsNullOrEmpty(eventInfo[0].Trim()))
			archiveType = Convert.ToInt32(eventInfo[0]);

		// Номер теплового ввода 
		int heatLeadIn = -1;
		if (!String.IsNullOrEmpty(eventInfo[1].Trim()))
			heatLeadIn = Convert.ToInt32(eventInfo[1]);

		// Номер канала 
		int channelNumber = -1;
		if (!String.IsNullOrEmpty(eventInfo[2].Trim()))
			channelNumber = Convert.ToInt32(eventInfo[2]);

		// Код события
		int code = -1;
		if (!String.IsNullOrEmpty(eventInfo[3].Trim()))
			code = Convert.ToInt32(eventInfo[3]);

		// Формируем символьное отображение событий 

		// Период отключения питания
		if (Array.Exists(codes_U, delegate(int c) { return (c == code); }) && eventCodesSymbol.IndexOf("U") == -1)
			eventCodesSymbol += "U";

		// Период t1-t2 < min
		else if (Array.Exists(codes_D, delegate(int c) { return (c == code); }) && eventCodesSymbol.IndexOf("D") == -1)
			eventCodesSymbol += "D";

		// Период функционального отказа
		else if (Array.Exists(codes_E, delegate(int c) { return (c == code); }) && eventCodesSymbol.IndexOf("E") == -1)
			eventCodesSymbol += "E";

		// Период G > max
		else if (Array.Exists(codes_G, delegate(int c) { return (c == code); }) && eventCodesSymbol.IndexOf("G") == -1)
			eventCodesSymbol += "G";

		// Период G < min
		else if (Array.Exists(codes_g, delegate(int c) { return (c == code); }) && eventCodesSymbol.IndexOf("g") == -1)
			eventCodesSymbol += "g";

		// Период прочих кодов
		else if (eventCodesSymbol.IndexOf("*") == -1)
			eventCodesSymbol += "*";
	}

	((XRTableCell)sender).Text = eventCodesSymbol;
}

// Формируем суммарные времена для групп событий
// Ячейка EventsDuration связана с полем DeviceEventDuration, в котором события записаны в виде строки:
// архив1|ввод1|канал1|код1|длительность1; архив2|ввод2|канал2|код2|длительность2; ... архивN|вводN|каналN|кодN|длительностьN
// Ячейка EventsDuration нужна только для расчета суммарных длительностей, поэтому ее можно сделать невидимой установив свойство Видимость = Нет
private void EventsDuration_BeforePrint(object sender, System.Drawing.Printing.PrintEventArgs e) 
{
	// Получаем содержимое ячейки.
	string eventDurationString = ((XRLabel)sender).Text;

	if (String.IsNullOrEmpty(eventDurationString))
		return;
	
	// Получаем массив кодов и длительностей событий
	// Каждый элемент мвссива - это строка формата: архив|ввод|канал|код|длительность
	string[] eventDurations = eventDurationString.Split(new string[]{";"}, StringSplitOptions.RemoveEmptyEntries);

	// Перебираем события и формируем суммарные длительности 	
	foreach (string eventDuration in eventDurations)
	{
		// eventDuration - строка c форматом: архив|ввод|канал|код|длительность
		string[] codeDuration = (eventDuration.Trim()).Split(new string[]{"|"}, StringSplitOptions.RemoveEmptyEntries);
		
		// Код типа архива 
		int archiveType = -1;
		if (!String.IsNullOrEmpty(codeDuration[0].Trim()))
			archiveType = Convert.ToInt32(codeDuration[0]);

		// Номер теплового ввода 
		int heatLeadIn = -1;
		if (!String.IsNullOrEmpty(codeDuration[1].Trim()))
			heatLeadIn = Convert.ToInt32(codeDuration[1]);

		// Номер канала 
		int channelNumber = -1;
		if (!String.IsNullOrEmpty(codeDuration[2].Trim()))
			channelNumber = Convert.ToInt32(codeDuration[2]);

		// Код события
		int code = -1;
		if (!String.IsNullOrEmpty(codeDuration[3].Trim()))
			code = Convert.ToInt32(codeDuration[3]);

		// Длительность события в секундах
		double duration = 0;
		if (!String.IsNullOrEmpty(codeDuration[4].Trim()))
			duration = Convert.ToDouble(codeDuration[4]);

		// Переводим длительность события из секунд в доли часа
		duration = duration / 3600D;

		// Период отключения питания
		if (Array.Exists(codes_U, delegate(int c) { return (c == code); }))
			period_U += duration;

		// Период t1-t2 < min
		else if (Array.Exists(codes_D, delegate(int c) { return (c == code); }))
			period_D += duration;

		// Период функционального отказа
		else if (Array.Exists(codes_E, delegate(int c) { return (c == code); }))
			period_E += duration;

		// Период G > max
		else if (Array.Exists(codes_G, delegate(int c) { return (c == code); }))
			period_G += duration;

		// Период G < min
		else if (Array.Exists(codes_g, delegate(int c) { return (c == code); }))
			period_g += duration;

		// Период прочих кодов
		else 
			period_other += duration;
	}
}
// Отображаем суммарные периоды событий
private void Period_BeforePrint(object sender, System.Drawing.Printing.PrintEventArgs e) 
{
	XRLabel label = (XRLabel)sender;

	double period = 0;
	switch (label.Name)
	{
		case "lblPeriod_U":	// Период отключения питания
			period = period_U;
			break;

		case "lblPeriod_D":	// Период t1-t2 < min
			period = period_D;
			break;

		case "lblPeriod_E":	// Период функционального отказа
			period = period_E;
			break;

		case "lblPeriod_Gmax":	// Период G > max
			period = period_G;
			break;

		case "lblPeriod_Gmin":	// Период G < min
			period = period_g;
			break;

		case "lblPeriod_Other":	// Период прочие
			period = period_other;
			break;
	}

	label.Text = String.Format("{0:F3}", period);
}


" SnapGridSize="31.75" ReportUnit="TenthsOfAMillimeter" Margins="249, 98, 99, 55" PaperKind="A4" PageWidth="2100" PageHeight="2970" Version="16.2" RequestParameters="false" DataMember="Архив суточный" DataSource="#Ref-0" Dpi="254" Tag_type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" Tag="1|321">
<Parameters>
<Item1 Ref="3" Description="Идентификатор учетной записи" ValueInfo="0" Name="ACCOUNT_ID" Type="#Ref-2" />
<Item2 Ref="5" Description="Дата начала отчетного периода" ValueInfo="2017-01-19" Name="DATE_START" Type="#Ref-4" />