2010-11-10 39 views
3

考慮:VSTO在VBA:AddIn.Object返回Nothing(空)有時

  • 一個VSTO外接
  • override object RequestComAddInAutomationService()它返回它在我的情況被稱爲Facade類的一個實例。
  • Excel 2007中的VBA宏,它訪問AddIn.Object以獲取Facade並使用它。
  • 很多時候,這工作得很好。
  • 有幾次,突然間,這似乎並不奏效。

更新:發現它是一個特定的用戶有問題。她擁有這一切的時候,別人也永遠不可能有它(?從來不說「從來沒有」)

在這個「好幾次」我得到

Error: Object variable or With block variable not set

在這行代碼它試圖訪問財產Facade。總之,我可以告訴你RequestComAddInAutomationService()中的代碼沒有任何容易出錯的魔法,並且訪問加載項的VBA代碼已經從網上獲取並且看起來也很好。較長的版本尚未推出,對於那些會花時間閱讀的人:-)

問題:有沒有人有線索爲什麼會發生這種情況?這是一個Excel問題?


詳情承諾:

MyAddIn.cs:

public partial class MyAddIn 
{ 
    public Facade Facade { get; private set; } 

    protected override object RequestComAddInAutomationService() 
    { 
     if (this.Facade == null) 
      this.Facade = new Facade(Controller.Instance); 

     return this.Facade; 
    } 
} 

Facade.cs:

[ComVisible(true)] 
[Guid("1972781C-A71A-48cd-9675-AE47EACE95E8")] 
[InterfaceType(ComInterfaceType.InterfaceIsDual)] 
public interface IFacade 
{ 
    // some methods 
} 

[ComVisible(true)] 
[ClassInterface(ClassInterfaceType.None)] 
public class Facade : IFacade 
{ 
    private Controller Controller { get; set; } 

    public Facade(Controller controller) 
    { 
     this.Controller = controller; 
    } 
} 

Facade有一些方法,但不是一個單一的領域。

Controller.cs:

public class Controller 
{ 
    private static Controller instance = null; 
    public static Controller Instance 
    { 
     get 
     { 
      if (instance == null) instance = new Controller(); 
      return instance; 
     } 
    } 

    private Controller() { } 
} 

Controller有一些私人領域。由於字段分配是在創建時執行的,因此我對它們進行了審閱。他們大多數都沒有初始化,或者他們被設置爲null,所以構造函數幾乎沒有任何操作。

VBA代碼:

Dim addin As Office.COMAddIn 
Dim automationObject As Object 

Set addin = Application.COMAddIns("My AddIn") 
Set automationObject = addin.Object 

Dim oResult As Object 
Set oResult = automationObject.SomeMethodThatReturnsAnObject() 

最後一行是在錯誤發生。雖然調用的方法返回一個對象,但我確信它不能成爲錯誤的來源:如果返回的引用是null,那麼該語句將簡單地評估爲Set oResult = Nothing,它仍然有效。無論何時在引用Nothing(在我的例子中爲automationObject)上執行方法時,VBA都會拋出此類錯誤。

另一方面,如果加載項根本不存在,那麼Application.COMAddIns(...)會引發一個索引超出範圍錯誤,我以前就看到過。

回答

1

原來,Excel中禁用的COM加載項。這被稱爲有時會悄悄發生,沒有Excel抱怨任何事情。

因此,由於加載了與Excel註冊,以下行成功:

Set addin = Application.COMAddIns("My AddIn") 

但由於它被禁用,未創建對象和

Set automationObject = addin.Object 

導致Nothing

+1

這個「答案」中說「excel禁用了COM加載項/已知有時會悄悄地發生」 ,然後解釋說這解釋了這些症狀。但是,它沒有解釋如何預防或解決這個問題。 – 2013-03-14 08:58:32

+0

@TonyD:你就在那裏 - 但這不在這個問題的範圍之內。問題只是它如何發生。原因原來是加載項被禁用。詢問爲什麼Excel可以想象禁用加載項會打開一個全新的可能答案空間...... – chiccodoro 2013-03-14 12:53:49

3

工作的大部分時間,有時失敗看起來像一個競爭條件。安德魯白教堂已經寫了有關RequestComAddInAutomationService 的競爭條件:

COMAddIns Race Condition

雖然他說,競爭條件不宜與進程VBA宏的問題,這可能是因爲這個問題可能在發生在您具體場景。

嘗試提出解決辦法和循環,直到你Addin.Object是有效的(C#代碼,在VBA類似):

while (utils == null) 
{ 
    utils = (ComServiceOleMarshal.IAddinUtilities)addin.Object; 
    System.Threading.Thread.Sleep(100); 
}  
utils.DoSomething(); 

有很多關於他的博客對你正在做的事情的有用信息,所以不要錯過相關文章。

+0

感謝您的提示。我讀過它了。不幸的是,它似乎不適用於我的情況:我*從VBA調用插件。我現在已經將細節添加到了我的問題中。如果你能在代碼中發現競爭狀況,我會很高興。雖然看起來更像是沒有任何...(當然,重試 - 幾次的技巧可能仍然會這樣做) – chiccodoro 2010-11-10 15:34:56

1

我也曾有過類似的問題,常常但並不總是,所以我不能肯定地說,但似乎解決它打算項目/應用/裝配信息的東西......和檢查使裝配COM - 可見,然後創建對象(在Excel VBA中):

Set automationObject = CreateObject("PlugInDllName.PlugInClass") 

沒有問題,因爲 - 手指交叉。

相關問題