1 | using System;
|
---|
2 | using System.Collections.Generic;
|
---|
3 | using System.Linq;
|
---|
4 | using System.Text;
|
---|
5 | using OfficeOpenXml.FormulaParsing.ExcelUtilities;
|
---|
6 | using OfficeOpenXml.FormulaParsing.ExpressionGraph;
|
---|
7 | using OfficeOpenXml.FormulaParsing.Utilities;
|
---|
8 | using OfficeOpenXml.Utils;
|
---|
9 | using Require = OfficeOpenXml.FormulaParsing.Utilities.Require;
|
---|
10 |
|
---|
11 | namespace OfficeOpenXml.FormulaParsing.Excel.Functions.Math
|
---|
12 | {
|
---|
13 | public class CountIf : ExcelFunction
|
---|
14 | {
|
---|
15 | private readonly NumericExpressionEvaluator _numericExpressionEvaluator;
|
---|
16 | private readonly WildCardValueMatcher _wildCardValueMatcher;
|
---|
17 |
|
---|
18 | public CountIf()
|
---|
19 | : this(new NumericExpressionEvaluator(), new WildCardValueMatcher())
|
---|
20 | {
|
---|
21 |
|
---|
22 | }
|
---|
23 |
|
---|
24 | public CountIf(NumericExpressionEvaluator evaluator, WildCardValueMatcher wildCardValueMatcher)
|
---|
25 | {
|
---|
26 | Require.That(evaluator).Named("evaluator").IsNotNull();
|
---|
27 | Require.That(wildCardValueMatcher).Named("wildCardValueMatcher").IsNotNull();
|
---|
28 | _numericExpressionEvaluator = evaluator;
|
---|
29 | _wildCardValueMatcher = wildCardValueMatcher;
|
---|
30 | }
|
---|
31 |
|
---|
32 | private bool Evaluate(object obj, string expression)
|
---|
33 | {
|
---|
34 | double? candidate = default(double?);
|
---|
35 | if (IsNumeric(obj))
|
---|
36 | {
|
---|
37 | candidate = ConvertUtil.GetValueDouble(obj);
|
---|
38 | }
|
---|
39 | if (candidate.HasValue)
|
---|
40 | {
|
---|
41 | return _numericExpressionEvaluator.Evaluate(candidate.Value, expression);
|
---|
42 | }
|
---|
43 | return _wildCardValueMatcher.IsMatch(expression, obj.ToString()) == 0;
|
---|
44 | }
|
---|
45 |
|
---|
46 | public override CompileResult Execute(IEnumerable<FunctionArgument> arguments, ParsingContext context)
|
---|
47 | {
|
---|
48 | var functionArguments = arguments as FunctionArgument[] ?? arguments.ToArray();
|
---|
49 | ValidateArguments(functionArguments, 2);
|
---|
50 | var range = functionArguments.ElementAt(0);
|
---|
51 | var criteria = ArgToString(functionArguments, 1);
|
---|
52 | double result = 0d;
|
---|
53 | if (range.IsExcelRange)
|
---|
54 | {
|
---|
55 | foreach (var cell in range.ValueAsRangeInfo)
|
---|
56 | {
|
---|
57 | if (Evaluate(cell.Value, criteria))
|
---|
58 | {
|
---|
59 | result++;
|
---|
60 | }
|
---|
61 | }
|
---|
62 | }
|
---|
63 | else if (range.Value is IEnumerable<FunctionArgument>)
|
---|
64 | {
|
---|
65 | foreach (var arg in (IEnumerable<FunctionArgument>) range.Value)
|
---|
66 | {
|
---|
67 | if(Evaluate(arg.Value, criteria))
|
---|
68 | {
|
---|
69 | result++;
|
---|
70 | }
|
---|
71 | }
|
---|
72 | }
|
---|
73 | else
|
---|
74 | {
|
---|
75 | if (Evaluate(range.Value, criteria))
|
---|
76 | {
|
---|
77 | result++;
|
---|
78 | }
|
---|
79 | }
|
---|
80 | return CreateResult(result, DataType.Integer);
|
---|
81 | }
|
---|
82 | }
|
---|
83 | }
|
---|