我有一个Excel模板,用于通过以下方法链接到我的应用程序:
Excel VBA:
objApp.SetExcelApp Application
在我的应用程序代码中,我想使用反射来连接Excel应用程序上的WorkbookBeforeClose事件,这样当该事件触发时我就可以做一些事情:
VB.NET:
Public Sub SetExcelApp(ByRef objExcel As Object)
Dim evWorkbookBeforeClose As Reflection.EventInfo = objExcel.GetType().GetEvent("WorkbookBeforeClose")
Dim mEvents As Reflection.EventInfo() = objExcel.GetType().GetEvents()
' do stuff
End Sub
令人惊讶的是,evWorkbookBeforeClose
是Nothing
——甚至mEvents
也是Nothing
!
我可以很好地使用方法和属性。像objExcel.ActiveWorkbook
和objExcel.Run("MyVBAMethod")
有人知道为什么这不起作用吗?这不可能使用反射吗?是否必须添加对Excel互操作的引用?
EDIT:因此,如果我添加Excel互操作作为引用,它将正常工作,因为我可以在事件上使用AddHandler
。但我仍然想知道为什么使用反射不起作用。。。
我看到的一件有趣的事情是,即使我将其更改为objExcel As Microsoft.Office.Interop.Excel.Application
,执行上述调用(GetEvent
/GetEvents
)仍然都返回Nothing!
可以使用System.Runtime.InteropServices.ComEventsHelper
类添加事件。
例如
// source: http://www.guysmithferrier.com/downloads/csharp4.pdf
public static void ExcelExample() {
Type ty = Type.GetTypeFromProgID("Excel.Application");
Object o1 = Activator.CreateInstance(ty); // COM Object
o1.GetType().InvokeMember("Visible", BindingFlags.SetProperty, null, o1, new Object[] { true });
// Sh = Sheet?
// Target = Range
// 0x616 is the SelectionChanged event
ComEventsHelper.Combine(o1, new Guid("00024413-0000-0000-C000-000000000046"), 0x616, new Action<Object,Object>((Sh, Target) => {
int breakPoint = 1;
}));
}
public static void WordExample() {
Type ty = Type.GetTypeFromProgID("Word.Application");
Object o1 = Activator.CreateInstance(ty); // COM Object
o1.GetType().InvokeMember("Visible", BindingFlags.SetProperty, null, o1, new Object[] { true });
//var wdg4 = new Guid("00020A01-0000-0000-C000-000000000046"); // ApplicationEvents4 (Word)
//var wdg3 = new Guid("00020A00-0000-0000-C000-000000000046"); // ApplicationEvents3 (Word)
//var wdg2 = new Guid("000209FE-0000-0000-C000-000000000046"); // ApplicationEvents2 (Word)
var wdg1 = new Guid("000209F7-0000-0000-C000-000000000046"); // ApplicationEventsInterface (Word)
// 2 = Quit event
ComEventsHelper.Combine(o1, wdg1, 2, new Action(() => {
int breakPoint = 1;
}));
// 4 = Document open
ComEventsHelper.Combine(o1, wdg1, 4, new Action<Object>((Doc) => {
int breakPoint = 1;
}));
}
调度ID(dispid)值似乎没有MSDN引用。我在网上找到了一些来源,所以我会把它们发布在这里:
来源:https://social.msdn.microsoft.com/Forums/sqlserver/en-US/3625e60d-0e9c-4871-a0e8-bcedbbb31ce0/is-there-an-fixed-version-of-microsoftofficeinteropworddll-on-msdn?forum=worddev
单词:
[DispId(0x00000001)]
void Startup();
[DispId(0x00000002)]
void Quit();
[DispId(0x00000003)]
void DocumentChange();
[DispId(0x00000004)]
void DocumentOpen(Word.Document Doc);
[DispId(0x00000006)]
void DocumentBeforeClose(Word.Document Doc, ref bool Cancel);
[DispId(0x00000007)]
void DocumentBeforePrint(Word.Document Doc, ref bool Cancel);
[DispId(0x00000008)]
void DocumentBeforeSave(Word.Document Doc, ref bool SaveAsUI, ref bool Cancel);
[DispId(0x00000009)]
void NewDocument(Word.Document Doc);
[DispId(0x0000000a)]
void WindowActivate(Word.Document Doc, Word.Window Wn);
[DispId(0x0000000b)]
void WindowDeactivate(Word.Document Doc, Word.Window Wn);
[DispId(0x0000000c)]
void WindowSelectionChange(Word.Selection Sel);
[DispId(0x0000000d)]
void WindowBeforeRightClick(Word.Selection Sel, ref bool Cancel);
[DispId(0x0000000e)]
void WindowBeforeDoubleClick(Word.Selection Sel, ref bool Cancel);
[DispId(0x0000000f)]
void EPostagePropertyDialog(Word.Document Doc);
[DispId(0x00000010)]
void EPostageInsert(Word.Document Doc);
[DispId(0x00000011)]
void MailMergeAfterMerge(Word.Document Doc, Word.Document DocResult);
[DispId(0x00000012)]
void MailMergeAfterRecordMerge(Word.Document Doc);
[DispId(0x00000013)]
void MailMergeBeforeMerge(Word.Document Doc, int StartRecord, int endRecord, ref bool Cancel);
[DispId(0x00000014)]
void MailMergeBeforeRecordMerge(Word.Document Doc, ref bool Cancel);
[DispId(0x00000015)]
void MailMergeDataSourceLoad(Word.Document Doc);
[DispId(0x00000016)]
void MailMergeDataSourceValidate(Word.Document Doc, ref bool Handled);
[DispId(0x00000017)]
void MailMergeWizardSendToCustom(Word.Document Doc);
[DispId(0x00000018)]
void MailMergeWizardStateChange(Word.Document Doc, ref int FromState, ref int ToState, ref bool Handled);
[DispId(0x00000019)]
void WindowSize(Word.Document Doc, Word.Window Wn);
Excel:
来源:http://www.codeforge.com/read/240027/AppEvents.java__html
@DISPID(1565)
public void newWorkbook(Wb)
@DISPID(1558)
public void sheetSelectionChange(Sh, Target)
@DISPID(1559)
public void sheetBeforeDoubleClick(Sh, Target, Cancel);
@DISPID(1560)
public void sheetBeforeRightClick(Sh, Target, Cancel);
@DISPID(1561)
public void sheetActivate(Sh)
@DISPID(1562)
public void sheetDeactivate(Sh)
@DISPID(1563)
public void sheetCalculate(Sh)
@DISPID(1564)
public void sheetChange(Sh, Target)
@DISPID(1567)
public void workbookOpen(Wb)
@DISPID(1568)
public void workbookActivate(Wb)
@DISPID(1569)
public void workbookDeactivate(Wb)
@DISPID(1570)
public void workbookBeforeClose(Wb, Cancel)
@DISPID(1571)
public void workbookBeforeSave(Wb, SaveAsUI, Cancel)
@DISPID(1572)
public void workbookBeforePrint(Wb, Cancel)
@DISPID(1573)
public void workbookNewSheet(Wb, Sh)
@DISPID(1574)
public void workbookAddinInstall(Wb)
@DISPID(1575)
public void workbookAddinUninstall(Wb)
@DISPID(1554)
public void windowResize(Wb, Window)
@DISPID(1556)
public void windowActivate(Wb, Window)
@DISPID(1557)
public void windowDeactivate(Wb, Window)
@DISPID(1854)
public void sheetFollowHyperlink(Sh, Hyperlink)
@DISPID(2157)
public void sheetPivotTableUpdate(Sh, PivotTable)
@DISPID(2160)
public void workbookPivotTableCloseConnection(Wb, PivotTable)
@DISPID(2161)
public void workbookPivotTableOpenConnection(Wb, PivotTable)
@DISPID(2289)
public void workbookSync(Wb, SyncEventType)
@DISPID(2290)
public void workbookBeforeXmlImport(Wb, XmlMap, Url, IsRefresh, Cancel)
@DISPID(2291)
public void workbookAfterXmlImport(Wb, XmlMap, IsRefresh, Result)
@DISPID(2292)
public void workbookBeforeXmlExport(Wb, XmlMap, Url, Cancel)
@DISPID(2293)
public void workbookAfterXmlExport(Wb, XmlMap, Url, Result)
@DISPID(2611)
public void workbookRowsetComplete(Wb, Description, Sheet, Success)
@DISPID(2612)
public void afterCalculate()