|  | using System; | 
|  | using System.Collections.Generic; | 
|  | using System.Linq; | 
|  | using System.Text; | 
|  | using OfficeOpenXml.FormulaParsing.ExpressionGraph; | 
|  |  | 
|  | namespace OfficeOpenXml.FormulaParsing.Excel.Functions.Math | 
|  | { | 
|  | public class Rank : ExcelFunction | 
|  | { | 
|  | bool _isAvg; | 
|  | public Rank(bool isAvg=false) | 
|  | { | 
|  | _isAvg=isAvg; | 
|  | } | 
|  | public override CompileResult Execute(IEnumerable<FunctionArgument> arguments, ParsingContext context) | 
|  | { | 
|  | ValidateArguments(arguments, 2); | 
|  | var number = ArgToDecimal(arguments, 0); | 
|  | var refer = arguments.ElementAt(1); | 
|  | bool asc = false; | 
|  | if (arguments.Count() > 2) | 
|  | { | 
|  | asc = base.ArgToBool(arguments, 2); | 
|  | } | 
|  | var l = new List<double>(); | 
|  |  | 
|  | foreach (var c in refer.ValueAsRangeInfo) | 
|  | { | 
|  | var v = Utils.ConvertUtil.GetValueDouble(c.Value, false, true); | 
|  | if (!double.IsNaN(v)) | 
|  | { | 
|  | l.Add(v); | 
|  | } | 
|  | } | 
|  | l.Sort(); | 
|  | double ix; | 
|  | if (asc) | 
|  | { | 
|  | ix = l.IndexOf(number)+1; | 
|  | if(_isAvg) | 
|  | { | 
|  | int st = Convert.ToInt32(ix); | 
|  | while (l.Count > st && l[st] == number) st++; | 
|  | if (st > ix) ix = ix + ((st - ix) / 2D); | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | ix = l.LastIndexOf(number); | 
|  | if (_isAvg) | 
|  | { | 
|  | int st = Convert.ToInt32(ix)-1; | 
|  | while (0 <= st && l[st] == number) st--; | 
|  | if (st+1 < ix) ix = ix - ((ix - st - 1) / 2D); | 
|  | } | 
|  | ix = l.Count - ix; | 
|  | } | 
|  | if (ix <= 0 || ix>l.Count) | 
|  | { | 
|  | return new CompileResult(ExcelErrorValue.Create(eErrorType.NA), DataType.ExcelError); | 
|  | } | 
|  | else | 
|  | { | 
|  | return CreateResult(ix, DataType.Decimal); | 
|  | } | 
|  | } | 
|  | } | 
|  | } |