简体   繁体   中英

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

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;
        }

PS 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.

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.

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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM