Esempio n. 1
0
        //Неглубокое копирование, все свойства копируются как ссылки, parent - приписываемый владелец значения
        public CalcValue LinkClone(CalcParamRun parent = null)
        {
            CalcValue cv = null;

            switch (Type)
            {
            case CalcValueType.Var:
                cv = new CalcValue(VarRun);
                break;

            case CalcValueType.Single:
                cv = new CalcValue(SingleValue);
                break;

            case CalcValueType.IntArray:
                cv = new CalcValue(IntArray);
                break;

            case CalcValueType.StringArray:
                cv = new CalcValue(StringArray);
                break;

            case CalcValueType.Void:
                cv = new CalcValue();
                break;
            }
            if (cv != null)
            {
                cv.Error       = Error;
                cv.ParentParam = parent;
            }
            return(cv);
        }
Esempio n. 2
0
 protected override CalcValue GetValue(CalcParamRun calcRun)
 {
     if (Grafic == null)
     {
         return(new CalcValue(new SingleValue(new Moment(0.0, new ErrorCalc("Не заполнены значения графика ", _calc.Code)))));
     }
     return(calcRun.ThreadCalc.Funs.GeneralFunction(Inputs, DataType.Real, calcRun, Grafic.CalculateMean, null));
 }
Esempio n. 3
0
 //Произвести расчет
 public void Calculate()
 {
     if (RunParam == null)
     {
         RunParam = new CalcParamRun(this, null, Owner == null ? Project.RootParam : Owner.RunParam, null);
     }
     if (ReceiverSignal != null)
     {
         ReceiverSignal.Value = RunParam.CalcValue.SingleValue;
     }
     RunParam.JoinArchiveParam(FullCode);
 }
Esempio n. 4
0
        protected override CalcValue GetValue(CalcParamRun calcRun)
        {
            SingleValue sv = Signal == null || Signal.SourceSignal == null ? null : Signal.SourceSignal.Value;

            if (!_isHand && ConstValue != null)
            {
                sv = new SingleValue(ConstValue.Clone(calcRun.ThreadCalc.PeriodBegin));
            }
            else if (sv == null || (sv.Type == SingleType.Moment && sv.Moment == null) || (sv.Type == SingleType.List && (sv.Moments == null || sv.Moments.Count == 0)))
            {
                sv = _isHand ? new SingleValue(ConstValue.Clone(calcRun.ThreadCalc.PeriodBegin)) : new SingleValue(new List <Moment>());
            }
            return(new CalcValue(sv, Signal));
        }
Esempio n. 5
0
        protected override CalcValue GetValue(CalcParamRun calcRun)
        {
            CalcParamRun cp = calcRun;

            while (!cp.Vars.ContainsKey(Code))
            {
                cp = cp.Owner;
            }
            if (IsUse)
            {
                return(cp.Vars[Code].CalcValue);
            }
            return(new CalcValue(cp.Vars[Code]));
        }
Esempio n. 6
0
        protected override CalcValue GetValue(CalcParamRun calcRun)
        {
            switch (Fun.CodeType)
            {
            case FunCodeType.Scalar:
                return(_thread.Funs.GeneralFunction(Inputs, DataType, calcRun, Fun.ScalarDelegate, null));

            case FunCodeType.List:
                return(_thread.Funs.GeneralFunction(Inputs, DataType, calcRun, null, Fun.ListDelegate));

            case FunCodeType.Array:
                return(Fun.ArrayDelegate(Inputs, calcRun));
            }
            return(null);
        }
Esempio n. 7
0
 public FunParams(CalcParamRun calc, List <MomentValue>[] listpar, int flags)
 {
     Flags        = flags;
     CalcParamRun = calc;
     ListPar      = listpar;
     Par          = new MomentValue[listpar.Length];
     Current      = new bool[listpar.Length];
     Number       = new int[listpar.Length];
     if ((flags & FunFlags.Filter) != 0)
     {
         Filter    = new LinkedList <MomentValue>();
         FilterNd  = new SortedList <int, int>();
         FilterErr = new SortedList <int, int>();
     }
     Time = calc.ThreadCalc.PeriodBegin;
 }
