Доброе утро, товарищи разработчики:
В настоящее время я пытаюсь исправить несколько проблем с производительностью общей надстройки Excel, унаследованной от предыдущего разработчика, в основном я пытаюсь найти, как надстройка работает внутри Excel, то есть я искал в сети информацию и я понимаю:
- В реестре для LoadBehaviour должно быть установлено значение 3.
- Книга Excel во время открытия события должна предварительно загрузить все надстройки, на которые есть ссылки в проекте VBA.
- После открытия документа моя надстройка должна быть доступна для использования кодом VBA.
Теперь я добавляю Log4Net в надстройку и, как ни странно, видел следующее поведение
Во время открытия события в книге Excel есть глобальная переменная
Public myAddin As Object
Set myAddin = New TradingAddin.TradingAddin
Таким образом вызывается Контруктор класса C #.
Через пару секунд конструктор вызывается еще раз, и все методы IDTExtensibility2 OnConnection, OnDisconnection и т. Д. Вызываются должным образом.
Я подумал, что как только Excel загрузит надстройку, она станет доступной для кода VBE, и я мог бы написать что-то вроде
Set myAddin = Application.COMAddins.Item("Trading").Object
Но он ничего не возвращает и дважды вызывая конструктор класса, уничтожает любое состояние, сохраненное внутри объекта C #, которое должно быть доступно в памяти в течение жизни книги Excel.
Обновление:
Платформа - это Visual Studio 2005 Team Edition, целевое приложение - Excel 2003, а надстройка - это общая надстройка. Я не использую VSTO.
Фактический код, который я пытался вызвать в VBA, это
Set addIn = Application.COMAddIns.Item("K2Trading.K2Trading").Connect
Set managedObject3 = addIn.Object <--- This value that I thought was an Instance of the Add-in is equal to Nothing (NULL)
Set addIn = Application.COMAddIns("K2Trading.K2Trading").Connect
Также изменение LoadBehaviour в реестре на 3 из 2 загружает надстройку в первый раз, правильно запускает все события расширяемости OnConnection, OnDisconecction и конструктор класса объектов, теперь мне нужно найти способ для части вызова из VBA Add- in, что означает, как подключить экземпляр надстройки к ссылке в VBA и оттуда вызвать все методы, представленные через интерфейс COM-объекта ????
Также я дважды проверил с помощью ProcMon, что надстройка была найдена и загружена Excel по этой ссылке (очень полезно) http://blogs.msdn.com/dvespa/archive/2008/10/15/устранениенеполадок-outlook-com-addins-using-procmon.aspx.
Есть идеи, которые, возможно, указывают в правильном направлении?
Как мне узнать, сколько экземпляров COM-объекта загружено? или другими словами можно было бы иметь единственный экземпляр COM-объекта?
TIA, Педро
Майку:
Я пробовал ваше решение, но при выполнении этого кода столкнулся с неопределенной ошибкой (исключение из HRESULT: 0x80004005 (E_FAIL))
public void OnConnection(object application, Extensibility.ext_ConnectMode connectMode,
object addInInst, ref System.Array custom)
{
object missing = System.Reflection.Missing.Value;
try
{
if (debug)
{
log.Debug("Connection Mode :" + connectMode);
}
this.excelApp = (Excel.Application)application;
this.addInInstance = addInInst;
Office.COMAddIn addIn = this.excelApp.COMAddIns.Item(ref addInInst);
//addIn.Object = this;
// We connect our Instance of the Add-in to the Arrya of COMAddins of Excel
VBA.Interaction.CallByName(addIn, "Object", VBA.CallType.Let, this);
^
|
The Exception occurs here.
Вы заметите, что это немного отличается от того, что вы опубликовали некоторое время назад.
public void OnConnection(
object application,
Extensibility.ext_ConnectMode connectMode,
object addInInst,
ref System.Array custom)
{
// Direct call fails b/c ".Object" is a late-bound call:
//
// addInInst.Object = this;
// Reflection fails I believe b/c .Object is a 'let' assigned
// property for reference type, which is very unusual even for
// COM (although legal) and is a foreign concept to .NET. Use
// of the right BindingFlags here *might* work, but I'm not sure:
//
// PropertyInfo propInfo;
// propInfo = addInInst.GetType().GetProperty("Object");
// propInfo.SetValue(addInInst, this, null);
// This works!:
VBA.Interaction.CallByName(addInInst, "Object", VBA.CallType.Let, this);
}
Поскольку addInInst не передается как Office.COMAddin, а является экземпляром моего класса, поэтому попытка присвоения свойству объекта неверна, поскольку его нет в этом классе
Также мне любопытно, как Excel загружает надстройки, что я имею в виду под этим, основано на моем наблюдении, когда я только что загрузил Excel, метод OnConnection не выполнялся сразу, но пока я не нажал функцию = AvgCost ()? ?
Любые идеи?