2013-07-11 52 views
2

我正在使用C#,Visual Studio 2012的Excel插件工作。我試圖獲取Excel的應用程序對象的實例,以跟蹤當前活動的工作簿和工作表(ActiveWorkbook,ActiveWorksheet)。C#.NET錯誤附加到運行Office應用程序實例

我看到,大多數其他相關問題,以便有答覆建議使用如下:

(Excel.Application)Globals.ThisAddIn.Application; 

在這兩種情況下,我得到的NullReferenceException:

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

我也用這個嘗試。在查看這裏建議的解決方法之後: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. 

在少數情況下 「B計劃」 做工作;我沒有看到第二個消息框。 CurrentSpreadSheet是一個單例,我打算在啓動期間從提供的類ThisAddIn中更新它。

在我的ThisAddIn有類似:

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

有越來越Application對象的更好的辦法?如果在啓動過程中這是不可能的,是否有更好的方式讓我可以從excel/my插件的啓動中直接跟蹤當前活動的工作表/工作簿?目前,我依賴於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

請記住,一個Office加載運行辦公室處理。所以你永遠不想找到一個外部過程。您使用Office項目模板時獲得的樣板ThisAddIn類會將您正在尋找的應用程序對象放在銀盤上,並使用它的Application屬性。您第一次可以進入Startup活動時,請確保您沒有嘗試過。因此,不要在構造函數中做任何激烈的操作,也不要用初始化表達式初始化類成員,等到啓動時觸發。

相關的MSDN頁面is here「訪問主機應用程序的對象模型」部分。

+0

我即使有同樣的問題當我把'CurrentSpreadSheet CSS = CurrentSpreadSheet.Instance;所述'ThisAddIn_Startup'方法內'一部分。這是一個不同的問題,還是我仍然試圖比可用的更早訪問對象? –

+0

這是一個不同的問題。請記住,當Excel啓動時,用戶還沒有選擇電子表格。使用WorkBooks等中的事件,查看電子表格加載和選擇的時間。 –

0

你可以仔細看看http://netoffice.codeplex.com/在那裏你可以找到更多關於Word/Excel/Powerpoint插件的東西。 當您加載加載項時,請記住GuidAttribute,因爲根據您的Office版本,它將不再工作,並且還要檢查以確保您的項目是32/64位,最好是任何CPU。另外,請記住將您的加載項註冊到註冊表以供進一步使用。如果你想了解更多信息,請不要猶豫,給我寫郵件。

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