示例#1
0
 private static void ValidateInsert(ExcelRangeBase range, eShiftTypeInsert shift)
 {
     if (range == null || (range.Addresses != null && range.Addresses.Count > 1))
     {
         throw new ArgumentException("Can't insert into range. ´range´ can't be null or have multiple addresses.", "range");
     }
 }
示例#2
0
        private static List <int> GetStylesForRange(ExcelRangeBase range, eShiftTypeInsert shift)
        {
            var list = new List <int>();

            if (shift == eShiftTypeInsert.Down)
            {
                for (int i = 0; i < range.Columns; i++)
                {
                    if (range._fromRow == 1)
                    {
                        list.Add(0);
                    }
                    else
                    {
                        list.Add(range.Offset(-1, i).StyleID);
                    }
                }
            }
            else
            {
                for (int i = 0; i < range.Rows; i++)
                {
                    if (range._fromCol == 1)
                    {
                        list.Add(0);
                    }
                    else
                    {
                        list.Add(range.Offset(i, -1).StyleID);
                    }
                }
            }
            return(list);
        }
示例#3
0
        internal static void Insert(ExcelRangeBase range, eShiftTypeInsert shift, bool styleCopy)
        {
            ValidateInsert(range, shift);

            var effectedAddress = GetEffectedRange(range, shift);

            WorksheetRangeHelper.ValidateIfInsertDeleteIsPossible(range, effectedAddress, GetEffectedRange(range, shift, 1), true);

            var ws = range.Worksheet;

            lock (ws)
            {
                var styleList = GetStylesForRange(range, shift);
                WorksheetRangeHelper.ConvertEffectedSharedFormulasToCellFormulas(ws, effectedAddress);

                if (shift == eShiftTypeInsert.Down)
                {
                    InsertCellStores(range._worksheet, range._fromRow, range._fromCol, range.Rows, range.Columns, range._toCol);
                }
                else
                {
                    InsertCellStoreShiftRight(range._worksheet, range);
                }
                AdjustFormulasInsert(range, effectedAddress, shift);
                InsertFilterAddress(range, effectedAddress, shift);
                WorksheetRangeHelper.FixMergedCells(ws, range, shift);

                if (styleCopy)
                {
                    SetStylesForRange(range, shift, styleList);
                }

                InsertTableAddress(ws, range, shift, effectedAddress);
                InsertPivottableAddress(ws, range, shift, effectedAddress);

                //Update data validation references
                foreach (var dv in ws.DataValidations)
                {
                    ((ExcelDataValidation)dv).SetAddress(InsertSplitAddress(dv.Address, range, effectedAddress, shift).Address);
                }

                //Update Conditional formatting references
                foreach (var cf in ws.ConditionalFormatting)
                {
                    ((ExcelConditionalFormattingRule)cf).Address = new ExcelAddress(InsertSplitAddress(cf.Address, range, effectedAddress, shift).Address);
                }

                InsertSparkLinesAddress(range, shift, effectedAddress);

                if (shift == eShiftTypeInsert.Down)
                {
                    WorksheetRangeHelper.AdjustDrawingsRow(ws, range._fromRow, range.Rows, range._fromCol, range._toCol);
                }
                else
                {
                    WorksheetRangeHelper.AdjustDrawingsColumn(ws, range._fromCol, range.Columns, range._fromRow, range._toRow);
                }
            }
        }
 private static void InsertDataValidation(ExcelRangeBase range, eShiftTypeInsert shift, ExcelAddressBase effectedAddress, ExcelWorksheet ws)
 {
     //Update data validation references
     foreach (var dv in ws.DataValidations)
     {
         ((ExcelDataValidation)dv).SetAddress(InsertSplitAddress(dv.Address, range, effectedAddress, shift).Address);
     }
 }
 private static void InsertConditionalFormatting(ExcelRangeBase range, eShiftTypeInsert shift, ExcelAddressBase effectedAddress, ExcelWorksheet ws)
 {
     //Update Conditional formatting references
     foreach (var cf in ws.ConditionalFormatting)
     {
         ((ExcelConditionalFormattingRule)cf).Address = new ExcelAddress(InsertSplitAddress(cf.Address, range, effectedAddress, shift).Address);
     }
 }