Esempio n. 8
0
        protected override CalcValue GetValue(CalcParamRun calcRun)
        {
            CalcParamRun c  = calcRun;
            var          pr = calcRun.CalcParam.Project;

            if (IsMet)
            {
                c = MetOwner.ParentParam;
                while (c != null && !c.CalcParam.Methods.ContainsKey(Code))
                {
                    c = c.CalcValue.ParentParam;
                }
            }
            else
            {
                while (c.CalcParam != null && !c.CalcParam.Methods.ContainsKey(Code))
                {
                    c = c.Owner;
                }
                if (c.CalcParam == null)
                {
                    c = pr.RootParam;
                }
            }

            CalcParamRun pp;

            if (c.Methods.ContainsKey(Code))
            {
                pp = c.Methods[Code];
            }
            else
            {
                var cp  = c.CalcParam == null ? pr.CalcParamsCode[Code] : c.CalcParam.Methods[Code];
                var cpr = new CalcParamRun(cp, Inputs, c, calcRun);
                pp = cpr;
            }
            //if (pp.CalcValue == null) return new CalcValue();
            var cv = pp.CalcValue;

            if (cv.Error != null)
            {
                cv = cv.Clone(calcRun.CalcParam.FullCode);
            }
            MetOwner = null;
            return(cv.LinkClone(pp));
        }
Esempio n. 9
0
        //Вычисление значения, свое для каждого типа выражения
        //На входе стек расчета и расчетный параметр, содержащий этот Expr
        public void ProcessCalcValue(Stack <CalcValue> stack, CalcParamRun calcRun)
        {
            Inputs = new CalcValue[ParamsCount];
            for (int i = ParamsCount - 1; i >= 0; i--)
            {
                Inputs[i] = stack.Pop();
            }
            var em = this as ExprCalc;

            if (em != null && em.IsMet)
            {
                em.MetOwner = stack.Pop();
            }
            var cv = GetValue(calcRun);

            //if (cv.Type != CalcValueType.Void)
            stack.Push(cv);
            Inputs = null;
        }
Esempio n. 10
0
        public FilterIf(FilterIf parent, CalcValue condition, CalcParamRun calc, bool isPoints)
        {
            var funs = calc.ThreadCalc.Funs;

            IsPoints = isPoints;
            var par = new CalcValue[2];

            par[0] = parent.True;
            par[1] = condition;
            True   = funs.GeneralFunction(par, DataType.Boolean, calc, funs.andbb, null);
            var parn = new[] { condition };

            par[1] = funs.GeneralFunction(parn, DataType.Boolean, calc, funs.notb, null);
            False  = funs.GeneralFunction(par, DataType.Boolean, calc, funs.andbb, null);
            var b = new CalcValue(new SingleValue(new Moment(true)));

            parn  = new[] { True, b };
            True  = funs.GeneralFunction(parn, DataType.Boolean, calc, null, funs.deleterepetitionsub);
            parn  = new[] { False, b };
            False = funs.GeneralFunction(parn, DataType.Boolean, calc, null, funs.deleterepetitionsub);
        }
Esempio n. 11
0
 //Вычисление значения, свое для каждого типа выражения
 protected virtual CalcValue GetValue(CalcParamRun calcRun)
 {
     return(null);
 }
