Initial commit of the ClosedXML library
Establishes the foundational structure, core Excel functionality, and tooling. - Implements base components for cells, ranges, columns, and rows. - Integrates a custom calculation engine with a wide range of Excel functions. - Adds comprehensive support for styling, conditional formatting, data validation, comments, pictures, and charts. - Configures build setup, project metadata (NuGet), and developer guidelines. - Includes editor and Git attributes for consistent code style and line endings.
This commit is contained in:
@@ -0,0 +1,152 @@
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using ClosedXML.Excel;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace ClosedXML_Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class CopyingRangesTests
|
||||
{
|
||||
[Test]
|
||||
public void CopyingColumns()
|
||||
{
|
||||
var wb = new XLWorkbook();
|
||||
IXLWorksheet ws = wb.Worksheets.Add("Sheet");
|
||||
|
||||
IXLColumn column1 = ws.Column(1);
|
||||
column1.Cell(1).Style.Fill.SetBackgroundColor(XLColor.Red);
|
||||
column1.Cell(2).Style.Fill.SetBackgroundColor(XLColor.FromArgb(1, 1, 1));
|
||||
column1.Cell(3).Style.Fill.SetBackgroundColor(XLColor.FromHtml("#CCCCCC"));
|
||||
column1.Cell(4).Style.Fill.SetBackgroundColor(XLColor.FromIndex(26));
|
||||
column1.Cell(5).Style.Fill.SetBackgroundColor(XLColor.FromColor(Color.MediumSeaGreen));
|
||||
column1.Cell(6).Style.Fill.SetBackgroundColor(XLColor.FromName("Blue"));
|
||||
column1.Cell(7).Style.Fill.SetBackgroundColor(XLColor.FromTheme(XLThemeColor.Accent3));
|
||||
|
||||
ws.Cell(1, 2).Value = column1;
|
||||
ws.Cell(1, 3).Value = column1.Column(1, 7);
|
||||
|
||||
IXLColumn column2 = ws.Column(2);
|
||||
Assert.AreEqual(XLColor.Red, column2.Cell(1).Style.Fill.BackgroundColor);
|
||||
Assert.AreEqual(XLColor.FromArgb(1, 1, 1), column2.Cell(2).Style.Fill.BackgroundColor);
|
||||
Assert.AreEqual(XLColor.FromHtml("#CCCCCC"), column2.Cell(3).Style.Fill.BackgroundColor);
|
||||
Assert.AreEqual(XLColor.FromIndex(26), column2.Cell(4).Style.Fill.BackgroundColor);
|
||||
Assert.AreEqual(XLColor.FromColor(Color.MediumSeaGreen),
|
||||
column2.Cell(5).Style.Fill.BackgroundColor);
|
||||
Assert.AreEqual(XLColor.FromName("Blue"), column2.Cell(6).Style.Fill.BackgroundColor);
|
||||
Assert.AreEqual(XLColor.FromTheme(XLThemeColor.Accent3), column2.Cell(7).Style.Fill.BackgroundColor);
|
||||
|
||||
IXLColumn column3 = ws.Column(3);
|
||||
Assert.AreEqual(XLColor.Red, column3.Cell(1).Style.Fill.BackgroundColor);
|
||||
Assert.AreEqual(XLColor.FromArgb(1, 1, 1), column3.Cell(2).Style.Fill.BackgroundColor);
|
||||
Assert.AreEqual(XLColor.FromHtml("#CCCCCC"), column3.Cell(3).Style.Fill.BackgroundColor);
|
||||
Assert.AreEqual(XLColor.FromIndex(26), column3.Cell(4).Style.Fill.BackgroundColor);
|
||||
Assert.AreEqual(XLColor.FromColor(Color.MediumSeaGreen),
|
||||
column3.Cell(5).Style.Fill.BackgroundColor);
|
||||
Assert.AreEqual(XLColor.FromName("Blue"), column3.Cell(6).Style.Fill.BackgroundColor);
|
||||
Assert.AreEqual(XLColor.FromTheme(XLThemeColor.Accent3), column3.Cell(7).Style.Fill.BackgroundColor);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CopyingRows()
|
||||
{
|
||||
var wb = new XLWorkbook();
|
||||
IXLWorksheet ws = wb.Worksheets.Add("Sheet");
|
||||
|
||||
IXLRow row1 = ws.Row(1);
|
||||
FillRow(row1);
|
||||
|
||||
ws.Cell(2, 1).Value = row1;
|
||||
ws.Cell(3, 1).Value = row1.Row(1, 7);
|
||||
|
||||
IXLRow row2 = ws.Row(2);
|
||||
Assert.AreEqual(XLColor.Red, row2.Cell(1).Style.Fill.BackgroundColor);
|
||||
Assert.AreEqual(XLColor.FromArgb(1, 1, 1), row2.Cell(2).Style.Fill.BackgroundColor);
|
||||
Assert.AreEqual(XLColor.FromHtml("#CCCCCC"), row2.Cell(3).Style.Fill.BackgroundColor);
|
||||
Assert.AreEqual(XLColor.FromIndex(26), row2.Cell(4).Style.Fill.BackgroundColor);
|
||||
Assert.AreEqual(XLColor.FromColor(Color.MediumSeaGreen), row2.Cell(5).Style.Fill.BackgroundColor);
|
||||
Assert.AreEqual(XLColor.FromName("Blue"), row2.Cell(6).Style.Fill.BackgroundColor);
|
||||
Assert.AreEqual(XLColor.FromTheme(XLThemeColor.Accent3), row2.Cell(7).Style.Fill.BackgroundColor);
|
||||
|
||||
IXLRow row3 = ws.Row(3);
|
||||
Assert.AreEqual(XLColor.Red, row3.Cell(1).Style.Fill.BackgroundColor);
|
||||
Assert.AreEqual(XLColor.FromArgb(1, 1, 1), row3.Cell(2).Style.Fill.BackgroundColor);
|
||||
Assert.AreEqual(XLColor.FromHtml("#CCCCCC"), row3.Cell(3).Style.Fill.BackgroundColor);
|
||||
Assert.AreEqual(XLColor.FromIndex(26), row3.Cell(4).Style.Fill.BackgroundColor);
|
||||
Assert.AreEqual(XLColor.FromColor(Color.MediumSeaGreen), row3.Cell(5).Style.Fill.BackgroundColor);
|
||||
Assert.AreEqual(XLColor.FromName("Blue"), row3.Cell(6).Style.Fill.BackgroundColor);
|
||||
Assert.AreEqual(XLColor.FromTheme(XLThemeColor.Accent3), row3.Cell(7).Style.Fill.BackgroundColor);
|
||||
|
||||
Assert.AreEqual(3, ws.ConditionalFormats.Count());
|
||||
Assert.IsTrue(ws.ConditionalFormats.Single(x => x.Range.RangeAddress.ToStringRelative() == "B1:B1").Values.Any(v => v.Value.Value == "G1" && v.Value.IsFormula));
|
||||
Assert.IsTrue(ws.ConditionalFormats.Single(x => x.Range.RangeAddress.ToStringRelative() == "B2:B2").Values.Any(v => v.Value.Value == "G2" && v.Value.IsFormula));
|
||||
Assert.IsTrue(ws.ConditionalFormats.Single(x => x.Range.RangeAddress.ToStringRelative() == "B3:B3").Values.Any(v => v.Value.Value == "G3" && v.Value.IsFormula));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CopyingConditionalFormats()
|
||||
{
|
||||
var wb = new XLWorkbook();
|
||||
IXLWorksheet ws = wb.Worksheets.Add("Sheet");
|
||||
|
||||
FillRow(ws.Row(1));
|
||||
FillRow(ws.Row(2));
|
||||
FillRow(ws.Row(3));
|
||||
|
||||
((XLConditionalFormats)ws.ConditionalFormats).Consolidate();
|
||||
|
||||
ws.Cell(5, 2).Value = ws.Row(2).Row(1, 7);
|
||||
|
||||
Assert.AreEqual(2, ws.ConditionalFormats.Count());
|
||||
Assert.IsTrue(ws.ConditionalFormats.Single(x => x.Range.RangeAddress.ToStringRelative() == "B1:B3").Values.Any(v => v.Value.Value == "G1" && v.Value.IsFormula));
|
||||
Assert.IsTrue(ws.ConditionalFormats.Single(x => x.Range.RangeAddress.ToStringRelative() == "C5:C5").Values.Any(v => v.Value.Value == "H5" && v.Value.IsFormula));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CopyingConditionalFormatsDifferentWorksheets()
|
||||
{
|
||||
var wb = new XLWorkbook();
|
||||
var ws1 = wb.Worksheets.Add("Sheet1");
|
||||
var format = ws1.Range("A1:J2").AddConditionalFormat();
|
||||
|
||||
var address = format.Ranges
|
||||
.First()
|
||||
.FirstCell()
|
||||
.CellRight(4)
|
||||
.Address
|
||||
.ToStringRelative();
|
||||
|
||||
format.WhenEquals("=" + address)
|
||||
.Fill
|
||||
.SetBackgroundColor(XLColor.Blue);
|
||||
|
||||
var ws2 = wb.Worksheets.Add("Sheet2");
|
||||
|
||||
ws2.FirstCell().Value = ws1.Range("B1:B4");
|
||||
|
||||
Assert.AreEqual(1, ws2.ConditionalFormats.Count());
|
||||
Assert.IsTrue(ws2.ConditionalFormats.All(x => x.Ranges.All(s => s.Worksheet == ws2)), "A conditional format was created for another worksheet.");
|
||||
Assert.IsTrue(ws2.ConditionalFormats
|
||||
.Single(x => x.Range.RangeAddress.ToStringRelative() == "A1:A2")
|
||||
.Values.Any(v => v.Value.Value == "E1" && v.Value.IsFormula), "The formula has not been transferred correctly.");
|
||||
|
||||
Assert.AreEqual("Sheet1", ws1.ConditionalFormats.First().Ranges.First().Worksheet.Name);
|
||||
Assert.AreEqual("Sheet2", ws2.ConditionalFormats.First().Ranges.First().Worksheet.Name);
|
||||
Assert.AreEqual("A1:J2", ws1.ConditionalFormats.First().Ranges.First().RangeAddress.ToString());
|
||||
Assert.AreEqual("A1:A2", ws2.ConditionalFormats.First().Ranges.First().RangeAddress.ToString());
|
||||
}
|
||||
|
||||
private static void FillRow(IXLRow row1)
|
||||
{
|
||||
row1.Cell(1).Style.Fill.SetBackgroundColor(XLColor.Red);
|
||||
row1.Cell(2).Style.Fill.SetBackgroundColor(XLColor.FromArgb(1, 1, 1));
|
||||
row1.Cell(3).Style.Fill.SetBackgroundColor(XLColor.FromHtml("#CCCCCC"));
|
||||
row1.Cell(4).Style.Fill.SetBackgroundColor(XLColor.FromIndex(26));
|
||||
row1.Cell(5).Style.Fill.SetBackgroundColor(XLColor.FromColor(Color.MediumSeaGreen));
|
||||
row1.Cell(6).Style.Fill.SetBackgroundColor(XLColor.FromName("Blue"));
|
||||
row1.Cell(7).Style.Fill.SetBackgroundColor(XLColor.FromTheme(XLThemeColor.Accent3));
|
||||
|
||||
row1.Cell(2).AddConditionalFormat().WhenEquals("=" + row1.FirstCell().CellRight(6).Address.ToStringRelative()).Fill.SetBackgroundColor(XLColor.Blue);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,298 @@
|
||||
using ClosedXML.Excel;
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace ClosedXML_Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class InsertingRangesTests
|
||||
{
|
||||
[Test]
|
||||
public void InsertingColumnsPreservesFormatting()
|
||||
{
|
||||
var wb = new XLWorkbook();
|
||||
IXLWorksheet ws = wb.Worksheets.Add("Sheet");
|
||||
IXLColumn column1 = ws.Column(1);
|
||||
column1.Style.Fill.SetBackgroundColor(XLColor.FrenchLilac);
|
||||
column1.Cell(2).Style.Fill.SetBackgroundColor(XLColor.Fulvous);
|
||||
IXLColumn column2 = ws.Column(2);
|
||||
column2.Style.Fill.SetBackgroundColor(XLColor.Xanadu);
|
||||
column2.Cell(2).Style.Fill.SetBackgroundColor(XLColor.MacaroniAndCheese);
|
||||
|
||||
column1.InsertColumnsAfter(1);
|
||||
column1.InsertColumnsBefore(1);
|
||||
column2.InsertColumnsBefore(1);
|
||||
|
||||
Assert.AreEqual(ws.Style.Fill.BackgroundColor, ws.Column(1).Style.Fill.BackgroundColor);
|
||||
Assert.AreEqual(XLColor.FrenchLilac, ws.Column(2).Style.Fill.BackgroundColor);
|
||||
Assert.AreEqual(XLColor.FrenchLilac, ws.Column(3).Style.Fill.BackgroundColor);
|
||||
Assert.AreEqual(XLColor.FrenchLilac, ws.Column(4).Style.Fill.BackgroundColor);
|
||||
Assert.AreEqual(XLColor.Xanadu, ws.Column(5).Style.Fill.BackgroundColor);
|
||||
|
||||
Assert.AreEqual(ws.Style.Fill.BackgroundColor, ws.Cell(2, 1).Style.Fill.BackgroundColor);
|
||||
Assert.AreEqual(XLColor.Fulvous, ws.Cell(2, 2).Style.Fill.BackgroundColor);
|
||||
Assert.AreEqual(XLColor.Fulvous, ws.Cell(2, 3).Style.Fill.BackgroundColor);
|
||||
Assert.AreEqual(XLColor.Fulvous, ws.Cell(2, 4).Style.Fill.BackgroundColor);
|
||||
Assert.AreEqual(XLColor.MacaroniAndCheese, ws.Cell(2, 5).Style.Fill.BackgroundColor);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void InsertingRowsAbove()
|
||||
{
|
||||
var wb = new XLWorkbook();
|
||||
IXLWorksheet ws = wb.Worksheets.Add("Sheet");
|
||||
|
||||
ws.Cell("B3").SetValue("X")
|
||||
.CellBelow().SetValue("B");
|
||||
|
||||
IXLRangeRow r = ws.Range("B4").InsertRowsAbove(1).First();
|
||||
r.Cell(1).SetValue("A");
|
||||
|
||||
Assert.AreEqual("X", ws.Cell("B3").GetString());
|
||||
Assert.AreEqual("A", ws.Cell("B4").GetString());
|
||||
Assert.AreEqual("B", ws.Cell("B5").GetString());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void InsertingRowsPreservesFormatting()
|
||||
{
|
||||
var wb = new XLWorkbook();
|
||||
IXLWorksheet ws = wb.Worksheets.Add("Sheet");
|
||||
IXLRow row1 = ws.Row(1);
|
||||
row1.Style.Fill.SetBackgroundColor(XLColor.FrenchLilac);
|
||||
row1.Cell(2).Style.Fill.SetBackgroundColor(XLColor.Fulvous);
|
||||
IXLRow row2 = ws.Row(2);
|
||||
row2.Style.Fill.SetBackgroundColor(XLColor.Xanadu);
|
||||
row2.Cell(2).Style.Fill.SetBackgroundColor(XLColor.MacaroniAndCheese);
|
||||
|
||||
row1.InsertRowsBelow(1);
|
||||
row1.InsertRowsAbove(1);
|
||||
row2.InsertRowsAbove(1);
|
||||
|
||||
Assert.AreEqual(ws.Style.Fill.BackgroundColor, ws.Row(1).Style.Fill.BackgroundColor);
|
||||
Assert.AreEqual(XLColor.FrenchLilac, ws.Row(2).Style.Fill.BackgroundColor);
|
||||
Assert.AreEqual(XLColor.FrenchLilac, ws.Row(3).Style.Fill.BackgroundColor);
|
||||
Assert.AreEqual(XLColor.FrenchLilac, ws.Row(4).Style.Fill.BackgroundColor);
|
||||
Assert.AreEqual(XLColor.Xanadu, ws.Row(5).Style.Fill.BackgroundColor);
|
||||
|
||||
Assert.AreEqual(ws.Style.Fill.BackgroundColor, ws.Cell(1, 2).Style.Fill.BackgroundColor);
|
||||
Assert.AreEqual(XLColor.Fulvous, ws.Cell(2, 2).Style.Fill.BackgroundColor);
|
||||
Assert.AreEqual(XLColor.Fulvous, ws.Cell(3, 2).Style.Fill.BackgroundColor);
|
||||
Assert.AreEqual(XLColor.Fulvous, ws.Cell(4, 2).Style.Fill.BackgroundColor);
|
||||
Assert.AreEqual(XLColor.MacaroniAndCheese, ws.Cell(5, 2).Style.Fill.BackgroundColor);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void InsertingRowsPreservesComments()
|
||||
{
|
||||
var wb = new XLWorkbook();
|
||||
var ws = wb.Worksheets.Add("Sheet1");
|
||||
|
||||
ws.Cell("A1").SetValue("Insert Below");
|
||||
ws.Cell("A2").SetValue("Already existing cell");
|
||||
ws.Cell("A3").SetValue("Cell with comment").Comment.AddText("Comment here");
|
||||
|
||||
ws.Row(1).InsertRowsBelow(2);
|
||||
Assert.AreEqual("Comment here", ws.Cell("A5").Comment.Text);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void InsertingColumnsPreservesComments()
|
||||
{
|
||||
var wb = new XLWorkbook();
|
||||
var ws = wb.Worksheets.Add("Sheet1");
|
||||
|
||||
ws.Cell("A1").SetValue("Insert to the right");
|
||||
ws.Cell("B1").SetValue("Already existing cell");
|
||||
ws.Cell("C1").SetValue("Cell with comment").Comment.AddText("Comment here");
|
||||
|
||||
ws.Column(1).InsertColumnsAfter(2);
|
||||
Assert.AreEqual("Comment here", ws.Cell("E1").Comment.Text);
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCase("C4:F7", "C4:F7", 2, "E4:H7")] // Coincide, shift right
|
||||
[TestCase("C4:F7", "C4:F7", -2, "C4:D7")] // Coincide, shift left
|
||||
[TestCase("D5:E6", "C4:F7", 2, "F5:G6")] // Inside, shift right
|
||||
[TestCase("D5:E6", "C4:F7", -2, "C5:C6")] // Inside, shift left
|
||||
[TestCase("B4:G7", "C4:F7", 2, "B4:I7")] // Includes, shift right
|
||||
[TestCase("B4:G7", "C4:F7", -2, "B4:E7")] // Includes, shift left
|
||||
[TestCase("B4:E7", "C4:F7", 2, "B4:G7")] // Intersects at left, shift right
|
||||
[TestCase("B4:E7", "C4:F7", -2, "B4:C7")] // Intersects at left, shift left
|
||||
[TestCase("D4:G7", "C4:F7", 2, "F4:I7")] // Intersects at right, shift right
|
||||
[TestCase("D4:G7", "C4:F7", -2, "C4:E7")] // Intersects at right, shift left
|
||||
[TestCase("A5:B6", "C4:F7", 2, "A5:B6")] // No intersection, at left, shift right
|
||||
[TestCase("A5:B6", "C4:F7", -1, "A5:B6")] // No intersection, at left, shift left
|
||||
[TestCase("H5:I6", "C4:F7", 2, "J5:K6")] // No intersection, at right, shift right
|
||||
[TestCase("H5:I6", "C4:F7", -2, "F5:G6")] // No intersection, at right, shift left
|
||||
[TestCase("C8:F11", "C4:F7", 2, "C8:F11")] // Different rows
|
||||
[TestCase("B1:B8", "A1:C4", 1, "B1:B8")] // More rows, shift right
|
||||
[TestCase("B1:B8", "A1:C4", -1, "B1:B8")] // More rows, shift left
|
||||
public void ShiftColumnsValid(string thisRangeAddress, string shiftedRangeAddress, int shiftedColumns, string expectedRange)
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.Worksheets.Add("Sheet1");
|
||||
var thisRange = ws.Range(thisRangeAddress) as XLRange;
|
||||
var shiftedRange = ws.Range(shiftedRangeAddress) as XLRange;
|
||||
|
||||
thisRange.WorksheetRangeShiftedColumns(shiftedRange, shiftedColumns);
|
||||
|
||||
Assert.IsTrue(thisRange.RangeAddress.IsValid);
|
||||
Assert.AreEqual(expectedRange, thisRange.RangeAddress.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCase("B1:B4", "A1:C4", -2)] // Shift left too much
|
||||
public void ShiftColumnsInvalid(string thisRangeAddress, string shiftedRangeAddress, int shiftedColumns)
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.Worksheets.Add("Sheet1");
|
||||
var thisRange = ws.Range(thisRangeAddress) as XLRange;
|
||||
var shiftedRange = ws.Range(shiftedRangeAddress) as XLRange;
|
||||
|
||||
thisRange.WorksheetRangeShiftedColumns(shiftedRange, shiftedColumns);
|
||||
|
||||
Assert.IsFalse(thisRange.RangeAddress.IsValid);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCase("C4:F7", "C4:F7", 2, "C6:F9")] // Coincide, shift down
|
||||
[TestCase("C4:F7", "C4:F7", -2, "C4:F5")] // Coincide, shift up
|
||||
[TestCase("D5:E6", "C4:F7", 2, "D7:E8")] // Inside, shift down
|
||||
[TestCase("D5:E6", "C4:F7", -2, "D4:E4")] // Inside, shift up
|
||||
[TestCase("C3:F8", "C4:F7", 2, "C3:F10")] // Includes, shift down
|
||||
[TestCase("C3:F8", "C4:F7", -2, "C3:F6")] // Includes, shift up
|
||||
[TestCase("C3:F6", "C4:F7", 2, "C3:F8")] // Intersects at top, shift down
|
||||
[TestCase("C2:F6", "C4:F7", -3, "C2:F3")] // Intersects at top, shift up to the sheet boundary
|
||||
[TestCase("C3:F6", "C4:F7", -2, "C3:F4")] // Intersects at top, shift up
|
||||
[TestCase("C5:F8", "C4:F7", 2, "C7:F10")] // Intersects at bottom, shift down
|
||||
[TestCase("C5:F8", "C4:F7", -2, "C4:F6")] // Intersects at bottom, shift up
|
||||
[TestCase("C1:F3", "C4:F7", 2, "C1:F3")] // No intersection, at top, shift down
|
||||
[TestCase("C1:F3", "C4:F7", -2, "C1:F3")] // No intersection, at top, shift up
|
||||
[TestCase("C8:F10", "C4:F7", 2, "C10:F12")] // No intersection, at bottom, shift down
|
||||
[TestCase("C8:F10", "C4:F7", -2, "C6:F8")] // No intersection, at bottom, shift up
|
||||
[TestCase("G4:J7", "C4:F7", 2, "G4:J7")] // Different columns
|
||||
[TestCase("A2:D2", "A1:C4", 1, "A2:D2")] // More columns, shift down
|
||||
[TestCase("A2:D2", "A1:C4", -1, "A2:D2")] // More columns, shift up
|
||||
public void ShiftRowsValid(string thisRangeAddress, string shiftedRangeAddress, int shiftedRows, string expectedRange)
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.Worksheets.Add("Sheet1");
|
||||
var thisRange = ws.Range(thisRangeAddress) as XLRange;
|
||||
var shiftedRange = ws.Range(shiftedRangeAddress) as XLRange;
|
||||
|
||||
thisRange.WorksheetRangeShiftedRows(shiftedRange, shiftedRows);
|
||||
|
||||
Assert.IsTrue(thisRange.RangeAddress.IsValid);
|
||||
Assert.AreEqual(expectedRange, thisRange.RangeAddress.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCase("A2:C2", "A1:C4", -2)] // Shift up too much
|
||||
public void ShiftRowsInvalid(string thisRangeAddress, string shiftedRangeAddress, int shiftedRows)
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.Worksheets.Add("Sheet1");
|
||||
var thisRange = ws.Range(thisRangeAddress) as XLRange;
|
||||
var shiftedRange = ws.Range(shiftedRangeAddress) as XLRange;
|
||||
|
||||
thisRange.WorksheetRangeShiftedRows(shiftedRange, shiftedRows);
|
||||
|
||||
Assert.IsFalse(thisRange.RangeAddress.IsValid);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void InsertZeroColumnsFails()
|
||||
{
|
||||
var ws = new XLWorkbook().AddWorksheet("Sheet1");
|
||||
var range = ws.FirstCell().AsRange();
|
||||
Assert.Throws(typeof(ArgumentOutOfRangeException), () => range.InsertColumnsAfter(0));
|
||||
Assert.Throws(typeof(ArgumentOutOfRangeException), () => range.InsertColumnsBefore(0));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void InsertNegativeNumberOfColumnsFails()
|
||||
{
|
||||
var ws = new XLWorkbook().AddWorksheet("Sheet1");
|
||||
var range = ws.FirstCell().AsRange();
|
||||
Assert.Throws(typeof(ArgumentOutOfRangeException), () => range.InsertColumnsAfter(-1));
|
||||
Assert.Throws(typeof(ArgumentOutOfRangeException), () => range.InsertColumnsBefore(-1));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void InsertTooLargeNumberOfColumnsFails()
|
||||
{
|
||||
var ws = new XLWorkbook().AddWorksheet("Sheet1");
|
||||
var range = ws.FirstCell().AsRange();
|
||||
Assert.Throws(typeof(ArgumentOutOfRangeException), () => range.InsertColumnsAfter(16385));
|
||||
Assert.Throws(typeof(ArgumentOutOfRangeException), () => range.InsertColumnsBefore(16385));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void InsertZeroRowsFails()
|
||||
{
|
||||
var ws = new XLWorkbook().AddWorksheet("Sheet1");
|
||||
var range = ws.FirstCell().AsRange();
|
||||
Assert.Throws(typeof(ArgumentOutOfRangeException), () => range.InsertRowsAbove(0));
|
||||
Assert.Throws(typeof(ArgumentOutOfRangeException), () => range.InsertRowsBelow(0));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void InsertNegativeNumberOfRowsFails()
|
||||
{
|
||||
var ws = new XLWorkbook().AddWorksheet("Sheet1");
|
||||
var range = ws.FirstCell().AsRange();
|
||||
Assert.Throws(typeof(ArgumentOutOfRangeException), () => range.InsertRowsAbove(-1));
|
||||
Assert.Throws(typeof(ArgumentOutOfRangeException), () => range.InsertRowsBelow(-1));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void InsertTooLargeNumberOrRowsFails()
|
||||
{
|
||||
var ws = new XLWorkbook().AddWorksheet("Sheet1");
|
||||
var range = ws.FirstCell().AsRange();
|
||||
Assert.Throws(typeof(ArgumentOutOfRangeException), () => range.InsertRowsAbove(1048577));
|
||||
Assert.Throws(typeof(ArgumentOutOfRangeException), () => range.InsertRowsBelow(1048577));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MergedRangesConsistencyWhenInsertingRows()
|
||||
{
|
||||
// https://github.com/ClosedXML/ClosedXML/issues/1013
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.AddWorksheet("Sheet1");
|
||||
|
||||
//create merged row
|
||||
ws.Cell("A1").Value = "Merged Row(1) of Range (A1:F1)";
|
||||
ws.Range("A1:F1").Row(1).Merge();
|
||||
|
||||
var row = ws.FirstRow();
|
||||
|
||||
// Add some lines and copy format & merging
|
||||
for (var r = 1; r <= 10; r++)
|
||||
{
|
||||
row.InsertRowsBelow(1); // insert a row below row 1, as a row 2
|
||||
row.CopyTo(row.RowBelow()); // copy format and merging from row 1 to row 2
|
||||
|
||||
var duplicates = ws.MergedRanges
|
||||
.GroupBy(s => s.ToString())
|
||||
.Where(g => g.Count() > 1)
|
||||
.Select(y => new { Element = y.Key, Counter = y.Count() })
|
||||
.ToList();
|
||||
|
||||
Assert.AreEqual(0, duplicates.Count);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,443 @@
|
||||
using ClosedXML.Excel;
|
||||
using NUnit.Framework;
|
||||
using System.Linq;
|
||||
|
||||
namespace ClosedXML_Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class MergedRangesTests
|
||||
{
|
||||
[Test]
|
||||
public void LastCellFromMerge()
|
||||
{
|
||||
var wb = new XLWorkbook();
|
||||
IXLWorksheet ws = wb.Worksheets.Add("Sheet");
|
||||
ws.Range("B2:D4").Merge();
|
||||
|
||||
string first = ws.FirstCellUsed(XLCellsUsedOptions.All).Address.ToStringRelative();
|
||||
string last = ws.LastCellUsed(XLCellsUsedOptions.All).Address.ToStringRelative();
|
||||
|
||||
Assert.AreEqual("B2", first);
|
||||
Assert.AreEqual("D4", last);
|
||||
}
|
||||
|
||||
[TestCase("A1:A2", "A1:A2")]
|
||||
[TestCase("A2:B2", "A2:B2")]
|
||||
[TestCase("A3:C3", "A3:E3")]
|
||||
[TestCase("B4:B6", "B4:B6")]
|
||||
[TestCase("C7:D7", "E7:F7")]
|
||||
public void MergedRangesShiftedOnColumnInsert(string originalRange, string expectedRange)
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.AddWorksheet("MRShift");
|
||||
var range = ws.Range(originalRange).Merge();
|
||||
|
||||
ws.Column(2).InsertColumnsAfter(2);
|
||||
|
||||
var mr = ws.MergedRanges.ToArray();
|
||||
Assert.AreEqual(1, mr.Length);
|
||||
Assert.AreSame(range, mr.Single());
|
||||
Assert.AreEqual(expectedRange, range.RangeAddress.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[TestCase("A1:B1", "A1:B1")]
|
||||
[TestCase("B1:B2", "B1:B2")]
|
||||
[TestCase("C1:C3", "C1:C5")]
|
||||
[TestCase("D2:F2", "D2:F2")]
|
||||
[TestCase("G4:G5", "G6:G7")]
|
||||
public void MergedRangesShiftedOnRowInsert(string originalRange, string expectedRange)
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.AddWorksheet("MRShift");
|
||||
var range = ws.Range(originalRange).Merge();
|
||||
|
||||
ws.Row(2).InsertRowsBelow(2);
|
||||
|
||||
var mr = ws.MergedRanges.ToArray();
|
||||
Assert.AreEqual(1, mr.Length);
|
||||
Assert.AreSame(range, mr.Single());
|
||||
Assert.AreEqual(expectedRange, range.RangeAddress.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[TestCase("A1:A2", true, "A1:A2")]
|
||||
[TestCase("A2:B2", true, "A2:A2")]
|
||||
[TestCase("A3:C3", true, "A3:B3")]
|
||||
[TestCase("B4:B6", false, "")]
|
||||
[TestCase("C7:D7", true, "B7:C7")]
|
||||
public void MergedRangesShiftedOnColumnDelete(string originalRange, bool expectedExist, string expectedRange)
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.AddWorksheet("MRShift");
|
||||
var range = ws.Range(originalRange).Merge();
|
||||
|
||||
ws.Column(2).Delete();
|
||||
|
||||
var mr = ws.MergedRanges.ToArray();
|
||||
if (expectedExist)
|
||||
{
|
||||
Assert.AreEqual(1, mr.Length);
|
||||
Assert.AreSame(range, mr.Single());
|
||||
Assert.AreEqual(expectedRange, range.RangeAddress.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.AreEqual(0, mr.Length);
|
||||
Assert.IsFalse(range.RangeAddress.IsValid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[TestCase("A1:B1", true, "A1:B1")]
|
||||
[TestCase("B1:B2", true, "B1:B1")]
|
||||
[TestCase("C1:C3", true, "C1:C2")]
|
||||
[TestCase("D2:F2", false, "")]
|
||||
[TestCase("G4:G5", true, "G3:G4")]
|
||||
public void MergedRangesShiftedOnRowDelete(string originalRange, bool expectedExist, string expectedRange)
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.AddWorksheet("MRShift");
|
||||
var range = ws.Range(originalRange).Merge();
|
||||
|
||||
ws.Row(2).Delete();
|
||||
|
||||
var mr = ws.MergedRanges.ToArray();
|
||||
if (expectedExist)
|
||||
{
|
||||
Assert.AreEqual(1, mr.Length);
|
||||
Assert.AreSame(range, mr.Single());
|
||||
Assert.AreEqual(expectedRange, range.RangeAddress.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.AreEqual(0, mr.Length);
|
||||
Assert.IsFalse(range.RangeAddress.IsValid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ShiftRangeRightBreaksMerges()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.AddWorksheet("MRShift");
|
||||
ws.Range("B2:C3").Merge();
|
||||
ws.Range("B4:C5").Merge();
|
||||
ws.Range("F2:G3").Merge(); // to be broken
|
||||
ws.Range("F4:G5").Merge(); // to be broken
|
||||
ws.Range("H1:I2").Merge();
|
||||
ws.Range("H5:I6").Merge();
|
||||
|
||||
ws.Range("D3:E4").InsertColumnsAfter(2);
|
||||
|
||||
var mr = ws.MergedRanges.ToArray();
|
||||
Assert.AreEqual(4, mr.Length);
|
||||
Assert.AreEqual("H1:I2", mr[0].RangeAddress.ToString());
|
||||
Assert.AreEqual("B2:C3", mr[1].RangeAddress.ToString());
|
||||
Assert.AreEqual("B4:C5", mr[2].RangeAddress.ToString());
|
||||
Assert.AreEqual("H5:I6", mr[3].RangeAddress.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ShiftRangeLeftBreaksMerges()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.AddWorksheet("MRShift");
|
||||
ws.Range("B2:C3").Merge();
|
||||
ws.Range("B4:C5").Merge();
|
||||
ws.Range("F2:G3").Merge(); // to be broken
|
||||
ws.Range("F4:G5").Merge(); // to be broken
|
||||
ws.Range("H1:I2").Merge();
|
||||
ws.Range("H5:I6").Merge();
|
||||
|
||||
ws.Range("D3:E4").Delete(XLShiftDeletedCells.ShiftCellsLeft);
|
||||
|
||||
var mr = ws.MergedRanges.ToArray();
|
||||
Assert.AreEqual(4, mr.Length);
|
||||
Assert.AreEqual("H1:I2", mr[0].RangeAddress.ToString());
|
||||
Assert.AreEqual("B2:C3", mr[1].RangeAddress.ToString());
|
||||
Assert.AreEqual("B4:C5", mr[2].RangeAddress.ToString());
|
||||
Assert.AreEqual("H5:I6", mr[3].RangeAddress.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RangeShiftDownBreaksMerges()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.AddWorksheet("MRShift");
|
||||
ws.Range("B2:C3").Merge();
|
||||
ws.Range("D2:E3").Merge();
|
||||
ws.Range("B6:C7").Merge(); // to be broken
|
||||
ws.Range("D6:E7").Merge(); // to be broken
|
||||
ws.Range("A8:B9").Merge();
|
||||
ws.Range("E8:F9").Merge();
|
||||
|
||||
ws.Range("C4:D5").InsertRowsBelow(2);
|
||||
|
||||
var mr = ws.MergedRanges.ToArray();
|
||||
Assert.AreEqual(4, mr.Length);
|
||||
Assert.AreEqual("B2:C3", mr[0].RangeAddress.ToString());
|
||||
Assert.AreEqual("D2:E3", mr[1].RangeAddress.ToString());
|
||||
Assert.AreEqual("A8:B9", mr[2].RangeAddress.ToString());
|
||||
Assert.AreEqual("E8:F9", mr[3].RangeAddress.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RangeShiftUpBreaksMerges()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.AddWorksheet("MRShift");
|
||||
ws.Range("B2:C3").Merge();
|
||||
ws.Range("D2:E3").Merge();
|
||||
ws.Range("B6:C7").Merge(); // to be broken
|
||||
ws.Range("D6:E7").Merge(); // to be broken
|
||||
ws.Range("A8:B9").Merge();
|
||||
ws.Range("E8:F9").Merge();
|
||||
|
||||
ws.Range("C4:D5").Delete(XLShiftDeletedCells.ShiftCellsUp);
|
||||
|
||||
var mr = ws.MergedRanges.ToArray();
|
||||
Assert.AreEqual(4, mr.Length);
|
||||
Assert.AreEqual("B2:C3", mr[0].RangeAddress.ToString());
|
||||
Assert.AreEqual("D2:E3", mr[1].RangeAddress.ToString());
|
||||
Assert.AreEqual("A8:B9", mr[2].RangeAddress.ToString());
|
||||
Assert.AreEqual("E8:F9", mr[3].RangeAddress.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MergedCellsAcquireFirstCellStyle()
|
||||
{
|
||||
using (XLWorkbook wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.AddWorksheet("Sheet1");
|
||||
ws.Cell("A1").Style.Fill.BackgroundColor = XLColor.Red;
|
||||
ws.Cell("A2").Style.Fill.BackgroundColor = XLColor.Yellow;
|
||||
ws.Cell("A3").Style.Fill.BackgroundColor = XLColor.Green;
|
||||
ws.Range("A1:A3").Merge();
|
||||
|
||||
Assert.AreEqual(XLColor.Red, ws.Cell("A1").Style.Fill.BackgroundColor);
|
||||
Assert.AreEqual(XLColor.Red, ws.Cell("A2").Style.Fill.BackgroundColor);
|
||||
Assert.AreEqual(XLColor.Red, ws.Cell("A3").Style.Fill.BackgroundColor);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MergedCellsLooseData()
|
||||
{
|
||||
using (XLWorkbook wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.AddWorksheet("Sheet1");
|
||||
ws.Range("A1:A3").SetValue(100);
|
||||
ws.Range("A1:A3").Merge();
|
||||
|
||||
Assert.AreEqual(100, ws.Cell("A1").Value);
|
||||
Assert.AreEqual("", ws.Cell("A2").Value);
|
||||
Assert.AreEqual("", ws.Cell("A3").Value);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MergedCellsLooseConditionalFormats()
|
||||
{
|
||||
using (XLWorkbook wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.AddWorksheet("Sheet1");
|
||||
ws.Cell("A1").AddConditionalFormat().WhenContains("1").Fill.BackgroundColor = XLColor.Red;
|
||||
ws.Cell("A2").AddConditionalFormat().WhenContains("2").Fill.BackgroundColor = XLColor.Yellow;
|
||||
|
||||
ws.Range("A1:A2").Merge();
|
||||
|
||||
Assert.AreEqual(1, ws.ConditionalFormats.Count());
|
||||
Assert.AreEqual("A1:A1", ws.ConditionalFormats.Single().Ranges.Single().RangeAddress.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MergedCellsLooseDataValidation()
|
||||
{
|
||||
using (XLWorkbook wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.AddWorksheet("Sheet1");
|
||||
ws.Cell("A1").NewDataValidation.WholeNumber.Between(1, 2);
|
||||
ws.Cell("A2").NewDataValidation.Date.GreaterThan(new System.DateTime(2018, 1, 1));
|
||||
|
||||
ws.Range("A1:A2").Merge();
|
||||
|
||||
Assert.IsTrue(ws.Cell("A1").HasDataValidation);
|
||||
Assert.AreEqual("1", ws.Cell("A1").DataValidation.MinValue);
|
||||
Assert.AreEqual("2", ws.Cell("A1").DataValidation.MaxValue);
|
||||
Assert.IsFalse(ws.Cell("A2").HasDataValidation);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void UnmergedCellsPreserveStyle()
|
||||
{
|
||||
using (XLWorkbook wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.AddWorksheet("Sheet1");
|
||||
var range = ws.Range("B2:D4");
|
||||
range.Style.Fill.SetBackgroundColor(XLColor.Yellow);
|
||||
range.Style.Border.SetOutsideBorder(XLBorderStyleValues.Thick)
|
||||
.Border.SetOutsideBorderColor(XLColor.DarkBlue)
|
||||
.Border.SetInsideBorder(XLBorderStyleValues.Thin)
|
||||
.Border.SetInsideBorderColor(XLColor.Pink);
|
||||
range.Cells().ForEach(c => c.Value = c.Address.ToString());
|
||||
|
||||
var firstCell = ws.Cell("B2");
|
||||
firstCell.Style.Fill.SetBackgroundColor(XLColor.Red)
|
||||
.Alignment.SetHorizontal(XLAlignmentHorizontalValues.Center)
|
||||
.Font.SetBold();
|
||||
|
||||
range.Merge();
|
||||
range.Unmerge();
|
||||
|
||||
Assert.IsTrue(range.Cells().All(c => c.Style.Fill.BackgroundColor == XLColor.Red));
|
||||
Assert.IsTrue(range.Cells().Where(c => c != firstCell).All(c => c.GetString().Length == 0));
|
||||
Assert.AreEqual("B2", firstCell.Value);
|
||||
|
||||
Assert.AreEqual(XLBorderStyleValues.Thick, ws.Cell("B2").Style.Border.TopBorder);
|
||||
Assert.AreEqual(XLBorderStyleValues.None, ws.Cell("B2").Style.Border.RightBorder);
|
||||
Assert.AreEqual(XLBorderStyleValues.None, ws.Cell("B2").Style.Border.BottomBorder);
|
||||
Assert.AreEqual(XLBorderStyleValues.Thick, ws.Cell("B2").Style.Border.LeftBorder);
|
||||
|
||||
Assert.AreEqual(XLBorderStyleValues.Thick, ws.Cell("C2").Style.Border.TopBorder);
|
||||
Assert.AreEqual(XLBorderStyleValues.None, ws.Cell("C2").Style.Border.RightBorder);
|
||||
Assert.AreEqual(XLBorderStyleValues.None, ws.Cell("C2").Style.Border.BottomBorder);
|
||||
Assert.AreEqual(XLBorderStyleValues.None, ws.Cell("C2").Style.Border.LeftBorder);
|
||||
|
||||
Assert.AreEqual(XLBorderStyleValues.Thick, ws.Cell("D2").Style.Border.TopBorder);
|
||||
Assert.AreEqual(XLBorderStyleValues.Thick, ws.Cell("D2").Style.Border.RightBorder);
|
||||
Assert.AreEqual(XLBorderStyleValues.None, ws.Cell("D2").Style.Border.BottomBorder);
|
||||
Assert.AreEqual(XLBorderStyleValues.None, ws.Cell("D2").Style.Border.LeftBorder);
|
||||
|
||||
Assert.AreEqual(XLBorderStyleValues.None, ws.Cell("B3").Style.Border.TopBorder);
|
||||
Assert.AreEqual(XLBorderStyleValues.None, ws.Cell("B3").Style.Border.RightBorder);
|
||||
Assert.AreEqual(XLBorderStyleValues.None, ws.Cell("B3").Style.Border.BottomBorder);
|
||||
Assert.AreEqual(XLBorderStyleValues.Thick, ws.Cell("B3").Style.Border.LeftBorder);
|
||||
|
||||
Assert.AreEqual(XLBorderStyleValues.None, ws.Cell("C3").Style.Border.TopBorder);
|
||||
Assert.AreEqual(XLBorderStyleValues.None, ws.Cell("C3").Style.Border.RightBorder);
|
||||
Assert.AreEqual(XLBorderStyleValues.None, ws.Cell("C3").Style.Border.BottomBorder);
|
||||
Assert.AreEqual(XLBorderStyleValues.None, ws.Cell("C3").Style.Border.LeftBorder);
|
||||
|
||||
Assert.AreEqual(XLBorderStyleValues.None, ws.Cell("D3").Style.Border.TopBorder);
|
||||
Assert.AreEqual(XLBorderStyleValues.Thick, ws.Cell("D3").Style.Border.RightBorder);
|
||||
Assert.AreEqual(XLBorderStyleValues.None, ws.Cell("D3").Style.Border.BottomBorder);
|
||||
Assert.AreEqual(XLBorderStyleValues.None, ws.Cell("D3").Style.Border.LeftBorder);
|
||||
|
||||
Assert.AreEqual(XLBorderStyleValues.None, ws.Cell("B4").Style.Border.TopBorder);
|
||||
Assert.AreEqual(XLBorderStyleValues.None, ws.Cell("B4").Style.Border.RightBorder);
|
||||
Assert.AreEqual(XLBorderStyleValues.Thick, ws.Cell("B4").Style.Border.BottomBorder);
|
||||
Assert.AreEqual(XLBorderStyleValues.Thick, ws.Cell("B4").Style.Border.LeftBorder);
|
||||
|
||||
Assert.AreEqual(XLBorderStyleValues.None, ws.Cell("C4").Style.Border.TopBorder);
|
||||
Assert.AreEqual(XLBorderStyleValues.None, ws.Cell("C4").Style.Border.RightBorder);
|
||||
Assert.AreEqual(XLBorderStyleValues.Thick, ws.Cell("C4").Style.Border.BottomBorder);
|
||||
Assert.AreEqual(XLBorderStyleValues.None, ws.Cell("C4").Style.Border.LeftBorder);
|
||||
|
||||
Assert.AreEqual(XLBorderStyleValues.None, ws.Cell("D4").Style.Border.TopBorder);
|
||||
Assert.AreEqual(XLBorderStyleValues.Thick, ws.Cell("D4").Style.Border.RightBorder);
|
||||
Assert.AreEqual(XLBorderStyleValues.Thick, ws.Cell("D4").Style.Border.BottomBorder);
|
||||
Assert.AreEqual(XLBorderStyleValues.None, ws.Cell("D4").Style.Border.LeftBorder);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MergedRangesCellValuesShouldNotBeSet()
|
||||
{
|
||||
using (var workbook = new XLWorkbook())
|
||||
{
|
||||
var ws = workbook.AddWorksheet();
|
||||
ws.Range("A2:A4").Merge();
|
||||
ws.Cell("A2").Value = "1";
|
||||
ws.Cell("A3").Value = "1";
|
||||
ws.Cell("A4").Value = "1";
|
||||
ws.Cell("B1").FormulaA1 = "SUM(A:A)";
|
||||
Assert.AreEqual(1, ws.Cell("B1").Value);
|
||||
}
|
||||
|
||||
using (var workbook = new XLWorkbook())
|
||||
{
|
||||
var ws = workbook.AddWorksheet();
|
||||
ws.Range("A2:A4").Merge().SetValue(1);
|
||||
ws.Cell("B1").FormulaA1 = "SUM(A:A)";
|
||||
Assert.AreEqual(1, ws.Cell("B1").Value);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MergedRangesCellFormulasShouldNotBeSet()
|
||||
{
|
||||
using (var workbook = new XLWorkbook())
|
||||
{
|
||||
var ws = workbook.AddWorksheet();
|
||||
ws.Range("A2:A4").Merge();
|
||||
ws.Cell("A2").FormulaA1 = "=1";
|
||||
ws.Cell("A3").FormulaA1 = "=1";
|
||||
ws.Cell("A4").FormulaA1 = "=1";
|
||||
ws.Cell("B1").FormulaA1 = "SUM(A:A)";
|
||||
Assert.AreEqual(1, ws.Cell("B1").Value);
|
||||
}
|
||||
|
||||
using (var workbook = new XLWorkbook())
|
||||
{
|
||||
var ws = workbook.AddWorksheet();
|
||||
ws.Range("A2:A4").Merge();
|
||||
ws.Cell("A2").SetFormulaA1("=1");
|
||||
ws.Cell("A3").SetFormulaA1("=1");
|
||||
ws.Cell("A4").SetFormulaA1("=1");
|
||||
ws.Cell("B1").SetFormulaA1("SUM(A:A)");
|
||||
Assert.AreEqual(1, ws.Cell("B1").Value);
|
||||
}
|
||||
|
||||
using (var workbook = new XLWorkbook())
|
||||
{
|
||||
var ws = workbook.AddWorksheet();
|
||||
ws.Range("A2:A4").Merge();
|
||||
ws.Cell("A2").FormulaR1C1 = "=1";
|
||||
ws.Cell("A3").FormulaR1C1 = "=1";
|
||||
ws.Cell("A4").FormulaR1C1 = "=1";
|
||||
ws.Cell("B1").FormulaR1C1 = "SUM(A:A)";
|
||||
Assert.AreEqual(1, ws.Cell("B1").Value);
|
||||
}
|
||||
|
||||
using (var workbook = new XLWorkbook())
|
||||
{
|
||||
var ws = workbook.AddWorksheet();
|
||||
ws.Range("A2:A4").Merge();
|
||||
ws.Cell("A2").SetFormulaR1C1("=1");
|
||||
ws.Cell("A3").SetFormulaR1C1("=1");
|
||||
ws.Cell("A4").SetFormulaR1C1("=1");
|
||||
ws.Cell("B1").SetFormulaR1C1("SUM(A:A)");
|
||||
Assert.AreEqual(1, ws.Cell("B1").Value);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MergeSingleCellRangeDoesNothing()
|
||||
{
|
||||
using var wb = new XLWorkbook();
|
||||
var ws = wb.AddWorksheet();
|
||||
var range = ws.Range(1, 1, 1, 1);
|
||||
|
||||
range.Merge();
|
||||
|
||||
Assert.IsFalse(range.IsMerged());
|
||||
Assert.AreEqual(0, ws.MergedRanges.Count);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,285 @@
|
||||
using ClosedXML.Excel;
|
||||
using ClosedXML.Excel.Patterns;
|
||||
using ClosedXML.Excel.Ranges.Index;
|
||||
using NUnit.Framework;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace ClosedXML_Tests.Excel.Ranges
|
||||
{
|
||||
[TestFixture]
|
||||
public class RangeIndexTest
|
||||
{
|
||||
private const int TEST_COUNT = 10000;
|
||||
|
||||
[Test]
|
||||
public void FindExistingMatches()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.Worksheets.Add("Sheet1") as XLWorksheet;
|
||||
var index = FillIndexWithTestData(ws);
|
||||
|
||||
for (int i = 1; i <= TEST_COUNT; i++)
|
||||
{
|
||||
for (int j = 2; j <= 4; j++)
|
||||
{
|
||||
var address = new XLAddress(ws, i * 2, j, false, false);
|
||||
Assert.True(index.Contains(in address));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FindNonExistingMatches()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.Worksheets.Add("Sheet1") as XLWorksheet;
|
||||
var index = FillIndexWithTestData(ws);
|
||||
|
||||
for (int i = 1; i <= TEST_COUNT; i++)
|
||||
{
|
||||
var address = new XLAddress(ws, i * 2 + 1, 3, false, false);
|
||||
Assert.False(index.Contains(in address));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FindExistingIntersections()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.Worksheets.Add("Sheet1") as XLWorksheet;
|
||||
var index = FillIndexWithTestData(ws);
|
||||
|
||||
for (int i = 1; i <= TEST_COUNT; i++)
|
||||
{
|
||||
var rangeAddress = new XLRangeAddress(
|
||||
new XLAddress(ws, i * 2, 1 + i % 4, false, false),
|
||||
new XLAddress(ws, i * 2 + 1, 8 - i % 3, false, false));
|
||||
|
||||
Assert.True(index.Intersects(in rangeAddress));
|
||||
}
|
||||
|
||||
for (int i = 2; i < 4; i++)
|
||||
{
|
||||
var columnAddress = XLRangeAddress.EntireColumn(ws, i);
|
||||
Assert.True(index.Intersects(in columnAddress));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FindNonExistingIntersections()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.Worksheets.Add("Sheet1") as XLWorksheet;
|
||||
var index = FillIndexWithTestData(ws);
|
||||
|
||||
for (int i = 1; i <= TEST_COUNT; i++)
|
||||
{
|
||||
var rangeAddress = new XLRangeAddress(
|
||||
new XLAddress(ws, i * 2 + 1, 1 + i % 4, false, false),
|
||||
new XLAddress(ws, i * 2 + 1, 8 - i % 3, false, false));
|
||||
|
||||
Assert.False(index.Intersects(in rangeAddress));
|
||||
}
|
||||
|
||||
var columnAddress = XLRangeAddress.EntireColumn(ws, 1);
|
||||
Assert.False(index.Intersects(in columnAddress));
|
||||
columnAddress = XLRangeAddress.EntireColumn(ws, 5);
|
||||
Assert.False(index.Intersects(in columnAddress));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FindMatchAfterColumnShifting()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.Worksheets.Add("Sheet1") as XLWorksheet;
|
||||
var index = FillIndexWithTestData(ws);
|
||||
|
||||
ws.Column(1).InsertColumnsBefore(1000);
|
||||
|
||||
var address = new XLAddress(ws, 102, 1004, false, false);
|
||||
|
||||
Assert.True(index.Contains(in address));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FindIntersectionsAfterColumnShifting()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.Worksheets.Add("Sheet1") as XLWorksheet;
|
||||
var index = FillIndexWithTestData(ws);
|
||||
|
||||
ws.Column(3).InsertColumnsBefore(2);
|
||||
|
||||
var rangeAddress = new XLRangeAddress(ws, "F102:E103");
|
||||
|
||||
Assert.True(index.Intersects(in rangeAddress));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FindMatchAfterRowShifting()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.Worksheets.Add("Sheet1") as XLWorksheet;
|
||||
var index = FillIndexWithTestData(ws);
|
||||
|
||||
ws.Row(10).InsertRowsBelow(3);
|
||||
|
||||
var address = new XLAddress(ws, 103, 4, false, false);
|
||||
|
||||
Assert.True(index.Contains(in address));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FindIntersectionsAfterRowShifting()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.Worksheets.Add("Sheet1") as XLWorksheet;
|
||||
var index = FillIndexWithTestData(ws);
|
||||
|
||||
ws.Row(10).InsertRowsBelow(3);
|
||||
|
||||
var rangeAddress = new XLRangeAddress(ws, "C103:E103");
|
||||
|
||||
Assert.True(index.Intersects(in rangeAddress));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CreateQuadTree()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.Worksheets.Add("Sheet1") as XLWorksheet;
|
||||
var quadTree = new Quadrant();
|
||||
var range = ws.Range("BT76:CA87");
|
||||
|
||||
quadTree.Add(range);
|
||||
|
||||
var level0 = quadTree;
|
||||
Assert.AreEqual(1, level0.MinimumColumn);
|
||||
Assert.AreEqual(XLHelper.MaxColumnNumber, level0.MaximumColumn);
|
||||
Assert.AreEqual(1, level0.MinimumRow);
|
||||
Assert.AreEqual(XLHelper.MaxRowNumber, level0.MaximumRow);
|
||||
Assert.IsNull(level0.Ranges);
|
||||
Assert.AreEqual(128, level0.Children.Count());
|
||||
Assert.True(level0.Children.All(child => child.Level == 1));
|
||||
Assert.AreEqual(64, level0.Children.Count(child =>
|
||||
child.MinimumColumn == 1 &&
|
||||
child.MaximumColumn == 8192 &&
|
||||
child.X == 0));
|
||||
Assert.AreEqual(64, level0.Children.Count(child =>
|
||||
child.MinimumColumn == 8193 &&
|
||||
child.MaximumColumn == 16384 &&
|
||||
child.X == 1));
|
||||
Assert.AreEqual(2, level0.Children.Count(child =>
|
||||
child.MinimumRow == 1 &&
|
||||
child.MaximumRow == 8192 &&
|
||||
child.Y == 0));
|
||||
Assert.AreEqual(2, level0.Children.Count(child =>
|
||||
child.MinimumRow == 16385 &&
|
||||
child.MaximumRow == 24576 &&
|
||||
child.Y == 2));
|
||||
|
||||
Assert.True(level0.Children.ElementAt(0).Children.Any());
|
||||
Assert.True(level0.Children.Skip(1).All(child => child.Children == null));
|
||||
|
||||
var level8 = level0
|
||||
.Children.First() // 1
|
||||
.Children.First() // 2
|
||||
.Children.First() // 3
|
||||
.Children.First() // 4
|
||||
.Children.First() // 5
|
||||
.Children.First() // 6
|
||||
.Children.First() // 7
|
||||
.Children.Last(); // 8
|
||||
|
||||
Assert.AreEqual(65, level8.MinimumColumn);
|
||||
Assert.AreEqual(65, level8.MinimumRow);
|
||||
Assert.AreEqual(128, level8.MaximumColumn);
|
||||
Assert.AreEqual(128, level8.MaximumRow);
|
||||
|
||||
var level9 = level8.Children.First();
|
||||
Assert.NotNull(level9.Ranges);
|
||||
Assert.AreEqual(range, level9.Ranges.Single());
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void XLRangesCountChangesCorrectly()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.Worksheets.Add("Sheet1") as XLWorksheet;
|
||||
var range1 = ws.Range("A1:B2");
|
||||
var range2 = ws.Range("A2:B3");
|
||||
var range3 = ws.Range("A1:B2"); // same as range1
|
||||
|
||||
var ranges = new XLRanges();
|
||||
ranges.Add(range1);
|
||||
Assert.AreEqual(1, ranges.Count);
|
||||
ranges.Add(range2);
|
||||
Assert.AreEqual(2, ranges.Count);
|
||||
ranges.Add(range3);
|
||||
Assert.AreEqual(2, ranges.Count);
|
||||
|
||||
Assert.AreEqual(ranges.Count, ranges.Count());
|
||||
|
||||
// Add many entries to activate QuadTree
|
||||
for (int i = 1; i <= TEST_COUNT; i++)
|
||||
{
|
||||
ranges.Add(ws.Range(i * 2, 2, i * 2, 4));
|
||||
}
|
||||
|
||||
Assert.AreEqual(2 + TEST_COUNT, ranges.Count);
|
||||
|
||||
for (int i = 1; i <= TEST_COUNT; i++)
|
||||
{
|
||||
ranges.Remove(ws.Range(i * 2, 2, i * 2, 4));
|
||||
}
|
||||
|
||||
Assert.AreEqual(2, ranges.Count);
|
||||
|
||||
ranges.Remove(range3);
|
||||
Assert.AreEqual(1, ranges.Count);
|
||||
ranges.Remove(range2);
|
||||
Assert.AreEqual(0, ranges.Count);
|
||||
ranges.Remove(range1);
|
||||
Assert.AreEqual(0, ranges.Count);
|
||||
}
|
||||
}
|
||||
|
||||
private IXLRangeIndex CreateRangeIndex(IXLWorksheet worksheet)
|
||||
{
|
||||
return new XLRangeIndex<IXLRangeBase>((XLWorksheet)worksheet);
|
||||
}
|
||||
|
||||
private IXLRangeIndex FillIndexWithTestData(IXLWorksheet worksheet)
|
||||
{
|
||||
var ranges = new List<IXLRange>();
|
||||
for (int i = 1; i <= TEST_COUNT; i++)
|
||||
{
|
||||
ranges.Add(worksheet.Range(i * 2, 2, i * 2, 4));
|
||||
}
|
||||
|
||||
var index = CreateRangeIndex(worksheet);
|
||||
ranges.ForEach(r => index.Add(r));
|
||||
return index;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
using ClosedXML.Excel;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace ClosedXML_Tests.Excel.Ranges
|
||||
{
|
||||
public class RangeShiftingTests
|
||||
{
|
||||
[Test]
|
||||
public void CellReferenceRemainAfterColumnDeleted()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.AddWorksheet();
|
||||
var d4 = ws.Cell("D4");
|
||||
|
||||
ws.Column("C").Delete();
|
||||
|
||||
Assert.AreSame(d4, ws.Cell("C4"));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CellReferenceRemainAfterRowDeleted()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.AddWorksheet();
|
||||
var d4 = ws.Cell("D4");
|
||||
|
||||
ws.Row(3).Delete();
|
||||
|
||||
Assert.AreSame(d4, ws.Cell("D3"));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CellReferenceRemainAfterColumnInserted()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.AddWorksheet();
|
||||
var d4 = ws.Cell("D4");
|
||||
|
||||
ws.Column("C").InsertColumnsBefore(1);
|
||||
|
||||
Assert.AreSame(d4, ws.Cell("E4"));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CellReferenceRemainAfterRowInserted()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.AddWorksheet();
|
||||
var d4 = ws.Cell("D4");
|
||||
|
||||
ws.Row(3).InsertRowsAbove(1);
|
||||
|
||||
Assert.AreSame(d4, ws.Cell("D5"));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CellReferenceRemainAfterRangeDeleted()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.AddWorksheet();
|
||||
var d4 = ws.Cell("D4");
|
||||
var f8 = ws.Cell("F8");
|
||||
|
||||
ws.Range("B2:C5").Delete(XLShiftDeletedCells.ShiftCellsLeft);
|
||||
ws.Range("E5:F7").Delete(XLShiftDeletedCells.ShiftCellsUp);
|
||||
|
||||
Assert.AreSame(d4, ws.Cell("B4"));
|
||||
Assert.AreSame(f8, ws.Cell("F5"));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
using ClosedXML.Excel;
|
||||
using NUnit.Framework;
|
||||
using System.Linq;
|
||||
|
||||
namespace ClosedXML_Tests.Excel.Ranges
|
||||
{
|
||||
[TestFixture]
|
||||
public class RangesConsolidationTests
|
||||
{
|
||||
[Test]
|
||||
public void ConsolidateRangesSameWorksheet()
|
||||
{
|
||||
var wb = new XLWorkbook();
|
||||
var ws = wb.Worksheets.Add("Sheet1");
|
||||
var ranges = new XLRanges();
|
||||
ranges.Add(ws.Range("A1:E3"));
|
||||
ranges.Add(ws.Range("A4:B10"));
|
||||
ranges.Add(ws.Range("E2:F12"));
|
||||
ranges.Add(ws.Range("C6:I8"));
|
||||
ranges.Add(ws.Range("G9:G9"));
|
||||
ranges.Add(ws.Range("C9:D9"));
|
||||
ranges.Add(ws.Range("H9:H9"));
|
||||
ranges.Add(ws.Range("I9:I13"));
|
||||
ranges.Add(ws.Range("C4:D5"));
|
||||
|
||||
var consRanges = ranges.Consolidate().ToList();
|
||||
|
||||
Assert.AreEqual(6, consRanges.Count);
|
||||
Assert.AreEqual("A1:E9", consRanges[0].RangeAddress.ToString());
|
||||
Assert.AreEqual("F2:F12", consRanges[1].RangeAddress.ToString());
|
||||
Assert.AreEqual("G6:I9", consRanges[2].RangeAddress.ToString());
|
||||
Assert.AreEqual("A10:B10", consRanges[3].RangeAddress.ToString());
|
||||
Assert.AreEqual("E10:E12", consRanges[4].RangeAddress.ToString());
|
||||
Assert.AreEqual("I10:I13", consRanges[5].RangeAddress.ToString());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ConsolidateWideRangesSameWorksheet()
|
||||
{
|
||||
var wb = new XLWorkbook();
|
||||
var ws = wb.Worksheets.Add("Sheet1");
|
||||
var ranges = new XLRanges();
|
||||
ranges.Add(ws.Row(5));
|
||||
ranges.Add(ws.Row(7));
|
||||
ranges.Add(ws.Row(6));
|
||||
ranges.Add(ws.Column("D"));
|
||||
ranges.Add(ws.Column("F"));
|
||||
ranges.Add(ws.Column("E"));
|
||||
|
||||
var consRanges = ranges.Consolidate()
|
||||
.OrderBy(r => r.Worksheet.Name)
|
||||
.ThenBy(r => r.RangeAddress.FirstAddress.RowNumber)
|
||||
.ThenBy(r => r.RangeAddress.FirstAddress.ColumnNumber)
|
||||
.ToList();
|
||||
|
||||
Assert.AreEqual(3, consRanges.Count);
|
||||
Assert.AreEqual("D:F", consRanges[0].RangeAddress.ToString());
|
||||
Assert.AreEqual("A5:C7", consRanges[1].RangeAddress.ToString());
|
||||
Assert.AreEqual("G5:XFD7", consRanges[2].RangeAddress.ToString());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ConsolidateRangesDifferentWorksheets()
|
||||
{
|
||||
var wb = new XLWorkbook();
|
||||
var ws1 = wb.Worksheets.Add("Sheet1");
|
||||
var ws2 = wb.Worksheets.Add("Sheet2");
|
||||
var ranges = new XLRanges();
|
||||
ranges.Add(ws1.Range("A1:E3"));
|
||||
ranges.Add(ws1.Range("A4:B10"));
|
||||
ranges.Add(ws1.Range("E2:F12"));
|
||||
ranges.Add(ws1.Range("C6:I8"));
|
||||
ranges.Add(ws1.Range("G9:G9"));
|
||||
|
||||
ranges.Add(ws2.Row(5));
|
||||
ranges.Add(ws2.Row(7));
|
||||
ranges.Add(ws2.Row(6));
|
||||
ranges.Add(ws2.Column("D"));
|
||||
ranges.Add(ws2.Column("F"));
|
||||
ranges.Add(ws2.Column("E"));
|
||||
|
||||
ranges.Add(ws1.Range("C9:D9"));
|
||||
ranges.Add(ws1.Range("H9:H9"));
|
||||
ranges.Add(ws1.Range("I9:I13"));
|
||||
ranges.Add(ws1.Range("C4:D5"));
|
||||
|
||||
var consRanges = ranges.Consolidate()
|
||||
.OrderBy(r => r.Worksheet.Name)
|
||||
.ThenBy(r => r.RangeAddress.FirstAddress.RowNumber)
|
||||
.ThenBy(r => r.RangeAddress.FirstAddress.ColumnNumber)
|
||||
.ToList();
|
||||
|
||||
Assert.AreEqual(9, consRanges.Count);
|
||||
Assert.AreEqual("Sheet1!$A$1:$E$9", consRanges[0].RangeAddress.ToStringFixed(XLReferenceStyle.Default, true));
|
||||
Assert.AreEqual("Sheet1!$F$2:$F$12", consRanges[1].RangeAddress.ToStringFixed(XLReferenceStyle.Default, true));
|
||||
Assert.AreEqual("Sheet1!$G$6:$I$9", consRanges[2].RangeAddress.ToStringFixed(XLReferenceStyle.Default, true));
|
||||
Assert.AreEqual("Sheet1!$A$10:$B$10", consRanges[3].RangeAddress.ToStringFixed(XLReferenceStyle.Default, true));
|
||||
Assert.AreEqual("Sheet1!$E$10:$E$12", consRanges[4].RangeAddress.ToStringFixed(XLReferenceStyle.Default, true));
|
||||
Assert.AreEqual("Sheet1!$I$10:$I$13", consRanges[5].RangeAddress.ToStringFixed(XLReferenceStyle.Default, true));
|
||||
|
||||
Assert.AreEqual("Sheet2!$D:$F", consRanges[6].RangeAddress.ToStringFixed(XLReferenceStyle.Default, true));
|
||||
Assert.AreEqual("Sheet2!$A$5:$C$7", consRanges[7].RangeAddress.ToStringFixed(XLReferenceStyle.Default, true));
|
||||
Assert.AreEqual("Sheet2!$G$5:$XFD$7", consRanges[8].RangeAddress.ToStringFixed(XLReferenceStyle.Default, true));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ConsolidateSparsedRanges()
|
||||
{
|
||||
var wb = new XLWorkbook();
|
||||
var ws = wb.Worksheets.Add("Sheet1");
|
||||
var ranges = new XLRanges();
|
||||
ranges.Add(ws.Range("A1:C1"));
|
||||
ranges.Add(ws.Range("E1:G1"));
|
||||
ranges.Add(ws.Range("A3:C3"));
|
||||
ranges.Add(ws.Range("E3:G3"));
|
||||
|
||||
var consRanges = ranges.Consolidate().ToList();
|
||||
|
||||
Assert.AreEqual(4, consRanges.Count);
|
||||
Assert.AreEqual("A1:C1", consRanges[0].RangeAddress.ToString());
|
||||
Assert.AreEqual("E1:G1", consRanges[1].RangeAddress.ToString());
|
||||
Assert.AreEqual("A3:C3", consRanges[2].RangeAddress.ToString());
|
||||
Assert.AreEqual("E3:G3", consRanges[3].RangeAddress.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,401 @@
|
||||
using ClosedXML.Excel;
|
||||
using NUnit.Framework;
|
||||
using System.Linq;
|
||||
|
||||
namespace ClosedXML_Tests.Excel.Ranges
|
||||
{
|
||||
[TestFixture]
|
||||
public class UsedAndUnusedCellsTests
|
||||
{
|
||||
private XLWorkbook workbook;
|
||||
|
||||
[SetUp]
|
||||
public void SetupWorkbook()
|
||||
{
|
||||
workbook = new XLWorkbook();
|
||||
var ws = workbook.AddWorksheet("Sheet1");
|
||||
ws.Cell(1, 1).Value = "A1";
|
||||
ws.Cell(1, 3).Value = "C1";
|
||||
ws.Cell(2, 2).Value = "B2";
|
||||
ws.Cell(4, 1).Value = "A4";
|
||||
ws.Cell(5, 2).Value = "B5";
|
||||
ws.Cell(6, 2).Style.Fill.BackgroundColor = XLColor.Red;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CountUsedCellsInRow()
|
||||
{
|
||||
int i = 0;
|
||||
var row = workbook.Worksheets.First().FirstRow();
|
||||
foreach (var cell in row.Cells()) // Cells() returns UnUsed cells by default
|
||||
{
|
||||
i++;
|
||||
}
|
||||
Assert.AreEqual(2, i);
|
||||
|
||||
i = 0;
|
||||
row = workbook.Worksheets.First().FirstRow().RowBelow();
|
||||
foreach (var cell in row.Cells())
|
||||
{
|
||||
i++;
|
||||
}
|
||||
Assert.AreEqual(1, i);
|
||||
|
||||
i = 0;
|
||||
row = workbook.Worksheets.First().LastRowUsed(XLCellsUsedOptions.All);
|
||||
Assert.AreEqual(6, row.RowNumber());
|
||||
foreach (var cell in row.Cells())
|
||||
{
|
||||
i++;
|
||||
}
|
||||
Assert.AreEqual(1, i);
|
||||
|
||||
i = 0;
|
||||
row = workbook.Worksheets.First().LastRowUsed(XLCellsUsedOptions.All);
|
||||
Assert.AreEqual(6, row.RowNumber());
|
||||
foreach (var cell in row.CellsUsed())
|
||||
{
|
||||
i++;
|
||||
}
|
||||
Assert.AreEqual(0, i);
|
||||
}
|
||||
|
||||
[Test(Description = "See 1443")]
|
||||
public void FirstRowUsedRegression()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.AddWorksheet();
|
||||
|
||||
ws.Range("B3:F6").SetValue(100);
|
||||
|
||||
Assert.AreEqual(3, ws.FirstRowUsed(XLCellsUsedOptions.AllContents).RowNumber());
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CountAllCellsInRow()
|
||||
{
|
||||
int i = 0;
|
||||
var row = workbook.Worksheets.First().FirstRow();
|
||||
foreach (var cell in row.Cells(false)) // All cells in range between first and last cells used
|
||||
{
|
||||
i++;
|
||||
}
|
||||
Assert.AreEqual(3, i);
|
||||
|
||||
i = 0;
|
||||
row = workbook.Worksheets.First().FirstRow().RowBelow(); //This row has no empty cells BETWEEN used cells
|
||||
foreach (var cell in row.Cells(false))
|
||||
{
|
||||
i++;
|
||||
}
|
||||
Assert.AreEqual(1, i);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CountUsedCellsInColumn()
|
||||
{
|
||||
int i = 0;
|
||||
var column = workbook.Worksheets.First().FirstColumn();
|
||||
foreach (var cell in column.Cells()) // Cells() returns UnUsed cells by default
|
||||
{
|
||||
i++;
|
||||
}
|
||||
Assert.AreEqual(2, i);
|
||||
|
||||
i = 0;
|
||||
column = workbook.Worksheets.First().FirstColumn().ColumnRight().ColumnRight();
|
||||
foreach (var cell in column.Cells())
|
||||
{
|
||||
i++;
|
||||
}
|
||||
Assert.AreEqual(1, i);
|
||||
|
||||
i = 0;
|
||||
column = workbook.Worksheets.First().Column(2);
|
||||
foreach (var cell in column.Cells())
|
||||
{
|
||||
i++;
|
||||
}
|
||||
Assert.AreEqual(3, i);
|
||||
|
||||
i = 0;
|
||||
column = workbook.Worksheets.First().Column(2);
|
||||
foreach (var cell in column.CellsUsed())
|
||||
{
|
||||
i++;
|
||||
}
|
||||
Assert.AreEqual(2, i);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CountAllCellsInColumn()
|
||||
{
|
||||
int i = 0;
|
||||
var column = workbook.Worksheets.First().FirstColumn();
|
||||
foreach (var cell in column.Cells(false)) // All cells in range between first and last cells used
|
||||
{
|
||||
i++;
|
||||
}
|
||||
Assert.AreEqual(4, i);
|
||||
|
||||
i = 0;
|
||||
column = workbook.Worksheets.First().FirstColumn().ColumnRight().ColumnRight(); //This column has no empty cells BETWEEN used cells
|
||||
foreach (var cell in column.Cells(false))
|
||||
{
|
||||
i++;
|
||||
}
|
||||
Assert.AreEqual(1, i);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CountCellsInWorksheet()
|
||||
{
|
||||
var ws = workbook.Worksheets.First();
|
||||
int i = 0;
|
||||
|
||||
foreach (var cell in ws.Cells()) // All cells with content or formats
|
||||
{
|
||||
i++;
|
||||
}
|
||||
Assert.AreEqual(6, i);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CountUsedCellsInWorksheet()
|
||||
{
|
||||
var ws = workbook.Worksheets.First();
|
||||
int i = 0;
|
||||
|
||||
foreach (var cell in ws.CellsUsed()) // Only used cells in worksheet
|
||||
{
|
||||
i++;
|
||||
}
|
||||
Assert.AreEqual(5, i);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CountAllCellsInWorksheet()
|
||||
{
|
||||
var ws = workbook.Worksheets.First();
|
||||
int i = 0;
|
||||
|
||||
foreach (var cell in ws.Cells(false)) // All cells in range between first and last cells used (cartesian product of range)
|
||||
{
|
||||
i++;
|
||||
}
|
||||
Assert.AreEqual(18, i);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetCellsUsedNonRectangular()
|
||||
{
|
||||
using (XLWorkbook wb = new XLWorkbook())
|
||||
{
|
||||
var sheet = wb.AddWorksheet("page1");
|
||||
|
||||
sheet.Range("C1:E1").Value = "row1";
|
||||
sheet.Range("A2:E2").Value = "row2";
|
||||
|
||||
var used = sheet.RangeUsed().RangeAddress.ToString(XLReferenceStyle.A1);
|
||||
|
||||
Assert.AreEqual("A1:E2", used);
|
||||
}
|
||||
}
|
||||
|
||||
[TestCase(true, "A1:D2", "A1")]
|
||||
[TestCase(true, "A2:D2", "A2")]
|
||||
[TestCase(true, "A1:D2", "A1", "B2")]
|
||||
[TestCase(true, "B2:D3", "C3")]
|
||||
[TestCase(true, "B2:F4", "F4")]
|
||||
[TestCase(false, "A1:D2", "A1")]
|
||||
[TestCase(false, "A2:D2", "A2")]
|
||||
[TestCase(false, "A1:D2", "A1", "B2")]
|
||||
[TestCase(false, "B2:D3", "C3")]
|
||||
[TestCase(false, "B2:F4", "F4")]
|
||||
public void RangeUsedIncludesMergedCells(bool includeFormatting, string expectedRange,
|
||||
params string[] cellsWithValues)
|
||||
{
|
||||
using (XLWorkbook wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.AddWorksheet("Sheet1");
|
||||
foreach (var cellAddress in cellsWithValues)
|
||||
{
|
||||
ws.Cell(cellAddress).Value = "Not empty";
|
||||
}
|
||||
ws.Range("B2:D2").Merge();
|
||||
|
||||
var options = includeFormatting
|
||||
? XLCellsUsedOptions.All
|
||||
: XLCellsUsedOptions.AllContents | XLCellsUsedOptions.MergedRanges;
|
||||
var actual = ws.RangeUsed(options).RangeAddress;
|
||||
|
||||
Assert.AreEqual(expectedRange, actual.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void LastCellUsedPredicateConsidersMergedRanges()
|
||||
{
|
||||
using (XLWorkbook wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.AddWorksheet("Sheet1");
|
||||
ws.Cell("A1").Style.Fill.BackgroundColor = XLColor.Red;
|
||||
ws.Cell("A2").Style.Fill.BackgroundColor = XLColor.Yellow;
|
||||
ws.Cell("A3").Style.Fill.BackgroundColor = XLColor.Green;
|
||||
ws.Range("A1:C1").Merge();
|
||||
ws.Range("A2:C2").Merge();
|
||||
ws.Range("A3:C3").Merge();
|
||||
|
||||
var actual = ws.LastCellUsed(XLCellsUsedOptions.All,
|
||||
c => c.Style.Fill.BackgroundColor == XLColor.Yellow);
|
||||
|
||||
Assert.AreEqual("C2", actual.Address.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FirstCellUsedPredicateConsidersMergedRanges()
|
||||
{
|
||||
using (XLWorkbook wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.AddWorksheet("Sheet1");
|
||||
ws.Cell("A1").Style.Fill.BackgroundColor = XLColor.Red;
|
||||
ws.Cell("A2").Style.Fill.BackgroundColor = XLColor.Yellow;
|
||||
ws.Cell("A3").Style.Fill.BackgroundColor = XLColor.Green;
|
||||
ws.Range("A1:C1").Merge();
|
||||
ws.Range("A2:C2").Merge();
|
||||
ws.Range("A3:C3").Merge();
|
||||
|
||||
var actual = ws.FirstCellUsed(XLCellsUsedOptions.All,
|
||||
c => c.Style.Fill.BackgroundColor == XLColor.Yellow);
|
||||
|
||||
Assert.AreEqual("A2", actual.Address.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ApplyingDataValidationMakesCellNotEmpty()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.Worksheets.Add("Sheet1");
|
||||
ws.Range("B2:B12").SetDataValidation()
|
||||
.Decimal.EqualOrGreaterThan(0);
|
||||
|
||||
var usedCells = ws.CellsUsed(XLCellsUsedOptions.All).ToList();
|
||||
|
||||
Assert.AreEqual(11, usedCells.Count);
|
||||
Assert.AreEqual("B2", usedCells.First().Address.ToString());
|
||||
Assert.AreEqual("B12", usedCells.Last().Address.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MergeMakesCellNotEmpty()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.Worksheets.Add("Sheet1");
|
||||
ws.Range("B2:B12").Merge();
|
||||
|
||||
var usedCells = ws.CellsUsed(XLCellsUsedOptions.All).ToList();
|
||||
|
||||
Assert.AreEqual(11, usedCells.Count);
|
||||
Assert.AreEqual("B2", usedCells.First().Address.ToString());
|
||||
Assert.AreEqual("B12", usedCells.Last().Address.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FirstCellUsedNotHangingOnLargeCFRules()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.Worksheets.Add("Sheet1");
|
||||
ws.AddConditionalFormat().WhenIsBlank().Fill.SetBackgroundColor(XLColor.Gold);
|
||||
|
||||
var firstCell = ws.FirstCellUsed(XLCellsUsedOptions.All);
|
||||
|
||||
Assert.AreEqual(1, (ws as XLWorksheet).Internals.CellsCollection.Count);
|
||||
Assert.AreEqual("A1", firstCell.Address.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void LastCellUsedNotHangingOnLargeCFRules()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.Worksheets.Add("Sheet1");
|
||||
ws.AddConditionalFormat().WhenIsBlank().Fill.SetBackgroundColor(XLColor.Gold);
|
||||
|
||||
var lastCell = ws.LastCellUsed(XLCellsUsedOptions.All);
|
||||
|
||||
Assert.AreEqual(1, (ws as XLWorksheet).Internals.CellsCollection.Count);
|
||||
Assert.AreEqual(XLHelper.LastCell, lastCell.Address.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FirstCellUsedNotHangingOnLargeDVRules()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.Worksheets.Add("Sheet1");
|
||||
ws.SetDataValidation().WholeNumber.GreaterThan(0);
|
||||
|
||||
var firstCell = ws.FirstCellUsed(XLCellsUsedOptions.All);
|
||||
|
||||
Assert.AreEqual(1, (ws as XLWorksheet).Internals.CellsCollection.Count);
|
||||
Assert.AreEqual("A1", firstCell.Address.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void LastCellUsedNotHangingOnLargeDVRules()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.Worksheets.Add("Sheet1");
|
||||
ws.SetDataValidation().WholeNumber.GreaterThan(0);
|
||||
|
||||
var lastCell = ws.LastCellUsed(XLCellsUsedOptions.All);
|
||||
|
||||
Assert.AreEqual(1, (ws as XLWorksheet).Internals.CellsCollection.Count);
|
||||
Assert.AreEqual(XLHelper.LastCell, lastCell.Address.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FirstCellUsedNotHangingOnLargeMergedRanges()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.Worksheets.Add("Sheet1");
|
||||
ws.Merge();
|
||||
|
||||
var firstCell = ws.FirstCellUsed(XLCellsUsedOptions.All);
|
||||
|
||||
Assert.AreEqual(1, (ws as XLWorksheet).Internals.CellsCollection.Count);
|
||||
Assert.AreEqual("A1", firstCell.Address.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void LastCellUsedNotHangingOnLargeMergedRanges()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.Worksheets.Add("Sheet1");
|
||||
ws.Merge();
|
||||
|
||||
var lastCell = ws.LastCellUsed(XLCellsUsedOptions.All);
|
||||
|
||||
Assert.AreEqual(2, (ws as XLWorksheet).Internals.CellsCollection.Count);
|
||||
Assert.AreEqual(XLHelper.LastCell, lastCell.Address.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,349 @@
|
||||
using ClosedXML.Excel;
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
|
||||
namespace ClosedXML_Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class XLRangeAddressTests
|
||||
{
|
||||
[Test]
|
||||
public void ToStringTest()
|
||||
{
|
||||
IXLWorksheet ws = new XLWorkbook().Worksheets.Add("Sheet1");
|
||||
IXLRangeAddress address = ws.Cell(1, 1).AsRange().RangeAddress;
|
||||
|
||||
Assert.AreEqual("A1:A1", address.ToString());
|
||||
Assert.AreEqual("Sheet1!R1C1:R1C1", address.ToString(XLReferenceStyle.R1C1, true));
|
||||
|
||||
Assert.AreEqual("A1:A1", address.ToStringRelative());
|
||||
Assert.AreEqual("Sheet1!A1:A1", address.ToStringRelative(true));
|
||||
|
||||
Assert.AreEqual("$A$1:$A$1", address.ToStringFixed());
|
||||
Assert.AreEqual("$A$1:$A$1", address.ToStringFixed(XLReferenceStyle.A1));
|
||||
Assert.AreEqual("R1C1:R1C1", address.ToStringFixed(XLReferenceStyle.R1C1));
|
||||
Assert.AreEqual("$A$1:$A$1", address.ToStringFixed(XLReferenceStyle.Default));
|
||||
Assert.AreEqual("Sheet1!$A$1:$A$1", address.ToStringFixed(XLReferenceStyle.A1, true));
|
||||
Assert.AreEqual("Sheet1!R1C1:R1C1", address.ToStringFixed(XLReferenceStyle.R1C1, true));
|
||||
Assert.AreEqual("Sheet1!$A$1:$A$1", address.ToStringFixed(XLReferenceStyle.Default, true));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ToStringTestWithSpace()
|
||||
{
|
||||
IXLWorksheet ws = new XLWorkbook().Worksheets.Add("Sheet 1");
|
||||
IXLRangeAddress address = ws.Cell(1, 1).AsRange().RangeAddress;
|
||||
|
||||
Assert.AreEqual("A1:A1", address.ToString());
|
||||
Assert.AreEqual("'Sheet 1'!R1C1:R1C1", address.ToString(XLReferenceStyle.R1C1, true));
|
||||
|
||||
Assert.AreEqual("A1:A1", address.ToStringRelative());
|
||||
Assert.AreEqual("'Sheet 1'!A1:A1", address.ToStringRelative(true));
|
||||
|
||||
Assert.AreEqual("$A$1:$A$1", address.ToStringFixed());
|
||||
Assert.AreEqual("$A$1:$A$1", address.ToStringFixed(XLReferenceStyle.A1));
|
||||
Assert.AreEqual("R1C1:R1C1", address.ToStringFixed(XLReferenceStyle.R1C1));
|
||||
Assert.AreEqual("$A$1:$A$1", address.ToStringFixed(XLReferenceStyle.Default));
|
||||
Assert.AreEqual("'Sheet 1'!$A$1:$A$1", address.ToStringFixed(XLReferenceStyle.A1, true));
|
||||
Assert.AreEqual("'Sheet 1'!R1C1:R1C1", address.ToStringFixed(XLReferenceStyle.R1C1, true));
|
||||
Assert.AreEqual("'Sheet 1'!$A$1:$A$1", address.ToStringFixed(XLReferenceStyle.Default, true));
|
||||
}
|
||||
|
||||
[TestCase("B2:E5", "B2:E5")]
|
||||
[TestCase("E5:B2", "B2:E5")]
|
||||
[TestCase("B5:E2", "B2:E5")]
|
||||
[TestCase("B2:E$5", "B2:E$5")]
|
||||
[TestCase("B2:$E$5", "B2:$E$5")]
|
||||
[TestCase("B$2:$E$5", "B$2:$E$5")]
|
||||
[TestCase("$B$2:$E$5", "$B$2:$E$5")]
|
||||
[TestCase("B5:E$2", "B$2:E5")]
|
||||
[TestCase("$B$5:E2", "$B2:E$5")]
|
||||
[TestCase("$B$5:E$2", "$B$2:E$5")]
|
||||
[TestCase("$B$5:$E$2", "$B$2:$E$5")]
|
||||
public void RangeAddressNormalizeTest(string inputAddress, string expectedAddress)
|
||||
{
|
||||
XLWorksheet ws = new XLWorkbook().Worksheets.Add("Sheet 1") as XLWorksheet;
|
||||
var rangeAddress = new XLRangeAddress(ws, inputAddress);
|
||||
|
||||
var normalizedAddress = rangeAddress.Normalize();
|
||||
|
||||
Assert.AreSame(ws, rangeAddress.Worksheet);
|
||||
Assert.AreEqual(expectedAddress, normalizedAddress.ToString());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void InvalidRangeAddressToStringTest()
|
||||
{
|
||||
var address = ProduceInvalidAddress();
|
||||
|
||||
Assert.AreEqual("#REF!", address.ToString());
|
||||
Assert.AreEqual("#REF!", address.ToString(XLReferenceStyle.A1));
|
||||
Assert.AreEqual("#REF!", address.ToString(XLReferenceStyle.Default));
|
||||
Assert.AreEqual("'Sheet 1'!#REF!", address.ToString(XLReferenceStyle.R1C1));
|
||||
Assert.AreEqual("'Sheet 1'!#REF!", address.ToString(XLReferenceStyle.A1, true));
|
||||
Assert.AreEqual("'Sheet 1'!#REF!", address.ToString(XLReferenceStyle.Default, true));
|
||||
Assert.AreEqual("'Sheet 1'!#REF!", address.ToString(XLReferenceStyle.R1C1, true));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void InvalidRangeAddressToStringFixedTest()
|
||||
{
|
||||
var address = ProduceInvalidAddress();
|
||||
|
||||
Assert.AreEqual("#REF!", address.ToStringFixed());
|
||||
Assert.AreEqual("#REF!", address.ToStringFixed(XLReferenceStyle.A1));
|
||||
Assert.AreEqual("#REF!", address.ToStringFixed(XLReferenceStyle.Default));
|
||||
Assert.AreEqual("#REF!", address.ToStringFixed(XLReferenceStyle.R1C1));
|
||||
Assert.AreEqual("'Sheet 1'!#REF!", address.ToStringFixed(XLReferenceStyle.A1, true));
|
||||
Assert.AreEqual("'Sheet 1'!#REF!", address.ToStringFixed(XLReferenceStyle.Default, true));
|
||||
Assert.AreEqual("'Sheet 1'!#REF!", address.ToStringFixed(XLReferenceStyle.R1C1, true));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void InvalidRangeAddressToStringRelativeTest()
|
||||
{
|
||||
var address = ProduceInvalidAddress();
|
||||
|
||||
Assert.AreEqual("#REF!", address.ToStringRelative());
|
||||
Assert.AreEqual("'Sheet 1'!#REF!", address.ToStringRelative(true));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RangeAddressOnDeletedWorksheetToStringTest()
|
||||
{
|
||||
var address = ProduceAddressOnDeletedWorksheet();
|
||||
|
||||
Assert.AreEqual("#REF!A1:B2", address.ToString());
|
||||
Assert.AreEqual("#REF!A1:B2", address.ToString(XLReferenceStyle.A1));
|
||||
Assert.AreEqual("#REF!A1:B2", address.ToString(XLReferenceStyle.Default));
|
||||
Assert.AreEqual("#REF!R1C1:R2C2", address.ToString(XLReferenceStyle.R1C1));
|
||||
Assert.AreEqual("#REF!A1:B2", address.ToString(XLReferenceStyle.A1, true));
|
||||
Assert.AreEqual("#REF!A1:B2", address.ToString(XLReferenceStyle.Default, true));
|
||||
Assert.AreEqual("#REF!R1C1:R2C2", address.ToString(XLReferenceStyle.R1C1, true));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RangeAddressOnDeletedWorksheetToStringFixedTest()
|
||||
{
|
||||
var address = ProduceAddressOnDeletedWorksheet();
|
||||
|
||||
Assert.AreEqual("#REF!$A$1:$B$2", address.ToStringFixed());
|
||||
Assert.AreEqual("#REF!$A$1:$B$2", address.ToStringFixed(XLReferenceStyle.A1));
|
||||
Assert.AreEqual("#REF!$A$1:$B$2", address.ToStringFixed(XLReferenceStyle.Default));
|
||||
Assert.AreEqual("#REF!R1C1:R2C2", address.ToStringFixed(XLReferenceStyle.R1C1));
|
||||
Assert.AreEqual("#REF!$A$1:$B$2", address.ToStringFixed(XLReferenceStyle.A1, true));
|
||||
Assert.AreEqual("#REF!$A$1:$B$2", address.ToStringFixed(XLReferenceStyle.Default, true));
|
||||
Assert.AreEqual("#REF!R1C1:R2C2", address.ToStringFixed(XLReferenceStyle.R1C1, true));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RangeAddressOnDeletedWorksheetToStringRelativeTest()
|
||||
{
|
||||
var address = ProduceAddressOnDeletedWorksheet();
|
||||
|
||||
Assert.AreEqual("#REF!A1:B2", address.ToStringRelative());
|
||||
Assert.AreEqual("#REF!A1:B2", address.ToStringRelative(true));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void InvalidRangeAddressOnDeletedWorksheetToStringTest()
|
||||
{
|
||||
var address = ProduceInvalidAddressOnDeletedWorksheet();
|
||||
|
||||
Assert.AreEqual("#REF!#REF!", address.ToString());
|
||||
Assert.AreEqual("#REF!#REF!", address.ToString(XLReferenceStyle.A1));
|
||||
Assert.AreEqual("#REF!#REF!", address.ToString(XLReferenceStyle.Default));
|
||||
Assert.AreEqual("#REF!#REF!", address.ToString(XLReferenceStyle.R1C1));
|
||||
Assert.AreEqual("#REF!#REF!", address.ToString(XLReferenceStyle.A1, true));
|
||||
Assert.AreEqual("#REF!#REF!", address.ToString(XLReferenceStyle.Default, true));
|
||||
Assert.AreEqual("#REF!#REF!", address.ToString(XLReferenceStyle.R1C1, true));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void InvalidRangeAddressOnDeletedWorksheetToStringFixedTest()
|
||||
{
|
||||
var address = ProduceInvalidAddressOnDeletedWorksheet();
|
||||
|
||||
Assert.AreEqual("#REF!#REF!", address.ToStringFixed());
|
||||
Assert.AreEqual("#REF!#REF!", address.ToStringFixed(XLReferenceStyle.A1));
|
||||
Assert.AreEqual("#REF!#REF!", address.ToStringFixed(XLReferenceStyle.Default));
|
||||
Assert.AreEqual("#REF!#REF!", address.ToStringFixed(XLReferenceStyle.R1C1));
|
||||
Assert.AreEqual("#REF!#REF!", address.ToStringFixed(XLReferenceStyle.A1, true));
|
||||
Assert.AreEqual("#REF!#REF!", address.ToStringFixed(XLReferenceStyle.Default, true));
|
||||
Assert.AreEqual("#REF!#REF!", address.ToStringFixed(XLReferenceStyle.R1C1, true));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void InvalidRangeAddressOnDeletedWorksheetToStringRelativeTest()
|
||||
{
|
||||
var address = ProduceInvalidAddressOnDeletedWorksheet();
|
||||
|
||||
Assert.AreEqual("#REF!#REF!", address.ToStringRelative());
|
||||
Assert.AreEqual("#REF!#REF!", address.ToStringRelative(true));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FullSpanAddressCannotChange()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.AddWorksheet("Sheet1");
|
||||
|
||||
var wsRange = ws.AsRange();
|
||||
var row = ws.FirstRow().RowBelow(4).AsRange();
|
||||
var column = ws.FirstColumn().ColumnRight(4).AsRange();
|
||||
|
||||
Assert.AreEqual($"1:{XLHelper.MaxRowNumber}", wsRange.RangeAddress.ToString());
|
||||
Assert.AreEqual("5:5", row.RangeAddress.ToString());
|
||||
Assert.AreEqual("E:E", column.RangeAddress.ToString());
|
||||
|
||||
ws.Columns("Y:Z").Delete();
|
||||
ws.Rows("9:10").Delete();
|
||||
|
||||
Assert.AreEqual($"1:{XLHelper.MaxRowNumber}", wsRange.RangeAddress.ToString());
|
||||
Assert.AreEqual("5:5", row.RangeAddress.ToString());
|
||||
Assert.AreEqual("E:E", column.RangeAddress.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RangeAddressIsNormalized()
|
||||
{
|
||||
var ws = new XLWorkbook().AddWorksheet();
|
||||
|
||||
XLRangeAddress rangeAddress;
|
||||
|
||||
rangeAddress = (XLRangeAddress)ws.Range(ws.Cell("A1"), ws.Cell("C3")).RangeAddress;
|
||||
Assert.IsTrue(rangeAddress.IsNormalized);
|
||||
|
||||
rangeAddress = (XLRangeAddress)ws.Range(ws.Cell("C3"), ws.Cell("A1")).RangeAddress;
|
||||
Assert.IsFalse(rangeAddress.IsNormalized);
|
||||
|
||||
rangeAddress = (XLRangeAddress)ws.Range("B2:B1").RangeAddress;
|
||||
Assert.IsFalse(rangeAddress.IsNormalized);
|
||||
|
||||
rangeAddress = (XLRangeAddress)ws.Range("B2:B10").RangeAddress;
|
||||
Assert.IsTrue(rangeAddress.IsNormalized);
|
||||
|
||||
rangeAddress = (XLRangeAddress)ws.Range("B:B").RangeAddress;
|
||||
Assert.IsTrue(rangeAddress.IsNormalized);
|
||||
|
||||
rangeAddress = (XLRangeAddress)ws.Range("2:2").RangeAddress;
|
||||
Assert.IsTrue(rangeAddress.IsNormalized);
|
||||
|
||||
rangeAddress = (XLRangeAddress)ws.RangeAddress;
|
||||
Assert.IsTrue(rangeAddress.IsNormalized);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AsRangeTests()
|
||||
{
|
||||
XLRangeAddress rangeAddress;
|
||||
rangeAddress = new XLRangeAddress
|
||||
(
|
||||
new XLAddress(1, 1, false, false),
|
||||
new XLAddress(5, 5, false, false)
|
||||
);
|
||||
|
||||
Assert.IsTrue(rangeAddress.IsValid);
|
||||
Assert.IsTrue(rangeAddress.IsNormalized);
|
||||
Assert.Throws<InvalidOperationException>(() => rangeAddress.AsRange());
|
||||
|
||||
var ws = new XLWorkbook().AddWorksheet() as XLWorksheet;
|
||||
rangeAddress = new XLRangeAddress
|
||||
(
|
||||
new XLAddress(ws, 1, 1, false, false),
|
||||
new XLAddress(ws, 5, 5, false, false)
|
||||
);
|
||||
|
||||
Assert.IsTrue(rangeAddress.IsValid);
|
||||
Assert.IsTrue(rangeAddress.IsNormalized);
|
||||
Assert.DoesNotThrow(() => rangeAddress.AsRange());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RelativeRanges()
|
||||
{
|
||||
var ws = new XLWorkbook().AddWorksheet();
|
||||
|
||||
IXLRangeAddress rangeAddress;
|
||||
|
||||
rangeAddress = ws.Range("D4:E4").RangeAddress.Relative(ws.Range("A1:E4").RangeAddress, ws.Range("B10:F14").RangeAddress);
|
||||
Assert.IsTrue(rangeAddress.IsValid);
|
||||
Assert.AreEqual("E13:F13", rangeAddress.ToString());
|
||||
|
||||
rangeAddress = ws.Range("D4:E4").RangeAddress.Relative(ws.Range("B10:F14").RangeAddress, ws.Range("A1:E4").RangeAddress);
|
||||
Assert.IsFalse(rangeAddress.IsValid);
|
||||
Assert.AreEqual("#REF!", rangeAddress.ToString());
|
||||
|
||||
rangeAddress = ws.Range("C3").RangeAddress.Relative(ws.Range("A1:B2").RangeAddress, ws.Range("C3").RangeAddress);
|
||||
Assert.IsTrue(rangeAddress.IsValid);
|
||||
Assert.AreEqual("E5:E5", rangeAddress.ToString());
|
||||
|
||||
rangeAddress = ws.Range("B2").RangeAddress.Relative(ws.Range("A1").RangeAddress, ws.Range("C3").RangeAddress);
|
||||
Assert.IsTrue(rangeAddress.IsValid);
|
||||
Assert.AreEqual("D4:D4", rangeAddress.ToString());
|
||||
|
||||
rangeAddress = ws.Range("A1").RangeAddress.Relative(ws.Range("B2").RangeAddress, ws.Range("A1").RangeAddress);
|
||||
Assert.IsFalse(rangeAddress.IsValid);
|
||||
Assert.AreEqual("#REF!", rangeAddress.ToString());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestSpanProperties()
|
||||
{
|
||||
var ws = new XLWorkbook().AddWorksheet() as XLWorksheet;
|
||||
|
||||
var range = ws.Range("B3:E5");
|
||||
var rangeAddress = range.RangeAddress as IXLRangeAddress;
|
||||
Assert.AreEqual(4, rangeAddress.ColumnSpan);
|
||||
Assert.AreEqual(3, rangeAddress.RowSpan);
|
||||
Assert.AreEqual(12, rangeAddress.NumberOfCells);
|
||||
|
||||
range = ws.Range("E5:B3");
|
||||
rangeAddress = range.RangeAddress as IXLRangeAddress;
|
||||
Assert.AreEqual(4, rangeAddress.ColumnSpan);
|
||||
Assert.AreEqual(3, rangeAddress.RowSpan);
|
||||
Assert.AreEqual(12, rangeAddress.NumberOfCells);
|
||||
|
||||
rangeAddress = ProduceAddressOnDeletedWorksheet();
|
||||
Assert.AreEqual(2, rangeAddress.ColumnSpan);
|
||||
Assert.AreEqual(2, rangeAddress.RowSpan);
|
||||
Assert.AreEqual(4, rangeAddress.NumberOfCells);
|
||||
|
||||
rangeAddress = ProduceInvalidAddress();
|
||||
Assert.Throws<InvalidOperationException>(() => { var x = rangeAddress.ColumnSpan; });
|
||||
Assert.Throws<InvalidOperationException>(() => { var x = rangeAddress.RowSpan; });
|
||||
Assert.Throws<InvalidOperationException>(() => { var x = rangeAddress.NumberOfCells; });
|
||||
}
|
||||
|
||||
#region Private Methods
|
||||
|
||||
private IXLRangeAddress ProduceInvalidAddress()
|
||||
{
|
||||
IXLWorksheet ws = new XLWorkbook().Worksheets.Add("Sheet 1");
|
||||
var range = ws.Range("A1:B2");
|
||||
|
||||
ws.Rows(1, 5).Delete();
|
||||
return range.RangeAddress;
|
||||
}
|
||||
|
||||
private IXLRangeAddress ProduceAddressOnDeletedWorksheet()
|
||||
{
|
||||
IXLWorksheet ws = new XLWorkbook().Worksheets.Add("Sheet 1");
|
||||
var address = ws.Range("A1:B2").RangeAddress;
|
||||
|
||||
ws.Delete();
|
||||
return address;
|
||||
}
|
||||
|
||||
private IXLRangeAddress ProduceInvalidAddressOnDeletedWorksheet()
|
||||
{
|
||||
var address = ProduceInvalidAddress();
|
||||
address.Worksheet.Delete();
|
||||
return address;
|
||||
}
|
||||
|
||||
#endregion Private Methods
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,520 @@
|
||||
using ClosedXML.Excel;
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace ClosedXML_Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class XLRangeBaseTests
|
||||
{
|
||||
[Test]
|
||||
public void IsEmpty1()
|
||||
{
|
||||
IXLWorksheet ws = new XLWorkbook().Worksheets.Add("Sheet1");
|
||||
IXLCell cell = ws.Cell(1, 1);
|
||||
IXLRange range = ws.Range("A1:B2");
|
||||
bool actual = range.IsEmpty();
|
||||
bool expected = true;
|
||||
Assert.AreEqual(expected, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsEmpty2()
|
||||
{
|
||||
IXLWorksheet ws = new XLWorkbook().Worksheets.Add("Sheet1");
|
||||
IXLCell cell = ws.Cell(1, 1);
|
||||
IXLRange range = ws.Range("A1:B2");
|
||||
bool actual = range.IsEmpty(XLCellsUsedOptions.All);
|
||||
bool expected = true;
|
||||
Assert.AreEqual(expected, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsEmpty3()
|
||||
{
|
||||
IXLWorksheet ws = new XLWorkbook().Worksheets.Add("Sheet1");
|
||||
IXLCell cell = ws.Cell(1, 1);
|
||||
cell.Style.Fill.BackgroundColor = XLColor.Red;
|
||||
IXLRange range = ws.Range("A1:B2");
|
||||
bool actual = range.IsEmpty();
|
||||
bool expected = true;
|
||||
Assert.AreEqual(expected, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsEmpty4()
|
||||
{
|
||||
IXLWorksheet ws = new XLWorkbook().Worksheets.Add("Sheet1");
|
||||
IXLCell cell = ws.Cell(1, 1);
|
||||
cell.Style.Fill.BackgroundColor = XLColor.Red;
|
||||
IXLRange range = ws.Range("A1:B2");
|
||||
bool actual = range.IsEmpty(XLCellsUsedOptions.AllContents);
|
||||
bool expected = true;
|
||||
Assert.AreEqual(expected, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsEmpty5()
|
||||
{
|
||||
IXLWorksheet ws = new XLWorkbook().Worksheets.Add("Sheet1");
|
||||
IXLCell cell = ws.Cell(1, 1);
|
||||
cell.Style.Fill.BackgroundColor = XLColor.Red;
|
||||
IXLRange range = ws.Range("A1:B2");
|
||||
bool actual = range.IsEmpty(XLCellsUsedOptions.All);
|
||||
bool expected = false;
|
||||
Assert.AreEqual(expected, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsEmpty6()
|
||||
{
|
||||
IXLWorksheet ws = new XLWorkbook().Worksheets.Add("Sheet1");
|
||||
IXLCell cell = ws.Cell(1, 1);
|
||||
cell.Value = "X";
|
||||
IXLRange range = ws.Range("A1:B2");
|
||||
bool actual = range.IsEmpty();
|
||||
bool expected = false;
|
||||
Assert.AreEqual(expected, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SingleCell()
|
||||
{
|
||||
var wb = new XLWorkbook();
|
||||
IXLWorksheet ws = wb.Worksheets.Add("Sheet1");
|
||||
ws.Cell(1, 1).Value = "Hello World!";
|
||||
wb.NamedRanges.Add("SingleCell", "Sheet1!$A$1");
|
||||
IXLRange range = wb.Range("SingleCell");
|
||||
Assert.AreEqual(1, range.CellsUsed().Count());
|
||||
Assert.AreEqual("Hello World!", range.CellsUsed().Single().GetString());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TableRange()
|
||||
{
|
||||
var wb = new XLWorkbook();
|
||||
IXLWorksheet ws = wb.Worksheets.Add("Sheet1");
|
||||
IXLRangeColumn rangeColumn = ws.Column(1).Column(1, 4);
|
||||
rangeColumn.Cell(1).Value = "FName";
|
||||
rangeColumn.Cell(2).Value = "John";
|
||||
rangeColumn.Cell(3).Value = "Hank";
|
||||
rangeColumn.Cell(4).Value = "Dagny";
|
||||
IXLTable table = rangeColumn.CreateTable();
|
||||
wb.NamedRanges.Add("FNameColumn", String.Format("{0}[{1}]", table.Name, "FName"));
|
||||
|
||||
IXLRange namedRange = wb.Range("FNameColumn");
|
||||
Assert.AreEqual(3, namedRange.Cells().Count());
|
||||
Assert.IsTrue(
|
||||
namedRange.CellsUsed().Select(cell => cell.GetString()).SequenceEqual(new[] { "John", "Hank", "Dagny" }));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WsNamedCell()
|
||||
{
|
||||
var wb = new XLWorkbook();
|
||||
IXLWorksheet ws = wb.Worksheets.Add("Sheet1");
|
||||
ws.Cell(1, 1).SetValue("Test").AddToNamed("TestCell", XLScope.Worksheet);
|
||||
Assert.AreEqual("Test", ws.Cell("TestCell").GetString());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WsNamedCells()
|
||||
{
|
||||
var wb = new XLWorkbook();
|
||||
IXLWorksheet ws = wb.Worksheets.Add("Sheet1");
|
||||
ws.Cell(1, 1).SetValue("Test").AddToNamed("TestCell", XLScope.Worksheet);
|
||||
ws.Cell(2, 1).SetValue("B");
|
||||
IXLCells cells = ws.Cells("TestCell, A2");
|
||||
Assert.AreEqual("Test", cells.First().GetString());
|
||||
Assert.AreEqual("B", cells.Last().GetString());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WsNamedRange()
|
||||
{
|
||||
var wb = new XLWorkbook();
|
||||
IXLWorksheet ws = wb.Worksheets.Add("Sheet1");
|
||||
ws.Cell(1, 1).SetValue("A");
|
||||
ws.Cell(2, 1).SetValue("B");
|
||||
IXLRange original = ws.Range("A1:A2");
|
||||
original.AddToNamed("TestRange", XLScope.Worksheet);
|
||||
IXLRange named = ws.Range("TestRange");
|
||||
Assert.AreEqual(original.RangeAddress.ToStringFixed(), named.RangeAddress.ToString());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WsNamedRanges()
|
||||
{
|
||||
var wb = new XLWorkbook();
|
||||
IXLWorksheet ws = wb.Worksheets.Add("Sheet1");
|
||||
ws.Cell(1, 1).SetValue("A");
|
||||
ws.Cell(2, 1).SetValue("B");
|
||||
ws.Cell(3, 1).SetValue("C");
|
||||
IXLRange original = ws.Range("A1:A2");
|
||||
original.AddToNamed("TestRange", XLScope.Worksheet);
|
||||
IXLRanges namedRanges = ws.Ranges("TestRange, A3");
|
||||
Assert.AreEqual(original.RangeAddress.ToStringFixed(), namedRanges.First().RangeAddress.ToString());
|
||||
Assert.AreEqual("$A$3:$A$3", namedRanges.Last().RangeAddress.ToStringFixed());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WsNamedRangesOneString()
|
||||
{
|
||||
var wb = new XLWorkbook();
|
||||
IXLWorksheet ws = wb.Worksheets.Add("Sheet1");
|
||||
ws.NamedRanges.Add("TestRange", "Sheet1!$A$1,Sheet1!$A$3");
|
||||
IXLRanges namedRanges = ws.Ranges("TestRange");
|
||||
|
||||
Assert.AreEqual("$A$1:$A$1", namedRanges.First().RangeAddress.ToStringFixed());
|
||||
Assert.AreEqual("$A$3:$A$3", namedRanges.Last().RangeAddress.ToStringFixed());
|
||||
}
|
||||
|
||||
//[Test]
|
||||
//public void WsNamedRangeLiteral()
|
||||
//{
|
||||
// var wb = new XLWorkbook();
|
||||
// var ws = wb.Worksheets.Add("Sheet1");
|
||||
// ws.NamedRanges.Add("TestRange", "\"Hello\"");
|
||||
// using (MemoryStream memoryStream = new MemoryStream())
|
||||
// {
|
||||
// wb.SaveAs(memoryStream, true);
|
||||
// var wb2 = new XLWorkbook(memoryStream);
|
||||
// var text = wb2.Worksheet("Sheet1").NamedRanges.First()
|
||||
// memoryStream.Close();
|
||||
// }
|
||||
|
||||
//}
|
||||
|
||||
[Test]
|
||||
public void GrowRange()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.AddWorksheet("Sheet1");
|
||||
Assert.AreEqual("A1:B2", ws.Cell("A1").AsRange().Grow().RangeAddress.ToString());
|
||||
Assert.AreEqual("A1:B3", ws.Cell("A2").AsRange().Grow().RangeAddress.ToString());
|
||||
Assert.AreEqual("A1:C2", ws.Cell("B1").AsRange().Grow().RangeAddress.ToString());
|
||||
|
||||
Assert.AreEqual("E4:G6", ws.Cell("F5").AsRange().Grow().RangeAddress.ToString());
|
||||
Assert.AreEqual("D3:H7", ws.Cell("F5").AsRange().Grow(2).RangeAddress.ToString());
|
||||
Assert.AreEqual("A1:DB105", ws.Cell("F5").AsRange().Grow(100).RangeAddress.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ShrinkRange()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.AddWorksheet("Sheet1");
|
||||
Assert.Null(ws.Cell("A1").AsRange().Shrink());
|
||||
Assert.Null(ws.Range("B2:C3").Shrink());
|
||||
Assert.AreEqual("C3:C3", ws.Range("B2:D4").Shrink().RangeAddress.ToString());
|
||||
Assert.AreEqual("K11:P16", ws.Range("A1:Z26").Shrink(10).RangeAddress.ToString());
|
||||
|
||||
// Grow and shrink back
|
||||
Assert.AreEqual("Z26:Z26", ws.Cell("Z26").AsRange().Grow(10).Shrink(10).RangeAddress.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Intersection()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.AddWorksheet("Sheet1");
|
||||
|
||||
Assert.AreEqual("D9:G11", ws.Range("B9:I11").Intersection(ws.Range("D4:G16")).ToString());
|
||||
Assert.AreEqual("E9:G11", ws.Range("E9:I11").Intersection(ws.Range("D4:G16")).ToString());
|
||||
Assert.AreEqual("E9:E9", ws.Cell("E9").AsRange().Intersection(ws.Range("D4:G16")).ToString());
|
||||
Assert.AreEqual("E9:E9", ws.Range("D4:G16").Intersection(ws.Cell("E9").AsRange()).ToString());
|
||||
|
||||
XLRangeAddress rangeAddress;
|
||||
|
||||
rangeAddress = (XLRangeAddress)ws.Cell("C3").AsRange().Intersection(ws.Cell("A1").AsRange());
|
||||
Assert.IsFalse(rangeAddress.IsValid);
|
||||
|
||||
rangeAddress = (XLRangeAddress)ws.Cell("A1").AsRange().Intersection(ws.Cell("C3").AsRange());
|
||||
Assert.IsFalse(rangeAddress.IsValid);
|
||||
|
||||
Assert.Null(ws.Range("A1:C3").Intersection(null));
|
||||
|
||||
var otherWs = wb.AddWorksheet("Sheet2");
|
||||
Assert.Null(ws.Intersection(otherWs));
|
||||
Assert.Null(ws.Cell("A1").AsRange().Intersection(otherWs.Cell("A2").AsRange()));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Union()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.AddWorksheet("Sheet1");
|
||||
|
||||
Assert.AreEqual(64, ws.Range("B9:I11").Union(ws.Range("D4:G16")).Count());
|
||||
Assert.AreEqual(58, ws.Range("E9:I11").Union(ws.Range("D4:G16")).Count());
|
||||
Assert.AreEqual(52, ws.Cell("E9").AsRange().Union(ws.Range("D4:G16")).Count());
|
||||
Assert.AreEqual(52, ws.Range("D4:G16").Union(ws.Cell("E9").AsRange()).Count());
|
||||
|
||||
Assert.AreEqual(2, ws.Cell("A1").AsRange().Union(ws.Cell("C3").AsRange()).Count());
|
||||
|
||||
Assert.AreEqual(9, ws.Range("A1:C3").Union(null).Count());
|
||||
|
||||
var otherWs = wb.AddWorksheet("Sheet2");
|
||||
Assert.False(ws.Union(otherWs).Any());
|
||||
Assert.False(ws.Cell("A1").AsRange().Union(otherWs.Cell("A2").AsRange()).Any());
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Difference()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.AddWorksheet("Sheet1");
|
||||
|
||||
Assert.AreEqual(12, ws.Range("B9:I11").Difference(ws.Range("D4:G16")).Count());
|
||||
Assert.AreEqual(6, ws.Range("E9:I11").Difference(ws.Range("D4:G16")).Count());
|
||||
Assert.AreEqual(0, ws.Cell("E9").AsRange().Difference(ws.Range("D4:G16")).Count());
|
||||
Assert.AreEqual(51, ws.Range("D4:G16").Difference(ws.Cell("E9").AsRange()).Count());
|
||||
|
||||
Assert.AreEqual(1, ws.Cell("A1").AsRange().Difference(ws.Cell("C3").AsRange()).Count());
|
||||
|
||||
Assert.AreEqual(9, ws.Range("A1:C3").Difference(null).Count());
|
||||
|
||||
var otherWs = wb.AddWorksheet("Sheet2");
|
||||
Assert.False(ws.Difference(otherWs).Any());
|
||||
Assert.False(ws.Cell("A1").AsRange().Difference(otherWs.Cell("A2").AsRange()).Any());
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SurroundingCells()
|
||||
{
|
||||
using (var wb = new XLWorkbook())
|
||||
{
|
||||
var ws = wb.AddWorksheet("Sheet1");
|
||||
|
||||
Assert.AreEqual(3, ws.FirstCell().AsRange().SurroundingCells().Count());
|
||||
Assert.AreEqual(8, ws.Cell("C3").AsRange().SurroundingCells().Count());
|
||||
Assert.AreEqual(16, ws.Range("C3:D6").AsRange().SurroundingCells().Count());
|
||||
|
||||
Assert.AreEqual(0, ws.Range("C3:D6").AsRange().SurroundingCells(c => !c.IsEmpty()).Count());
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ClearConditionalFormattingsWhenRangeAbove1()
|
||||
{
|
||||
var ws = new XLWorkbook().Worksheets.Add("Sheet1");
|
||||
ws.Range("C3:D7").AddConditionalFormat();
|
||||
ws.Range("B2:E3").Clear(XLClearOptions.ConditionalFormats);
|
||||
|
||||
Assert.AreEqual(1, ws.ConditionalFormats.Count());
|
||||
Assert.AreEqual("C4:D7", ws.ConditionalFormats.Single().Range.RangeAddress.ToStringRelative());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ClearConditionalFormattingsWhenRangeAbove2()
|
||||
{
|
||||
var ws = new XLWorkbook().Worksheets.Add("Sheet1");
|
||||
ws.Range("C3:D7").AddConditionalFormat();
|
||||
ws.Range("C3:D3").Clear(XLClearOptions.ConditionalFormats);
|
||||
|
||||
Assert.AreEqual(1, ws.ConditionalFormats.Count());
|
||||
Assert.AreEqual("C4:D7", ws.ConditionalFormats.Single().Range.RangeAddress.ToStringRelative());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ClearConditionalFormattingsWhenRangeBelow1()
|
||||
{
|
||||
var ws = new XLWorkbook().Worksheets.Add("Sheet1");
|
||||
ws.Range("C3:D7").AddConditionalFormat();
|
||||
ws.Range("B7:E8").Clear(XLClearOptions.ConditionalFormats);
|
||||
|
||||
Assert.AreEqual(1, ws.ConditionalFormats.Count());
|
||||
Assert.AreEqual("C3:D6", ws.ConditionalFormats.Single().Range.RangeAddress.ToStringRelative());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ClearConditionalFormattingsWhenRangeBelow2()
|
||||
{
|
||||
var ws = new XLWorkbook().Worksheets.Add("Sheet1");
|
||||
ws.Range("C3:D7").AddConditionalFormat();
|
||||
ws.Range("C7:D7").Clear(XLClearOptions.ConditionalFormats);
|
||||
|
||||
Assert.AreEqual(1, ws.ConditionalFormats.Count());
|
||||
Assert.AreEqual("C3:D6", ws.ConditionalFormats.Single().Range.RangeAddress.ToStringRelative());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ClearConditionalFormattingsWhenRangeRowInMiddle()
|
||||
{
|
||||
var ws = new XLWorkbook().Worksheets.Add("Sheet1");
|
||||
ws.Range("C3:D7").AddConditionalFormat();
|
||||
ws.Range("C5:E5").Clear(XLClearOptions.ConditionalFormats);
|
||||
|
||||
Assert.AreEqual(1, ws.ConditionalFormats.Count());
|
||||
Assert.AreEqual("C3:D4", ws.ConditionalFormats.First().Ranges.First().RangeAddress.ToStringRelative());
|
||||
Assert.AreEqual("C6:D7", ws.ConditionalFormats.First().Ranges.Last().RangeAddress.ToStringRelative());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ClearConditionalFormattingsWhenRangeColumnInMiddle()
|
||||
{
|
||||
var ws = new XLWorkbook().Worksheets.Add("Sheet1");
|
||||
ws.Range("C3:G4").AddConditionalFormat();
|
||||
ws.Range("E2:E4").Clear(XLClearOptions.ConditionalFormats);
|
||||
|
||||
Assert.AreEqual(1, ws.ConditionalFormats.Count());
|
||||
Assert.AreEqual("C3:D4", ws.ConditionalFormats.First().Ranges.First().RangeAddress.ToStringRelative());
|
||||
Assert.AreEqual("F3:G4", ws.ConditionalFormats.First().Ranges.Last().RangeAddress.ToStringRelative());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ClearConditionalFormattingsWhenRangeContainsFormatWhole()
|
||||
{
|
||||
var ws = new XLWorkbook().Worksheets.Add("Sheet1");
|
||||
ws.Range("C3:G4").AddConditionalFormat();
|
||||
ws.Range("B2:G4").Clear(XLClearOptions.ConditionalFormats);
|
||||
|
||||
Assert.AreEqual(0, ws.ConditionalFormats.Count());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void NoClearConditionalFormattingsWhenRangePartiallySuperimposed()
|
||||
{
|
||||
var ws = new XLWorkbook().Worksheets.Add("Sheet1");
|
||||
ws.Range("C3:G4").AddConditionalFormat();
|
||||
ws.Range("C2:D3").Clear(XLClearOptions.ConditionalFormats);
|
||||
|
||||
Assert.AreEqual(1, ws.ConditionalFormats.Count());
|
||||
Assert.AreEqual(1, ws.ConditionalFormats.Single().Ranges.Count);
|
||||
Assert.AreEqual("C3:G4", ws.ConditionalFormats.Single().Ranges.Single().RangeAddress.ToStringRelative());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RangesRemoveAllWithoutDispose()
|
||||
{
|
||||
var ws = new XLWorkbook().Worksheets.Add("Sheet1");
|
||||
var ranges = new XLRanges();
|
||||
ranges.Add(ws.Range("A1:A2"));
|
||||
ranges.Add(ws.Range("B1:B2"));
|
||||
var rangesCopy = ranges.ToList();
|
||||
|
||||
ranges.RemoveAll(null, false);
|
||||
ws.FirstColumn().InsertColumnsBefore(1);
|
||||
|
||||
Assert.AreEqual(0, ranges.Count);
|
||||
// if ranges were not disposed they addresses should change
|
||||
Assert.AreEqual("B1:B2", rangesCopy.First().RangeAddress.ToString());
|
||||
Assert.AreEqual("C1:C2", rangesCopy.Last().RangeAddress.ToString());
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void RangesRemoveAllByCriteria()
|
||||
{
|
||||
var ws = new XLWorkbook().Worksheets.Add("Sheet1");
|
||||
var ranges = new XLRanges();
|
||||
ranges.Add(ws.Range("A1:A2"));
|
||||
ranges.Add(ws.Range("B1:B3"));
|
||||
ranges.Add(ws.Range("C1:C4"));
|
||||
var otherRange = ws.Range("A3:D3");
|
||||
|
||||
ranges.RemoveAll(r => r.Intersects(otherRange));
|
||||
|
||||
Assert.AreEqual(1, ranges.Count);
|
||||
Assert.AreEqual("A1:A2", ranges.Single().RangeAddress.ToString());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void XLRangesReturnsRangesInDeterministicOrder()
|
||||
{
|
||||
var wb = new XLWorkbook();
|
||||
var ws1 = wb.Worksheets.Add("Sheet1");
|
||||
var ws2 = wb.Worksheets.Add("Another sheet");
|
||||
|
||||
var ranges = new XLRanges();
|
||||
ranges.Add(ws2.Range("F1:F12"));
|
||||
ranges.Add(ws1.Range("F12:F16"));
|
||||
ranges.Add(ws1.Range("B1:F2"));
|
||||
ranges.Add(ws2.Range("A13:B14"));
|
||||
ranges.Add(ws2.Range("E1:E2"));
|
||||
ranges.Add(ws1.Range("E1:H2"));
|
||||
ranges.Add(ws1.Range("G2:G13"));
|
||||
ranges.Add(ws1.Range("G20:G20"));
|
||||
|
||||
var expectedRanges = new List<IXLRange>
|
||||
{
|
||||
ws1.Range("B1:F2"),
|
||||
ws1.Range("E1:H2"),
|
||||
ws1.Range("G2:G13"),
|
||||
ws1.Range("F12:F16"),
|
||||
ws1.Range("G20:G20"),
|
||||
|
||||
ws2.Range("E1:E2"),
|
||||
ws2.Range("F1:F12"),
|
||||
ws2.Range("A13:B14"),
|
||||
};
|
||||
|
||||
var actualRanges = ranges.ToList();
|
||||
|
||||
Assert.AreEqual(expectedRanges.Count, actualRanges.Count);
|
||||
for (int i = 0; i < actualRanges.Count; i++)
|
||||
{
|
||||
Assert.AreEqual(expectedRanges[i], actualRanges[i]);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ClearRangeRemovesSparklines()
|
||||
{
|
||||
IXLWorksheet ws = new XLWorkbook().Worksheets.Add("Sheet1");
|
||||
ws.SparklineGroups.Add("B1:B3", "C1:E3");
|
||||
|
||||
ws.Range("B1:C1").Clear(XLClearOptions.All);
|
||||
ws.Range("B2:C2").Clear(XLClearOptions.Sparklines);
|
||||
|
||||
Assert.AreEqual(1, ws.SparklineGroups.Single().Count());
|
||||
Assert.IsFalse(ws.Cell("B1").HasSparkline);
|
||||
Assert.IsFalse(ws.Cell("B2").HasSparkline);
|
||||
Assert.IsTrue(ws.Cell("B3").HasSparkline);
|
||||
|
||||
}
|
||||
|
||||
[TestCase("B2:G7", "D4:E5", true, "B2:G3,B4:C5,D4:E5,F4:G5,B6:G7")]
|
||||
[TestCase("B2:G7", "D4:E5", false, "B2:G3,B4:C5,F4:G5,B6:G7")]
|
||||
[TestCase("B2:G7", "B2:G7", true, "B2:G7")]
|
||||
[TestCase("B2:G7", "B2:G7", false, "")]
|
||||
[TestCase("B2:G7", "A1:H8", true, "B2:G7")]
|
||||
[TestCase("B2:G7", "A1:H8", false, "")]
|
||||
[TestCase("B2:G7", "A1:B2", true, "B2:B2,C2:G2,B3:G7")]
|
||||
[TestCase("B2:G7", "A1:B2", false, "C2:G2,B3:G7")]
|
||||
[TestCase("B2:G7", "E4:J5", true, "B2:G3,B4:D5,E4:G5,B6:G7")]
|
||||
[TestCase("B2:G7", "E4:J5", false, "B2:G3,B4:D5,B6:G7")]
|
||||
[TestCase("B2:G7", "A11:H18", true, "B2:G7")]
|
||||
[TestCase("B2:G7", "A11:H18", false, "B2:G7")]
|
||||
[TestCase("B2:G7", "A1:H1", true, "B2:G7")]
|
||||
[TestCase("B2:G7", "A1:A12", true, "B2:G7")]
|
||||
[TestCase("B2:G7", "A8:H8", true, "B2:G7")]
|
||||
[TestCase("B2:G7", "H1:H8", true, "B2:G7")]
|
||||
public void CanSplitRange(string rangeAddress, string splitBy, bool includeIntersection, string expectedResult)
|
||||
{
|
||||
var wb = new XLWorkbook();
|
||||
var ws = wb.AddWorksheet();
|
||||
var range = ws.Range(rangeAddress) as XLRange;
|
||||
var splitter = ws.Range(splitBy);
|
||||
|
||||
var result = range.Split(splitter.RangeAddress, includeIntersection);
|
||||
|
||||
var actualAddresses = string.Join(",", result.Select(r => r.RangeAddress.ToString()));
|
||||
|
||||
Assert.AreEqual(expectedResult, actualAddresses);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user