示例#6
0
 internal static void FixMergedCells(ExcelWorksheet ws, ExcelRangeBase range, eShiftTypeInsert shift)
 {
     if (shift == eShiftTypeInsert.Down)
     {
         FixMergedCellsRow(ws, range._fromRow, range.Rows, false, range._fromCol, range._toCol);
     }
     else
     {
         FixMergedCellsColumn(ws, range._fromCol, range.Columns, false, range._fromRow, range._toRow);
     }
 }
        internal static void Insert(ExcelRangeBase range, eShiftTypeInsert shift, bool styleCopy)
        {
            ValidateInsert(range, shift);

            var effectedAddress = GetEffectedRange(range, shift);

            WorksheetRangeHelper.ValidateIfInsertDeleteIsPossible(range, effectedAddress, GetEffectedRange(range, shift, 1), true);

            var ws = range.Worksheet;

            lock (ws)
            {
                var styleList = GetStylesForRange(range, shift);
                WorksheetRangeHelper.ConvertEffectedSharedFormulasToCellFormulas(ws, effectedAddress);

                if (shift == eShiftTypeInsert.Down)
                {
                    InsertCellStores(range._worksheet, range._fromRow, range._fromCol, range.Rows, range.Columns, range._toCol);
                }
                else
                {
                    InsertCellStoreShiftRight(range._worksheet, range);
                }
                AdjustFormulasInsert(range, effectedAddress, shift);
                InsertFilterAddress(range, effectedAddress, shift);
                WorksheetRangeHelper.FixMergedCells(ws, range, shift);

                if (styleCopy)
                {
                    SetStylesForRange(range, shift, styleList);
                }

                InsertTableAddress(ws, range, shift, effectedAddress);
                InsertPivottableAddress(ws, range, shift, effectedAddress);

                InsertDataValidation(range, shift, effectedAddress, ws);
                InsertConditionalFormatting(range, shift, effectedAddress, ws);

                InsertSparkLinesAddress(range, shift, effectedAddress);

                if (shift == eShiftTypeInsert.Down)
                {
                    WorksheetRangeHelper.AdjustDrawingsRow(ws, range._fromRow, range.Rows, range._fromCol, range._toCol);
                }
                else
                {
                    WorksheetRangeHelper.AdjustDrawingsColumn(ws, range._fromCol, range.Columns, range._fromRow, range._toRow);
                }
            }
        }
示例#8
0
        private static void InsertSparkLinesAddress(ExcelRangeBase range, eShiftTypeInsert shift, ExcelAddressBase effectedAddress)
        {
            foreach (var slg in range.Worksheet.SparklineGroups)
            {
                if (slg.DateAxisRange != null && effectedAddress.Collide(slg.DateAxisRange) >= ExcelAddressBase.eAddressCollition.Inside)
                {
                    string address;
                    if (shift == eShiftTypeInsert.Down)
                    {
                        address = slg.DateAxisRange.AddRow(range._fromRow, range.Rows).Address;
                    }
                    else
                    {
                        address = slg.DateAxisRange.AddColumn(range._fromCol, range.Columns).Address;
                    }
                    slg.DateAxisRange = range.Worksheet.Cells[address];
                }

                foreach (var sl in slg.Sparklines)
                {
                    if (shift == eShiftTypeInsert.Down)
                    {
                        if (effectedAddress.Collide(sl.RangeAddress) >= ExcelAddressBase.eAddressCollition.Inside ||
                            range.CollideFullRow(sl.RangeAddress._fromRow, sl.RangeAddress._toRow))
                        {
                            sl.RangeAddress = sl.RangeAddress.AddRow(range._fromRow, range.Rows);
                        }

                        if (sl.Cell.Row >= range._fromRow && sl.Cell.Column >= range._fromCol && sl.Cell.Column <= range._toCol)
                        {
                            sl.Cell = new ExcelCellAddress(sl.Cell.Row + range.Rows, sl.Cell.Column);
                        }
                    }
                    else
                    {
                        if (effectedAddress.Collide(sl.RangeAddress) >= ExcelAddressBase.eAddressCollition.Inside ||
                            range.CollideFullColumn(sl.RangeAddress._fromCol, sl.RangeAddress._toCol))
                        {
                            sl.RangeAddress = sl.RangeAddress.AddColumn(range._fromCol, range.Columns);
                        }

                        if (sl.Cell.Column >= range._fromCol && sl.Cell.Row >= range._fromRow && sl.Cell.Row <= range._toRow)
                        {
                            sl.Cell = new ExcelCellAddress(sl.Cell.Row, sl.Cell.Column + range.Columns);
                        }
                    }
                }
            }
        }
