How to “clean up” Microsoft.Office.Interop.Excel.W

2019-08-05 11:03发布

So I have a Microsoft.Office.Interop.Excel.Workbook object. It basically uses a template Excel file to construct itself. The Excel file contains a template column color for the results section, etc. and then the code basically just prints over those template columns, it doesn't actually customize the look of the file itself, only puts the data into it.

However, this is an issue because after it's done, our template accounts for the most POSSIBLE rows it can, but a lot of the times (most of the time), we use not even half of them.

What's the easiest way to remove all rows that DO NOT have cell data in them after the file has been created, working directly with the Microsoft.Office.Interop.Excel.Workbook object. We already have a "cleanup" method that runs after creation, but I want to add that logic to it. Here's our current cleanup:

private void CleanupExcel()
        {
            if (!_visible && _workbook != null)
            {
                _workbook.Close(false, Missing.Value, Missing.Value);
            }
            _workbook = null;
            _sheet = null;
            if (_excel != null)
            {
                System.Runtime.InteropServices.Marshal.ReleaseComObject(_excel);
                // WW, 5/26/09: not sure if a problem here, but it probably is since the code was taken from here
                // but in the indicator, Excel exists in the process even after the app is closed.  The code here seems to fix it.
                GC.Collect();
                GC.WaitForPendingFinalizers();
            }
            _excel = null;
        }

P.S. It's the first of two sheets in the document by the way. I also have access to the Microsoft.Office.Interop.Excel.Worksheet object if it's easier to do that way.

标签: c# .net excel
2条回答
兄弟一词,经得起流年.
2楼-- · 2019-08-05 11:59

Assuming that all the empty rows are at the bottom of the sheets, you should be able to select them as a range and then delete them all, something like this I think:

Excel.Range range = _sheet.get_Range("A501", "A60000");
Excel.Range row = range.EntireRow; 
rowDelete(Type.Missing);

If they're not at the bottom, maybe you could do a sort so that they all end up at the bottom and then use something similar to my code.

查看更多
成全新的幸福
3楼-- · 2019-08-05 12:05

Try the following. It basically goes through a range (which I've hard-coded to be A1:A10), checks which rows are empty, marks them for deletion, then sweeps though and deletes them.

        public void RemoveRows()
        {
            Excel.Range rng =  Application.get_Range("A1", "A10");
            List<int> rowsMarkedForDeletion = new List<int>();

            for(int i = 0; i < rng.Rows.Count; i++)
            {
                if(Application.WorksheetFunction.CountA(rng[i + 1].EntireRow) == 0)
                {
                    rowsMarkedForDeletion.Add(i + 1);
                }
            }

            for(int i = rowsMarkedForDeletion.Count - 1; i >= 0; i--)
            {                
                rng[rowsMarkedForDeletion[i]].EntireRow.Delete();
            }
        }

To give full credit, using COUNTA is a technique I learned from OzGrid.

查看更多
登录 后发表回答