示例#1
0
 protected MultipleRangeCriteriasFunction(NumericExpressionEvaluator evaluator, WildCardValueMatcher wildCardValueMatcher)
 {
     Require.That(evaluator).Named("evaluator").IsNotNull();
     Require.That(wildCardValueMatcher).Named("wildCardValueMatcher").IsNotNull();
     _numericExpressionEvaluator = evaluator;
     _wildCardValueMatcher       = wildCardValueMatcher;
 }
示例#2
0
 public CountIf(NumericExpressionEvaluator evaluator, WildCardValueMatcher wildCardValueMatcher)
 {
     Require.That(evaluator).Named("evaluator").IsNotNull();
     Require.That(wildCardValueMatcher).Named("wildCardValueMatcher").IsNotNull();
     _numericExpressionEvaluator = evaluator;
     _wildCardValueMatcher       = wildCardValueMatcher;
 }
        /// <summary>
        /// Gets a value indicating if the given input string matches the regular expression.
        /// </summary>
        /// <param name="input">The string to find the patter in.</param>
        /// <param name="isNumericType">A flag indicating if the input string is a numerical value.</param>
        /// <returns>True if a match is found; otherwise false.</returns>
        public bool MatchesFilterCriteriaResult(string input, bool isNumericType)
        {
            bool   match       = false;
            string filterValue = this.HasCustomFilters ? this.CustomFilters.First().TopOrBottomValue : this.Filters.First().TopOrBottomValue;

            if (this.FieldFilterType == FieldFilter.Label)
            {
                bool hasWildcard = filterValue.Contains("*") || filterValue.Contains("?");
                filterValue = new WildCardValueMatcher().ExcelWildcardToRegex(filterValue);
                var matches = Regex.Match(input, filterValue, RegexOptions.IgnoreCase);

                if (this.LabelFilterType == LabelFilterType.CaptionEqual ||
                    this.LabelFilterType == LabelFilterType.CaptionBeginsWith ||
                    this.LabelFilterType == LabelFilterType.CaptionEndsWith ||
                    this.LabelFilterType == LabelFilterType.CaptionContains ||
                    this.LabelFilterType == LabelFilterType.CaptionLessThanOrEqual)
                {
                    match = matches == Match.Empty ? false : true;
                }
                else if (this.LabelFilterType == LabelFilterType.CaptionNotEqual ||
                         this.LabelFilterType == LabelFilterType.CaptionNotBeginsWith ||
                         this.LabelFilterType == LabelFilterType.CaptionNotEndsWith ||
                         this.LabelFilterType == LabelFilterType.CaptionNotContains ||
                         this.LabelFilterType == LabelFilterType.CaptionGreaterThan)
                {
                    match = matches == Match.Empty ? true : false;
                }

                if (this.LabelFilterType == LabelFilterType.CaptionEqual || this.LabelFilterType == LabelFilterType.CaptionBeginsWith)
                {
                    match = this.CheckFilterAtStartOfString(filterValue, input, match, false, true);
                }
                else if (this.LabelFilterType == LabelFilterType.CaptionNotEqual || this.LabelFilterType == LabelFilterType.CaptionNotBeginsWith)
                {
                    match = this.CheckFilterAtStartOfString(filterValue, input, match, true, true);
                }
                else if (this.LabelFilterType == LabelFilterType.CaptionEndsWith)
                {
                    match = this.CheckFilterAtStartOfString(filterValue, input, match, false, false);
                }
                else if (this.LabelFilterType == LabelFilterType.CaptionNotEndsWith)
                {
                    match = this.CheckFilterAtStartOfString(filterValue, input, match, true, false);
                }
                else if (this.LabelFilterType == LabelFilterType.CaptionBetween || this.LabelFilterType == LabelFilterType.CaptionNotBetween)
                {
                    match = this.SatisfiesBetweenAndNotBetweenLabelFilter(input, filterValue, hasWildcard, isNumericType);
                }
                else
                {
                    match = this.SatisfiesInequalityLabelFilter(input, filterValue, match, hasWildcard, isNumericType);
                }
            }
            return(match);
        }