示例#9
0
 private static void SetStylesForRange(ExcelRangeBase range, eShiftTypeInsert shift, List <int> list)
 {
     if (shift == eShiftTypeInsert.Down)
     {
         for (int i = 0; i < range.Columns; i++)
         {
             range.Offset(0, i, range.Rows, 1).StyleID = list[i];
         }
     }
     else
     {
         for (int i = 0; i < range.Rows; i++)
         {
             range.Offset(i, 0, 1, range.Columns).StyleID = list[i];
         }
     }
 }
示例#10
0
 private static ExcelAddressBase GetEffectedRange(ExcelRangeBase range, eShiftTypeInsert shift, int?start = null)
 {
     if (shift == eShiftTypeInsert.Down)
     {
         return(new ExcelAddressBase(start ?? range._fromRow, range._fromCol, ExcelPackage.MaxRows, range._toCol));
     }
     else if (shift == eShiftTypeInsert.Right)
     {
         return(new ExcelAddressBase(range._fromRow, start ?? range._fromCol, range._toRow, ExcelPackage.MaxColumns));
     }
     else if (shift == eShiftTypeInsert.EntireColumn)
     {
         return(new ExcelAddressBase(1, range._fromCol, ExcelPackage.MaxRows, ExcelPackage.MaxColumns));
     }
     else
     {
         return(new ExcelAddressBase(range._fromRow, 1, ExcelPackage.MaxRows, ExcelPackage.MaxColumns));
     }
 }
示例#11
0
 private static void InsertTableAddress(ExcelWorksheet ws, ExcelRangeBase range, eShiftTypeInsert shift, ExcelAddressBase effectedAddress)
 {
     foreach (var tbl in ws.Tables)
     {
         if (shift == eShiftTypeInsert.Down)
         {
             if (tbl.Address._fromCol >= range._fromCol && tbl.Address._toCol <= range._toCol)
             {
                 tbl.Address = tbl.Address.AddRow(range._fromRow, range.Rows);
             }
         }
         else
         {
             if (tbl.Address._fromRow >= range._fromRow && tbl.Address._toRow <= range._toRow)
             {
                 tbl.Address = tbl.Address.AddColumn(range._fromCol, range.Columns);
             }
         }
     }
 }
示例#12
0
        private static void InsertPivottableAddress(ExcelWorksheet ws, ExcelRangeBase range, eShiftTypeInsert shift, ExcelAddressBase effectedAddress)
        {
            foreach (var ptbl in ws.PivotTables)
            {
                if (shift == eShiftTypeInsert.Down)
                {
                    if (ptbl.Address._fromCol >= range._fromCol && ptbl.Address._toCol <= range._toCol)
                    {
                        ptbl.Address = ptbl.Address.AddRow(range._fromRow, range.Rows);
                    }
                }
                else
                {
                    if (ptbl.Address._fromRow >= range._fromRow && ptbl.Address._toRow <= range._toRow)
                    {
                        ptbl.Address = ptbl.Address.AddColumn(range._fromCol, range.Columns);
                    }
                }

                if (ptbl.CacheDefinition.SourceRange.Worksheet == ws)
                {
                    var address = ptbl.CacheDefinition.SourceRange;
                    if (shift == eShiftTypeInsert.Down)
                    {
                        if (address._fromCol >= range._fromCol && address._toCol <= range._toCol)
                        {
                            ptbl.CacheDefinition.SourceRange = ws.Cells[address.AddRow(range._fromRow, range.Rows).Address];
                        }
                    }
                    else
                    {
                        if (address._fromRow >= range._fromRow && address._toRow <= range._toRow)
                        {
                            ptbl.CacheDefinition.SourceRange = ws.Cells[address.AddColumn(range._fromCol, range.Columns).Address];
                        }
                    }
                }
            }
        }
