diff --git a/ClosedXML/Excel/CalcEngine/Functions/Lookup.cs b/ClosedXML/Excel/CalcEngine/Functions/Lookup.cs index 8a9ac19..964e72b 100644 --- a/ClosedXML/Excel/CalcEngine/Functions/Lookup.cs +++ b/ClosedXML/Excel/CalcEngine/Functions/Lookup.cs @@ -15,7 +15,7 @@ //ce.RegisterFunction("COLUMNS", , Columns); // Returns the number of columns in a reference //ce.RegisterFunction("FORMULATEXT", , Formulatext); // Returns the formula at the given reference as text //ce.RegisterFunction("GETPIVOTDATA", , Getpivotdata); // Returns data stored in a PivotTable report - ce.RegisterFunction("HLOOKUP", 4, Hlookup); // Looks in the top row of an array and returns the value of the indicated cell + ce.RegisterFunction("HLOOKUP", 3, 4, Hlookup); // Looks in the top row of an array and returns the value of the indicated cell //ce.RegisterFunction("HYPERLINK", , Hyperlink); // Creates a shortcut or jump that opens a document stored on a network server, an intranet, or the Internet //ce.RegisterFunction("INDEX", , Index); // Uses an index to choose a value from a reference or array //ce.RegisterFunction("INDIRECT", , Indirect); // Returns a reference indicated by a text value @@ -26,7 +26,7 @@ //ce.RegisterFunction("ROWS", , Rows); // Returns the number of rows in a reference //ce.RegisterFunction("RTD", , Rtd); // Retrieves real-time data from a program that supports COM automation //ce.RegisterFunction("TRANSPOSE", , Transpose); // Returns the transpose of an array - ce.RegisterFunction("VLOOKUP", 4, Vlookup); // Looks in the first column of an array and moves across the row to return the value of a cell + ce.RegisterFunction("VLOOKUP", 3, 4, Vlookup); // Looks in the first column of an array and moves across the row to return the value of a cell } private static object Hlookup(List p) @@ -34,20 +34,25 @@ var lookup_value = p[0]; var table_array = p[1] as XObjectExpression; + if (table_array == null) + throw new ArgumentException("table_array has to be a range"); + var range_reference = table_array.Value as CellRangeReference; + if (range_reference == null) + throw new ArgumentException("table_array has to be a range"); + var range = range_reference.Range; var row_index_num = (int)(p[2]); - var range_lookup = p.Count < 4 || (bool)(p[3]); - - if (table_array == null || range_reference == null) - throw new ApplicationException("table_array has to be a range"); + var range_lookup = p.Count < 4 + || p[3] is EmptyValueExpression + || (bool)(p[3]); if (row_index_num < 1) - throw new ApplicationException("col_index_num has to be positive"); + throw new ArgumentOutOfRangeException("Row index", "row_index_num has to be positive"); if (row_index_num > range.RowCount()) - throw new ApplicationException("col_index_num must be smaller or equal to the number of rows in the table array"); + throw new ArgumentOutOfRangeException("Row index", "row_index_num has to be positive"); IXLRangeColumn matching_column; matching_column = range.FindColumn(c => !c.Cell(1).IsEmpty() && new Expression(c.Cell(1).Value).CompareTo(lookup_value) == 0); @@ -67,7 +72,7 @@ } if (matching_column == null) - throw new ApplicationException("No matches found."); + throw new ArgumentException("No matches found."); return matching_column .Cell(row_index_num) @@ -79,20 +84,25 @@ var lookup_value = p[0]; var table_array = p[1] as XObjectExpression; + if (table_array == null) + throw new ArgumentException("table_array has to be a range"); + var range_reference = table_array.Value as CellRangeReference; + if (range_reference == null) + throw new ArgumentException("table_array has to be a range"); + var range = range_reference.Range; var col_index_num = (int)(p[2]); - var range_lookup = p.Count < 4 || (bool)(p[3]); - - if (table_array == null || range_reference == null) - throw new ApplicationException("table_array has to be a range"); + var range_lookup = p.Count < 4 + || p[3] is EmptyValueExpression + || (bool)(p[3]); if (col_index_num < 1) - throw new ApplicationException("col_index_num has to be positive"); + throw new ArgumentOutOfRangeException("Column index", "col_index_num has to be positive"); if (col_index_num > range.ColumnCount()) - throw new ApplicationException("col_index_num must be smaller or equal to the number of columns in the table array"); + throw new ArgumentOutOfRangeException("Column index", "col_index_num must be smaller or equal to the number of columns in the table array"); IXLRangeRow matching_row; matching_row = range.FindRow(r => !r.Cell(1).IsEmpty() && new Expression(r.Cell(1).Value).CompareTo(lookup_value) == 0); @@ -112,7 +122,7 @@ } if (matching_row == null) - throw new ApplicationException("No matches found."); + throw new ArgumentException("No matches found."); return matching_row .Cell(col_index_num) diff --git a/ClosedXML_Tests/Excel/CalcEngine/LookupTests.cs b/ClosedXML_Tests/Excel/CalcEngine/LookupTests.cs index 60427e6..7d39689 100644 --- a/ClosedXML_Tests/Excel/CalcEngine/LookupTests.cs +++ b/ClosedXML_Tests/Excel/CalcEngine/LookupTests.cs @@ -106,6 +106,12 @@ value = workbook.Evaluate("=VLOOKUP(3,Data!$B$2:$I$71,8,TRUE)"); Assert.AreEqual(179.64, value); + value = workbook.Evaluate("=VLOOKUP(3,Data!$B$2:$I$71,8)"); + Assert.AreEqual(179.64, value); + + value = workbook.Evaluate("=VLOOKUP(3,Data!$B$2:$I$71,8,)"); + Assert.AreEqual(179.64, value); + value = workbook.Evaluate("=VLOOKUP(14.5,Data!$B$2:$I$71,8,TRUE)"); Assert.AreEqual(174.65, value);