Esempio n. 12
0
        //Вычисляет значение функции Пред f от параметров par
        private SingleValue CalcPrev(string f, CalcValue[] par, CalcParamRun calcRun)
        {
            string acode = par[0].SingleValue.LastMoment.String;
            string scode = acode.Split('.')[0];
            var    pr    = _calc.Project;
            var    cpr   = calcRun;

            while (cpr != pr.RootParam && !cpr.CalcParam.Methods.ContainsKey(scode))
            {
                cpr = cpr.Owner;
            }
            while (cpr != pr.RootParam)
            {
                while (cpr.Inputs.Count != 0)
                {
                    cpr = cpr.Caller;
                }
                acode = cpr.CalcParam.Code + "." + acode;
                cpr   = cpr.Owner;
            }
            if (!pr.ArchiveParams.ContainsKey(acode))
            {
                var err = new ErrorCalc("Не найден архивный параметр " + acode, _calc.FullCode);
                return(new SingleValue(new Moment(par[1].SingleValue.DataType, err)));
            }
            var beg = pr.ThreadCalc.PeriodBegin;
            var p1  = par[1].SingleValue.LastMoment.Clone(beg);

            if (f == "prevabs")
            {
                var ap = pr.ArchiveParams[acode];
                var m  = ((ap.AbsoluteEnd == beg && ap.AbsoluteValue != null) ? ap.AbsoluteValue : p1).Clone();
                if (par.Length == 2 || !par[2].SingleValue.LastMoment.Boolean)
                {
                    m.Time = beg;
                }
                return(new SingleValue(m));
            }
            var    pp  = pr.PrevParams[acode];
            Moment mom = null;

            if (f == "prev")
            {
                mom = (pp.LastBase == null || pp.LastBase.DataType == DataType.Value) ? p1 : pp.LastBase;
            }
            if (f == "prevhour")
            {
                mom = (pp.LastHour == null || pp.LastHour.DataType == DataType.Value) ? p1 : pp.LastHour;
            }
            if (f == "prevday")
            {
                mom = (pp.LastDay == null || pp.LastDay.DataType == DataType.Value) ? p1 : pp.LastDay;
            }
            if (mom != null)
            {
                return(new SingleValue(mom.Clone(beg)));
            }
            if (f == "prevmom")
            {
                return(new SingleValue(pp.ManyMoments.Where(m => beg.Subtract(m.Time).TotalMinutes <= p1.Real).ToList()));
            }
            if (f == "prevperiod")
            {
                return(new SingleValue(pp.ManyBase.Where(m => beg.Subtract(m.Time).TotalMinutes <= p1.Real).ToList()));
            }
            if (f == "prevhourperiod")
            {
                return(new SingleValue(pp.ManyHour.Where(m => beg.Subtract(m.Time).TotalHours <= p1.Real).ToList()));
            }
            if (f == "prevdayperiod")
            {
                return(new SingleValue(pp.ManyDay.Where(m => beg.Subtract(m.Time).TotalDays <= p1.Real).ToList()));
            }
            return(null);
        }
