/// <summary> /// Конструктор /// </summary> /// <param name="dtStartClien">Начало по времени клиента</param> /// <param name="dtEndClient">Окончание по времени клиента</param> /// <param name="clientTimeZoneId">Идентификатор часового пояса клиента</param> /// <param name="unitDigit">Запрошенные ед. измерения</param> /// <param name="discreteType"></param> public RecalculatorResiudes(DateTime dtStartClien, DateTime dtEndClient, string clientTimeZoneId, EnumUnitDigit unitDigit, enumTimeDiscreteType discreteType) { _tiForRecalculateResiudes = new ConcurrentStack <TArchivesValue>(); TiForResaveResiudes = new ConcurrentStack <DBResiduesTable>(); _dtStartClient = dtStartClien; _dtStartServer = _dtStartClient.ClientToServer(clientTimeZoneId); _unitDigit = unitDigit; _discreteType = discreteType; _resiudes24Hindexes = MyListConverters.GetIntervalTimeList(dtStartClien, dtEndClient, enumTimeDiscreteType.DB24Hour, clientTimeZoneId); }
private MemoryStream ФормируемАктУчетаЭэ(XlsFileExBase xls, BalanceFreeHierarchyCalculatedResult balanceCalculatedResult, bool isHeaderFormed) { xls.ActiveSheet = 1; xls.SheetName = "Report"; xls.SheetZoom = 100; xls.StartRow = 5; xls.StartCol = 1; var f = xls.GetCellVisibleFormatDef(3, 6); f.Font.Style = TFlxFontStyles.Bold; //if (_adapterType == TExportExcelAdapterType.toHTML) //{ // f.FillPattern.Pattern = TFlxPatternStyle.Solid; // f.FillPattern.FgColor = Color.FromArgb(255, 244, 250, 254); //} var boldFormat = xls.AddFormat(f); List <IFreeHierarchyBalanceSignature> signatures = null; if (_signaturesByBalance != null) { _signaturesByBalance.TryGetValue(balanceCalculatedResult.BalanceFreeHierarchyUn, out signatures); } #region Шапка if (!isHeaderFormed) { xls.SetCellValue(1, 3, "Акт учета (оборота) электрической энергии "); xls.SetCellValue(2, 3, "Субъект ОРЭ: " + _branchName); xls.SetCellValue(3, 3, "Расчетный период: " + _dtStart.ToString("dd-MM-yyyy HH:mm") + "-" + _dtEnd.ToString("dd-MM-yyyy HH:mm")); } else { //Обрабатываем наши ф-ии SpreadsheetFunctionHelper.Evaluate(xls, this, out xls.StartRow, _errors); } #endregion //f.Font.Name = "Arial Cyr"; //f.Font.Size20 = 180; f.Font.Style = TFlxFontStyles.None; f.VAlignment = TVFlxAlignment.center; f.HAlignment = THFlxAlignment.center; f.Borders.Bottom.Color = _borderColor; f.Borders.Left.Color = _borderColor; f.Borders.Right.Color = _borderColor; f.Borders.Top.Color = _borderColor; f.Borders.Bottom.Style = TFlxBorderStyle.Dotted; f.Borders.Left.Style = TFlxBorderStyle.Dotted; f.Borders.Right.Style = TFlxBorderStyle.Dotted; f.Borders.Top.Style = TFlxBorderStyle.Dotted; f.WrapText = true; var centerFormat = xls.AddFormat(f); f.WrapText = false; f.HAlignment = THFlxAlignment.right; var rightFormat = xls.AddFormat(f); f.Font.Style = TFlxFontStyles.Bold; var rightBoldFormat = xls.AddFormat(f); f.Format = "### ### ### ### ##0." + new string('0', _doublePrecisionProfile); var rightDoubleBoldFormat = xls.AddFormat(f); f.Font.Style = TFlxFontStyles.None; var rightDoubleFormat = xls.AddFormat(f); f.HAlignment = THFlxAlignment.left; f.Font.Style = TFlxFontStyles.None; f.WrapText = true; f.Format = ""; var leftFormat = xls.AddFormat(f); xls.Row = xls.StartRow; var days = new List <int>(); var hours = 0; #region Колонка с датой временем var prevDay = 0; var prevRow = -1; foreach (var dt in _dts) { //смена дня if (dt.Day != prevDay) { if (prevRow > 0) { xls.MergeCells(prevRow, xls.StartCol, xls.Row, xls.StartCol); xls.SetCellFormat(prevRow, xls.StartCol, xls.Row, xls.StartCol, centerFormat); xls.SetCellValue(xls.Row, xls.StartCol + 1, "Итого", rightBoldFormat); xls.Row++; days.Add(hours); xls.Row++; hours = 0; } xls.SetCellValue(xls.Row, xls.StartCol, "Дата", centerFormat); xls.MergeCells(xls.Row, xls.StartCol, xls.Row + 3, xls.StartCol); xls.SetCellValue(xls.Row, xls.StartCol + 1, "Время", centerFormat); xls.MergeCells(xls.Row, xls.StartCol + 1, xls.Row + 3, xls.StartCol + 1); prevDay = dt.Day; xls.Row = xls.Row + 4; prevRow = xls.Row; xls.SetCellValue(xls.Row, xls.StartCol, dt.ToString("dd.MM.yyyy"), rightFormat); } xls.SetCellValue(xls.Row, xls.StartCol + 1, dt.ToString("HH:mm-") + dt.AddMinutes(((int)_discreteType + 1) * 30).ToString("HH:mm"), rightFormat); hours++; xls.Row++; } //Последняя запись if (prevRow > 0) { xls.MergeCells(prevRow, xls.StartCol, xls.Row, xls.StartCol); xls.SetCellFormat(prevRow, xls.StartCol, xls.Row, xls.StartCol, centerFormat); xls.SetCellValue(xls.Row, xls.StartCol + 1, "Итого", rightBoldFormat); days.Add(hours); } //Итого за период xls.Row++; xls.SetCellValue(xls.Row, xls.StartCol, "ИТОГО за период, " + _unitDigitName, rightBoldFormat); xls.MergeCells(xls.Row, xls.StartCol, xls.Row, xls.StartCol + 1); #endregion xls.Col = xls.StartCol + 2; foreach (var itemParams in balanceCalculatedResult.ItemsParamsBySection.Values) { foreach (var itemParam in itemParams.OrderBy(itm => itm.SortNumber)) { if (itemParam.HalfHours == null) { continue; } var archives = MyListConverters.ConvertHalfHoursToOtherList(_discreteType, itemParam.HalfHours, 0, _intervalTimeList); xls.SetColWidth(xls.Col, 4364); xls.Row = xls.StartRow; var totalHours = 0; var totalSum = 0.0; //Перебираем дни foreach (var dayHours in days) { xls.SetCellValue(xls.Row, xls.Col, itemParam.Name + ",\n" + _unitDigitName, centerFormat); xls.MergeCells(xls.Row, xls.Col, xls.Row + 3, xls.Col); xls.Row = xls.Row + 4; var daySum = 0.0; var row1 = xls.Row; //Перебираем часы в этом дне for (var hour = 0; hour < dayHours; hour++) { var aVal = archives.ElementAtOrDefault(totalHours + hour); if (aVal != null) { daySum += aVal.F_VALUE; xls.SetCellValue(xls.Row, xls.Col, aVal.F_VALUE, rightDoubleFormat); } else { xls.SetCellFormat(xls.Row, xls.Col, rightDoubleFormat); } xls.Row++; } //Итого WriteRowRangeFormulaToCell(xls, "-1", xls.Row, xls.Col, rightDoubleFormat, daySum, new FormulaRowsRange { Col = xls.Col, Row1 = row1, Row2 = xls.Row - 1 }); AddRowRangeToFormulaSum(xls, "1", new FormulaRowsRange { Col = xls.Col, Row1 = xls.Row, Row2 = xls.Row }); totalSum += daySum; xls.Row++; xls.Row++; totalHours += dayHours; } //Итого за период WriteRowRangeFormulaToCell(xls, "1", xls.Row - 1, xls.Col, rightDoubleBoldFormat, totalSum); //_xls.SetCellValue(xls._row - 1, xls._col, totalSum, rightDoubleBoldFormat); xls.Col++; } } #region Подписанты xls.StartRow = xls.Row; xls.Row++; xls.Row++; WriteSignatures(xls, signatures, boldFormat, leftFormat); //_xls.SetCellFormat(startRow, 1, xls._row, 9, leftFormat); #endregion xls.SetCellFormat(1, 1, 4, xls.Col - 1, boldFormat); return(Export(xls)); }
public void RecalculateResiudes(TDRParams param, Action <TDRParams, ConcurrentStack <TArchivesValue>, List <TI_ChanelType>, bool> getArchivesAndCalculateResiudesFromMonthStartAction) { if (getArchivesAndCalculateResiudesFromMonthStartAction == null) { return; } #if DEBUG var sw = new System.Diagnostics.Stopwatch(); sw.Start(); #endif if (_tiForRecalculateResiudes != null && _tiForRecalculateResiudes.Count > 0) { //Перерасчет ТИ по которым небыло найдено остатков в предыдущем дне var tiArray = _tiForRecalculateResiudes .Select(t => new TI_ChanelType { TI_ID = t.TI_Ch_ID.TI_ID, ChannelType = t.TI_Ch_ID.ChannelType, ClosedPeriod_ID = t.TI_Ch_ID.ClosedPeriod_ID, DataSourceType = t.DataSourceType, IsCA = t.TI_Ch_ID.IsCA, MsTimeZone = t.TI_Ch_ID.MsTimeZone, TP_ID = t.TI_Ch_ID.TP_ID, }) .ToList(); var archivesValue30OrHour = new ConcurrentStack <TArchivesValue>(); //Дата/время с которого пересчитываем var dtStartMonthClient = param.DtServerStart.AddMonths(-MonthForRecalculateResidues); dtStartMonthClient = new DateTime(dtStartMonthClient.Year, dtStartMonthClient.Month, 1); var newParam = new TDRParams(param.IsCoeffEnabled, param.isCAEnabled, param.OvMode, param.isCAReverse, enumTimeDiscreteType.DBHalfHours, param.UnitDigit, param.IsPower, param.TIs, dtStartMonthClient.ClientToServer(param.ClientTimeZoneId), param.DtServerStart.AddMinutes(-30), MyListConverters.GetIntervalTimeList(dtStartMonthClient, param.DtServerStart.AddMinutes(-30).ServerToClient(param.ClientTimeZoneId), enumTimeDiscreteType.DBHalfHours, param.ClientTimeZoneId), param.ClientTimeZoneId, param.IsValidateOtherDataSource, param.IsReadCalculatedValues, param.IsReadAbsentChannel, param.RoundData) { IsNotRecalculateResiudes = true }; //Запрос данных с начала месяца getArchivesAndCalculateResiudesFromMonthStartAction(newParam, archivesValue30OrHour, tiArray, false); #if DEBUG sw.Stop(); Console.WriteLine("Запрос архивов для перерасчета - > ПУ: {0} шт, время: {1} млс", tiArray.Count, sw.ElapsedMilliseconds); sw.Restart(); #endif //if (newParam.RecalculatorResiudes != null && newParam.RecalculatorResiudes.TiForResaveResiudes.Count > 0) //{ //TiForResaveResiudes.PushRange(newParam.RecalculatorResiudes.TiForResaveResiudes.ToArray()); //} var prev24HEventDate = param.DtServerStart.AddMinutes(-30); Dictionary <int, List <DBResiduesTable> > resiudesDict = null; if (newParam.RecalculatorResiudes != null && newParam.RecalculatorResiudes.TiForResaveResiudes != null) { resiudesDict = newParam.RecalculatorResiudes.TiForResaveResiudes .GroupBy(r => r.TI_ID) .ToDictionary(k => k.Key, v => v.ToList()); } //Дорасчитываем остатки по ТИ у которых их нет в предыдущих сутках foreach (var av in _tiForRecalculateResiudes) { List <DBResiduesTable> resiudesTi; DBResiduesTable prevDayResiude = null; if (resiudesDict != null && resiudesDict.TryGetValue(av.TI_Ch_ID.TI_ID, out resiudesTi) && resiudesTi != null) { prevDayResiude = resiudesTi .FirstOrDefault(r => r.ChannelType == av.TI_Ch_ID.ChannelType && r.EventDate < prev24HEventDate && //Коллеция идет от Stack поэтому дата, время идет по убывающей r.DataSourceType == av.DataSourceType); } CalculateResiudes(av, prevDayResiude, true, param.UseLossesCoefficient, isNotRecalculateResiudes: param.IsNotRecalculateResiudes); } #if DEBUG sw.Stop(); Console.WriteLine("Расчет остатков - > {0} млс", sw.ElapsedMilliseconds); sw.Restart(); #endif } //Запускаем сохранение остатков и выходим if (TiForResaveResiudes.Count > 0) { Task.Factory.StartNew(() => SaveResiudes(TiForResaveResiudes, param.HalfHoursShiftClientFromServer, param.IsReadCalculatedValues)); } #if DEBUG sw.Stop(); Console.WriteLine("Сохранение остатков - > {0} млс", sw.ElapsedMilliseconds); #endif }
private MemoryStream ФормируемПриложение51(XlsFileExBase xls, BalanceFreeHierarchyCalculatedResult balanceCalculatedResult, bool isHeaderFormed) { xls.ActiveSheet = 1; var sheetName = xls.SheetName = "Приложение"; xls.SetPrintMargins(new TXlsMargins(0.75, 1, 0.75, 1, 0.5, 0.5)); xls.SheetZoom = 100; #region Добавление форматов var f = xls.GetCellVisibleFormatDef(1, 4); f.Font.Name = "Tahoma"; f.Font.Family = 2; f.HAlignment = THFlxAlignment.center; f.WrapText = true; if (_doublePrecisionProfile == 0) { f.Format = "#,##0"; } else { f.Format = "#,##0." + new string(_need0 ? '0' : '#', _doublePrecisionProfile); } var centerFormat = xls.AddFormat(f); f = xls.GetCellVisibleFormatDef(4, 1); if (_doublePrecisionProfile == 0) { f.Format = "#,##0"; } else { f.Format = "#,##0." + new string(_need0 ? '0' : '#', _doublePrecisionProfile); } f.Font.Name = "Tahoma"; f.Font.Family = 2; f.Borders.Left.Style = TFlxBorderStyle.Thin; f.Borders.Left.Color = Color.FromArgb(0x00, 0x00, 0x00); f.Borders.Right.Style = TFlxBorderStyle.Thin; f.Borders.Right.Color = Color.FromArgb(0x00, 0x00, 0x00); f.Borders.Top.Style = TFlxBorderStyle.Thin; f.Borders.Top.Color = Color.FromArgb(0x00, 0x00, 0x00); f.Borders.Bottom.Style = TFlxBorderStyle.Thin; f.Borders.Bottom.Color = Color.FromArgb(0x00, 0x00, 0x00); f.HAlignment = THFlxAlignment.center; f.VAlignment = TVFlxAlignment.center; f.WrapText = true; var borderedCenterFormat = xls.AddFormat(f); f.Font.Style = TFlxFontStyles.Bold; var boldBorderedCenterFormat = xls.AddFormat(f); var startRow = 18; var startCol = 1; #endregion xls.ProfileFormat = xls.NoDecimalFormat = borderedCenterFormat; List <Dict_Balance_FreeHierarchy_Section> sections = null; if (_balanceCalculated.SectionsByType != null) { _balanceCalculated.SectionsByType.TryGetValue(balanceCalculatedResult.BalanceFreeHierarchyType, out sections); } if (!isHeaderFormed) { #region Шапка xls.SetColWidth(1, 9142); //(34.96 + 0.75) * 256 xls.SetColWidth(2, 4554); //(11.96 + 0.75) * 256 xls.SetColWidth(3, 6582); //(24.96 + 0.75) * 256 xls.SetColWidth(4, 6582); //(24.96 + 0.75) * 256 xls.MergeCells(10, 1, 10, 3); xls.MergeCells(12, 1, 12, 3); xls.MergeCells(1, 2, 3, 3); xls.MergeCells(4, 1, 4, 3); xls.MergeCells(6, 1, 6, 3); xls.MergeCells(8, 1, 8, 3); xls.SetCellFormat(1, 1, 3, 3, centerFormat); xls.SetCellValue(1, 2, "Приложение № 63\nк приказу Минэнерго России\nот 23 июля 2012г. №340"); xls.SetCellFormat(4, 1, 4, 3, boldBorderedCenterFormat); //_xls.Add //_xls.SetCellFromHtml(4, 1, "<b>121212</b> weqeeqewq <i>wwewewewe</i>"); xls.SetCellValue(4, 1, "Показатели баланса производства и потребления электроэнергии\n" + "и отпуска тепловой энергии по субьектам электроэнергетики\n" + "в границах субьектов Российской Федерации\n" + "за " + DateTime.Now.Date.Year.ToString() + " год."); xls.SetRowHeight(4, 1000); xls.SetCellFormat(6, 1, 6, 3, borderedCenterFormat); xls.SetCellValue(6, 1, "КОНФИДЕНЦИАЛЬНОСТЬ ГАРАНТИРУЕТСЯ ПОЛУЧАТЕЛЕМ ИНФОРМАЦИИ"); xls.SetCellFormat(8, 1, 8, 3, borderedCenterFormat); xls.SetCellValue(8, 1, "ВОЗМОЖНО ПРЕДСТАВЛЕНИЕ В ЭЛЕКТРОННОМ ВИДЕ"); xls.SetCellFormat(9, 1, 10, 3, borderedCenterFormat); xls.SetCellValue(10, 1, "1. Предоставляется электростанциями генерирующих компаний и других собственников, ФГУП `Концерн " + "Росэнергоатом`, котельными"); xls.SetRowHeight(10, 500); xls.SetCellFormat(12, 1, 12, 3, borderedCenterFormat); xls.SetCellValue(12, 1, balanceCalculatedResult.DocumentName.Replace("№51", "№63") + " филиал " + _branchName); xls.SetCellFormat(13, 1, 14, 3, centerFormat); xls.SetCellValue(14, 2, string.Format("{0:dd.MM.yyyy}", _dtEnd)); xls.SetCellValue(14, 3, _unitDigitName + ", " + _unitDigitHeatName); #endregion } else { //Обрабатываем наши ф-ии SpreadsheetFunctionHelper.Evaluate(xls, this, out startRow, _errors); } #region Заголовок таблицы xls.SetCellFormat(startRow, 1, startRow + 2, 3, borderedCenterFormat); xls.SetCellValue(startRow, 1, "Наименование показателя"); xls.MergeCells(startRow, 1, startRow + 1, 1); xls.SetCellValue(startRow, 2, "Фактические значения показателя"); xls.MergeCells(startRow, 2, startRow, 3); xls.SetRowHeight(startRow, 400); xls.SetCellValue(startRow + 1, 2, "за сутки"); xls.SetCellValue(startRow + 1, 3, "нарастающим итогом с начала месяца"); startRow++; startRow++; xls.SetCellValue(startRow, 1, "А"); xls.SetCellValue(startRow, 2, "1"); xls.SetCellValue(startRow, 3, "2"); startRow++; #endregion #region Таблица if (_doublePrecisionProfile == 0) { f.Format = "#,##0"; } else { f.Format = "#,##0." + new string(_need0 ? '0' : '#', _doublePrecisionProfile); } var boldBorderedDoubleFormat = xls.AddFormat(f); xls.ProfileBoldFormat = boldBorderedDoubleFormat; var sectionNumber = 1; var row = startRow; double potreb = 0.0, potrebDaily = 0.0; foreach (var section in sections.OrderBy(s => s.SortNumber)) { xls.SetCellValue(row, startCol, section.SectionName, boldBorderedCenterFormat); xls.SetCellValue(row, startCol + 1, row - startRow + 1, boldBorderedCenterFormat); var sectionRow = row; List <BalanceFreeHierarchyItemParams> itemParams; //Все объекты для данного раздела balanceCalculatedResult.ItemsParamsBySection.TryGetValue(section.Section_UN, out itemParams); var formulaIdSumm = "summ" + section.SortNumber; var formulaIdDailySumm = "dailySumm" + section.SortNumber; double sectionSum = 0.0, sectionDailySum = 0.0; var itemNumber = 1; if (itemParams != null && itemParams.Count > 0) { //Перебираем объекты в разделе foreach (var itemParam in itemParams.OrderBy(itm => itm.SortNumber)) { TVALUES_DB latestDay = null; var daysSumm = 0.0; var coeff = itemParam.Coef ?? 1; if (itemParam.HalfHours != null) { var archives = MyListConverters.ConvertHalfHoursToOtherList(_discreteType, itemParam.HalfHours, 0, _intervalTimeList); latestDay = archives.LastOrDefault(); //Нарастающее с начала месяца daysSumm = archives.Sum(itm => itm.F_VALUE); } //Объекты в разделе отображаем только для поступления if (Equals(section.MetaString1, "postupilo")) { row++; xls.SetCellValue(row, startCol, sectionNumber + "." + itemNumber + " " + itemParam.Name, borderedCenterFormat); //_xls.SetCellValue(row, startCol + 1, row - startRow + 1, borderedCenterFormat); if (latestDay != null) { //Факт за последние сутки xls.SetCellFloatValue(row, startCol + 1, latestDay.F_VALUE * coeff, false); } else { xls.SetCellFormat(row, startCol + 1, borderedCenterFormat); } xls.SetCellFloatValue(row, startCol + 2, daysSumm * coeff, false); AddRowRangeToFormulaSum(xls, formulaIdSumm, new FormulaRowsRange { Row1 = row, Row2 = row, Col = startCol + 1, }); AddRowRangeToFormulaSum(xls, formulaIdDailySumm, new FormulaRowsRange { Row1 = row, Row2 = row, Col = startCol + 2, }); itemNumber++; } if (latestDay != null) { sectionSum += latestDay.F_VALUE * coeff; } sectionDailySum += daysSumm * coeff; } } if (Equals(section.MetaString1, "postupilo")) { potreb += sectionSum; potrebDaily += sectionDailySum; } else if (Equals(section.MetaString1, "saldo")) { potreb -= sectionSum; potrebDaily -= sectionDailySum; } if (Equals(section.MetaString1, "potreb")) { sectionSum = potreb; sectionDailySum = potrebDaily; } if (!string.IsNullOrEmpty(section.MetaString1)) { if (!Equals(section.MetaString1, "potreb")) { WriteFormulaToCell(xls, formulaIdSumm, sectionRow, startCol + 1, boldBorderedDoubleFormat, sectionSum); WriteFormulaToCell(xls, formulaIdDailySumm, sectionRow, startCol + 2, boldBorderedDoubleFormat, sectionDailySum); } else { xls.SetCellFloatValue(sectionRow, startCol + 1, sectionSum, false); xls.SetCellFloatValue(sectionRow, startCol + 2, sectionDailySum, false); } } else { xls.SetCellFormat(sectionRow, startCol + 1, sectionRow, startCol + 2, boldBorderedDoubleFormat); } sectionNumber++; row++; } #endregion return(Export(xls)); }
public ExcelReportFreeHierarchyAdapter(BalanceFreeHierarchyResults balanceCalculated, Dictionary <string, List <IFreeHierarchyBalanceSignature> > signaturesByBalance, TExportExcelAdapterType adapterType, StringBuilder errors, bool isFormingSeparateList, bool isUseThousandKVt, bool printLandscape, string branchName, byte doublePrecisionProfile, byte doublePrecisionIntegral, bool need0, bool isAnalisIntegral, string timeZoneId, bool setPercisionAsDisplayed) { _branchName = branchName; _printLandscape = printLandscape; _balanceCalculated = balanceCalculated; _signaturesByBalance = signaturesByBalance; AdapterType = adapterType; _discreteType = balanceCalculated.DiscreteType; _errors = errors; _dtStart = balanceCalculated.DTStart; _dtEnd = balanceCalculated.DTEnd; _dts = MyListConverters.GetDateTimeListForPeriod(balanceCalculated.DTStart, balanceCalculated.DTEnd, balanceCalculated.DiscreteType, balanceCalculated.TimeZoneId.GeTimeZoneInfoById()); _isFormingSeparateList = isFormingSeparateList && (AdapterType == TExportExcelAdapterType.toXLS || AdapterType == TExportExcelAdapterType.toXLSx); _unitDigitIntegrals = balanceCalculated.UnitDigitIntegrals; _unitDigit = balanceCalculated.UnitDigit; _doublePrecisionIntegral = doublePrecisionIntegral; _doublePrecisionProfile = doublePrecisionProfile; _need0 = need0; IsAnalisIntegral = isAnalisIntegral; _setPercisionAsDisplayed = setPercisionAsDisplayed; _intervalTimeList = MyListConverters.GetIntervalTimeList(_dtStart, _dtEnd, _discreteType, timeZoneId); switch (_unitDigit) { case EnumUnitDigit.Null: case EnumUnitDigit.None: _unitDigitName = ""; break; case EnumUnitDigit.Kilo: _unitDigitName = "к"; break; case EnumUnitDigit.Mega: _unitDigitName = isUseThousandKVt ? "тыс.к" : "М"; break; } switch (_unitDigitIntegrals) { case EnumUnitDigit.Null: case EnumUnitDigit.None: _unitDigitIntegralName = ""; break; case EnumUnitDigit.Kilo: _unitDigitIntegralName = "к"; break; case EnumUnitDigit.Mega: _unitDigitIntegralName = isUseThousandKVt ? "тыс.к" : "М"; break; } _unitDigitHeatName = "Гкал"; //решили что отпуск тепла будет хранится/отображаться как есть (например в ЛЭРС) в Гкал _unitDigitName += "Вт*ч"; _unitDigitIntegralName += "Вт*ч"; }
/// <summary> /// Берем первую попавшуюся модель прогнозирования для объекта /// </summary> /// <param name="forecastObjectUn"></param> /// <returns></returns> public static List <TForecastCalculateParams> GetForecastObjectParams(HashSet <string> forecastObjectUns, DateTime dtStart, DateTime dtEnd, int?forecastModelUserSelected, string timeZoneId, StringBuilder errors, EnumUnitDigit unitDigit, enumTimeDiscreteType forecastDiscreteType, bool isReadCalculatedValues) { var tis = new List <TI_ChanelType>(); var formulas = new List <TFormulaParam>(); var tps = new List <TP_ChanelType>(); var nodes = new List <long>(); var result = new Dictionary <string, TForecastCalculateParams>(); var periodsPriorityByForecastObject = new Dictionary <string, Dictionary <string, Queue <PeriodHierarchy> > >(); if (forecastObjectUns == null) { return(result.Values.ToList()); } #region Читаем параметры объектов прогнозирования из базы var forecastObjectUnsString = string.Join(",", forecastObjectUns); try { using (var db = new LightDBDataContext(Settings.DbConnectionString) { ObjectTrackingEnabled = false, //Указываем что это у нас ReadOnly DeferredLoadingEnabled = false, CommandTimeout = 180, }) { var multiResult = db.usp2_ForecastObjectParams(forecastObjectUnsString, dtStart.ClientToServer(timeZoneId), dtEnd.ClientToServer(timeZoneId)); //Читаем доступные модели, которым будем считать foreach (var modelsGroupByObject in multiResult.GetResult <usp2_ForecastObjectParamsResult1>().ToList().GroupBy(g => g.ForecastObject_UN)) { result[modelsGroupByObject.Key] = new TForecastCalculateParams(modelsGroupByObject.Key, forecastModelUserSelected, new HashSet <int>(modelsGroupByObject.Where(m => m.ForecastCalculateModel_ID.HasValue).OrderBy(m => m.Priority ?? 1000).Select(m => (int)(m.ForecastCalculateModel_ID ?? 0)))); } #region Читаем ТИ, ТП формулы и т.д. для обсчета foreach (var inputParamByObject in multiResult.GetResult <usp2_ForecastObjectParamsResult2>().ToList().GroupBy(g => g.ForecastObject_UN)) { TForecastCalculateParams calculateParams; if (!result.TryGetValue(inputParamByObject.Key, out calculateParams) || calculateParams == null) { continue; } calculateParams.DtStart = dtStart; calculateParams.DtEnd = dtEnd; calculateParams.DiscreteType = forecastDiscreteType; var periodsByInputParam = new Dictionary <string, Queue <PeriodHierarchy> >(); periodsPriorityByForecastObject[inputParamByObject.Key] = periodsByInputParam; foreach (var inputParam in inputParamByObject.GroupBy(g => g.ForecastInputParam_UN)) { var periods = new Queue <PeriodHierarchy>(); periodsByInputParam[inputParam.Key] = periods; var archiveByInputParam = new ForecastByInputParamArchives(inputParam.Key); calculateParams.ArchivesByInputParam.Add(archiveByInputParam); var isFirst = true; foreach (var physicalParam in inputParam) { bool isFullPeriod; var period = BuildHalfHoursPeriods(physicalParam, dtStart, dtEnd, timeZoneId, out isFullPeriod); if (isFirst) { archiveByInputParam.MeasureQuantityType_UN = physicalParam.MeasureQuantityType_UN; isFirst = false; } //Формула if (!string.IsNullOrEmpty(physicalParam.Formula_UN)) { var formulaParam = new TFormulaParam { FormulaID = physicalParam.Formula_UN, FormulasTable = enumFormulasTable.Info_Formula_Description, IsFormulaHasCorrectDescription = true, }; formulas.Add(formulaParam); //archiveByInputParam.Formulas.Add(formulaParam); periods.Enqueue(new PeriodHierarchy { Id = new ID_Hierarchy_Channel(enumTypeHierarchy.Formula, physicalParam.Formula_UN, 0), IsFullPeriod = isFullPeriod, IndxStart = period.Item1, IndxFinish = period.Item2, }); if (isFullPeriod) { continue; //Объект действует на весь период, остальные объекты пропускаем } } //OPC пока не используется, т.к. не понятно как приводить к получасовкам if (physicalParam.UANode_ID.HasValue) { //archiveByInputParam.Nodes.Add(physicalParam.UANode_ID.Value); nodes.Add(physicalParam.UANode_ID.Value); periods.Enqueue(new PeriodHierarchy { Id = new ID_Hierarchy_Channel(enumTypeHierarchy.UANode, physicalParam.UANode_ID.Value.ToString(), 0), IsFullPeriod = isFullPeriod, IndxStart = period.Item1, IndxFinish = period.Item2, }); if (isFullPeriod) { continue; //Объект действует на весь период, остальные объекты пропускаем } } //Для остальных нужен канал, если не указан пропускаем //if (!inputParam.ChannelType.HasValue) continue; //ТИ if (physicalParam.TI_ID.HasValue) { if (!physicalParam.ChannelType.HasValue) { errors.Append("Для ТИ {").Append(physicalParam.TI_ID).Append("} нужно указать канал"); continue; } var tiId = new TI_ChanelType { ChannelType = physicalParam.ChannelType.Value, TI_ID = physicalParam.TI_ID.Value, MsTimeZone = timeZoneId, //Это возможно не нужно }; //archiveByInputParam.TiIds.Add(tiId); tis.Add(tiId); periods.Enqueue(new PeriodHierarchy { Id = new ID_Hierarchy_Channel(enumTypeHierarchy.Info_TI, physicalParam.TI_ID.Value.ToString(), physicalParam.ChannelType.Value), IsFullPeriod = isFullPeriod, IndxStart = period.Item1, IndxFinish = period.Item2, }); if (isFullPeriod) { continue; //Объект действует на весь период, остальные объекты пропускаем } } //ТП if (physicalParam.TP_ID.HasValue) { if (!physicalParam.ChannelType.HasValue) { errors.Append("Для ТП {").Append(physicalParam.TP_ID).Append("} нужно указать канал"); continue; } var tpId = new TP_ChanelType { ChannelType = physicalParam.ChannelType.Value, TP_ID = physicalParam.TP_ID.Value, }; //archiveByInputParam.TpIds.Add(tpId); tps.Add(tpId); periods.Enqueue(new PeriodHierarchy { Id = new ID_Hierarchy_Channel(enumTypeHierarchy.Info_TP, physicalParam.TP_ID.Value.ToString(), physicalParam.ChannelType.Value), IsFullPeriod = isFullPeriod, IndxStart = period.Item1, IndxFinish = period.Item2, }); } } } } #endregion } } catch (Exception ex) { errors.Append(ex.Message); } #endregion #region Читаем архивы //Пока запрашиваем только получасовки var resultCommonTi = new ArchivesValues_List2(tis, dtStart, dtEnd, true, false, enumTimeDiscreteType.DBHalfHours, enumTypeInformation.Energy, false, unitDigit, enumOVMode.NormalMode, timeZoneId, isReadCalculatedValues: isReadCalculatedValues); if (resultCommonTi.Errors != null) { errors.Append(resultCommonTi.Errors); } //Запрос значений всех ТП var resultCommonTp = new ArchivesTPValues(tps, dtStart, dtEnd, enumBusRelation.PPI_OurSide, enumTimeDiscreteType.DBHalfHours, null, enumTypeInformation.Energy, unitDigit, timeZoneId, false, isSupressTpNotFound: true, isReadCalculatedValues: isReadCalculatedValues); if (resultCommonTp.Errors != null) { errors.Append(resultCommonTp.Errors); } //Все формулы var resultCommonFormula = new FormulasResult(formulas, dtStart, dtEnd, enumTimeDiscreteType.DBHalfHours, null, 0, enumTypeInformation.Energy, unitDigit, timeZoneId, //Для описанных здесь формул ед. изм. не учитываем true, false, false, false, isReadCalculatedValues: isReadCalculatedValues, ovMode: enumOVMode.NormalMode); //Для формулы сумму с ОВ считаем всегда!!! if (resultCommonFormula.Errors != null) { errors.Append(resultCommonFormula.Errors); } //Чтение архивов OPC UADataReader resultCommonUAData = null; try { resultCommonUAData = new UADataReader(nodes, dtStart, dtEnd, false, false, false, timeZoneId); } catch { } #endregion #region Подготовка архивов var numberHalfHoursForForecasting = MyListConverters.GetNumbersValuesInPeriod(enumTimeDiscreteType.DBHalfHours, dtStart, dtEnd, timeZoneId); result.Values.AsParallel().ForAll(calculateParam => //AsParallel().ForAll() { //new TVALUES_DB[numberHalfHoursForForecasting].Select(v => new TVALUES_DB(VALUES_FLAG_DB.IsNull, 0)).ToList(); Dictionary <string, Queue <PeriodHierarchy> > periodsByInputParam; if (!periodsPriorityByForecastObject.TryGetValue(calculateParam.ForecastObject_UN, out periodsByInputParam) || periodsByInputParam.Count == 0) { return; //Нет параметров для обсчета } foreach (var paramArchives in calculateParam.ArchivesByInputParam) { Queue <PeriodHierarchy> periods; if (!periodsByInputParam.TryGetValue(paramArchives.ForecastInputParamUn, out periods) || periods.Count == 0) { continue; //Нет параметров для обсчета } //var period = periods.Dequeue(); //Первый объект в интервале PeriodHierarchy period = null; var halfHours = new List <TVALUES_DB>(); for (var hh = 0; hh < numberHalfHoursForForecasting; hh++) { if (!PeriodInHalfHour(ref period, periods, hh, resultCommonTi, resultCommonFormula, resultCommonTp, resultCommonUAData) || period.Archives == null) { halfHours.Add(new Servers.Calculation.DBAccess.Interface.Data.TVALUES_DB(VALUES_FLAG_DB.IsNull, 0)); //Получасовка не входит в наш диапазон, или нет архива continue; } var aVal = period.Archives.ElementAtOrDefault(hh); if (aVal == null) { aVal = new Servers.Calculation.DBAccess.Interface.Data.TVALUES_DB(VALUES_FLAG_DB.IsNull, 0); //Непонятная ситуация, помечаем как отсутствующие } var cVal = halfHours.ElementAtOrDefault(hh); if (cVal == null) { cVal = new Servers.Calculation.DBAccess.Interface.Data.TVALUES_DB(aVal.F_FLAG, aVal.F_VALUE); halfHours.Add(cVal); } else { cVal.F_VALUE = aVal.F_VALUE; cVal.F_FLAG = aVal.F_FLAG; } } paramArchives.Archives.AddRange(MyListConverters.ConvertHalfHoursToOtherList(forecastDiscreteType, halfHours, dtStart, dtEnd, timeZoneId).Select(v => new Servers.Calculation.DBAccess.Interface.Data.TVALUES_DB(v.F_FLAG, v.F_VALUE))); } }); #endregion return(result.Values.ToList()); }
public BalanceFreeHierarchyCalculator(List <string> balanceFreeHierarchyUN, bool isGenerateDoc, StringBuilder errors, enumTimeDiscreteType discreteType, DateTime dtStart, DateTime dtEnd, string timeZoneId, ConcurrentDictionary <TI_ChanelType, ConcurrentStack <BalanceFreeHierarchyItemParams> > tiForRequestAdditionalInfo, EnumUnitDigit unitDigit, EnumUnitDigit unitDigitIntegrals) { _errors = errors ?? new StringBuilder(); _discreteType = discreteType; _dtStart = dtStart; _dtEnd = dtEnd; _timeZoneId = timeZoneId; _tiForRequestAdditionalInfo = tiForRequestAdditionalInfo; _unitDigit = unitDigit; _unitDigitIntegrals = unitDigitIntegrals; _intervalTimeList = MyListConverters.GetIntervalTimeList(_dtStart, _dtEnd, _discreteType, timeZoneId); _dtServerStart = dtStart.ClientToServer(timeZoneId); _dtServerEnd = dtEnd.ClientToServer(timeZoneId); _isGenerateDoc = isGenerateDoc; _numbersHalfHours = MyListConverters.GetNumbersValuesInPeriod(enumTimeDiscreteType.DBHalfHours, dtStart, dtEnd, timeZoneId); var transIds = new ConcurrentDictionary <int, string>(); var reactorsIds = new ConcurrentStack <int>(); var tiForTransformatorsAndReactors = new ConcurrentStack <TI_ChanelType>(); var tis = new ConcurrentStack <TI_ChanelType>(); var integralTis = new ConcurrentStack <TI_ChanelType>(); var tps = new ConcurrentStack <TP_ChanelType>(); var formulas = new ConcurrentStack <TFormulaParam>(); var sections = new ConcurrentStack <TSectionChannel>(); var formulaConstantIds = new ConcurrentStack <string>(); try { _itemsResultByBalance = ReadBalanceParams(balanceFreeHierarchyUN, transIds, reactorsIds, tis, integralTis, tps, formulas, sections, formulaConstantIds); } catch (AggregateException aex) { //критическая ошибка throw aex.ToException(); } #region Параметры трансформаторов и реакторов try { ReadTransformatorsParams(transIds, tiForTransformatorsAndReactors, _itemsResultByBalance); } catch (AggregateException aex) { //не критическая ошибка _errors.Append(aex.ToException()); } #endregion _archiveHalfhours = new TArchiveHalfhours(isGenerateDoc, dtStart, dtEnd, unitDigit, timeZoneId, unitDigitIntegrals, tiForTransformatorsAndReactors, tis, integralTis, tps, formulas, sections, formulaConstantIds, _intervalTimeList); _numbersByDiscreteType = MyListConverters.GetNumbersValuesInPeriod(_discreteType, _dtStart, _dtEnd, timeZoneId); SectionsByType = new ConcurrentDictionary <EnumBalanceFreeHierarchyType, List <Dict_Balance_FreeHierarchy_Section> >(GetFreeHierarchyBalanceSections(_itemsResultByBalance.Values.Select(v => (byte)v.BalanceFreeHierarchyType).Distinct()) .GroupBy(g => (EnumBalanceFreeHierarchyType)g.BalanceFreeHierarchyType_ID) .ToDictionary(k => k.Key, v => v.ToList())); }