示例#13
0
 private static ExcelAddressBase ShiftAddress(ExcelAddressBase address, ExcelAddressBase range, eShiftTypeInsert shift)
 {
     if (shift == eShiftTypeInsert.Down)
     {
         return(address.AddRow(range._fromRow, range.Rows));
     }
     else
     {
         return(address.AddColumn(range._fromCol, range.Columns));
     }
 }
示例#14
0
        private static ExcelAddressBase InsertSplitAddress(ExcelAddressBase address, ExcelAddressBase range, ExcelAddressBase effectedAddress, eShiftTypeInsert shift)
        {
            var collide = effectedAddress.Collide(address);

            if (collide == ExcelAddressBase.eAddressCollition.Partly)
            {
                var addressToShift = effectedAddress.Intersect(address);
                var shiftedAddress = ShiftAddress(addressToShift, range, shift);
                var newAddress     = "";
                if (address._fromRow < addressToShift._fromRow)
                {
                    newAddress = ExcelCellBase.GetAddress(address._fromRow, address._fromCol, addressToShift._fromRow - 1, address._toCol) + ",";
                }
                if (address._fromCol < addressToShift._fromCol)
                {
                    var fromRow = Math.Max(address._fromRow, addressToShift._fromRow);
                    newAddress += ExcelCellBase.GetAddress(fromRow, address._fromCol, address._toRow, addressToShift._fromCol - 1) + ",";
                }

                newAddress += $"{shiftedAddress},";

                if (address._toRow > addressToShift._toRow)
                {
                    newAddress += ExcelCellBase.GetAddress(addressToShift._toRow + 1, address._fromCol, address._toRow, address._toCol) + ",";
                }
                if (address._toCol > addressToShift._toCol)
                {
                    newAddress += ExcelCellBase.GetAddress(address._fromRow, addressToShift._toCol + 1, address._toRow, address._toCol) + ",";
                }
                return(new ExcelAddressBase(newAddress.Substring(0, newAddress.Length - 1)));
            }
            else if (collide != ExcelAddressBase.eAddressCollition.No)
            {
                return(ShiftAddress(address, range, shift));
            }
            return(address);
        }
示例#15
0
        private static void InsertFilterAddress(ExcelRangeBase range, ExcelAddressBase effectedAddress, eShiftTypeInsert shift)
        {
            var ws = range.Worksheet;

            if (ws.AutoFilterAddress != null && effectedAddress.Collide(ws.AutoFilterAddress) != ExcelAddressBase.eAddressCollition.No)
            {
                if (shift == eShiftTypeInsert.Down)
                {
                    ws.AutoFilterAddress = ws.AutoFilterAddress.AddRow(range._fromRow, range.Rows);
                }
                else
                {
                    ws.AutoFilterAddress = ws.AutoFilterAddress.AddColumn(range._fromCol, range.Columns);
                }
            }
        }
 private static ExcelAddressBase InsertSplitAddress(ExcelAddressBase address, ExcelAddressBase range, ExcelAddressBase effectedAddress, eShiftTypeInsert shift)
 {
     if (address.Addresses == null)
     {
         return(InsertSplitIndividualAddress(address, range, effectedAddress, shift));
     }
     else
     {
         var newAddress = "";
         foreach (var a in address.Addresses)
         {
             newAddress += InsertSplitIndividualAddress(a, range, effectedAddress, shift) + ",";
         }
         return(new ExcelAddressBase(newAddress.Substring(0, newAddress.Length - 1)));
     }
 }
