C# 如何在Excel互操作中强制单元格停止编辑?

C# 如何在Excel互操作中强制单元格停止编辑?,c#,.net,excel-interop,C#,.net,Excel Interop,我有一个带功能区的Excel 2007外接程序。功能区中的一个按钮会触发当前工作表的大量操作,出于速度和用户体验的原因,我在操作过程中将各种Excel.Application属性(如Interactive和EnableEvents)设置为false 我的问题是功能区不会窃取焦点,因此如果用户在单击“我的功能区”按钮时正在编辑单元格,则在设置Application.Interactive=false时会引发异常,因为Excel认为用户仍在编辑单元格 有没有办法通过保存或放弃对单元格所做的更改来停止

我有一个带功能区的Excel 2007外接程序。功能区中的一个按钮会触发当前工作表的大量操作,出于速度和用户体验的原因,我在操作过程中将各种Excel.Application属性(如Interactive和EnableEvents)设置为false

我的问题是功能区不会窃取焦点,因此如果用户在单击“我的功能区”按钮时正在编辑单元格,则在设置Application.Interactive=false时会引发异常,因为Excel认为用户仍在编辑单元格

有没有办法通过保存或放弃对单元格所做的更改来停止编辑

似乎Range.DiscardChanges可能会解决我的问题,但它在2007 API中不可用

编辑:似乎Range.DiscardChanges是针对基于OLAP数据源的范围的,所以它无论如何都不会解决我的问题


编辑:我已尝试呼叫范围。在另一个手机上激活。虽然我确实看到GUI中的单元格焦点发生了变化,但仍然会引发异常。范围。选择不起任何作用。

如果选择其他单元格或所有单元格,错误是否消失

私有函数 { xlSheet.Cells.Select; //剩下的工作 }

因此,在环顾四周几天并询问MSDN之后,最终的答案是API中根本没有这方面的内容,如果不使用黑客解决方案,这是不可能的1

Excel本身处理这类事情的方式只是在用户编辑时将其菜单灰显,因此我这样做是为了与宿主应用程序保持一致


1:Hacky,因为使用SendKeys等技术需要返回GUI以确保操作得到处理,然后调用要求单元格不在编辑中的方法。这在一个地方是可以的,但对Excel互操作的每个方法调用都这样做是疯狂的。

您不能停止编辑,但可以检查编辑是否已启用,然后告诉用户停止编辑:

private bool IsEditing(Microsoft.Office.Interop.Excel.Application excelApp)
{
    if (excelApp.Interactive)
    {
        try
        {
            excelApp.Interactive = false;
            excelApp.Interactive = true;
        }
        catch (Exception)
        {
            MessageBox.Show("Please stop cell editing before you continue.");
            return true;
        }
    }
    return false;
}
我在本页找到了答案,并将其从VBA更改为C:
现在回答这个问题可能太晚了。但是认为有人在寻找解决方案时使用了这个技巧

由于某些原因,sendkeys和Cells/Range activate命令无法运行

解决此问题的唯一方法是将焦点更改为另一个工作表,然后返回到当前工作表以欺骗excel:-

ExcelUtil.ActivateWorksheet("Sheet1");
currentWorksheet.Activate();

public static void ActivateWorksheet(string strWorksheetName)
    {
        bool found = false;

        foreach (Excel.Worksheet sheet in Globals.ThisAddIn.Application.Worksheets)
        {
            if (sheet.Name.ToLower() == strWorksheetName.ToLower())
            {
                found = true;
                break;
            }
        }

        if (!found)
            Globals.ThisAddIn.AddNewWorksheet(strWorksheetName);

        ((Excel.Worksheet)Globals.ThisAddIn.Application.Worksheets[strWorksheetName]).Activate();
    }
希望这有帮助


Ram

我检测到问题,并显示一条消息告诉用户: 如果是excelHelper.ExcelIsEditing,则 System.Media.SystemSounds.Beep.Play msgbox请完成对工作表的编辑vbCrLf&vbCrLf&将光标移出当前单元格,然后重试按钮。 退出功能 如果结束

作为布尔函数进行优化编辑 卓越编辑=错误

  If ExcelApp.Interactive = False Then Return False
  Try
     ExcelApp.Interactive = False
     ExcelApp.Interactive = True
  Catch
     Return True
  End Try
端函数


这是我能想到的最好的解决方案:

在这个链接的底部附近有一个解决方案,它可以帮助@kevchadders。这个解决方案使用Excel中的第三方脚本库,我想要一个.NET解决方案。虽然看起来这一切都归结为发送和ESC,但对于我来说,Application.SendKeys不起作用。我觉得功能区在那个时间点上有焦点,ESC不会影响编辑中的单元格。事实上,SendKeys不起作用的原因是ESC只有在执行完成并且GUI控制时才生效。它不起作用。Activate看起来更有希望,但仍然会引发异常。我已经在问题中添加了这些信息。一个丑陋的方法是Application.SendKeys{ESC}。这将发送到应用程序转义密钥,该密钥将丢弃更改。但我不认为这是一个可靠的解决方案。是的,我已经尝试过了,但它没有像问题评论中提到的那样工作。除非单元格正在被积极编辑,否则应用程序不会响应任何方法调用。这需要通过try/except来处理。