Esempio n. 13
0
        protected override CalcValue GetValue(CalcParamRun calcRun)
        {
            switch (Code)
            {
            case "void":
                return(new CalcValue());

            case "owner":
                var cv = calcRun.Owner.CalcValue;
                if (cv.ParentParam == null)
                {
                    cv = cv.LinkClone(calcRun.Owner);
                }
                return(cv);

            case "caller":
                return(new CalcValue {
                    ParentParam = calcRun.Caller
                });

            case "getelement":
                if (Inputs[1].Type != CalcValueType.Single || Inputs[1].SingleValue.Type != SingleType.Moment)
                {
                    return(new CalcValue(new SingleValue(new Moment(false, new ErrorCalc("Индекс массива должен быть отдельным значением", _calc.Code)))));
                }
                Moment m = Inputs[1].SingleValue.Moment;
                if (m.DataType.LessOrEquals(DataType.Integer))
                {
                    if (Inputs[0].IntArray == null || !Inputs[0].IntArray.ContainsKey(m.Integer))
                    {
                        return(new CalcValue(new SingleValue(new Moment(false, new ErrorCalc("Несуществующий индекс массива (" + m.Integer + ")", _calc.Code)))));
                    }
                    return(Inputs[0].IntArray[m.Integer].CalcValue);
                }
                if (Inputs[0].StringArray == null || !Inputs[0].StringArray.ContainsKey(m.String))
                {
                    return(new CalcValue(new SingleValue(new Moment(false, new ErrorCalc("Несуществующий индекс массива (" + m.String + ")", _calc.Code)))));
                }
                return(Inputs[0].StringArray[m.String].CalcValue);

            case "signal":
                try { return(Inputs[0].Signal.Object.Signals[Inputs[1].SingleValue.LastMoment.String].CalcValue); }
                catch { return(new CalcValue(new SingleValue(new Moment(false, new ErrorCalc("Недопустимые параметры функции Сигнал", _calc.Code))))); }

            case "signalbool":
            case "signalint":
            case "signalreal":
            case "signalstring":
                string   c   = Inputs[0].SingleValue.LastMoment.String ?? "";
                CalcUnit sig = null;
                if (_calc.Project.SignalsSources.ContainsKey(c))
                {
                    sig = _calc.Project.SignalsSources[c];
                }
                if (_calc.Project.Objects.ContainsKey(c))
                {
                    sig = _calc.Project.Objects[c].DefaultSignal;
                }
                if (sig == null || !sig.DataType.LessOrEquals(Code.Substring(6).ToDataType()))
                {
                    return(new CalcValue(new SingleValue(new Moment(false, new ErrorCalc("Строка задает несуществующий сигнал или сигнал недопустимого типа (" + c + ")", _calc.Code)))));
                }
                return(sig.CalcValue);

            case "takecode":
            case "takename":
            case "takeunits":
            case "taketask":
            case "takecomment":
            case "takecodesignal":
            case "takenamesignal":
                CalcParam cp = null;
                if (Inputs.Length == 0)
                {
                    cp = _calc;
                }
                else if (Inputs[0].ParentParam != null)
                {
                    cp = Inputs[0].ParentParam.CalcParam;
                }
                else if (Inputs[0].Signal != null)
                {
                    var si = Inputs[0].Signal;
                    return(new CalcValue(new SingleValue(new Moment(calcRun.ThreadCalc.PeriodBegin,
                                                                    Code == "takecode" ? si.CodeObject :
                                                                    Code == "takecodesignal" ? si.CodeSignal :
                                                                    Code == "takename" ? si.NameObject :
                                                                    Code == "takenamesignal" ? si.NameSignal : si.Units))));
                }
                if (cp != null)
                {
                    return(new CalcValue(new SingleValue(new Moment(calcRun.ThreadCalc.PeriodBegin,
                                                                    Code == "takecode" ? cp.Code :
                                                                    Code == "takename" ? cp.Name :
                                                                    Code == "taketask" ? cp.Task :
                                                                    Code == "takecomment" ? cp.Comment : cp.Units))));
                }
                return(new CalcValue(new SingleValue(new Moment(false, new ErrorCalc("Параметр функции получения характеристики не задает расчетный параметр или сигнал", _calc.Code)))));

            case "prevabs":
            case "prevmom":
            case "prev":
            case "prevperiod":
            case "prevhour":
            case "prevhourperiod":
            case "prevday":
            case "prevdayperiod":
                return(new CalcValue(CalcPrev(Code, Inputs, calcRun)));
            }
            return(null);
        }
Esempio n. 14
0
        protected override CalcValue GetValue(CalcParamRun calcRun)
        {
            string s = Inputs.Length == 0 ? Code : Inputs[0].SingleValue.LastMoment.String + "." + Code;

            return(new CalcValue(new SingleValue(new Moment(calcRun.ThreadCalc.PeriodBegin, s))));
        }
