blob: 7087b5fe84ddcc4f888f8c8badb29916ab5d0bcf [file] [log] [blame]
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);
}
}
}
}