Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/EPPlus/ExcelAddressBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1333,8 +1333,9 @@ internal ExcelAddressBase AddColumnFirstAddress(int col, int cols, bool setFixed
var toCol = GetColumn((setFixed && _toColFixed ? _toCol : _toCol + cols), setRefOnMinMax);
if (col <= _fromCol)
{
var fromCol = GetColumn((setFixed && _fromColFixed ? _fromCol : _fromCol + cols), setRefOnMinMax);
return new ExcelAddressBase(_fromRow, fromCol, _toRow, toCol, _fromRowFixed, _fromColFixed, _toRowFixed, _toColFixed, WorkSheetName, _address);
var fromCol = setFixed && _fromColFixed ? _fromCol : _fromCol + cols;
if (fromCol > ExcelPackage.MaxColumns) return null;
return new ExcelAddressBase(_fromRow, GetColumn(fromCol, setRefOnMinMax), _toRow, toCol, _fromRowFixed, _fromColFixed, _toRowFixed, _toColFixed, WorkSheetName, _address);
}
else
{
Expand Down
1 change: 1 addition & 0 deletions src/EPPlus/ExcelNamedRange.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ private enum NameRelativeType
/// </summary>
RelativeTableAddress = 2
}

ExcelWorksheet _sheet;
/// <summary>
/// A named range
Expand Down
61 changes: 55 additions & 6 deletions src/EPPlus/ExcelNamedRangeCollection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -179,22 +179,71 @@ internal void Insert(int rowFrom, int colFrom, int rows, int cols, int lowerLimi
Insert(rowFrom, colFrom, rows, cols, n => true, lowerLimint, upperLimit);
}

internal void Insert(int rowFrom, int colFrom, int rows, int cols, Func<ExcelNamedRange, bool> filter, int lowerLimint = 0, int upperLimit=int.MaxValue)
internal void Insert(int rowFrom, int colFrom, int rows, int cols, Func<ExcelNamedRange, bool> filter, int lowerLimit = 0, int upperLimit=int.MaxValue)
{
var namedRanges = this._list.Where(filter);
foreach(var namedRange in namedRanges)
{
if (namedRange._fromRow <= 0) continue;
var address = new ExcelAddressBase(namedRange.Address);
if (rows > 0 && address._toCol<=upperLimit && address._fromCol>=lowerLimint && address.Rows < ExcelPackage.MaxRows)
if (rows > 0 && address._toCol<=upperLimit && address._fromCol>=lowerLimit && address.Rows < ExcelPackage.MaxRows)
{
address = address.AddRow(rowFrom, rows, false);
if(address._toRow + rows > ExcelPackage.MaxRows)
{
if (address._fromRowFixed == false)
{
//if relative the address should remain as is
}
else if (address._fromRowFixed | address._toRowFixed)
{
//This may look strange at a glance but appears to be how excel does it despite absolute refs
address = address.AddRow(rowFrom, rows, false, false);
}
else
{
//If over MaxRows this results in null
address = address.AddRow(rowFrom, rows, false);
}
}
else
{
//If over MaxRows this results in null
address = address.AddRow(rowFrom, rows, false);
}
}
if(cols > 0 && colFrom > 0 && address._toRow <= upperLimit && address._fromRow >= lowerLimint && address.Columns < ExcelPackage.MaxColumns)
if(cols > 0 && colFrom > 0 && address._toRow <= upperLimit && address._fromRow >= lowerLimit && address.Columns < ExcelPackage.MaxColumns)
{
address = address.AddColumn(colFrom, cols, false,false);
if (address._toCol + cols > ExcelPackage.MaxColumns)
{
if (address._toColFixed == false && address._fromColFixed == false)
{
//if relative the address should remain as is
}
else if (address._fromColFixed | address._toColFixed)
{
//This may look strange at a glance but appears to be how excel does it despite absolute refs
address = address.AddColumn(colFrom, cols, false, false);
}
else
{
address = address.AddColumn(colFrom, cols, false);
}
}
else
{
//If over MaxRows this results in null
address = address.AddColumn(colFrom, cols, false, false);
}
}

if(address == null)
{
namedRange.Address = $"{namedRange.WorkSheetName}!{ExcelErrorValue.Values.Ref}";
}
else
{
namedRange.Address = address.Address;
}
namedRange.Address = address.Address;
}
}
internal void Delete(int rowFrom, int colFrom, int rows, int cols, int lowerLimint = 0, int upperLimit = int.MaxValue)
Expand Down
158 changes: 158 additions & 0 deletions src/EPPlusTest/Core/Range/Insert/RangeInsertTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1526,5 +1526,163 @@ public void EnsureInsertWorksCorrectlyWithColumnCollection()
SaveAndCleanup(p);
}
}

#region NamedRange insert Max row/col tests
[TestMethod]
public void InsertRowRangeMaxRelativeMultipleLines()
{
using (var p = OpenPackage("namedRangeMaxRelativeLargerRange.xlsx", true))
{
var ws = p.Workbook.Worksheets.Add("ANamedRange");

string rangeString = "A1048570:A1048576";

//Add relative reference to max row
var namedRange = ws.Names.Add("EndNamedRangeA", ws.Cells[rangeString], true);

//Insert row somewhere above max row
ws.InsertRow(347, 1, 346);

//address should remain unchanged
Assert.AreEqual(rangeString, namedRange.Address);
SaveAndCleanup(p);
}
}