Esempio n. 15
0
        //calc - CalcParam с формулой для расчета, inputs - список входных значений
        //owner - владелец, caller - параметр, из которого вызывается
        public CalcParamRun(CalcParam calc, CalcValue[] inputs, CalcParamRun owner, CalcParamRun caller)
        {
            CalcParam = calc;
            Owner     = owner;
            Caller    = caller;
            if (inputs == null || inputs.Length == 0)
            {
                Owner.Methods.Add(calc.Code, this);
                if (calc.IsNotObject)
                {
                    calc.RunParam = this;
                }
            }

            StackDepth = caller == null ? 1 : caller.StackDepth + 1;
            if (StackDepth > 500)
            {
                CalcValue = new CalcValue(new SingleValue(new Moment(DataType.Value, new ErrorCalc("Переполнение стека", CalcParam.FullCode))));
                return;
            }

            foreach (var k in calc.Vars.Keys)
            {
                Vars.Add(k, new VarRun(calc.Vars[k]));
            }

            if (inputs != null)
            {
                for (int i = 0; i < inputs.Length; i++)
                {
                    VarRun v = Vars[calc.Inputs[i]];
                    v.CalcValue = inputs[i];
                    Inputs.Add(v);
                }
            }

            ThreadCalc = CalcParam.Project.ThreadCalc;
            //Сразу производится расчет
            Calculate();

            //Добавление ошибок расчета в проект
            if (CalcParam.Inputs.Count == 0)
            {
                var errors = CalcParam.Project.CalcErrors;
                if (CalcValue.Type != CalcValueType.Single)
                {
                    if (CalcValue.Error != null)
                    {
                        errors.Add(CalcValue.Error);
                    }
                }
                else
                {
                    var sv = CalcValue.SingleValue;
                    if (sv.Moment != null && sv.Moment.Error != null)
                    {
                        errors.Add(sv.Moment.Error);
                    }
                    if (sv.Moments != null)
                    {
                        foreach (var m in sv.Moments)
                        {
                            if (m.Error != null)
                            {
                                errors.Add(m.Error);
                                break;
                            }
                        }
                    }
                    if (sv.Segments != null)
                    {
                        foreach (var seg in sv.Segments)
                        {
                            if (seg.Error != null)
                            {
                                errors.Add(seg.Error);
                                break;
                            }
                        }
                    }
                }
            }
        }
Esempio n. 16
0
 protected override CalcValue GetValue(CalcParamRun calcRun)
 {
     return(new CalcValue(new SingleValue(_moment.Clone(_thread.PeriodBegin))));
 }
