I have an app using Excel COM interop. It copies a template XLS to an existing doc, replacing same-named tabs by Delete old then Copy new from template.
I am getting 800A03ec exception when my app tries to delete a worksheet.
This problem is in code that has been working for years but now fails after an upgrade to Office 2016.
I find that if I set app.Visible = true, the operation completes properly! But I do not want Excel visible.
If app.Visible = false, I do not get an error from the first worksheet Delete(), but exception occurs on the second.
The first delete of the last tab seems to go OK, but 'Sheets' array of the worksheets object doesn't decrease as I would expect. However the corresponding Sheet item in the array becomes a "null" worksheet.
The second delete, of the tab before it, throws an exception on delete.
I have thoroughly ensured:
- No COM reference leaks
- All COM references are discarded before each delete, except for the worksheet to be deleted and its parent app, etc. objects
- DisplayAlerts is false
- Worksheets are simple and ordinary, nothing hidden etc.
Why would it work when app is visible, but not work when app is hidden??
UPDATE: code fragment
int _DeleteTargetTab(string tabName)
{
List<object> comRefs = new List<object>();
int prevTabIndex;
int tabToDelete = _FindTargetTemplateIndex(tabName, out prevTabIndex);
if (tabToDelete > 0)
{
try
{
Excel.Sheets targetSheets = _workbook.Sheets;
comRefs.Add(targetSheets);
Excel.Worksheet targetWorksheet = targetSheets[tabToDelete];
comRefs.Add(targetWorksheet);
targetWorksheet.Delete();
}
finally
{
ExcelUtility.ReleaseAll(comRefs);
}
}
return prevTabIndex;
}
and ExcelUtility.ReleaseAll() calls Marshal.ReleaseComObject(), then GC.Collect() and GC.WaitForPendingFinalizers().
Target worksheet has 8 tabs. Last tab is deleted, then copied, without exception. Then on tab 7 delete throws an exception, only when app is hidden. Works fine on older Office.
Copy code is
void _CopyTemplateTabToTarget(Excel.Worksheet templateWorksheet, int prevTargetTabIndex)
{
List<object> comRefs = new List<object>();
try
{
Excel.Sheets targetSheets = _workbook.Sheets;
comRefs.Add(targetSheets);
Excel.Worksheet prevSheet = targetSheets[prevTargetTabIndex];
comRefs.Add(prevSheet);
templateWorksheet.Copy(Type.Missing, prevSheet);
}
finally
{
ExcelUtility.ReleaseAll(comRefs);
}
}
Init code is
_app = new Excel.Application();
_app.DisplayAlerts = false;
_app.Visible = false;