示例#4
0
        /// <summary>
        /// Executes the function with the specified <paramref name="arguments"/> in the specified <paramref name="context"/>.
        /// </summary>
        /// <param name="arguments">The arguments with which to evaluate the function.</param>
        /// <param name="context">The context in which to evaluate the function.</param>
        /// <returns>An address range <see cref="CompileResult"/> if successful, otherwise an error result.</returns>
        public override CompileResult Execute(IEnumerable <FunctionArgument> arguments, ParsingContext context)
        {
            if (this.ArgumentsAreValid(arguments, 2, out eErrorType argumentError) == false)
            {
                return(new CompileResult(argumentError));
            }

            if (!this.TryGetSearchValue(arguments.ElementAt(0), context, out var searchValue, out var error))
            {
                return(error);
            }

            var lookupRange     = arguments.ElementAt(1).ValueAsRangeInfo;
            var matchType       = this.GetMatchType(arguments);
            var args            = new LookupArguments(searchValue, lookupRange.Address.Address, 0, 0, false, lookupRange);
            var lookupDirection = this.GetLookupDirection(lookupRange.Address);
            var navigator       = LookupNavigatorFactory.Create(lookupDirection, args, context);
            int?lastValidIndex  = null;

            do
            {
                if (navigator.CurrentValue == null && searchValue == null)
                {
                    return(this.CreateResult(ExcelErrorValue.Create(eErrorType.NA), DataType.ExcelError));
                }
                int?matchResult;
                if (matchType == MatchType.ExactMatch)
                {
                    matchResult = new WildCardValueMatcher().IsMatch(searchValue, navigator.CurrentValue);
                }
                else
                {
                    matchResult = new LookupValueMatcher().IsMatch(searchValue, navigator.CurrentValue);
                }
                // For all match types, if the match result indicated equality, return the index (1 based)
                if (matchResult == 0)
                {
                    return(this.CreateResult(navigator.Index + 1, DataType.Integer));
                }
                if ((matchType == MatchType.ClosestBelow && matchResult > 0) || (matchType == MatchType.ClosestAbove && matchResult < 0))
                {
                    lastValidIndex = navigator.Index + 1;
                }
                // If matchType is ClosestBelow or ClosestAbove and the match result test failed, no more searching is required
                else if (matchType == MatchType.ClosestBelow || matchType == MatchType.ClosestAbove)
                {
                    break;
                }
            }while (navigator.MoveNext());
            if (lastValidIndex == null)
            {
                return(this.CreateResult(ExcelErrorValue.Create(eErrorType.NA), DataType.ExcelError));
            }
            return(this.CreateResult(lastValidIndex, DataType.Integer));
        }
示例#5
0
        protected IEnumerable <double> GetMatches(string functionName, IEnumerable <FunctionArgument> arguments, out CompileResult errorResult)
        {
            ValidateArguments(arguments, 3);
            errorResult = null;
            var maxRange           = arguments.ElementAt(0).ValueAsRangeInfo;
            var maxArgs            = arguments.Count() < (126 * 2 + 1) ? arguments.Count() : 126 * 2 + 1;
            var valueMatcher       = new WildCardValueMatcher();
            var matches            = new List <double>();
            var rangeSizeEvaluated = false;

            for (var valueIx = 0; valueIx < maxRange.Count(); valueIx++)
            {
                var isMatch = true;
                for (var criteriaIx = 1; criteriaIx < maxArgs; criteriaIx += 2)
                {
                    var criteriaRange = arguments.ElementAt(criteriaIx).ValueAsRangeInfo;
                    if (!rangeSizeEvaluated)
                    {
                        if (criteriaRange.Count() < maxRange.Count())
                        {
                            errorResult = CreateResult(eErrorType.Value);
                            return(Enumerable.Empty <double>());
                        }
                    }
                    var matchCriteria = arguments.ElementAt(criteriaIx + 1).Value;

                    var candidate = criteriaRange.ElementAt(valueIx).Value;
                    if (valueMatcher.IsMatch(matchCriteria, candidate) != 0)
                    {
                        isMatch = false;
                        break;
                    }
                }
                rangeSizeEvaluated = true;
                if (isMatch)
                {
                    matches.Add(maxRange.ElementAt(valueIx).ValueDouble);
                }
            }
            return(matches);
        }
示例#6
0
文件: Search.cs 项目: nxoxn/EPPlus
        public override CompileResult Execute(IEnumerable <FunctionArgument> arguments, ParsingContext context)
        {
            var functionArguments = arguments as FunctionArgument[] ?? arguments.ToArray();

            if (this.ArgumentsAreValid(functionArguments, 2, out eErrorType argumentError) == false)
            {
                return(new CompileResult(argumentError));
            }
            var search   = base.ArgToString(functionArguments, 0);
            var searchIn = base.ArgToString(functionArguments, 1);
            // Subtract 1 because Excel uses 1-based index
            var startIndex = functionArguments.Count() > 2 ? base.ArgToInt(functionArguments, 2) - 1 : 0;
            int result     = -1;

            // If the search string contains Excel wildcard values, convert it to regular expression values and find match.
            if (search.Contains('~') || search.Contains('?') || search.Contains('*'))
            {
                var pattern = new WildCardValueMatcher().ExcelWildcardToRegex(search);
                var matches = Regex.Match(searchIn.Substring(startIndex), pattern, RegexOptions.IgnoreCase);
                if (matches == Match.Empty)
                {
                    return(base.CreateResult(ExcelErrorValue.Create(eErrorType.Value), DataType.ExcelError));
                }
                else
                {
                    result = matches.Index + startIndex;
                }
            }
            // Otherwise, find the index of the search string.
            else
            {
                result = searchIn.IndexOf(search, startIndex, System.StringComparison.OrdinalIgnoreCase);
                if (result == -1)
                {
                    return(base.CreateResult(ExcelErrorValue.Create(eErrorType.Value), DataType.ExcelError));
                }
            }
            // Adding 1 because Excel uses 1-based index
            return(base.CreateResult(result + 1, DataType.Integer));
        }
示例#7
0
 public void Setup()
 {
     _matcher = new WildCardValueMatcher();
 }
 public RowMatcher(WildCardValueMatcher wildCardValueMatcher, ExpressionEvaluator expressionEvaluator)
 {
     _wildCardValueMatcher = wildCardValueMatcher;
     _expressionEvaluator  = expressionEvaluator;
 }
 public RowMatcher(WildCardValueMatcher wildCardValueMatcher, NumericExpressionEvaluator numericExpressionEvaluator)
 {
     _wildCardValueMatcher       = wildCardValueMatcher;
     _numericExpressionEvaluator = numericExpressionEvaluator;
 }