Обходной путь, чтобы видеть, находится ли Excel в режиме редактирования ячейки в .NET - PullRequest
2 голосов
/ 21 января 2009

У меня есть приложение, написанное на VB.NET, которое взаимодействует с Excel через взаимодействие. В конце концов я столкнулся с известной проблемой режима редактирования ячеек (см. MSDN и stackoverflow для получения дополнительной информации).

Я пытался преобразовать предложенный код в 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 и повторно добавлять ссылки, но не могу понять, в чем проблема. есть идеи?

Ответы [ 4 ]

3 голосов
/ 21 января 2009

В качестве быстрого и грязного исправления я использовал следующий код в качестве альтернативы

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 голос
/ 25 апреля 2013

Ранее мы использовали метод 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;
}
1 голос
/ 02 сентября 2012
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
0 голосов
/ 07 августа 2014

Следующий код определит, находится ли 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);
...