用微軟VS2017為Word開(kāi)發(fā)加載項(xiàng)的技巧
Word是一個(gè)大家平時(shí)辦公中最常用的文字處理軟件之一,其功能包羅萬(wàn)象,十分強(qiáng)大。但不排除某些用戶有獨(dú)特而專有的需求,Word自帶的功能并沒(méi)有考慮到,要由用戶手動(dòng)操作若干步方能完成。這些操作有時(shí)存在復(fù)用的價(jià)值,那么不妨把它們抽象并固定下來(lái),變成Word里的一項(xiàng)功能吧。
對(duì)于簡(jiǎn)單的操作復(fù)用,我們可以通過(guò)內(nèi)置的宏或VBA來(lái)實(shí)現(xiàn)。Word中甚至還提供了“錄制宏”的功能,來(lái)降低編寫代碼的門檻。不過(guò)宏和VBA有個(gè)缺點(diǎn),即不能利用Ribbon欄。(有同學(xué)說(shuō)過(guò)可以使用XML映射來(lái)實(shí)現(xiàn),但我沒(méi)試過(guò)。)而開(kāi)發(fā)一個(gè)加載項(xiàng),或者說(shuō)VSTO外接程序,就可以克服這個(gè)缺點(diǎn)。
今天,我們就來(lái)編寫一個(gè)簡(jiǎn)單的VSTO外接程序,作為入門。
一、安裝Visual Studio 2017,并在安裝時(shí)確保選中Office/SharePoint這一選項(xiàng)。
二、打開(kāi)VS2017,新建項(xiàng)目。分別選中Visual Basic→OfficeSharePoint→Word 2013和2016 VSTO外接程序。(選擇VB是因?yàn)槠湔Z(yǔ)法與VBA的語(yǔ)法類似,學(xué)過(guò)VBA的同學(xué)可以馬上上手,當(dāng)然選擇C#也是可以的。嚴(yán)格來(lái)說(shuō),此處的VB指的是VB.net,而VBA則基本繼承VB6.0,兩者的語(yǔ)法在某些地方還是有很大區(qū)別的。)為這個(gè)項(xiàng)目起個(gè)名字,比如WordAddInTest。
三、新建項(xiàng)目后,呈現(xiàn)在面前的是ThisAddIn.vb里的內(nèi)容,我們稍后再來(lái)關(guān)注它。現(xiàn)在先來(lái)創(chuàng)造一個(gè)Ribbon界面。通過(guò)解決方案資源管理器添加一個(gè)新項(xiàng),類型則選擇“功能區(qū)(可視化編輯器)”,這樣我們就得到了一個(gè)新的帶有空組的Ribbon欄。
四、接下來(lái),就是“搭積木”時(shí)間了。我們可以看到,在工具欄中出現(xiàn)了一些Ribbon控件,它們分別是Box、Button、ButtonGroup、CheckBox、DropDown、EditBox、Gallery、Group、Label、Menu、Separator、Tab、ToggleButton。
現(xiàn)在就對(duì)這些控件做一些簡(jiǎn)單的介紹。
1.容器控件:Tab、Group、Box和ButtonGroup。
a.Tab是選項(xiàng)卡,如果你希望使用不止一個(gè)選項(xiàng)卡,你可以拖放一個(gè)新的Tab。
b.Group是選項(xiàng)組,通常一個(gè)選項(xiàng)卡由若干個(gè)選項(xiàng)組組成。有時(shí)選項(xiàng)組右下角會(huì)標(biāo)有一個(gè)灰色箭頭,單擊它能啟動(dòng)一個(gè)窗體。這種窗體的啟動(dòng)可以通過(guò)Group的DialogLauncher來(lái)實(shí)現(xiàn)。
c.Box(不可見(jiàn))是用來(lái)排列具體的控件的,可以使控件橫向或者縱向排列,目的是使界面井然有序。
d.ButtonGroup(不可見(jiàn))則是專為排列按鈕而存在的,而且只能是橫向排列。
2.不可操作控件:Label和Separator。
a.Label即標(biāo)簽,是用來(lái)顯示提示性文本的。
b.Separator即分割線,它可以用來(lái)位于同一個(gè)選項(xiàng)組中而功能又有所區(qū)別的控件或控件組。
3.單一控件:Button、CheckBox、CombolBox、DropDown、EditBox和ToggleButton。
a.Button是最普通的按鈕,可以通過(guò)單擊它執(zhí)行一些操作。
b.CheckBox是復(fù)選框,可以用它來(lái)打鉤。
c.CombolBox是組合框,可以用它來(lái)輸入文本或從下拉列表中選擇。
d.DropDown是下拉框,無(wú)法向它輸入文本,只能從列表中選擇。
e.EditBox是編輯框,可以用它來(lái)輸入文本。
f.ToggleButton是類似開(kāi)關(guān)的按鈕,按鈕在按下(呈現(xiàn)深色)時(shí),是一種狀態(tài);松開(kāi)時(shí)(恢復(fù)淺色)又是一種狀態(tài)。
4.復(fù)合控件:Gallery、Menu和SplitButton。
這三個(gè)控件的作用比較相似,都是能生成下拉選項(xiàng)供用戶選擇。Gallery的特點(diǎn)是可以在下拉選項(xiàng)的一行中橫向排列項(xiàng)目,且本身不能被用作按鈕響應(yīng)單擊事件;Menu本身也不能用作按鈕;而SplitButton則可以相應(yīng)單擊事件。
我們來(lái)看一張這些控件的示意圖,就容易明白了。
五、做完界面以后,就可以著手編寫代碼了,但在開(kāi)發(fā)具體的功能前,我們要先寫一點(diǎn)必需的代碼,為后續(xù)的工作鋪路。
1.新建一個(gè)標(biāo)準(zhǔn)模塊,用來(lái)存放公共的數(shù)據(jù)。我們把這個(gè)模塊命名為mdlPublic。
定位到Module mdlPublic的下一行,聲明Application接口,為了簡(jiǎn)便,就叫App吧。
Module mdlPublic
Public App As Word.Application
End Module
2.回到第三步中提及的ThisAddIn.vb文件中,定位到Private Sub ThisAddIn_Startup() Handles Me.Startup的下一行,對(duì)接口App進(jìn)行實(shí)例化。
Private Sub ThisAddIn_Startup() Handles Me.Startup
App = Globals.ThisAddIn.Application
End Sub
這段代碼的意思是,在加載項(xiàng)啟動(dòng)時(shí)(Word顯示啟動(dòng)畫面時(shí),正是加載項(xiàng)啟動(dòng)的時(shí)候),獲取當(dāng)前運(yùn)行的Word實(shí)例,并賦值給尚未實(shí)例化的接口App。這跟開(kāi)發(fā)具體的功能有很大的關(guān)系,因?yàn)槲覀円ㄟ^(guò)這個(gè)接口來(lái)對(duì)Word文檔進(jìn)行操作。
好了,路已經(jīng)鋪好了,熟悉VBA的同學(xué)馬上就可以自己玩兒去了,只要把VBA中的Application全部改成這里的App就可以了。不過(guò)還是來(lái)看簡(jiǎn)單的一個(gè)例子。
當(dāng)我們從網(wǎng)頁(yè)等地方復(fù)制文本時(shí),有時(shí)會(huì)伴隨著大量討厭的空行,下面我們就通過(guò)代碼來(lái)去除這些空行。
1.在Ribbon欄上放置一個(gè)按鈕,更改名字為btnDeleteEmptyLine,標(biāo)題為“刪除空行”。然后在設(shè)計(jì)界面時(shí)雙擊它,進(jìn)入代碼編輯模式。
2.為了編寫代碼的便利,在首行先引入一個(gè)命名空間。
Imports Microsoft.Office.Interop.Word
3.然后編寫如下代碼,以實(shí)現(xiàn)具體的功能:
Private Sub btnDeleteEmptyLine_Click(sender As Object, e As RibbonControlEventArgs) Handles btnDeleteEmptyLine.Click
If App.Selection.Start = App.Selection.End Then App.ActiveDocument.Select()
With App.Selection.Find
.ClearFormatting()
.Text = "^p^p"
.MatchWildcards = False
.Forward = True
.Replacement.ClearFormatting()
.Replacement.Text = "^p"
.Execute(Replace:=WdReplace.wdReplaceAll)
End With
End Sub
3.單擊VS工具欄上的啟動(dòng)按鈕,片刻后Word就啟動(dòng)了,開(kāi)始了調(diào)試過(guò)程。我們可以測(cè)試代碼是否按預(yù)期工作。
這個(gè)例子其實(shí)是調(diào)用了Word的查找替換功能來(lái)實(shí)現(xiàn)刪除空行的目的,用VBA也能完成。
那么VSTO相較于VBA,其優(yōu)越性體現(xiàn)在哪里呢?我認(rèn)為有以下幾個(gè)方面:
1.VSTO可以用最新的VS以VB.net和C#等語(yǔ)言進(jìn)行開(kāi)發(fā),而VBA基于老舊的VB6.0,不光是語(yǔ)法,連開(kāi)發(fā)環(huán)境都幾乎照搬,代碼會(huì)寫得很不舒服。
2.VBA是存儲(chǔ)在文檔中的,沒(méi)有做到功能與文檔的分離;而VSTO可以做到。而Office移動(dòng)版會(huì)拒絕打開(kāi)帶有宏和VBA的文檔,給人帶來(lái)不便。
3.VSTO可以使用.net Framework提供的豐富的類庫(kù),輕松地實(shí)現(xiàn)五花八門的功能,相對(duì)來(lái)說(shuō),用VBA實(shí)現(xiàn)就比較麻煩。
4.與VB6.0一樣,VBA對(duì)Unicode的支持不良,無(wú)法讀取以UTF-8、UTF-16等編碼的文本,只支持以系統(tǒng)默認(rèn)代碼頁(yè)(ANSI)編碼的文本;而VSTO根本沒(méi)有這種問(wèn)題。
當(dāng)然VBA相較于VSTO唯一的優(yōu)點(diǎn)是輕便,由Office程序內(nèi)置,而開(kāi)發(fā)VSTO外接程序要安裝VS。而綜合來(lái)看,肯定是VSTO的潛力要優(yōu)于VBA的。
好了,入門就到這里了,大家自己玩去吧!