C# VBA中的VSTO:AddIn.Object有时不返回任何内容(null)
鉴于:C# VBA中的VSTO:AddIn.Object有时不返回任何内容(null),c#,vba,.net-3.5,vsto,excel-2007,C#,Vba,.net 3.5,Vsto,Excel 2007,鉴于: 要加载项的VSTO 一个重写对象RequestComAddInAutomationService(),它返回一个类的实例,在我的场景中该类被称为Facade Excel 2007中的VBA宏,它访问AddIn.Object以获取外观并使用它 很多时候,这种方法都非常有效 有几次,突然之间,这似乎不起作用。 更新:结果发现问题出在某个特定用户身上。她一直拥有它,其他人从未拥有过它(?永远不要说“永远”) 在这“几次”中,我得到了 错误:未设置对象变量或带块变量 在试图访问Facade属
- 要加载项的VSTO
- 一个
,它返回一个类的实例,在我的场景中该类被称为重写对象RequestComAddInAutomationService()
Facade
- Excel 2007中的VBA宏,它访问
以获取外观并使用它AddIn.Object
- 很多时候,这种方法都非常有效
- 有几次,突然之间,这似乎不起作用。
Facade
属性的代码行。简而言之,我可以告诉您,RequestComAddInAutomationService()
中的代码没有任何容易出错的魔力,访问外接程序的VBA代码也是从web获取的,看起来也不错。对于那些愿意花时间阅读的人来说,更长的版本还没有出现:——)
问题:有人知道为什么会发生这种情况吗?这是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
的引用执行方法时,VBA就会抛出这种类型的错误,在我的例子中,这是automationObject
另一方面,如果外接程序根本不存在,
应用程序.COMAddIns(…)
将引发索引越界错误,我以前见过这种情况。大部分时间都在工作,失败有时看起来像竞争条件。安德鲁·怀特查普(Andrew Whitechapel)曾写过一篇关于RequestComAddInAutomationService
1:
虽然他说竞争条件不应该是进程内VBA宏的问题,但问题可能发生在您的特定场景中
尝试建议的解决方法并循环,直到您的Addin.Object
有效(C#code,类似于VBA):
1他的博客上有很多关于您正在做的事情的有用信息,因此不要错过相关文章。结果是Excel禁用了COM加载项。众所周知,这种情况有时会悄无声息地发生,没有任何抱怨 因此,由于外接程序已在excel中注册,以下行成功:
Set addin = Application.COMAddIns("My AddIn")
但由于该对象已禁用,因此未创建和删除该对象
Set automationObject = addin.Object
结果是
什么都没有
我也遇到过类似的问题,经常但不总是,所以我不能肯定地说,但似乎解决它的问题是项目/应用程序/程序集信息。。。并选中“使部件COM可见”,然后使用以下命令创建对象(在Excel VBA中):
从那以后没有问题-祝你好运。谢谢你的提示。我读过了。不幸的是,这似乎不适用于我的情况:我确实从VBA调用了外接程序。我现在已经在我的问题中添加了细节。如果你能在代码中找到一个比赛条件,我会很高兴的。虽然看起来好像没有什么。。。(当然,重试几次的技巧可能仍然可以)这个“答案”说“excel禁用了COM加载项/已知有时会无声发生”,然后解释说这解释了症状。但是,它没有解释如何预防或解决这个问题。@TonyD:你说得对,但这超出了这个问题的范围。问题只是它如何发生。原因是外接程序已被禁用。询问Excel为什么可以禁用外接程序,打开了一个全新的可能答案空间。。。
Set automationObject = addin.Object
Set automationObject = CreateObject("PlugInDllName.PlugInClass")