要解决Excel是否处于.NET中的单元格编辑模式

问题描述 投票:2回答:5

我有一个用VB.NET编写的应用程序,可以通过互操作与Excel进行交互。我最终遇到了单元格编辑模式的已知问题(有关某些背景,请参阅MSDNstackoverflow)。

我一直在尝试将建议的代码转换为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

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

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

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

c# vb.net excel interop excel-interop
5个回答
3
投票

作为快速修复程序,我使用以下代码作为替代方法

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

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

附加的一点是,不需要引用Microsoft Office对象(Microsoft.Office.Core)库。


1
投票
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

1
投票

我们以前使用过Application.CommandBars["Worksheet Menu Bar"]方法,但是遇到了一个缺陷。在编辑模式下退出Excel时,编辑模式会取消,但该功能仍会返回true,因为在关闭过程中已禁用了菜单项。

我们改为使用以下解决方案:

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

0
投票

以下代码将检测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);

0
投票

帖子较旧,但不是旧问题。上面检测和退出的解决方案很好,但是我找到了另一个使Excel退出编辑模式的解决方案,不需要使用API​​查找窗口或使用Sendkeys单击单元格,我的解决方案使用事件。 Excel甚至可以处于编辑模式并最小化,此解决方案仍然可以使用。如果您正在阅读本文,则可能不需要确切的代码,但如果需要,请告诉我。首先使用类似于先前解决方案的try catch检测Excel编辑模式,如果Excel处于编辑模式,则将全局标志设置为True。然后告诉Excel关闭。即使在编辑模式下,此操作也将可用。在Excel OnClosing事件中,检查是否设置了全局标志,如果已设置,则将“关闭时”事件“ e.Cancel”设置为True,这将停止Excel关闭。将您的全局标志设置回False,当Excel返回时,它将退出编辑模式,并且写入到已编辑单元格中的所有内容仍然存在。

© www.soinside.com 2019 - 2024. All rights reserved.