VSTO 學習筆記(十一)開發Excel 2010 64位自定義公式
Excel包含很多公式,如數學、日期、文本、邏輯等公式,非常方便,可以靈活快捷的對數據進行處理,達到我們想要的效果。Excel的內置公式雖然強大,但是在ERP等系統中,往往需要進行很多業務上的計算,如收發存臺賬、指定年、月、部門的消耗查詢等,都是需要從數據庫中查詢的,且和業務緊密相連。這時僅僅依靠Excel的內置公式就不夠了,需要添加自定義的公式來進行這些業務計算。
本系列所有測試代碼均在Visual Studio 2010 Ultimate + Office 2010 Professional Plus x64 上測試通過
轉載請注明出處: http://www.rzrgm.cn/brooks-dotnet/archive/2011/01/16/1936871.html
Exel允許我們創建用戶自定義函數,并用到Excel公式中。
一、VBA
不使用VSTO,只用經典的VBA就可以編寫Excel自定義函數。VBA我沒有研究過(接觸開發較晚,錯過了VBA時代),感興趣的朋友請自行搜索,有很多示例。
二、XLL
XLL是Excel的加載宏文件,是一個標準dll,主要使用C++開發。為此,微軟提供了Excel 2010 XLL SDK,可以在這里下載。
雖然微軟官方不推薦使用.NET來開發XLL,但是有人在CodePlex上發布了一個開源項目ExcelDNA,可以使用.NET來開發XLL。不過網上有人說貌似不支持Excel 2010 x64,待后續驗證。
三、XLW
XLW(A Wrapper for the Excel API)是一個C++語言對Excel的開發者工具包(SDK)的一個封裝,簡化了C++程序操作Excel文檔的方法,XLW4.0已經支持Excel 2007。使用XLW可以很方便的使用C++對Excel功能進行擴展,首先它提供了一個模板生成器xlwTemplateExtractor.exe,可以生成相應的工程文件,然后又具有一個接口生成器InterfaceGenerator.exe來自動生成相應的接口包裝文件(xlwWrapper.cpp),從而大大減少了只使用Excel SDK來完成XLL開發所需的相關代碼,降低了開發難度,避免一些錯誤的產生。
官方說明只支持到Excel 2007,估計Excel 2010 x64沒戲了,期待后續更新。
四、.NET
VSTO的出現大大提高了開發人員的效率,我們可以享受現代開發工具帶來的快捷與方便。借助于COM可以使用托管代碼來開發Excel自定義公式。
4.1、打開VS2010,新建一個Class Library項目:
4.2、添加COM相關的特性:
[Guid("DDE8AA59-9860-44B3-B1AF-923ABB4A8EEE")]
[ClassInterface(ClassInterfaceType.AutoDual)]
[ComVisible(true)]
注意要生成一個GUID:
這里我使用的LinqPad,一個輕量級的IDE,支持C#、VB.NET、Linq、F#、SQL語句,非常適合用來測試少量代碼。
4.3、寫一個簡單的函數,返回兩個整數的和:
public int AnotherSumFunc(int a, int b)
{
return a + b;
}
4.4、添加COM注冊與反注冊函數:
[ComRegisterFunction]
public static void RegisterFunction(Type type)
{
Registry.ClassesRoot.CreateSubKey(GetSubKeyName(type, "Programmable"));
var key = Registry.ClassesRoot.OpenSubKey(GetSubKeyName(type, "InprocServer32"), true);
key.SetValue("", Environment.SystemDirectory + @"\mscoree.dll", RegistryValueKind.String);
}
[ComUnregisterFunction]
public static void UnregisterFunction(Type type)
{
Registry.ClassesRoot.DeleteSubKey(GetSubKeyName(type, "Programmable"), false);
}
private static string GetSubKeyName(Type type, string subKeyName)
{
var s = new System.Text.StringBuilder();
s.Append(@"CLSID\{");
s.Append(type.GUID.ToString().ToUpper());
s.Append(@"}\");
s.Append(subKeyName);
return s.ToString();
}
這兩個函數的格式是固定的,為了向注冊表中添加必須的鍵值。
4.5、修改項目屬性,取消COM注冊:
4.6、編譯項目。
4.7、32位的Excel可以選中上述復選框來自動注冊,從Excel 2010 x64開始,我們需要手動注冊該dll。
在DOS下輸入:cd /d %windir%\Microsoft.NET\Framework64\v4.0.30319
4.8、使用regasm來注冊我們的dll:
出現警告是因為未簽名,因為是測試就沒有進行簽名,如果是正式部署則一定要進行簽名。
下述說明摘自MSDN,原文地址:http://msdn.microsoft.com/zh-cn/library/tzat5yw6(v=VS.100).aspx。
Regeasm.exe 是一個程序集注冊工具,Regeasm.exe讀取程序集中的元數據,并將所需的項添加到注冊表中。注冊表允許 COM 客戶程序以透明方式創建 .NET Framework 類。 類一經注冊,任何 COM 客戶程序都可以使用它,就好像該類是一個 COM 類。 類僅在安裝程序集時注冊一次。 程序集中的類實例直到被實際注冊時,才能從 COM 中創建。
regasm assemblyFile [options]
assemblyFile
要向 COM 注冊的程序集。
選項說明
/codebase
在注冊表中創建一個 Codebase 項。 Codebase 項指定未安裝到全局程序集緩存中的程序集的文件路徑。 如果隨后要安裝正在注冊到全局程序集緩存中的程序集,則不應指定此選項。 用 /codebase 選項指定的 assemblyFile 參數必須是具有強名稱的程序集。
/registered
指定此工具將僅引用已經注冊的類型庫。
/asmpath:directory
指定包含程序集引用的目錄。 必須和 /regfile 選項一起使用。
/nologo
取消顯示 Microsoft 啟動標題。
/regfile [:regFile]
為程序集生成指定的 .reg 文件,該文件包含所需的注冊表項。 指定此選項不更改注冊表。 此選項不能與 /u 選項或 /tlb 選項一起使用。
/silent 或 /s
取消顯示成功消息。
/tlb [:typeLibFile]
從指定的程序集生成類型庫,該類型庫包含在程序集中定義的可訪問類型的定義。
/unregister 或 /u
注銷在 assemblyFile 中找到的可創建類。 省略此選項將導致 Regasm.exe 注冊程序集中的可創建類。
/verbose
指定詳細模式;當用 /tlb 選項指定時,顯示所有需要為其生成類型庫的引用程序集的列表。
/?或 /help
顯示該工具的命令語法和選項。
4.9、在Excel中激活該公式
打開一個Excel文件,若尚未顯示"Developer(開發人員)"選項卡,則可以通過在Ribbon – 右鍵 – "Custom the Ribbon" – "選中Developer"來顯示:
在Developer選項卡中,點擊【Add-Ins】:
點擊【Automation】選擇我們編寫的自定義函數:
選中該函數,點擊【OK】:
回到Excel中,在一個單元格的公示欄中輸入:=AnotherSumFunc(1,2),回車,可以看到得到了我們期望的結果:3
4.10、刪除自定義函數
若該函數我們不想要了,要刪除怎么辦呢?只需在CMD中反注冊dll:
4.11、調試自定義函數
在項目屬性的Debug選項卡中,將擴展啟動程序設置為Excel 2010 x64的路徑:
F5運行,會自動打開Excel,當我們輸入該自定義函數時,會自動進入斷點:
除此之外,還可以通過附加Excel的進程來進行調試。
小結:
Office 2010首次推出的64位版本的Office在帶給我們欣喜的同時,也帶來了版本維護成本的提升。因此VSTO程序的向后兼容性就顯得尤為重要,Excel自定義函數只是冰山一角。后續篇章會討論下Office插件的兼容性問題,以及從VBA轉向VSTO的解決方案。

浙公網安備 33010602011771號