/// <summary> /// Проверка формулы /// </summary> /// <param name="formulaParams">формула</param> /// <param name="dataSourceType">Источник данных</param> public void CheckFormula(IFormulaParam formulaParams) { _recursionCallStack.Clear(); int?tpId = null; if (formulaParams.tP_CH_ID != null) { tpId = formulaParams.tP_CH_ID.TP_ID; } var formula = GetFormulaByID(formulaParams.FormulaID); var polskaParams = new PolskaParams(formula.F_ID, _formulasTable, formulaParams.StartDateTime, formulaParams.FinishDateTime.GetValueOrDefault(), enumTimeDiscreteType.DBHalfHours, 1, null); var parser = ComposeExpressionPolskaya(formula, polskaParams, 0, 1, 1, false); parser.EvaluateStringValue(0); }
/// <summary> /// Набор расчетных параметров для обсчета формулы /// </summary> /// <param name="formulaParams"></param> /// <param name="resultTi"></param> /// <param name="resultIntegral"></param> /// <param name="resultTp"></param> /// <param name="resultSection"></param> public void BuildVariableParams(IFormulaParam formulaParams, string msTimeZoneId = null, bool isArchTech = false) { if (_recursionCallStack.Contains(formulaParams.FormulaID)) { throw new FormulaParseException("Обнаружена рекурсия формулы\n[" + GetOperNameFromDB(formulaParams.FormulaID, F_OPERATOR.F_OPERAND_TYPE.Formula, null) + "]"); } _recursionCallStack.Add(formulaParams.FormulaID); _formulasTable = formulaParams.FormulasTable; int?tpId = null; if (formulaParams.tP_CH_ID != null) { tpId = formulaParams.tP_CH_ID.TP_ID; } if (Archives == null) { Archives = new FormulaArchives(isArchTech, tpId); } //Часовой пояс в котором запрашиваем данные //var tz = (string.IsNullOrEmpty(msTimeZoneId) ? formulaParams.MsTimeZoneId : msTimeZoneId); var f = GetFormulaByID(formulaParams.FormulaID); if (f == null) { //Ф-ла не описана, либо не входит в наш диапазон _recursionCallStack.Remove(formulaParams.FormulaID); return; } foreach (var operators in f.F_OPERATORS) { var operIdInt = 0; if (string.IsNullOrEmpty(operators.OPER_ID)) { continue; } if (operators.OPER_TYPE != F_OPERATOR.F_OPERAND_TYPE.Formula && operators.OPER_TYPE != F_OPERATOR.F_OPERAND_TYPE.FormulaConstant) { if (int.TryParse(operators.OPER_ID, out operIdInt) == false) { throw new FormulaParseException("Идентификатор ТИ [" + operators.OPER_ID + "] должен быть целочисленным!"); } if (!operators.TI_CHANNEL.HasValue) { throw new FormulaParseException("В формуле не указан канал измерения!"); } } switch (operators.OPER_TYPE) { case F_OPERATOR.F_OPERAND_TYPE.UANode: Archives.FormulaUaNodeVariableDataTypeList.Add(new TUANodeDataId { UANodeId = operIdInt, DataType = (UANodeDataIdDataTypeEnum)operators.TI_CHANNEL.GetValueOrDefault() }); break; case F_OPERATOR.F_OPERAND_TYPE.Section: Archives.SectionSorted.Add(new TSectionChannel { Section_ID = operIdInt, ChannelType = operators.TI_CHANNEL.Value }); break; case F_OPERATOR.F_OPERAND_TYPE.TP_channel: HashSet <TP_ChanelType> tpChannelTypes; if (!Archives.TPChanelTypeList.TryGetValue(operIdInt, out tpChannelTypes) || tpChannelTypes == null) { Archives.TPChanelTypeList[operIdInt] = tpChannelTypes = new HashSet <TP_ChanelType>(new TP_ChanelComparer()); } tpChannelTypes.Add(new TP_ChanelType { TP_ID = operIdInt, ChannelType = operators.TI_CHANNEL.Value, ClosedPeriod_ID = formulaParams.ClosedPeriod_ID, }); break; case F_OPERATOR.F_OPERAND_TYPE.Integral_Channel: HashSet <TI_ChanelType> integralChannelTypes; if (!Archives.IntegralChanelTypeList.TryGetValue(operIdInt, out integralChannelTypes) || integralChannelTypes == null) { Archives.IntegralChanelTypeList[operIdInt] = integralChannelTypes = new HashSet <TI_ChanelType>(new ITI_ChanelComparer()); } integralChannelTypes.Add(new TI_ChanelType { TI_ID = operIdInt, ChannelType = operators.TI_CHANNEL.Value, IsCA = operators.OPER_TYPE == F_OPERATOR.F_OPERAND_TYPE.ContrTI_Chanel, TP_ID = tpId, DataSourceType = InterpretatorParams.DataSourceType, ClosedPeriod_ID = formulaParams.ClosedPeriod_ID, //MsTimeZone = tz, }); break; case F_OPERATOR.F_OPERAND_TYPE.ContrTI_Chanel: case F_OPERATOR.F_OPERAND_TYPE.TI_channel: HashSet <TI_ChanelType> tiChannelTypes; if (!Archives.TIChanelTypeList.TryGetValue(operIdInt, out tiChannelTypes) || tiChannelTypes == null) { Archives.TIChanelTypeList[operIdInt] = tiChannelTypes = new HashSet <TI_ChanelType>(new ITI_ChanelComparer()); } tiChannelTypes.Add(new TI_ChanelType { TI_ID = operIdInt, ChannelType = operators.TI_CHANNEL.Value, IsCA = operators.OPER_TYPE == F_OPERATOR.F_OPERAND_TYPE.ContrTI_Chanel, TP_ID = tpId, DataSourceType = InterpretatorParams.DataSourceType, ClosedPeriod_ID = formulaParams.ClosedPeriod_ID, //MsTimeZone = tz, }); break; case F_OPERATOR.F_OPERAND_TYPE.FormulaConstant: Archives.FormulaConstantIds.Add(operators.OPER_ID); break; case F_OPERATOR.F_OPERAND_TYPE.Formula: IFormulaParam fId = new FormulaParam { FormulaID = operators.OPER_ID, FormulasTable = _formulasTable, tP_CH_ID = formulaParams.tP_CH_ID, MsTimeZoneId = formulaParams.MsTimeZoneId }; //Собираем переменные из вложенной формулы BuildVariableParams(fId, msTimeZoneId); break; } } _recursionCallStack.Remove(formulaParams.FormulaID); }