Esempio n. 17
0
        //Вычисление значения функций типа scalar и list
        public CalcValue GeneralFunction(CalcValue[] par, DataType dt, CalcParamRun calc, ScalarDelegate scalar, ListDelegate fun)
        {
            bool isScalar = scalar != null;
            int  n        = par.Count();

            _calc     = calc.CalcParam;
            Begin     = calc.ThreadCalc.PeriodBegin;
            End       = calc.ThreadCalc.PeriodEnd;
            _interpol = _calc.Interpolation;
            var sv = new SingleValue[n];
            int ki = 0, ks = 0;

            for (int i = 0; i < n; i++)
            {
                var cvt = par[i].Type;
                if (ki == 0 && cvt == CalcValueType.IntArray)
                {
                    ki = i;
                }
                if (ks == 0 && cvt == CalcValueType.StringArray)
                {
                    ks = i;
                }
                if (cvt != CalcValueType.IntArray && cvt != CalcValueType.StringArray)
                {
                    sv[i] = par[i].SingleValue;
                }
            }
            if (ki == 0 && ks == 0)//Нет массивов
            {
                if (isScalar)
                {
                    return(new CalcValue(ScalarFunction(sv, dt, scalar)));
                }
                var ss = new SingleValue();
                foreach (var s in sv)
                {
                    ss.Error |= s.Error;
                }
                fun(sv, ss);
                if (ss.Type != SingleType.Segments && ss.Moment == null && ss.Moments == null)
                {
                    ss.Moments = new List <Moment>();
                }
                if (ss.Type == SingleType.Segments && ss.Segments == null)
                {
                    ss.Segments = new List <Segment>();
                }
                return(new CalcValue(ss));
            }
            var cv = new CalcValue[n];

            if (ki > 0)//Массивы с целыми индексами
            {
                var resi = new CalcValue(new SortedDictionary <int, VarRun>());
                foreach (var key in par[ki].IntArray.Keys)
                {
                    bool e = true;
                    for (int i = 0; i < n; i++)
                    {
                        var p = par[i];
                        if (p.Type == CalcValueType.StringArray || (p.Type == CalcValueType.IntArray && !p.IntArray.ContainsKey(key)))
                        {
                            e = false;
                        }
                        else if (p.Type == CalcValueType.IntArray)
                        {
                            cv[i] = p.IntArray[key].CalcValue;
                        }
                        else
                        {
                            cv[i] = p;
                        }
                    }
                    if (e)
                    {
                        var c = GeneralFunction(cv, dt, calc, scalar, fun);
                        resi.Error |= c.Error;
                        resi.IntArray.Add(key, new VarRun(c));
                    }
                }
                return(resi);
            }
            //Массивы со строковыми индексами
            var ress = new CalcValue(new SortedDictionary <int, VarRun>());

            foreach (var key in par[ki].StringArray.Keys)
            {
                bool e = true;
                for (int i = 0; i < n; i++)
                {
                    var p = par[i];
                    if (p.Type == CalcValueType.IntArray || (p.Type == CalcValueType.StringArray && !p.StringArray.ContainsKey(key)))
                    {
                        e = false;
                    }
                    else if (p.Type == CalcValueType.StringArray)
                    {
                        cv[i] = p.StringArray[key].CalcValue;
                    }
                    else
                    {
                        cv[i] = p;
                    }
                }
                if (e)
                {
                    var c = GeneralFunction(cv, dt, calc, scalar, fun);
                    ress.Error |= c.Error;
                    ress.StringArray.Add(key, new VarRun(c));
                }
            }
            return(ress);
        }
Esempio n. 18
0
 public ParamVal(CalcParamRun calcRun, ErrMom err = null)
 {
     _val      = calcRun.Value;
     CalcParam = calcRun.CalcParam;
     _error    = err;
 }
Esempio n. 19
0
        //Расчет по всем формулам
        public void Calculate()
        {
            try
            {
                CalcErrors.Clear();
                RootParam = new CalcParamRun();
                int n = CalcParamsId.Count, i = 0;
                foreach (var c in CalcParamsId.Values)
                {
                    if (c == null)
                    {
                        AddError("Список расчетных параметров загружен с ошибками, необходима повторная компиляция расчета");
                    }
                    else
                    {
                        c.RunParam = null;
                        foreach (var m in c.Methods.Values)
                        {
                            if (m == null)
                            {
                                AddError("Список расчетных параметров загружен с ошибками, необходима повторная компиляция расчета");
                            }
                            else
                            {
                                m.RunParam = null;
                            }
                        }
                    }
                }
                if (IsError)
                {
                    return;
                }

                foreach (var c in CalcParamsId.Values)
                {
                    if (c.IsNotObject)
                    {
                        c.Calculate();
                        foreach (var m in c.Methods.Values)
                        {
                            if (m.IsNotObject)
                            {
                                m.Calculate();
                            }
                        }
                    }
                    if (IsError)
                    {
                        return;
                    }
                    if (n > 40 && ++i % (n / 20) == 0)
                    {
                        Procent = 80.0 * i / n;
                    }
                }

                //Запись ошибок расчета в лог
                var count = CalcErrors.Count;
                if (count > 0)
                {
                    string s = "";
                    int    j = 0;
                    while (j < 10 && j < count)
                    {
                        s += (s == "" ? "" : ", ") + CalcErrors[j++].Address;
                    }
                    string p = count % 10 == 1 ? "параметр" : (count % 10 == 2 || count % 10 == 3 || count % 10 == 4 ? "параметра" : "параметров");
                    AddWarning("При расчете произошли ошибки", null, count + " " + p + " с ошибками: " + s + (j < count ? " и др." : ""));
                }
                AddEvent("Объем используемой памяти", GC.GetTotalMemory(false).ToString());
            }
            catch (OutOfMemoryException ex)
            {
                AddEvent("Объем используемой памяти", GC.GetTotalMemory(false).ToString());
                AddError("Ошибка при расчете", ex);
                throw;
            }
            catch (Exception ex)
            {
                AddError("Ошибка при расчете", ex);
            }
        }
