在.NET中查看Excel是否处于单元格编辑模式

我有一个用VB.NET编写的应用程序,通过互操作与Excel交互。 我最终遇到了单元格编辑模式的已知问题(请参阅MSDN和一些背景的计算器)。

我一直在尝试将build议的代码转换为VB.NET,但不断收到以下错误:

Reference required to assembly 'office, Version=11.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c' containing the type 'Microsoft.Office.Core.CommandBars'. Add one to your project. (BC30652) - E:\ ... .vb:3471 

原来的C#代码(从前面提到的文章)如下

 private bool IsEditMode() { object m = Type.Missing; const int MENU_ITEM_TYPE = 1; const int NEW_MENU = 18; // Get the "New" menu item. CommandBarControl oNewMenu = Application.CommandBars["Worksheet Menu Bar"].FindControl(MENU_ITEM_TYPE, NEW_MENU, m, m, true ); if ( oNewMenu != null ) { // Check if "New" menu item is enabled or not. if ( !oNewMenu.Enabled ) { return true; } } return false; } 

我转换的VB.NET代码如下

 Private Function isEditMode() As Boolean isEditMode = False Dim m As Object = Type.Missing Const MENU_ITEM_TYPE As Integer = 1 Const NEW_MENU As Integer = 18 Dim oNewMenu As Office.CommandBarControl ' oExcel is the Excel Application object ' the error is related to the below line oNewMenu = oExcel.CommandBars("Worksheet Menu Bar").FindControl(MENU_ITEM_TYPE, NEW_MENU, m, m, True) If oNewMenu IsNot Nothing Then If Not oNewMenu.Enabled Then isEditMode = True End If End If End Function 

我已经添加(COM)引用到Microsoft Office对象库

 Imports Office = Microsoft.Office.Core Imports Microsoft.Office.Interop 

我有点卡住了。 我已经尝试间接引用CommandBar对象,并重新添加refrences,但无法弄清楚是什么问题。 有任何想法吗?

作为一个快速和肮脏的修复我使用下面的代码作为替代

 Private Function isEditMode() As Boolean isEditMode = False Try oExcel.GoTo("###") Catch Ex As Exception ' Either returns "Reference is not valid." ' or "Exception from HRESULT: 0x800A03EC" If ex.Message.StartsWith("Exception") then isEditMode = True End Try End Function 

当Excel处于单元格编辑模式时,.GoTo函数(和相应的菜单项)不可用。 赋予.GoTo函数一个虚拟目标将不会做任何事情,并且不会影响任何如果用户在代码运行时在单元格中工作。

另外额外的是,不需要引用Microsoft Office Object(Microsoft.Office.Core)库。

 Function ExcelIsBusy() ExcelIsBusy = Not Application.Ready Dim m m = Empty Const MENU_ITEM_TYPE = 1 Const NEW_MENU = 18 Dim oNewMenu Set oNewMenu = Application.CommandBars("Worksheet Menu Bar").FindControl(MENU_ITEM_TYPE, NEW_MENU, m, m, True) If Not (oNewMenu Is Nothing) Then If Not oNewMenu.Enabled Then ExcelIsBusy = True 'throw new Exception("Excel is in Edit Mode") End If End If End Function 

我们以前使用Application.CommandBars["Worksheet Menu Bar"]方法,但我们遇到了一个缺陷。 在编辑模式下退出Excel时,编辑模式将取消,但函数仍然返回true,因为菜单项已在closures期间被禁用。

我们使用了以下解决scheme:

 public static bool ApplicationIsInEditMode(Application application) { try { application.ReferenceStyle = application.ReferenceStyle; } catch (COMException e) { return true; } return false; } 

以下代码将检测excel是否处于编辑模式,并将退出:

 private void exitEditMode() { if (!isExcelInteractive()) { // get the current range Excel.Range r = Globals.ThisAddIn.Application.ActiveCell; // bring Excel to the foreground, with focus // and issue keys to exit the cell xlBringToFront(); Globals.ThisAddIn.Application.ActiveWindow.Activate(); SendKeys.Flush(); SendKeys.SendWait("{ENTER}"); // now make sure the original cell is // selected… r.Select(); } } private bool isExcelInteractive() { try { // this line does nothing if Excel is not // in edit mode. However, trying to set // this property while Excel is in edit // cell mdoe will cause an exception Globals.ThisAddIn.Application.Interactive = Globals.ThisAddIn.Application.Interactive; return true; // no exception, ecel is // interactive } catch { return false; // in edit mode } } private void xlBringToFront() { SetForegroundWindow(Globals.ThisAddIn.Application.Hwnd); } [DllImport("User32.dll")] public static extern Int32 SetForegroundWindow(int hWnd);