Дано:
- Надстройка VSTO
-
override object RequestComAddInAutomationService()
, который возвращает экземпляр класса, который называется Facade
в моем сценарии.
- Макрос VBA в Excel 2007, который обращается к
AddIn.Object
для получения Фасада и использует его.
- Много раз, когда это прекрасно работает.
- Пару раз, когда неожиданно это не сработало.
Обновление: выясняется, что проблема связана с конкретным пользователем. Она есть у нее все время, у других ее нет (никогда не говори «никогда»)
В эту "пару раз" я получаю
Ошибка: переменная объекта или переменная блока не установлена
в строке кода, которая пытается получить доступ к свойству 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
, который все еще действителен. VBA скорее генерирует этот тип ошибки всякий раз, когда метод выполняется по ссылке, равной Nothing
, которая в моем случае равна automationObject
.
С другой стороны, если надстройки не было вообще, Application.COMAddIns(...)
поднял бы индекс за пределы , я видел это раньше.