2013-07-11 3 views
2

Я работаю над Excel Addin с помощью C#, Visual Studio 2012. Я пытаюсь получить экземпляр объекта приложения Excel, чтобы отслеживать текущую рабочую книгу и рабочий лист (ActiveWorkbook, ActiveWorksheet).Ошибка C# .NET при запуске экземпляра приложения Office

Я вижу, что большинство других связанных с этим вопросов на SO есть ответы предполагая использовать следующее:

(Excel.Application)Marshal.GetActiveObject("Excel.Application"); 

Я также попытался использовать это:

(Excel.Application)Globals.ThisAddIn.Application; 

В обоих случаях я получаю NullReferenceException , После рассмотрения обходного пути, предложенного здесь: http://support.microsoft.com/kb/316125/en-us, я попробовал следующее, чтобы проверить оба метода.

public CurrentSpreadSheet() 
    { 
     try 
     { 
      this.CurrentApplication = (Excel.Application)Globals.ThisAddIn.Application; 

     } 
     catch (NullReferenceException) 
     { 
      MessageBox.Show("Excel application object not registered. Trying plan B.."); 

      //Getting Excel's application object instance 
      int iSection = 0, iTries = 0; 

     tryAgain: 
      try 
      { 
       iSection = 1; //Attempting GetActiveObject 
       this.CurrentApplication = (Excel.Application)Marshal.GetActiveObject("Excel.Application"); 
       iSection = 0; //GetActiveObject succeeded so resume or go for normal error handling if needed 
       this.CurrentApplication.Visible = true; 
      } 
      catch (Exception err) 
      { 
       System.Console.WriteLine("Visual C# .NET Error Attaching to Running Instance of Office Application .. yet."); 
       if (iSection == 1) 
       { 
        //GetObject may have failed because the 
        //Shell function is asynchronous; enough time has not elapsed 
        //for GetObject to find the running Office application. Wait 
        //1/2 seconds and retry the GetObject. If we try 20 times 
        //and GetObject still fails, we assume some other reason 
        //for GetObject failing and exit the procedure. 
        iTries++; 
        if (iTries < 20) 
        { 
         System.Threading.Thread.Sleep(500); // Wait 1/2 seconds. 
         goto tryAgain; //resume code at the GetObject line 
        } 
        else 
        { 
         MessageBox.Show("GetObject still failing. Process ended."); 
        } 

       } 
       else 
       { 
        //iSection == 0 so normal error handling 
        MessageBox.Show(err.Message); 
       } 
      } 
     } 


    } 

Выход:

Excel application object not registered. Trying plan B.. 
GetObject still failing. Process ended. 

В некоторых редких случаях "план Б" делает работу; Я не вижу второго окна сообщения. CurrentSpreadSheet - это singleton, и я намерен обновить его во время запуска из предоставленного класса ThisAddIn.

В ThisAddIn у меня есть что-то вроде:

private CurrentSpreadSheet css = CurrentSpreadSheet.Instance; 
private void ThisAddIn_Startup(object sender, System.EventArgs e) 
    { 
     ///...Some code 
     css.updateCurrentSpreadSheet(); 
} 

Есть ли лучший способ получить объект Application? Если это невозможно во время запуска, есть ли лучший способ, с помощью которого я могу отслеживать текущий активный рабочий лист/книгу сразу после запуска excel/моей надстройки? В настоящее время я зависим от объекта Application (например, (Excel.Workbook)this.CurrentApplication.ActiveWorkbook;) и некоторых обработчиков событий, чтобы отслеживать текущую рабочую книгу и рабочий лист.

Я попытался с помощью ExcelDNA:

this.CurrentApplication = (Excel.Application)ExcelDna.Integration.ExcelDnaUtil.Application; 

Это работает несколько раз, но в основном дает эту ошибку:

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> ExcelDna.Integration.XlCallException: Exception of type 'ExcelDna.Integration.XlCallException' was thrown. 

ответ

3

Имейте в виду, что Управление надстройка работает внутри Управления обработать. Поэтому вы никогда не захотите найти внешний процесс. Шаблонный шаблон ThisAddIn, который вы получаете при использовании шаблона проекта Office, передает вам объект приложения, который вы ищете на серебряном блюде, используйте его свойство Application. В первый раз, когда вы можете добраться до него, это событие Startup, убедитесь, что вы не пытаетесь его использовать раньше. Поэтому не делайте ничего решительного в своем конструкторе и не инициализируйте членов класса выражениями инициализации, подождите, пока не запустится Startup.

Соответствующая страница MSDN is here, раздел «Доступ к объектной модели хост-приложения».

+0

Я имел такую ​​же проблему, даже когда я поставил 'CurrentSpreadSheet CSS = CurrentSpreadSheet.Instance;' часть внутри 'ThisAddIn_Startup' метода. Является ли это другой проблемой или я все еще пытаюсь получить доступ к объекту раньше, чем доступно? –

+0

Это другая проблема. Имейте в виду, что при запуске Excel пользователь еще не выбрал расширенный лист. Используйте события в WorkBooks и т. Д., Поэтому см., Когда электронные таблицы загружаются и выбираются. –

0

Вы можете почитать более подробно об http://netoffice.codeplex.com/ Там вы можете найти больше информации о Add-In для Word/Excel/Powerpoint. Также обратите внимание на GuidAttribute, когда вы загружаете надстройку, потому что в зависимости от вашей версии Office она больше не будет работать, а также проверьте, сохранил ли ваш проект 32/64-разрядный, лучше всего любой процессор. Кроме того, имейте в виду, чтобы зарегистрировать надстройку в реестре для дальнейшего использования. Если вы хотите получить дополнительную информацию, не стесняйтесь писать мне почту.

http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.guidattribute.aspx

Смежные вопросы