public MemoryStream BuildBalanceFreeHier(BalanceFreeHierarchyCalculatedResult balanceCalculatedResult) { if (balanceCalculatedResult == null) { return(null); } bool isHeaderFormed; var xls = InitBalanceFreeHierarchy(balanceCalculatedResult.BalanceFreeHierarchyUn, out isHeaderFormed); //Формируем балансы в зависимости от выбранного типа switch (balanceCalculatedResult.DocumentType) { case EnumBalanceFreeHierarchyType.БалансНаПодстанции: case EnumBalanceFreeHierarchyType.БалансЭлектростанции: return(ФормируемПодстанцийЭлектростанций(xls, balanceCalculatedResult, isHeaderFormed)); break; case EnumBalanceFreeHierarchyType.АктУчетаЭэ: return(ФормируемАктУчетаЭэ(xls, balanceCalculatedResult, isHeaderFormed)); break; case EnumBalanceFreeHierarchyType.Приложение51: return(ФормируемПриложение51(xls, balanceCalculatedResult, isHeaderFormed)); break; case EnumBalanceFreeHierarchyType.СводныйИнтегральныйАкт: return(ФормируемСводныйИнтегральныйАкт(balanceCalculatedResult)); break; default: lock (_errors) { _errors.Append(balanceCalculatedResult.DocumentName + " - документ не создан"); } break; } return(null); }
private void асчетПодстанцийЭлектростанций(BalanceFreeHierarchyCalculatedResult balanceResult) { var calculatedByDiscretePeriods = balanceResult.CalculatedByDiscretePeriods; #region Обсчитываем трансформаторы foreach (var transformator in balanceResult.Transformators) { transformator.CalculateLosses(_archiveHalfhours.ResultCommonForTransformatorsAndReactors, _numbersHalfHours, null, _errors, _dtStart, _dtEnd, _unitDigit); transformator.CalculateLossesByDiscretePeriod(enumTimeDiscreteType.DBHalfHours, _dtStart, _dtEnd, _intervalTimeList); } #endregion #region Обсчитываем реакторы foreach (var reactor in balanceResult.Reactors) { reactor.CalculateLosses(_archiveHalfhours.ResultCommonForTransformatorsAndReactors, 0.5, null); } #endregion var ovInfos = new List <IOV_Values>(); //Информация по ОВ которую нужно дополнить дополнительно var ovIdsForIntegral = new List <TI_ChanelType>(); //Идентификаторы ОВ для дозапросов и дорасчетов интегралов по ним foreach (var paramPair in balanceResult.ItemsParamsBySection) { foreach (var itemParam in paramPair.Value) { _archiveHalfhours.PopulateArchivesByHierarchyType(itemParam, _tiForRequestAdditionalInfo, _discreteType, //В данном документе работаем только с получасовками true, balanceResult.Transformators, balanceResult.Reactors, _numbersHalfHours); if (itemParam.OV_Values_List != null && itemParam.OV_Values_List.Count > 0) { ovInfos.AddRange(itemParam.OV_Values_List); } } } //GetOvInfos(ovInfos); List <Dict_Balance_FreeHierarchy_Section> sections; SectionsByType.TryGetValue(balanceResult.BalanceFreeHierarchyType, out sections); if (sections == null) { return; } var dopustNebalnsUn = sections.First(s => Equals(s.MetaString1, "dopust_nebalns")) .BalanceFreeHierarchySection_UN; var hlv = balanceResult.HighLimitValue; var llv = balanceResult.LowerLimitValue; var hlp = balanceResult.HighLimit; var llp = balanceResult.LowerLimit; var balanceResultInfo = balanceResult.ResultInfo; //Для обсчетов итогов в заданном периоде дискретизации var discretePeriodStepOfReadHalfHours = 0; var discretePeriodNumbersHalfHoursInOurPeriod = _intervalTimeList.FirstOrDefault(); var ourPeriodCounter = 0; var sectionValues = sections.ToDictionary(k => k.BalanceFreeHierarchySection_UN, v => 0.0); var discretePeriodOtpusk = 0.0; var discretePeriodPostupilo = 0.0; var discretePeriodFlag = VALUES_FLAG_DB.None; var totalFlag = VALUES_FLAG_DB.None; var totalBalanceStatus = EnumBalanceStatus.None; var totalOtpusk = 0.0; var totalPostupilo = 0.0; var factUnBalancePercentAverage = 0.0; double?factUnBalancePercentMax = null; double?factUnBalancePercentMin = null; var factUnBalancePercentMaxIndx = 0.0; var factUnBalancePercentMinIndx = 0.0; for (var archiveIndex = 0; archiveIndex < _numbersHalfHours; archiveIndex++) { //Обсчитываем всё в рамках одной получасовки var o = 0.0; var p = 0.0; var flag = VALUES_FLAG_DB.None; #region Считаем сумму по подгруппам участвующим в балансе foreach (var paramPair in balanceResult.ItemsParamsBySection) { var sectionUn = paramPair.Key; var halfhourSum = 0.0; var integralSum = 0.0; foreach (var itemParam in paramPair.Value) { if (!itemParam.IsInput && !itemParam.IsOutput || itemParam.HalfHours == null) { continue; //Объект не участвует в балансе } if (archiveIndex == 0) { integralSum = _archiveHalfhours.GetIntegral(itemParam); } var aVal = itemParam.HalfHours.ElementAtOrDefault(archiveIndex); if (aVal == null || !itemParam.Coef.HasValue || itemParam.Coef.Value == 0) { continue; } var v = aVal.F_VALUE * itemParam.Coef.Value; halfhourSum += v; //Сумма по подгруппе if (itemParam.IsInput) { p += v; } else if (itemParam.IsOutput) { o += v; } flag = flag.CompareAndReturnMostBadStatus(aVal.F_FLAG); itemParam.F_FLAG = itemParam.F_FLAG.CompareAndReturnMostBadStatus(aVal.F_FLAG); } sectionValues[sectionUn] += halfhourSum; } #endregion var halfHourBalanceStatus = EnumBalanceStatus.None; double halfHourFactUnbalancePercent; double halfHourFactUnbalanceValues; double?halfHourResolvedUnbalancePercent; #region Смотрим превышение CalculateBalanceInfo(balanceResult.ItemsParamsBySection.Values, p, o, archiveIndex, 1, out halfHourFactUnbalancePercent, out halfHourFactUnbalanceValues, out halfHourResolvedUnbalancePercent); if (halfHourResolvedUnbalancePercent.HasValue) { sectionValues[dopustNebalnsUn] += halfHourResolvedUnbalancePercent.Value; } if (hlv.HasValue && halfHourFactUnbalanceValues > hlv.Value) { halfHourBalanceStatus |= EnumBalanceStatus.ExcessHiValueLimit; } else if (llv.HasValue && halfHourFactUnbalanceValues < llv.Value) { halfHourBalanceStatus |= EnumBalanceStatus.ExcessLoValueLimit; } if (hlp.HasValue && halfHourFactUnbalancePercent > hlp.Value) { halfHourBalanceStatus |= EnumBalanceStatus.ExcessHiPercentLimit; } else if (llp.HasValue && halfHourFactUnbalancePercent < llp.Value) { halfHourBalanceStatus |= EnumBalanceStatus.ExcessLoPercentLimit; } if (Math.Abs(halfHourFactUnbalancePercent) - halfHourResolvedUnbalancePercent > 0) { halfHourBalanceStatus |= EnumBalanceStatus.Unbalance; // balanceResult.FactUnbalanceInfo.UnbalanceDates.Add(timeList.ElementAtOrDefault(archiveIndex)); } #endregion //Информация для графика balanceResult.BalanceHalfhours.Add(new TBalanceHalfhour { BalanceStatus = halfHourBalanceStatus, FactUnBalancePercent = halfHourFactUnbalancePercent, FactUnBalanceValue = halfHourFactUnbalanceValues, ResolvedUnBalancePercent = halfHourResolvedUnbalancePercent.GetValueOrDefault(), Flag = flag, }); #region Накапливаем состояния для заданного периода дискретизации discretePeriodPostupilo += p; discretePeriodOtpusk += o; discretePeriodFlag = discretePeriodFlag.CompareAndReturnMostBadStatus(flag); totalBalanceStatus |= halfHourBalanceStatus; #endregion #region Итоговые состояния factUnBalancePercentAverage = (halfHourFactUnbalancePercent + factUnBalancePercentAverage * archiveIndex) / (archiveIndex + 1); if (!factUnBalancePercentMax.HasValue || factUnBalancePercentMax < halfHourFactUnbalancePercent) { factUnBalancePercentMax = halfHourFactUnbalancePercent; factUnBalancePercentMaxIndx = archiveIndex; } if (!factUnBalancePercentMin.HasValue || factUnBalancePercentMin > halfHourFactUnbalancePercent) { factUnBalancePercentMin = halfHourFactUnbalancePercent; factUnBalancePercentMinIndx = archiveIndex; } #endregion #region Накапливаем результат в нужном нам периоде дискретизации if (discretePeriodStepOfReadHalfHours == discretePeriodNumbersHalfHoursInOurPeriod) //Закрываем нужный нам период дискретизвции { double discretePeriodFactUnbalancePercent; double discretePeriodFactUnbalanceValues; double?discretePeriodResolvedUnbalancePercent; if (_discreteType == enumTimeDiscreteType.DBHalfHours) { //Нужны получасовки, ничего дорасчитывать не нужно discretePeriodFactUnbalancePercent = halfHourFactUnbalancePercent; discretePeriodFactUnbalanceValues = halfHourFactUnbalanceValues; discretePeriodResolvedUnbalancePercent = halfHourResolvedUnbalancePercent.GetValueOrDefault(); } else { //Подитоги нужно дорасчитать только в нужном периоде дискретизации CalculateBalanceInfo(balanceResult.ItemsParamsBySection.Values, discretePeriodPostupilo, discretePeriodOtpusk, archiveIndex, discretePeriodNumbersHalfHoursInOurPeriod + 1, out discretePeriodFactUnbalancePercent, out discretePeriodFactUnbalanceValues, out discretePeriodResolvedUnbalancePercent); } //Поитог по периоду дискретизации, для Excel и таблицы calculatedByDiscretePeriods.Add(new BalanceFreeHierarchyCalculatedDiscretePeriod { SectionValues = sectionValues, //Фактический небаланс ((I-(II+III)-IV-V - Потери автортансформаторов)/I)*100% FactUnbalancePercent = discretePeriodFactUnbalancePercent, //Небаланс, кВт*ч FactUnbalanceValue = discretePeriodFactUnbalanceValues, //Допустимый небаланс (VII), % ResolvedUnBalanceValues = discretePeriodResolvedUnbalancePercent.GetValueOrDefault(), //Отпуск и расход + трансформаторы и реакторы OutValues = discretePeriodOtpusk, //Поступило на шины, всего (I) InBusValues = discretePeriodPostupilo, F_FLAG = discretePeriodFlag, }); //Накапливаем для общего итога totalOtpusk += discretePeriodOtpusk; totalPostupilo += discretePeriodPostupilo; totalFlag = discretePeriodFlag.CompareAndReturnMostBadStatus(discretePeriodFlag); if (++ourPeriodCounter < _intervalTimeList.Count) { //Сбрасываем накопленные состояния для накопления в последующем периоде (час, сутки или месяц) discretePeriodNumbersHalfHoursInOurPeriod = _intervalTimeList[ourPeriodCounter]; discretePeriodFlag = VALUES_FLAG_DB.None; discretePeriodStepOfReadHalfHours = 0; discretePeriodOtpusk = 0.0; discretePeriodPostupilo = 0.0; sectionValues = sections.ToDictionary(k => k.BalanceFreeHierarchySection_UN, v => 0.0); //totalBalanceStatus = EnumBalanceStatus.None; } else { break; } } else { discretePeriodStepOfReadHalfHours++; //Дальше считаем получасовки до нужного нам количества } #endregion } //Перебираем получасовки #region Общий итог balanceResultInfo.FactUnBalancePercentAverage = factUnBalancePercentAverage; balanceResultInfo.FactUnBalancePercentMax = factUnBalancePercentMax; balanceResultInfo.FactUnBalancePercentMin = factUnBalancePercentMin; if (factUnBalancePercentMax.HasValue) { balanceResultInfo.FactUnBalancePercentMaxDt = _dtServerStart.ServerToUtc() .AddMinutes(factUnBalancePercentMaxIndx * 30).UtcToClient(_timeZoneId); } if (factUnBalancePercentMin.HasValue) { balanceResultInfo.FactUnBalancePercentMinDt = _dtServerStart.ServerToUtc() .AddMinutes(factUnBalancePercentMinIndx * 30).UtcToClient(_timeZoneId); } double totalFactUnbalancePercent; double totalFactUnbalanceValue; double?totalResolvedUnbalancePercent; if (_discreteType != enumTimeDiscreteType.DBInterval || calculatedByDiscretePeriods.Count == 0) { CalculateBalanceInfo(balanceResult.ItemsParamsBySection.Values, totalPostupilo, totalOtpusk, _numbersHalfHours - 1, _numbersHalfHours, out totalFactUnbalancePercent, out totalFactUnbalanceValue, out totalResolvedUnbalancePercent); } else { //Для интервального общий итог не нужно пересчитывать, уже посчитали var cv = calculatedByDiscretePeriods.First(); totalFactUnbalancePercent = cv.FactUnbalancePercent; totalFactUnbalanceValue = cv.FactUnbalanceValue; totalResolvedUnbalancePercent = cv.ResolvedUnBalanceValues; } balanceResultInfo.FactUnBalancePercent = totalFactUnbalancePercent; balanceResultInfo.FactUnBalanceValue = totalFactUnbalanceValue; balanceResultInfo.ResolvedUnBalancePercent = totalResolvedUnbalancePercent; balanceResultInfo.BalanceStatus = totalBalanceStatus & (~EnumBalanceStatus.Unbalance); //Статус небаланса берем не из получасовок balanceResultInfo.TotalTiFlag = totalFlag; #endregion if (Math.Abs(balanceResultInfo.FactUnBalancePercent.GetValueOrDefault()) - balanceResultInfo.ResolvedUnBalancePercent > 0) { balanceResultInfo.BalanceStatus |= EnumBalanceStatus.Unbalance; } }