本文算是一個VBA很有意義的啟蒙,本文的內(nèi)容我以前只給兩個有VBA基礎(chǔ)的朋友講過
現(xiàn)在這倆,一個在學(xué)python,一個已經(jīng)開了Office排版公司
本文內(nèi)容對于小白,有巨大的啟蒙作用:
一、理解對象模型
Office有多種文檔格式,doc、docm、docx、xls、xlsm、xlsx、ppt、ppa、pptm、vsd、vsdx等等
不管是WPS還是微軟,開發(fā)這些Office程序之前,肯定要先定義好這些格式的文件結(jié)構(gòu)。
注:微軟現(xiàn)在已經(jīng)公開了所有office文件的結(jié)構(gòu),這也是為什么現(xiàn)在有不少第三方office文件解析庫(例如java的POI, .net的NPOI, 還有商業(yè)庫aspose系列等等……)的原因。
文件結(jié)構(gòu)里會明確定義,文件頭長啥樣,文字、圖片、表格、OLE對象等等,在文檔里以什么形式擺放,等等一套復(fù)雜的規(guī)則。
定義好之后,就開始寫各種代碼實現(xiàn)讀寫這些定義好的文檔。
期間會定義很多常量、很多全局變量、會寫很多類、定義不少接口,寫出很多輸入輸出的函數(shù)……
這個時候,有必要說一下office對象模型,其實是COM(Component Object Model),這個貨是微軟一個了不起的創(chuàng)造。至于為什么這么說,以后在VBA高階應(yīng)用里介紹。
現(xiàn)在你只需要理解,這個對象模型,其實就是微軟把他們的工程師開發(fā)的一些對象、方法、屬性、事件,以一個可視化的文檔結(jié)構(gòu)形式展示給用戶了,方便用戶直接通過對象模型調(diào)用底層的一些接口,來實現(xiàn)目標(biāo)文件的讀寫操作。
微軟爸爸把VB6改造了一下,結(jié)合了一下COM,移植到了Office里,改名叫Visual Basic for Application(VBA),然后VBAer就很輕松的,在VBA里通過F2查看對象模型,通過IDE提供的成員提醒(上一講講過的Ctrl J記得吧)訪問對象模型。很輕松地完成對Office文件的訪問了。其酸爽刺激簡直不可言喻。
學(xué)習(xí)Office VBA童鞋們,你們不知道你們是多么的幸運。這么簡單的一門語言,給你一個禮拜學(xué)不會,都對不起微軟爸爸。
對于對象、方法、屬性、事件,這幾個外星語言,看我來給NewBee舉個栗子解釋一哈:
你是廚師
柴米油鹽醬醋茶鍋碗瓢盆就是對象
煎炸燜煮蒸燉炒就是方法
香辣咸淡就是屬性
高壓鍋里的飯煮熟了,就會“?!币幌峦ㄖ悖@個叮就可以理解為事件
總結(jié)一下,對象模型,你就簡單理解為對象、方法、屬性、事件等的顯式集合。
這個時候,應(yīng)該有幾張圖片:
上圖看到木?直接光標(biāo)放在Address這里,按F1,自動彈出Range.Address屬性的官方幫助。你們是真的沒有意識到F1是個多么龐大的代碼寶庫吧。
學(xué)VBA,花7天時間入門,然后多花時間看看F1,玩玩窗體、數(shù)組、集合、字典、正則,不出1個月就能獨立解決自己碰到的所有問題了。
二、前期綁定和后期綁定
前期綁定:就是在使用改對象庫之前,像講它引用到工程里,這樣就可以在IDE里方便的看到其對象模型成員(啥成員,上面剛講的那些)了。
添加引用
工具-引用,就可以看到上圖界面。
已經(jīng)勾選的,是當(dāng)前已經(jīng)添加的引用,這些我們叫前期綁定好了
如果還想添加列表里沒有的內(nèi)容(不在列表里,證明其沒有注冊),就直接從瀏覽按鈕進(jìn)去選中響應(yīng)的組件加進(jìn)來。
這里不得不吐槽一下,這個引用界面其實不怎么好用,不過,誰叫微軟是你爸爸呢,你也不敢嫌棄,嫌棄也沒用,反正爸爸也不會理你。
前期綁定后,怎么玩呢,下面來一個代碼。
以Word里訪問Excel為例:
在WordVBA里加上Excel的引用
Sub UserModel()Dim xlApp As Excel.Application Dim xlBook As Excel.Workbook Dim xlSht As Excel.WorksheetDim xlRng As Excel.Range '注意對象賦值用SetSet xlApp = New Excel.Application '新建一個Excel.Application進(jìn)程Set xlBook = xlApp.Workbooks.Open('c:\1.xlsm') '通過進(jìn)程打開一個已有Excel工作簿Set xlSht = xlBook.Worksheets('Sheet1') '訪問這個工作簿里名稱為'Sheet1'的工作表Set xlRng = xlSht.UsedRange '返回該工作表里使用的區(qū)域Debug.Print xlRng.Address '打印Range對象的地址屬性End Sub
上面四句聲明做幾條簡單解釋:
1.前期綁定后,才能這樣聲明Excel里的對象
2.強烈建議新手在前期綁定時,不要省略前綴,這樣才能加快你對對象模型的理解
很多人在寫代碼時,跟上面的風(fēng)格完全不同,他們習(xí)慣這樣寫的。
Dim xl As Application
Dim bk as workbook
dim sht as worksheet
dim r as range
下面,請你們自己把我上面的代碼,改成下面的這些
然后F5運行,再F8單步試試,看看到底發(fā)生了什么。有收獲可以在評論里分享。
3.寫VBA代碼時,嚴(yán)格按照對象模型來聲明和使用是有很大的好處的
Dim r, s
set r = range('A1')
s = worksheets(1).name
代碼TM這樣寫,遺患無窮。
所以,經(jīng)常會見到新人提問,我的代碼怎么又報錯了,F(xiàn)8試過了,怎么還是不對啊,都瘋了。
原因其實就在這里。
上述代碼相當(dāng)于如下代碼:
Dim r As Variant, s as Variant '一個效率極低的類型
Set r = Application.ActiveWorkbook.ActiveSheet.Range('A1') '省略的是當(dāng)前激活的工作表
s = Application.ActiveWorkbook.Worksheets(1).Name
都怪微軟爸爸對你們太好,讓你們不認(rèn)祖先,都可以寫代碼,而且大部分情況下,還都能成功完成任務(wù)。
如果你像我前面說的那樣寫代碼,時刻注意返回值適不適合存到變量里。你特么最少能少60%的問題。
很多人在學(xué)VBA時,學(xué)習(xí)的方法就錯了,不停地走彎路。
很多人在教VBA時,教育的方法就錯了,光教怎么吃魚,不教怎么釣魚。
后期綁定:我想你也能猜出來,就是你不用引用就可以直接使用咯。
先來后期綁定的語法:
Dim xlApp As Object, xlBook as Object
Set xlApp = CreateObject('Excel.Application')
Set xlBook = xlApp.Workbooks.Open('c:\1.xlsx')
是不是發(fā)現(xiàn)跟上面差別不大?
然而,你圖樣了,變量聲明的時候全部用的是Object,為毛不像有些人那樣就偷懶,Dim xlApp, xlBook呢,使用Variant又不是不能存Object。
我TM大寶劍都快按捺不住了。Object本身效率就沒有前期綁定高,然后Variant比Object效率還要低,你說你用啥。
肯定還會有人抬杠,這點效率差別,相比代碼完成后的效率前后對比,可以忽略不計。
如果你這么說,我只能說:好的,好的,你說的都對,你開心就好。
還有在后期綁定里,可就沒有一分半點相關(guān)的成員提醒了,你按Ctrl J按到手抽筋也不會有。
當(dāng)然后期綁定也有一大好處:就是我特么就不用管你引用的類庫的版本了。
你的代碼是Word里引用了Excel 2010,如果是前期綁定,放到Excel2013里,還得重新引用。
而用后期綁定,極大概率代碼不需要修改。除非相關(guān)使用到的內(nèi)容,在2013的對象模型里相比2010有調(diào)整。
下面給一張前期綁定和后期綁定的對應(yīng)整理(不全):
常用的對象的前期綁定和后期綁定都有了。
當(dāng)然,怎么知道后期綁定的字符呢。這個暫時也不講了,后面在高階應(yīng)用里一起扒,因為文章是發(fā)出去了再被我撤回來加的上面圖片。
一下子又扒了3k多字,本來還預(yù)定了一個實戰(zhàn)操作,改下一講分解吧。