/// <summary> /// Auto fill specified serial in range. /// </summary> /// <param name="fromRange">Range to read filling rules.</param> /// <param name="toRange">Range to be filled.</param> public void AutoFillSerial(RangePosition fromRange, RangePosition toRange) { fromRange = this.FixRange(fromRange); toRange = this.FixRange(toRange); #region Arguments Check if (fromRange.IntersectWith(toRange)) { throw new ArgumentException("fromRange and toRange cannot being intersected."); } if (toRange != CheckMergedRange(toRange)) { throw new ArgumentException("cannot change a part of merged range."); } #endregion // Arguments Check List <CellPosition> fromCells, toCells; if (CheckRangeReadonly(toRange)) { throw new RangeContainsReadonlyCellsException(toRange); } if (fromRange.Col == toRange.Col && fromRange.Cols == toRange.Cols) { for (var c = toRange.Col; c <= toRange.EndCol; c++) { fromCells = GetColumnCellPositionsFromRange(fromRange, c); toCells = GetColumnCellPositionsFromRange(toRange, c); AutoFillSerialCells(fromCells, toCells); } } else if (fromRange.Row == toRange.Row && fromRange.Rows == toRange.Rows) { for (var r = toRange.Row; r <= toRange.EndRow; r++) { fromCells = GetRowCellPositionsFromRange(fromRange, r); toCells = GetRowCellPositionsFromRange(toRange, r); AutoFillSerialCells(fromCells, toCells); } } else { throw new InvalidOperationException("The fromRange and toRange must be having same number of rows or same number of columns."); } }
/// <summary> /// Auto fill specified serial in range. /// </summary> /// <param name="fromRange">Range to read filling rules.</param> /// <param name="toRange">Range to be filled.</param> public void AutoFillSerial(RangePosition fromRange, RangePosition toRange) { fromRange = this.FixRange(fromRange); toRange = this.FixRange(toRange); #region Arguments Check if (fromRange.IntersectWith(toRange)) { throw new ArgumentException("fromRange and toRange cannot being intersected."); } if (toRange != CheckMergedRange(toRange)) { throw new ArgumentException("cannot change a part of merged range."); } #endregion // Arguments Check if (fromRange.Col == toRange.Col && fromRange.Cols == toRange.Cols) { #region Vertical Fill for (int c = toRange.Col; c <= toRange.EndCol; c++) { double diff = 1; #region Calc diff if (fromRange.Rows > 1) { for (int r = fromRange.Row; r < fromRange.EndRow; r++) { double val1 = 0; if (!this.TryGetNumberData(r, c, out val1)) { break; } double val2; if (this.TryGetNumberData(r + 1, c, out val2)) { if (r == fromRange.Row) { diff = (val2 - val1); } else { diff = (diff + (val2 - val1)) / 2; } } } } #endregion // Calc diff #region Up to Down for (int toRow = toRange.Row, index = 0; toRow < toRange.EndRow + 1; index++) { Cell toCell = this.cells[toRow, c]; if (toCell != null && toCell.Rowspan < 0) { toRow++; continue; } CellPosition fromPos = new CellPosition(fromRange.Row + (index % fromRange.Rows), c); Cell fromCell = this.cells[fromPos.Row, fromPos.Col]; if (fromCell == null || fromCell.Rowspan <= 0) { this[toRow, c] = null; toRow++; continue; } if (fromCell != null && !string.IsNullOrEmpty(fromCell.InnerFormula)) { #region Fill Formula FormulaRefactor.Reuse(this, fromPos, new RangePosition(toRow, c, 1, 1)); #endregion // Fill Formula } else { #region Fill Number double refValue = 0; if (CellUtility.TryGetNumberData(fromCell.Data, out refValue)) { this[toRow, c] = refValue + diff * (toRow - fromPos.Row); } #endregion // Fill Number } toRow += Math.Max(fromCell.Rowspan, toCell == null ? 1 : toCell.Rowspan); } #endregion // Up to Down } #endregion // Vertical Fill } else if (fromRange.Row == toRange.Row && fromRange.Rows == toRange.Rows) { #region Horizontal Fill for (int r = toRange.Row; r <= toRange.EndRow; r++) { double diff = 1; #region Calc diff if (fromRange.Cols > 1) { for (int c = fromRange.Col; r < fromRange.EndCol; c++) { double val1 = 0; if (!this.TryGetNumberData(r, c, out val1)) { break; } double val2; if (this.TryGetNumberData(r, c + 1, out val2)) { if (c == fromRange.Col) { diff = (val2 - val1); } else { diff = (diff + (val2 - val1)) / 2; } } } } #endregion // Calc diff #region Left to Right for (int toCol = toRange.Col, index = 0; toCol < toRange.EndCol + 1; index++) { Cell toCell = this.cells[r, toCol]; if (toCell != null && toCell.Colspan < 0) { toCol++; continue; } CellPosition fromPos = new CellPosition(r, fromRange.Col + (index % fromRange.Cols)); Cell fromCell = this.cells[fromPos.Row, fromPos.Col]; if (fromCell == null || fromCell.Colspan <= 0) { this[r, toCol] = null; toCol++; continue; } if (fromCell != null && !string.IsNullOrEmpty(fromCell.InnerFormula)) { #region Fill Formula FormulaRefactor.Reuse(this, fromPos, new RangePosition(r, toCol, 1, 1)); #endregion // Fill Formula } else { #region Fill Number double refValue = 0; if (CellUtility.TryGetNumberData(fromCell.Data, out refValue)) { this[r, toCol] = refValue + diff * (toCol - fromPos.Col); } #endregion // Fill Number } toCol += Math.Max(fromCell.Colspan, toCell == null ? 1 : toCell.Colspan); } #endregion // Left to Right } #endregion // Vertical Fill } else { throw new InvalidOperationException("The fromRange and toRange must be having same number of rows or same number of columns."); } }