筆者曾經有若干篇文章介紹了在BDS 2006下開發Interop程序的一般步驟。有 興趣的讀者可以參考這些文章的匯總: http://www.go4pro.org/cate_list.asp?cate=20。
上面提到的開發方法,是 建立一個程序,然後創建Excel的應用對象(Application),再獲得相應接口( 如Workbook,Worksheet,Cells)的引用並對其進行進一步的操作。調用方式是 通過由外(自己開發的程序)到內(Excel)。
今天我要介紹一種新的利用.NET開發Interop應用的方法。這種方法與上述方 法最大的不同就在於它是由內(Excel)到外(自己開發的程序)進行的。
一、開發工具和准備工作:
這次我使用的是免費的C#開發工具:SharpDeveloper。大家可以免費下載, 免費使用。操作系統是Vista Business,但是XP平台應該一樣可用。Office平台 是2003.
同樣的,要使用Office的Interop PIA,必須在安裝時(或在安裝後)選擇各 個Office應用(Word/Excel/...)的.NET編程支持,詳細的步驟見前文描述,這 裡不再重復。
二、建立Excel加載項
啟動#Developer後,選擇File|New|Solution,在彈出窗口中選擇C#模板中的 Class Library。設置項目的位置、名稱後單擊“Create”,即可。
#Developer會自動創建程序的項目文件,這時界面如下:
我們首先要在左側的Solution Explorer中的References節點下加入對Excel PIA的引用。右擊References節點,並選擇Add Reference,在彈出窗口中選擇 GAC中的Microsoft.Office.Interop.Excel如下:
注意,必須使用GAC中的類!而不是COM中的類!
我們對IDE自動 生成的MyClass.cs文件要做一些修改,增加兩行代碼(以粗體標出):
using System;
using System.Collections.Generic;
using Excel=Microsoft.Office.Interop.Excel;
[assembly: System.ComponentModel.DescriptionAttribute("OfficeStartupClass, Version=1.0, Class=TestOLE.MyClass")]
其中的using子句是 常規的。而特別重要的,而且是必須要加的是[assembly: ...]這一行。用戶可 能需要修改的是Class=TestOLE.MyClass。在我的應用中,我創建的DLL的 namespace是TestOLE,而其中的類是MyClass。
在MyClass類中,需要創 建兩個Excel調用的特定函數:_Startup/_Shutdown。代碼如下:
public void _Startup(object thisApp, object thisWorkbook)
{
this.MyApp=thisApp as Excel.Application;
this.MyWorkBook=thisWorkbook as Excel.Workbook;
this.MyWorksheet=MyWorkBook.Worksheets[1] as Excel.Worksheet;
MyWorksheet.Cells[1,1]="The add-on starts!";
}
public void _Shutdown()
{
MyApp=null;
MyWorkBook=null;
// 本文轉自 C++Builder研究 - http://www.ccrun.com/article.asp?i=1050&d=uqn8b2
MyWorksheet=null;
}
其中的MyApp/MyWorkBook/MyWorksheet 是一些自己定義的變量。此時我們可以編譯該程序,生成MyClass.dll了。
三、安全因素
值得注意的是,即使我們是在.NET 2.0/3.0下開發我們的DLL,但是這個DLL 的安全性需要在.NET 1.x下進行配置。有關.NET 1.x的安全性配置,可以參考其 它文檔,這裡不再贅述。
四、與Excel的工作簿鏈接
現在我們的程序雖然已經編譯完畢,但是還沒有和一個Excel工作簿關聯。要 做到這一步,需要創建(或者打開)一個工作簿,對該工作簿做一些修改。在菜 單中選擇“文件|屬性”,在彈出的對話框中選擇“自定義”:
我們需要加入兩個自定義屬性:_AssemblyLocation0和_AssemblyName0。第 一個屬性設置為我們的DLL所在的位置,在我的應用中是D:\Go4Pro Programs\00017\bin\Debug,而第二個屬性是我們的DLL的名稱,我的是TestOLE。
保存這個文件,然後重新打開,可以看到在A1這個單元格中顯示:“The add-on starts!”字樣。這證明我們編寫的DLL已經被該工作簿加載並執行。
五、交互
只有這樣的功能顯然不是我們想要的。我們需要加入一個交互的過程,讓用 戶最終控制工作簿的行為。在這裡我選擇修改工作簿的標題作為演示。
首先我們在MyClass.cs中創建兩個方法,一個消息響應:
private Excel.WorkbookEvents_SheetFollowHyperlinkEventHandler followHyperlinksEvent;
public void _Startup(object thisApp, object thisWorkbook)
{
this.MyApp=thisApp as Excel.Application;
this.MyWorkBook=thisWorkbook as Excel.Workbook;
this.MyWorksheet=MyWorkBook.Worksheets[1] as Excel.Worksheet;
MyWorksheet.Cells[1,1]="The add-on starts!";
followHyperlinksEvent=new Excel.WorkbookEvents_SheetFollowHyperlinkEventHandler (ThisWorkbook_SheetFollowHyperlink);
MyWorkBook.SheetFollowHyperlink+=followHyperlinksEvent;
}
protected void ThisWorkbook_SheetFollowHyperlink(System.Object s, Excel.Hyperlink l)
{
switch (l.SubAddress)
{
case "ChangeTitle":
ChangeTitle();
break;
default:
break;
}
}
public void ChangeTitle()
{
MyApp.Caption="Invoked from Excel (supported by C#)";
}
在ThisWorkbook_SheetFollowHyperlink中,我們可以看到我們采用的是超鏈 接的方式來激活相應的方法。這就還需要我們在Excel工作簿中進行一些工作。
在我們剛才的工作簿中,隨便選擇一個單元格,輸入一些內容,諸如“Click here to change the title!”。然後將該單元格命名為ChangeTitle(這個名字 必須和上面代碼中case段的內容一致)。然後在該單元格選中的情況下,選擇菜 單“插入|超鏈接”:
選擇“本文檔中的位置”中的“定義的名稱”中的ChangeTitle即可。保存 Excel文件並再次打開,點擊“Click here to change the title!”單元格,我 們可以看到工作簿的名稱得以改變:
六、與以前方法的比較
顯然,這個方法比以前的方法更加靈活而友好,因為用戶將在一個界面中進 行操作,而不用在兩個界面中進行切換。而且只要關閉工作簿就可以結束DLL, 不用再關閉另一個主程序。
但是,這個方法需要我們開啟.NET 1.x的安全性,需要一些額外的設置,並 不一定是每個終端用戶都能勝任的。
孰優孰劣,留待開發者和用戶進行判斷。