/// <summary> /// Делаем расчет по формуле /// </summary> /// <param name="formulaId">Идентификатор формулы</param> /// <param name="inDataTI">Данные по ТИ</param> /// <param name="inDataIntegrals">Интегральные данные</param> /// <param name="inDataTP">Данные по ТП</param> /// <param name="inDataSection">Данные по сечению</param> /// <param name="indxStart">Начальный индекс, с которого формула активна</param> /// <param name="indxEnd">Конечный индекс</param> /// <param name="unitDigitCoeff">Коэфф. дорасчета ед. измерения</param> /// <param name="formulaTPType">Тип формулы ТП</param> /// <param name="formulasTable">Табличный тип формулы (обычная или ТП)</param> /// <param name="tpId">Идентификатор ТП к которой привязана формула</param> /// <param name="rangeInSectionForEntirePeriod">Используется ли формула в сечении, где действует ограничение на период действия ТП</param> /// <param name="rangeIndexesInSectionList">Индексы с которого действуют ТП в сечении</param> /// <param name="hiHiSetpoint">Верхняя уставка, по которой проверяем формулу</param> /// <param name="loLoSetpoint">Нижняя уставка, по которой проверяем формулу</param> /// <param name="inFormulaConstants">Данные по константам, используемым в формуле</param> /// <param name="formulasDisabledPeriods">Индексы получасовок между которыми формула не считается</param> /// <returns></returns> public List <TVALUES_DB> InterpretFormula(string formulaId , bool isSumm , int indxStart, int indxEnd, double unitDigitCoeff, enumClientFormulaTPType formulaTPType, enumFormulasTable formulasTable, bool rangeInSectionForEntirePeriod = true, IEnumerable <IPeriodIndexesTpInSection> rangeIndexesInSectionList = null, double?hiHiSetpoint = null, double?loLoSetpoint = null, IEnumerable <IFormulasDisabledPeriod> formulasDisabledPeriods = null, string measureUnitUn = null, PeriodFactory manualEnteredHalfHourIndexes = null) { var isCalculateBetweenIndexes = !InterpretatorParams.TechProfilePeriod.HasValue && (indxStart > 0 || indxEnd < (InterpretatorParams.NumbersHalfHours - 1)); var isExistDisablePeriod = formulasDisabledPeriods != null && formulasDisabledPeriods.ToList().Count > 0; _recursionCallStack.Clear(); double?coeff; if (string.IsNullOrEmpty(measureUnitUn)) { if (unitDigitCoeff > 1) { coeff = 1 / unitDigitCoeff; if (InterpretatorParams.TypeInformation == enumTypeInformation.Power) { coeff *= 2; } } else if (InterpretatorParams.TypeInformation == enumTypeInformation.Power) { coeff = 2; } else { coeff = null; } } else { coeff = null; } _formulasTable = formulasTable; var formula = GetFormulaByID(formulaId); var polskaParams = new PolskaParams(formula.F_ID, _formulasTable, InterpretatorParams.StartDateTime, InterpretatorParams.EndDateTime, InterpretatorParams.DiscreteType, InterpretatorParams.NumbersHalfHours, formula.UnitDigit, InterpretatorParams.TechProfilePeriod.HasValue); var parser = ComposeExpressionPolskaya(formula, polskaParams, indxStart, indxEnd, InterpretatorParams.NumbersHalfHours, isCalculateBetweenIndexes); parser.Compile(); //var result = new List<TVALUES_DB>(); using (var accamulator = new FormulaAccamulator(InterpretatorParams.IntervalTimeList, isSumm, formula.UnitDigit)) { //Считаем всегда по получасовкам for (var halfHourIndex = 0; halfHourIndex < InterpretatorParams.NumbersHalfHours; halfHourIndex++) { // рассчет по формуле if (!isCalculateBetweenIndexes || halfHourIndex >= indxStart && halfHourIndex <= indxEnd) { #region Ограничиваем диапазоном в сечении if (!rangeInSectionForEntirePeriod) { if (!rangeIndexesInSectionList.Any(range => range.StartIndex <= halfHourIndex && (range.FinishIndex ?? InterpretatorParams.NumbersHalfHours - 1) >= halfHourIndex)) { accamulator.Accamulate(0, VALUES_FLAG_DB.TpNotInSectionRange, enumClientFormulaTPType.TpNotInSectionRange); continue; } } #endregion #region Ограничиваем когда формула заблокирована напряму таблицей Info_Formula_DisabledPeriod if (isExistDisablePeriod) { if (formulasDisabledPeriods.Any(range => halfHourIndex >= range.StartIndx && halfHourIndex <= range.FinishIndx)) { accamulator.Accamulate(0, VALUES_FLAG_DB.FormulaNotInRange); //result.Add(new Formula_VALUES_DB(VALUES_FLAG_DB.FormulaNotInRange, 0)); continue; } } #endregion #region Ограничиваем периодами, когда данные были введены вручную (считать не нужно) if (manualEnteredHalfHourIndexes != null && manualEnteredHalfHourIndexes.HavePeriod(halfHourIndex)) { //result.Add(new Formula_VALUES_DB(VALUES_FLAG_DB.None, 0)); accamulator.Accamulate(0, VALUES_FLAG_DB.None); continue; } #endregion var val = parser.EvaluateStringValue(halfHourIndex); #region Обрабатываем уставки if (hiHiSetpoint.HasValue && val.F_VALUE >= hiHiSetpoint) { val.F_FLAG |= VALUES_FLAG_DB.HiHiSetpointExcess; } if (loLoSetpoint.HasValue && val.F_VALUE <= loLoSetpoint) { val.F_FLAG |= VALUES_FLAG_DB.LoLoSetpointExcess; } #endregion //Учитываем что это мощность или размерность (кило, мега и т.д.) if (coeff.HasValue) { val.F_VALUE *= coeff.Value; } val.FormulaTPType = formulaTPType; accamulator.Accamulate(val.F_VALUE, val.F_FLAG, formulaTPType); //result.Add(val.F_VALUE, val.F_FLAG); } else { accamulator.Accamulate(0, VALUES_FLAG_DB.FormulaNotInRange, enumClientFormulaTPType.NotInRange); //Ограничения по времени действия формулы //result.Add(new Formula_VALUES_DB(VALUES_FLAG_DB.FormulaNotInRange, 0, enumClientFormulaTPType.NotInRange)); } } return(accamulator.Result); } //return result; }