示例#1
0
        private static object SumIf(List <Expression> p)
        {
            // get parameters
            var range    = p[0] as IEnumerable;                         // range of values to match the criteria against
            var sumRange = p.Count < 3 ?
                           p[0] as XObjectExpression :
                           p[2] as XObjectExpression; // range of values to sum up
            var criteria = p[1].Evaluate();           // the criteria to evaluate

            var rangeValues    = range.Cast <object>().ToList();
            var sumRangeValues = sumRange.Cast <object>().ToList();

            // compute total
            var ce    = new CalcEngine();
            var tally = new Tally();

            for (var i = 0; i < Math.Max(rangeValues.Count, sumRangeValues.Count); i++)
            {
                var targetValue = i < rangeValues.Count ? rangeValues[i] : string.Empty;
                if (CalcEngineHelpers.ValueSatisfiesCriteria(targetValue, criteria, ce))
                {
                    var value = i < sumRangeValues.Count ? sumRangeValues[i] : 0d;
                    tally.AddValue(value);
                }
            }

            // done
            return(tally.Sum());
        }
示例#2
0
        private static object SumIfs(List <Expression> p)
        {
            // get parameters
            var sumRange = p[0] as IEnumerable;

            var sumRangeValues = new List <object>();

            foreach (var value in sumRange)
            {
                sumRangeValues.Add(value);
            }

            var ce    = new CalcEngine();
            var tally = new Tally();

            int numberOfCriteria = p.Count / 2; // int division returns floor() automatically, that's what we want.

            // prepare criteria-parameters:
            var criteriaRanges = new Tuple <object, List <object> > [numberOfCriteria];

            for (int criteriaPair = 0; criteriaPair < numberOfCriteria; criteriaPair++)
            {
                var criterion           = p[criteriaPair * 2 + 1].Evaluate();
                var criteriaRange       = p[(criteriaPair + 1) * 2] as IEnumerable;
                var criteriaRangeValues = new List <object>();
                foreach (var value in criteriaRange)
                {
                    criteriaRangeValues.Add(value);
                }

                criteriaRanges[criteriaPair] = new Tuple <object, List <object> >(
                    criterion,
                    criteriaRangeValues);
            }

            for (var i = 0; i < sumRangeValues.Count; i++)
            {
                bool shouldUseValue = true;

                foreach (var criteriaPair in criteriaRanges)
                {
                    if (!CalcEngineHelpers.ValueSatisfiesCriteria(
                            criteriaPair.Item2[i],
                            criteriaPair.Item1,
                            ce))
                    {
                        shouldUseValue = false;
                        break; // we're done with the inner loop as we can't ever get true again.
                    }
                }

                if (shouldUseValue)
                {
                    tally.AddValue(sumRangeValues[i]);
                }
            }

            // done
            return(tally.Sum());
        }
示例#3
0
        private static object SumIf(List <Expression> p)
        {
            // get parameters
            var range    = p[0] as IEnumerable;
            var sumRange = p.Count < 3 ? range : p[2] as IEnumerable;
            var criteria = p[1].Evaluate();

            // build list of values in range and sumRange
            var rangeValues = new List <object>();

            foreach (var value in range)
            {
                rangeValues.Add(value);
            }
            var sumRangeValues = new List <object>();

            foreach (var value in sumRange)
            {
                sumRangeValues.Add(value);
            }

            // compute total
            var ce    = new CalcEngine();
            var tally = new Tally();

            for (var i = 0; i < Math.Min(rangeValues.Count, sumRangeValues.Count); i++)
            {
                if (ValueSatisfiesCriteria(rangeValues[i], criteria, ce))
                {
                    tally.AddValue(sumRangeValues[i]);
                }
            }

            // done
            return(tally.Sum());
        }