Esempio n. 20
0
        //Сохранение одного параметра или одной переменной, возвращает словарь ключи - коды переменных, значения - величичны
        //code - полный код для для записи в DebugParams
        //debugType - Параметр, Подпараметр, Объект, Переменная, Сигнал, paramId - id параметра или подпараметра, для остальных 0
        //c - расчетный параметр, v - переменная, всегда одно из двух, level - уровень вложенности,
        //saveToRec - сохранять в рекордсет и переменные, если false, то сам параметр не сохраняется но могут сохраняться его подпараметры и переменные
        public Dictionary <string, string> SaveValues(string code, string debugType, int paramId, CalcParamRun c, VarRun v, int level, bool saveToRec = true)
        {
            if (level > 3)
            {
                return(null);
            }
            var       dic = new Dictionary <string, string>();
            CalcValue cv;
            string    adderr = "";

            if (v != null)
            {
                cv = v.CalcValue;
            }
            else
            {
                if (c == null || c.CalcValue == null)
                {
                    return(null);
                }
                if (_thread.IsSaveProperties)
                {
                    foreach (var met in c.Methods.Values)
                    {
                        bool e = met.CalcParam.IsNotObject;
                        AddDic(dic, SaveValues(code + "." + met.CalcParam.Code, e ? "Подпараметр" : "Порождаемый", e ? met.CalcParam.Id : 0, met, null, level + 1), met.CalcParam.Code);
                        if (met.CalcValue.Error != null && adderr.IsEmpty())
                        {
                            adderr = "Ошибки в " + (e ? "" : "порожденных ") + "подпараметрах";
                        }
                    }
                }
                if (_thread.IsSaveVariables)
                {
                    foreach (var vr in c.Vars.Dic)
                    {
                        if (vr.Key != "calc" || (c.CalcValue.Type == CalcValueType.Single && c.CalcValue.SingleValue != vr.Value.CalcValue.SingleValue))
                        {
                            AddDic(dic, SaveValues(code + "." + vr.Key, "Переменная", 0, null, vr.Value, level + 1), vr.Key);
                        }
                    }
                }
                cv = c.CalcValue;
            }

            if (cv != null)
            {
                switch (cv.Type)
                {
                case CalcValueType.Void:
                case CalcValueType.Single:
                    if ((saveToRec && cv.SingleValue != null) || !adderr.IsEmpty())
                    {
                        ValuesToRec(code, debugType, paramId, dic, cv.SingleValue ?? new SingleValue(), adderr);
                        dic.Add("", SvToStr(cv.SingleValue));
                    }
                    break;

                case CalcValueType.IntArray:
                    foreach (var a in cv.IntArray)
                    {
                        AddDic(dic, SaveValues(code + "[" + a.Key + "]", "Переменная", 0, null, a.Value, level + 1), null);
                    }
                    break;

                case CalcValueType.StringArray:
                    foreach (var a in cv.StringArray)
                    {
                        AddDic(dic, SaveValues(code + "[" + a.Key + "]", "Переменная", 0, null, a.Value, level + 1), null);
                    }
                    break;
                }
                if (cv.ParentParam != null && cv.ParentParam.Inputs.Count != 0)
                {
                    if (c == cv.ParentParam)
                    {
                        ValuesToRec(code, debugType, paramId, dic, new SingleValue());
                    }
                    else
                    {
                        AddDic(dic, SaveValues(code + ":" + cv.ParentParam.CalcParam.Code, debugType, paramId, cv.ParentParam, null, level, false), null);
                    }
                }
            }
            return(dic);
        }