VBA 中的 VSTO:AddIn.Object 有时不返回任何内容(空)

chi*_*oro 5 c# vba vsto excel-2007 .net-3.5

鉴于:

  • VSTO 插件
  • Anoverride object RequestComAddInAutomationService()返回Facade在我的场景中调用的类的实例。
  • Excel 2007 中的 VBA 宏,它访问AddIn.Object以获取 Facade 并使用它。
  • 很多时候这工作得很好。
  • 有几次出乎意料,这似乎不起作用。

更新:原来是特定用户有问题。她一直都有,别人从来没有(?永远不要说“从不”)

在这“几次”中,我得到

错误:对象变量或未设置块变量

在试图访问Facade. 简而言之,我可以告诉您,其中的代码RequestComAddInAutomationService()没有任何容易出错的魔法,而且用于访问加载项的 VBA 代码也取自网络,看起来也不错。更长的版本尚未推出,对于那些花时间阅读它的人:-)

问题:有没有人知道为什么会发生这种情况?是Excel问题吗?


承诺的细节:

我的插件.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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

Facade 有一些方法,但没有一个字段。

控制器.cs:

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

    private Controller() { }
}
Run Code Online (Sandbox Code Playgroud)

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()
Run Code Online (Sandbox Code Playgroud)

最后一行是错误发生的地方。尽管调用的方法返回一个对象,但我很确定它不会是错误的来源:如果返回的引用是null,则该语句将简单地评估Set oResult = Nothing哪个仍然有效。每当在 是 的引用上执行方法时,VBA 都会抛出这种类型的错误Nothing,这就是automationObject我的情况。

另一方面,如果加载项根本不存在,Application.COMAddIns(...)则会引发索引越界错误,我以前见过。

chi*_*oro 2

结果发现 Excel 禁用了 COM 加载项。众所周知,有时这种情况会悄无声息地发生,Excel 不会抱怨任何事情。

因此,由于加载项已注册到 Excel,因此以下行成功:

Set addin = Application.COMAddIns("My AddIn")
Run Code Online (Sandbox Code Playgroud)

但由于它被禁用,该对象没有被创建并且

Set automationObject = addin.Object
Run Code Online (Sandbox Code Playgroud)

结果是Nothing.