Excel C#interop工作表删除

时间:2017-01-06 15:13:55

标签: c# excel interop

我有一个使用Excel COM互操作的应用程序。它将模板XLS复制到现有文档,将Delete old替换为同名的选项卡,然后从模板复制新文件。

当我的应用尝试删除工作表时,我收到800A03ec异常。

此问题出现在已运行多年的代码中,但现在在升级到Office 2016后失败。

我发现如果我设置app.Visible = true,操作就会正常完成!但我不希望Excel可见。

如果app.Visible = false,我从第一个工作表Delete()中得不到错误,但第二个工作表发生异常。

最后一个标签的第一次删除似乎没问题,但是'表格'工作表对象的数组并没有像我预期的那样减少。但是,数组中相应的Sheet项变为" null"工作表。

第二次删除它之前的选项卡会在删除时抛出异常。

我已经彻底确保了:

  • 没有COM引用泄漏
  • 除了要删除的工作表及其父应用程序等对象
  • 之外,每次删除前都会丢弃所有COM引用
  • DisplayAlerts为false
  • 工作表简单而普通,没有任何隐藏等。

为什么当应用程序可见时它会起作用,但是当隐藏应用程序时它不起作用?

更新:代码片段

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

和ExcelUtility.ReleaseAll()调用Marshal.ReleaseComObject(),然后调用GC.Collect()和GC.WaitForPendingFinalizers()。

目标工作表有8个标签。删除最后一个选项卡,然后复制,无例外。然后在选项卡7上,删除仅在隐藏应用程序时抛出异常。在较旧的Office上正常工作。

复制代码是

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

初始化代码

        _app = new Excel.Application();
        _app.DisplayAlerts = false;
        _app.Visible = false;

1 个答案:

答案 0 :(得分:0)

我进一步补充说:

//
// Super important to activate a tab other than what needs to be deleted.
// Cast is required because an event and method have the same name "Activate".
//

((Excel._Worksheet)_weeklyDataSheet).Activate();

然后,这让我找到了我的应用程序的保存功能的一些代码,这些功能曾经起作用,但却抛出异常:

_weeklyDataSheet.Select(Type.Missing);

我也将其更改为Activate()并取得了更多进展。但是这次Excel仍然在第三个工作簿上删除了Delete()。

我被迫在本周的报告中运行app Visible。但是,即使是大约80个工作簿,然后Excel锁定,鼠标光标在箭头和等待计时器动画之间快速闪烁,我的应用程序最终得到RPC错误。

结论:Office 2016的ABANDON COM APIS。微软似乎不再适当地支持它们了。