示例#17
0
        private static void AdjustFormulasInsert(ExcelRangeBase range, ExcelAddressBase effectedAddress, eShiftTypeInsert shift)
        {
            //Adjust formulas
            foreach (var ws in range._workbook.Worksheets)
            {
                var workSheetName = range.Worksheet.Name;
                var rowFrom       = range._fromRow;
                var columnFrom    = range._fromCol;
                var rows          = range.Rows;

                foreach (var f in ws._sharedFormulas.Values)
                {
                    if (workSheetName == ws.Name)
                    {
                        var a = new ExcelAddressBase(f.Address);
                        var c = effectedAddress.Collide(a);
                        if (c == ExcelAddressBase.eAddressCollition.Partly)
                        {
                            throw new Exception("Invalid shared formula"); //This should never happend!
                        }
                        if (f.StartCol >= columnFrom && c != ExcelAddressBase.eAddressCollition.No)
                        {
                            if (f.StartRow >= rowFrom)
                            {
                                f.StartRow += rows;
                            }
                            if (a._fromRow >= rowFrom)
                            {
                                a._fromRow += rows;
                                a._toRow   += rows;
                            }
                            else if (a._toRow >= rowFrom)
                            {
                                a._toRow += rows;
                            }
                            f.Address = ExcelCellBase.GetAddress(a._fromRow, a._fromCol, a._toRow, a._toCol);
                            f.Formula = ExcelCellBase.UpdateFormulaReferences(f.Formula, range, effectedAddress, shift, ws.Name, workSheetName);
                        }
                    }
                    else if (f.Formula.Contains(workSheetName))
                    {
                        f.Formula = ExcelCellBase.UpdateFormulaReferences(f.Formula, range, effectedAddress, shift, ws.Name, workSheetName);
                    }
                }

                var cse = new CellStoreEnumerator <object>(ws._formulas);
                while (cse.Next())
                {
                    if (cse.Value is string v)
                    {
                        if (workSheetName == ws.Name)
                        {
                            cse.Value = ExcelCellBase.UpdateFormulaReferences(v, range, effectedAddress, shift, ws.Name, workSheetName);
                        }
                        else if (v.Contains(workSheetName))
                        {
                            cse.Value = ExcelCellBase.UpdateFormulaReferences(v, range, effectedAddress, shift, ws.Name, workSheetName);
                        }
                    }
                }
            }
        }
示例#18
0
        /// <summary>
        /// Updates the Excel formula so that all the cellAddresses are incremented by the row and column increments
        /// if they fall after the afterRow and afterColumn.
        /// Supports inserting rows and columns into existing templates.
        /// </summary>
        /// <param name="formula">The Excel formula</param>
        /// <param name="range">The range that is inserted</param>
        /// <param name="effectedRange">The range effected by the insert</param>
        /// <param name="shift">Shift operation</param>
        /// <param name="currentSheet">The sheet that contains the formula currently being processed.</param>
        /// <param name="modifiedSheet">The sheet where cells are being inserted or deleted.</param>
        /// <param name="setFixed">Fixed address</param>
        /// <returns>The updated version of the <paramref name="formula"/>.</returns>
        internal static string UpdateFormulaReferences(string formula, ExcelAddressBase range, ExcelAddressBase effectedRange, eShiftTypeInsert shift, string currentSheet, string modifiedSheet, bool setFixed = false)
        {
            int rowIncrement;
            int colIncrement;

            if (shift == eShiftTypeInsert.Down || shift == eShiftTypeInsert.EntireRow)
            {
                rowIncrement = range.Rows;
                colIncrement = 0;
            }
            else
            {
                colIncrement = range.Columns;
                rowIncrement = 0;
            }

            return(UpdateFormulaReferncesPrivate(formula, range, effectedRange, currentSheet, modifiedSheet, setFixed, rowIncrement, colIncrement));
        }