[TestMethod]
public void InsertRowRangeMaxAbsoluteMultipleLines()
{
using (var p = OpenPackage("namedRangeMaxAbsoluteLargerRange.xlsx", true))
{
var ws = p.Workbook.Worksheets.Add("ANamedRange");

//Add absolute reference to max row
var namedRange = ws.Names.Add("EndNamedRangeA", ws.Cells["A1048570:A1048576"]);

//Insert row somewhere above max row
ws.InsertRow(347, 1, 346);

//from row should be added to by one
Assert.AreEqual("$A$1048571:$A$1048576", namedRange.Address);
SaveAndCleanup(p);
}
}

[TestMethod]
public void InsertRowNamedRangeMaxAbsolute()
{
using (var p = OpenPackage("namedRangeMaxAbsolute.xlsx", true))
{
var ws = p.Workbook.Worksheets.Add("ANamedRange");

//Add absolute reference to max row
var namedRange = ws.Names.Add("EndNamedRangeA", ws.Cells["A1048576"]);

//Insert row somewhere above max row
ws.InsertRow(347, 1, 346);

Assert.AreEqual($"ANamedRange!{ExcelErrorValue.Values.Ref}", namedRange.Address);
Assert.AreEqual(null, namedRange.Value);
}
}

[TestMethod]
public void InsertRowNamedRangeMaxRelative()
{
using (var p = OpenPackage("namedRangeMaxRelative.xlsx", true))
{
var ws = p.Workbook.Worksheets.Add("ANamedRange");

var relativeRange = ws.Names.Add("EndNamedRangeB", ws.Cells["B1048576"], true);

//Insert row somewhere above max row
ws.InsertRow(347, 1, 346);

Assert.AreEqual("B1048576", relativeRange.Address);
SaveAndCleanup(p);
}
}

//Column tests start

[TestMethod]
public void InsertColNamedRangeMaxAbsolute()
{
using (var p = OpenPackage("namedRangeMaxColAbsolute.xlsx", true))
{
var ws = p.Workbook.Worksheets.Add("colNamedRange");

var maxCols = ExcelPackage.MaxColumns;

//Add absolute reference to max col
var namedRange = ws.Names.Add("EndNamedRangeMaxCols", ws.Cells[3, maxCols]);

//Insert col somewhere left of max col
ws.InsertColumn(347, 1, 346);

Assert.AreEqual($"colNamedRange!{ExcelErrorValue.Values.Ref}", namedRange.Address);
Assert.AreEqual(null, namedRange.Value);
}
}

[TestMethod]
public void InsertColNamedRangeMaxRelative()
{
using (var p = OpenPackage("namedRangeMaxColRelative.xlsx", true))
{
var ws = p.Workbook.Worksheets.Add("colNamedRange");

var maxCols = ExcelPackage.MaxColumns;

//Add absolute reference to max col
var namedRange = ws.Names.Add("EndNamedRangeMaxCols", ws.Cells[3, maxCols], true);

//Insert col somewhere left of max col
ws.InsertColumn(347, 1, 346);

Assert.AreEqual("XFD3", namedRange.Address);
}
}

[TestMethod]
public void InsertColRangeMaxRelativeMultipleLines()
{
using (var p = OpenPackage("namedRangeMaxColRelativeLargerRange.xlsx", true))
{
var ws = p.Workbook.Worksheets.Add("ANamedRange");

string rangeString = "XFB3:XFD3";

//Add relative reference to max row
var namedRange = ws.Names.Add("EndNamedRangeA", ws.Cells[rangeString], true);

//Insert col somewhere left of max col
ws.InsertColumn(347, 1, 346);

//address should remain unchanged
Assert.AreEqual(rangeString, namedRange.Address);
}
}

[TestMethod]
public void InsertColRangeMaxAbsoluteMultipleLines()
{
using (var p = OpenPackage("namedRangeMaxColAbsoluteLargerRange.xlsx", true))
{
var ws = p.Workbook.Worksheets.Add("ANamedRange");

string rangeString = "XFB3:XFD3";

//Add relative reference to max row
var namedRange = ws.Names.Add("EndNamedRangeA", ws.Cells[rangeString]);

//Insert col somewhere left of max col
ws.InsertColumn(347, 1, 346);

//address should remain unchanged
Assert.AreEqual("$XFC$3:$XFD$3", namedRange.Address);
}
}
#endregion
}
}
15 changes: 15 additions & 0 deletions src/EPPlusTest/WorkSheetTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2747,5 +2747,20 @@ internal ExcelRangeBase GenerateRowsFromTemplate(ExcelWorksheet wks, ExcelRangeB

return wks.Cells[$"{originalTemplateRow}:{originalTemplateRow + insertCount}"];
}

[TestMethod]
public void InsertRowIssue()
{
using (var p = OpenTemplatePackage("s1019.xlsx"))
{
var ws = p.Workbook.Worksheets.GetByName("披露附注");
var namedRange = ws.Names["上一行"];

var adress = namedRange.Address;

ws.InsertRow(347, 1, 346);
SaveAndCleanup(p);
}
}
}
}