VBA類(lèi)模塊完全教程_第1頁(yè)
VBA類(lèi)模塊完全教程_第2頁(yè)
VBA類(lèi)模塊完全教程_第3頁(yè)
VBA類(lèi)模塊完全教程_第4頁(yè)
VBA類(lèi)模塊完全教程_第5頁(yè)
已閱讀5頁(yè),還剩13頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、-VBA類(lèi)模塊完全教程寫(xiě)下這個(gè)題目,可能會(huì)讓很多朋友疑惑,筆者先埋下一個(gè)關(guān)子,很快我會(huì)讓您知道這個(gè)標(biāo)題的寓意。這份禮物送給現(xiàn)在想學(xué)習(xí)類(lèi)知識(shí)或曾經(jīng)學(xué)過(guò)但因?yàn)楦鞣N原因沒(méi)有“修成正果的朋友,我期望的結(jié)果是這篇文章后,您可以在類(lèi)模塊中像在標(biāo)準(zhǔn)模塊中寫(xiě)代碼一樣熟練,我也期望不至于太乏味而使您沒(méi)有耐心看完整篇文章,或者說(shuō)期望您學(xué)習(xí)的過(guò)程是輕松愉悅的,但愿我可以做到。文章構(gòu)劃為8局部:1什么是類(lèi)2為什么要學(xué)習(xí)類(lèi)3類(lèi)的預(yù)備知識(shí)4創(chuàng)立類(lèi)屬性5創(chuàng)立類(lèi)方法6創(chuàng)立類(lèi)事件7一個(gè)完整的類(lèi)實(shí)例8未完的結(jié)尾什么是類(lèi)在我們身邊,一樣或相似的物品無(wú)處不在,從生活用品,到工業(yè)產(chǎn)品,通常它們都是由同一個(gè)可以稱(chēng)為“模具的東西生產(chǎn)出來(lái)。

2、理解類(lèi),一般要先從對(duì)象談起,但由于從不同的角度,有不同的理解,從而也有不同的關(guān)于類(lèi)的定義,本文不去探討一個(gè)完整并且公認(rèn)的類(lèi)概念,在這一局部后,只要你有一個(gè)根本的判斷并且在遇到時(shí)知道是類(lèi)就可以了。在上面的這個(gè)例子中,一個(gè)“模具就是一個(gè)“類(lèi),而由它生產(chǎn)出的每一個(gè)產(chǎn)品,就是一個(gè)“對(duì)象。看下面的VBA語(yǔ)句:Dim t*1 As Te*tbo* 不用解釋它的意思吧,這里我們用到一個(gè)類(lèi)Te*tbo*定義了一個(gè)對(duì)象t*1,再來(lái)看:Dim t*1 As Te*tbo* Dim t*2 As Te*tbo* 又定義了一個(gè)對(duì)象t*2,如果你不嫌煩,我還可以繼續(xù)下去。對(duì)象增加了,但As后的Te*tbo*沒(méi)有變,它可

3、以無(wú)限制的使用下去。類(lèi)是一個(gè)隱者,上面Te*tbo*是VBA已經(jīng)給我們準(zhǔn)備好的一個(gè)類(lèi),我們無(wú)法知道VBA是怎么準(zhǔn)備的它的真身被隱藏了,但我們可以知道對(duì)象t*1怎么用。VBA把對(duì)對(duì)象的使用劃分為三種,屬性、方法和事件后面預(yù)備知識(shí)我們?cè)偬?。然而,Te*tbo*是一個(gè)類(lèi),仍然不是本文要說(shuō)的類(lèi),因?yàn)樗荲BA已經(jīng)給我們準(zhǔn)備好了的,我們要做的,只是知道如何使用它而已。本文要介紹的,是利用VBA已經(jīng)給我們提供的資源,來(lái)構(gòu)建我們自己的類(lèi),姑且可稱(chēng)之為自定義類(lèi)。這需要在VBE下,通過(guò)插入類(lèi)模塊,然后向類(lèi)模塊中寫(xiě)入代碼來(lái)完成。這就是你常常聽(tīng)說(shuō)的類(lèi),本文的主題就是這個(gè)包含代碼的模塊!通過(guò)這個(gè)模塊,可以提供給我們一

4、個(gè)和VBA提供給我們的諸如Te*tbo*功能性質(zhì)完全一樣的類(lèi),然后,再由我們自己象使用Te*tbo*一樣使用!類(lèi)是一個(gè)隱者,她把自己藏在所有模塊的最后,甚至在多數(shù)情況,她從不出場(chǎng)?,F(xiàn)在,她掛著神秘的微笑,向你走來(lái),你要拒絕嗎為什么要學(xué)習(xí)類(lèi)模塊類(lèi)通常被認(rèn)為是學(xué)習(xí)VBA的難點(diǎn)之一,之所以如此,因?yàn)橄鄬?duì)于制造一個(gè)標(biāo)準(zhǔn)模塊或用戶(hù)窗體,我們可以找到的類(lèi)的學(xué)習(xí)資源少之又少,甚至很多VB的書(shū)籍也只有繆繆字語(yǔ)在后面的預(yù)備知識(shí),我們?cè)偬崃硪粋€(gè)重要的原因。從技術(shù)角度上看,類(lèi)的構(gòu)建,不象窗體,VBA的類(lèi)也不象有些語(yǔ)言提供了可視的設(shè)計(jì)界面,感性上那樣直接,隱者!她是不可視的設(shè)計(jì),所有的構(gòu)建都是通過(guò)在類(lèi)模塊中寫(xiě)代碼來(lái)實(shí)

5、現(xiàn)的。1學(xué)習(xí)是一種興趣的追求俗語(yǔ)云:學(xué)的千千萬(wàn),用的有幾何.又曰:書(shū)到用時(shí)方恨少。林語(yǔ)堂先生將做學(xué)問(wèn)劃分為三重境界,第二重說(shuō)“為伊消得人憔悴,衣帶漸寬終不悔,大多數(shù)朋友,包括本人,都不是專(zhuān)業(yè)程序員,學(xué)習(xí)程序只是一種興趣和愛(ài)好,就好象有人喜歡修煉網(wǎng)游一樣,對(duì)喜歡程序的人,不斷地學(xué)習(xí)和提高,也是一種追求優(yōu)秀的態(tài)度,并且樂(lè)意享受這個(gè)追求的過(guò)程。模塊、控件、庫(kù)和類(lèi)構(gòu)成軟件工程開(kāi)發(fā)的四大技術(shù),而類(lèi)技術(shù)是控件和庫(kù)技術(shù)的根底,我們不得不學(xué)。2類(lèi)有什么用如你前面看到的我們使用Te*tbo*類(lèi),類(lèi)可以創(chuàng)立大量性質(zhì)相近的對(duì)象,減輕我們的程序量,簡(jiǎn)潔代碼并提高效率。類(lèi)定義后,在其它模塊中使用時(shí),我們就可以暫時(shí)忘記或

6、不必考慮它部復(fù)雜的細(xì)節(jié),讓我們變得輕松,VBA雖然不能真正封裝類(lèi)的形式,但在這里,我們可以封裝它的概念。這并不是類(lèi)的全部好處,其它的,留著朋友們用的時(shí)候慢慢體會(huì)吧。類(lèi)掛著神秘的微笑,已經(jīng)走到你的大門(mén)口,開(kāi)門(mén)迎接她吧,你還等什么.類(lèi)的預(yù)備知識(shí)廣義上講,所有VBA的知識(shí),包括語(yǔ)句、函數(shù)以及為我們提供的標(biāo)準(zhǔn)類(lèi)甚至第三方的資源都可以在類(lèi)中被使用。本文無(wú)法也不準(zhǔn)備逐一探討,這里只說(shuō)一些最密切最根本的,但即使這樣,筆者仍然不能把這些點(diǎn)的知識(shí)都寫(xiě)到,甚至因?yàn)閷?duì)問(wèn)題解釋清晰或符合邏輯的需要,采用非規(guī)的表述,對(duì)專(zhuān)門(mén)問(wèn)題的全面理解,請(qǐng)讀者注意參考有關(guān)標(biāo)準(zhǔn)幫助文檔并加以甄別。1從構(gòu)建者的角度理解對(duì)象上一回我們提到,

7、類(lèi)被認(rèn)為是VBA難點(diǎn)還有一個(gè)原因,這就是我們的思想!VBA提供了大量的現(xiàn)成的類(lèi),我們幾乎不再需要去構(gòu)建自己的類(lèi),這種結(jié)果,我們熟練地習(xí)慣了從使用者的角度去理解類(lèi)的實(shí)例:對(duì)象,包括它的屬性、方法和事件。但是,現(xiàn)在你還要嘗試做一個(gè)提供者,這和你作為使用者時(shí)的思考方法是完全不同的,甚至是革命性的。這種角色的轉(zhuǎn)位是痛苦的,它需要你放棄你原本可以自豪地解釋出對(duì)象以及它的屬性、方法、事件的定義,它們?cè)臼侨绱诉壿嫷乇粍澐?,如此清晰,但現(xiàn)在,類(lèi)模塊中的一切,彼此交織,你會(huì)發(fā)現(xiàn)它們都模糊了!是需要你忘掉所有固執(zhí)的“招勢(shì)的時(shí)候了,當(dāng)你心中無(wú)劍時(shí),轉(zhuǎn)位也就完成了,隱者變得清晰了,她是如此美麗。且慢,在你完全忘掉前

8、,讓我們最后再看一眼它們的樣子,呵呵,如果你實(shí)在忘不掉,你就提醒一下自己構(gòu)建者的身份吧。下面是通常情況下關(guān)于對(duì)象、屬性、方法、事件的根本表述,如果你以前沒(méi)了解過(guò),則應(yīng)當(dāng)找些資料先認(rèn)真地理解它們,然后再按照上面的提示去做。對(duì)象是由類(lèi)創(chuàng)立的一個(gè)實(shí)例,它是類(lèi)的實(shí)體化。對(duì)象的引用和操作被邏輯上劃分為不重疊的三個(gè)局部:屬性是指對(duì)象的特性。以前面的Te*tbo*為例,有長(zhǎng)度,高度,框中顯示的文字等等。方法是指對(duì)象的*個(gè)操作。如讓Te*tbo*成為當(dāng)前的焦點(diǎn)即光標(biāo)移動(dòng)到它上面。事件是指對(duì)象對(duì)外部動(dòng)作的響應(yīng)。如我們用鼠標(biāo)點(diǎn)擊Te*tbo*時(shí),會(huì)產(chǎn)生一個(gè)Click事件,改變它的值,則產(chǎn)生一個(gè)Change事件變量

9、的作用域變量因?yàn)槁暶鞯奈恢煤头绞讲煌瑥亩胁煌淖饔糜?。作用域是指變量在多大圍能被代碼識(shí)別??梢詣澐譃檫^(guò)程級(jí)、模塊級(jí)和全局變量。過(guò)程級(jí)變量在過(guò)程中聲明,這里過(guò)程指的是一個(gè)Sub或Function,也包括后面提到到屬性過(guò)程。通常用Dim或Static進(jìn)展聲明。Dim聲明的變量,只在該過(guò)程執(zhí)行時(shí)存在,過(guò)程完畢,變量的值也就消失了。Static聲明的變量稱(chēng)為靜態(tài)變量,這個(gè)值在整個(gè)程序運(yùn)行期間都存在。模塊級(jí)變量對(duì)整個(gè)模塊的所有過(guò)程都有效,但對(duì)其它模塊不可用。可以在模塊頂部聲明。聲明模塊級(jí)變量用Private關(guān)鍵字和直接使用Dim沒(méi)有區(qū)別。但推薦使用Private進(jìn)展聲明,因?yàn)檫@樣可以方便地與后面的全

10、局變量區(qū)分開(kāi)來(lái)。全局變量是對(duì)整個(gè)VBA工程的所有過(guò)程都有效的變量,使用Public關(guān)鍵字在標(biāo)準(zhǔn)模塊的頂部來(lái)聲明。在類(lèi)模塊中,對(duì)變量作用域的理解要注意下面兩點(diǎn):a由于類(lèi)是生成對(duì)象的模具,每生成一個(gè)對(duì)象,相當(dāng)于產(chǎn)生了一個(gè)副本,這個(gè)副本就是對(duì)象的“真身,副本間是相互獨(dú)立的,從而,模塊級(jí)的變量只作用于副本自身。b類(lèi)模塊中使用Public關(guān)鍵字,只有當(dāng)對(duì)象變量是這個(gè)類(lèi)的實(shí)例時(shí),才能被。過(guò)程和函數(shù)變量、過(guò)程Sub、函數(shù)Function是我們?cè)跇?biāo)準(zhǔn)模塊中使用的最根本的構(gòu)件,在類(lèi)摸塊中,它們?nèi)匀皇亲罡竞椭匾慕巧?duì)于它們,你已經(jīng)再熟悉不過(guò),之所以前面還要花這么多文字,是為了突出它的重要,也是想讓你放松一下

11、,哦,我花了很短的時(shí)間已經(jīng)看了這么多我也寫(xiě)了這么多!。過(guò)程和函數(shù)并無(wú)實(shí)質(zhì)的區(qū)別,當(dāng)需要返回值時(shí),就使用Function,如果不需要返回任何結(jié)果,隨你的愛(ài)好,但這時(shí)推薦你使用Sub,因?yàn)檫@樣更符合微軟的本意。過(guò)程Sub、函數(shù)Function也有作用域,在標(biāo)準(zhǔn)模塊過(guò)使用Private和Public關(guān)鍵字可以省略Public關(guān)鍵字,因?yàn)樗悄J(rèn)的,可以劃分為模塊級(jí)和全局級(jí),以決定它是在當(dāng)前的模塊有效還是整個(gè)工程有效。同變量一樣,在類(lèi)模塊中使用Public關(guān)鍵字,只有當(dāng)引用對(duì)象變量是這個(gè)類(lèi)的實(shí)例時(shí),才能被。通用部控件ControlsVBA提供Control類(lèi)作為一般部控件類(lèi)型,當(dāng)使用Dim Ct As

12、 Control 聲明了一個(gè)變量后,就可以將任何控件賦給該變量,而不管具體的類(lèi)型,因?yàn)樵陬?lèi)的使用通常是處理大量相近的對(duì)象,所以這種特性非常有用。在實(shí)際使用時(shí),我們多是通過(guò)容器控件的Controls屬性來(lái)返回一個(gè)Control的集合對(duì)象。Dim Ct As Control For Each Ct In Me.Controls   If TypeName(Ct) = "mandButton" Then MsgBo* Ct.Caption Ne*t 上面這段代碼可以遍歷窗體的所有控件并報(bào)告找到的命令按鈕。集合Collection Collection是我們?cè)谑褂妙?lèi)時(shí)最常

13、用到的對(duì)象。一個(gè)Collection對(duì)象代表一組相關(guān)的工程,雖然它的成員并不被強(qiáng)制要同一類(lèi)型的的,但請(qǐng)記住,這通常并不能給我們帶來(lái)額外的方便,相反,我們通常是用來(lái)收集同一類(lèi)型的數(shù)據(jù)。建立集合的方法和建立其它對(duì)象一樣,如:Dim col As New Collection 集合建立后,可以使用Add方法添加成員,用Remove方法刪除成員,用Item方法從集合中返回特定成員。Private Sub mandButton1_Click()   Dim col As New Collection   Dim i%   Dim ct As Control   F

14、or Each ct In Me.Controls     If Left(ct.Name, 7) = "Te*tBo*" Then col.Add ct   Ne*t ct   For i = col.Count To 1 Step -1     MsgBo* "下面刪除成員" & col.Item(i).Name     col.Remove i   Ne*t i End Sub 上面的代碼先將窗體上所有的Te*tBo*參加

15、到集合中,然后再刪除掉。Count屬性返回集合的成員數(shù)量,Remove方法后面的參數(shù)是集合成員的索引號(hào)。成員的索引號(hào)通常是按照參加的順序自然編號(hào),從1開(kāi)場(chǎng),但可以在參加時(shí)使用Add方法的參數(shù)進(jìn)展改變。Add方法的完整語(yǔ)法是:object.Add item, key, before, afteritem 必需的。任意類(lèi)型的表達(dá)式,指定要添加到集合中的成員。key 可選的。唯一字符串表達(dá)式,指定可以使用的鍵字符串,代替位置索引來(lái)集合中的成員。before/after 可選的。表達(dá)式,指定集合中的相對(duì)位置。下面語(yǔ)句向集合增加一個(gè)對(duì)象Te*tBo*1,并定義該成員的關(guān)鍵字為t*1。col.Add Te

16、*tBo*1, "t*1" 然后,下面兩句都可以向集合中增加一個(gè)Te*tBo*2,并把它放在成員Te*tBo*1的前面。col.Add Te*tBo*2, , col.Count col.Add Te*tBo*2, , "t*1" 第一句中,因?yàn)橹挥幸粋€(gè)成員,所以col.Count也是索引號(hào)使用事件的WithEvents變量WithEvents不是一個(gè)單獨(dú)的語(yǔ)句,為了使用對(duì)象的事件,需要在聲明該對(duì)象時(shí)使用WithEvents關(guān)鍵字。例如:Dim WithEvents app As Application 將上面的語(yǔ)句寫(xiě)入ThisWorkBook的模塊,可

17、以看到在通用框中出現(xiàn)了一個(gè)變量app:此主題相關(guān)圖片如下:在通用框選擇app后,左邊的聲明框便會(huì)顯示app的事件。此主題相關(guān)圖片如下:需要注意的是,使用WithEvents只是聲明了對(duì)象變量,而并不實(shí)際生成對(duì)象,為了生成真實(shí)的對(duì)象,你仍然需要在聲明后向生成其它對(duì)象一樣,使用Set語(yǔ)句進(jìn)展指定。此外,WithEvents變量不能是通用類(lèi)變量如Object,而必須指定類(lèi)名,也不能把WithEvents變量聲明為As New。不能在標(biāo)準(zhǔn)模塊中使用WithEvents.初識(shí)類(lèi)模塊現(xiàn)在,請(qǐng)翻開(kāi)你的VBE,主菜單-插入-類(lèi)模塊。插入了一個(gè)類(lèi)模塊,也就建立了一個(gè)類(lèi)。類(lèi)模塊的名字就是類(lèi)的名字。你現(xiàn)在看到的,她

18、的名字叫“類(lèi)1,這是VBA按她姐妹排行給她取的的,是的,VBA一貫如此,你早就熟悉了這種規(guī)則,現(xiàn)在,在標(biāo)準(zhǔn)模塊或其它模塊中輸入Dim As的時(shí)候,提示框中她已經(jīng)出現(xiàn)了。但我知道,有件事你正耿耿于懷,“類(lèi)1,太沒(méi)個(gè)性了,想改成自己要的名字吧。很容易,和你改標(biāo)準(zhǔn)模塊的名字一樣,翻開(kāi)屬性窗口,看到了吧,第一行就是她的名字,隨你的意愿修改吧。此主題相關(guān)圖片如下:你或許已經(jīng)注意到,在名字下面,只有一個(gè)屬性:Instancing,其值也只有兩個(gè)選項(xiàng):Private和PubliotCreatable。事實(shí)上,你完全可以忽略這個(gè)Instancing,就象你完全忽略條件編譯指令一樣,因?yàn)樵赩BA中我們幾乎用不到

19、它們,而只需維持她的默認(rèn)值即可。至少我是這樣認(rèn)為的,但我給不了您充足的理由,而只是個(gè)人的一種狹隘經(jīng)歷。既然提到了,就簡(jiǎn)單說(shuō)明一下:Instancing屬性決定該“類(lèi)在其它工程中是否可以被使用。我們知道,標(biāo)準(zhǔn)模塊中的Public過(guò)程,可以保存在宏工作簿甚至直接被另一工作簿的工程調(diào)用,但類(lèi)中的代碼是不可分割的整體,所以必須整體決定是否允許外用。當(dāng)Instancing屬性設(shè)為Private默認(rèn)時(shí),不允許其它工程。當(dāng)設(shè)置為PubliotCreatable時(shí),只有在自己的工程創(chuàng)立了該類(lèi)的對(duì)象時(shí),其它工程才允許使用這個(gè)對(duì)象,注意,僅僅是在本工程中創(chuàng)立的對(duì)象,而不能用她在其它工程中創(chuàng)立對(duì)象。隱者已經(jīng)來(lái)到你的

20、身邊,透過(guò)薄薄的面紗,你似乎已看到她神秘的微笑。站起身來(lái),走過(guò)去吧!創(chuàng)立類(lèi)屬性讓我們想一下作為類(lèi)的使用者時(shí),我們是如何操作對(duì)象的屬性的,對(duì)象屬性的操作不外乎讀和寫(xiě)兩種。當(dāng)我們要給對(duì)象的*個(gè)屬性賦值時(shí),我們會(huì):Te*tBo*1.Te*t=abc 當(dāng)我們要讀取對(duì)象的屬性時(shí),S= Te*tBo*1.Te*t 現(xiàn)在,看看作為類(lèi)的提供者需要怎樣做。我們將“類(lèi)1改名為“MyClass并為它創(chuàng)立一個(gè)名稱(chēng)為*的字符型屬性。1使用Public變量創(chuàng)立類(lèi)屬性在類(lèi)模塊中寫(xiě)下行代碼:Public *$ 是的,就這么簡(jiǎn)單,通常情況下,只需要這么簡(jiǎn)單使用Property過(guò)程創(chuàng)立類(lèi)屬性Private s$ Public P

21、roperty Get *() As String   * = s End Property Public Property Let *(ByVal c As String)   s = c End Property 我們可以省去上面默認(rèn)的Public。但看上去還是有點(diǎn)麻煩哦,不僅需要兩個(gè)公共過(guò)程,而且還要一個(gè)輔助的私有變量s和一個(gè)參數(shù)c。在類(lèi)模塊中,Property過(guò)程把對(duì)屬性的讀寫(xiě)分開(kāi)了,說(shuō)一下Property過(guò)程的工作機(jī)制,當(dāng)標(biāo)準(zhǔn)模塊中的代碼讀取對(duì)象的屬性時(shí),便會(huì)觸發(fā)存在的Property Get過(guò)程,或者說(shuō)Property Get過(guò)程提供了屬性的讀功能,同樣,Pro

22、perty Let過(guò)程提供了寫(xiě)屬性。這樣,上面的兩個(gè)過(guò)程當(dāng)然在模塊中沒(méi)有先后的要求,可以只有一個(gè),或者雖然兩個(gè)都有,但卻不全是Public,從而提供出去的屬性是只讀或只寫(xiě)呵呵,沒(méi)見(jiàn)過(guò)只寫(xiě)哈。僅僅是為了提供只讀或只寫(xiě)的屬性,代碼就從一行變成了七行.!這樣的理由,你不會(huì)信服, VBA中的類(lèi)通常是提供給我們自己使用的!如果它確實(shí)是只讀的,我們自覺(jué)地去只讀就是了!我們使用Property過(guò)程還有其它理由,最根本的一條,我們可以利用這個(gè)“過(guò)程來(lái)做我們想做的事??匆豢矗篜ublic Property Let *(ByVal c As String)   s = Format(c, "0

23、000") End Property 這里我們只是簡(jiǎn)單的利用了一下,更多的在后面你會(huì)看到。此外,誰(shuí)會(huì)保證有一天你不使用VB給別人提供類(lèi)呢,這個(gè)技術(shù)可是通用的。提供一段標(biāo)準(zhǔn)模塊的測(cè)試代碼,來(lái)看看我們上面構(gòu)建的類(lèi)屬性,你自己試試吧。Sub aTest()   Dim mc As New MyClass   mc.* = "123"   Debug.Print mc.* End Sub 就象我們給普通變量和對(duì)象變量賦值的方式不同一樣,對(duì)象變量是使用Set賦值的。對(duì)“對(duì)象屬性,VBA提供了Property Set來(lái)代替構(gòu)建“普通屬性使用的Pr

24、operty Let。來(lái)看一段代碼:Private t* As Object Property Get *() As Object   Set * = t* End Property Property Set *(ByVal o As Object)   Set t* = o End Property 和前面的比較一下,除了多一個(gè)Set,實(shí)在沒(méi)有什么不同。告訴你一個(gè)小秘訣,你可以按照Function去記住Property Get的用法,按照Sub去記住Property Let /Set 屬性的初始值我們常常希望,當(dāng)一個(gè)對(duì)象建立的時(shí)候,它的*些屬性會(huì)被自動(dòng)賦予一個(gè)初始值,這樣

25、,對(duì)具有最常見(jiàn)的屬性值的對(duì)象可以減少重復(fù)性的賦值工作。這需要借助于類(lèi)的構(gòu)建函數(shù)來(lái)完成。在類(lèi)模塊代碼窗口的“通用框中點(diǎn)擊向下的小三角箭頭,選擇“Class,右面聲明框中可以看到兩個(gè)選項(xiàng),“Initialize和“Terminate,我們對(duì)它們應(yīng)該不陌生,很多對(duì)象都有這兩個(gè)事件,Initialize事件當(dāng)對(duì)象建立時(shí)發(fā)生,Terminate事件在對(duì)象對(duì)釋放時(shí)發(fā)生。由于類(lèi)是靜態(tài)存在的,它并不是真正的對(duì)象,所以在類(lèi)模塊中,它們通常被稱(chēng)為構(gòu)建函數(shù)和析構(gòu)函數(shù),或構(gòu)建過(guò)程和析構(gòu)過(guò)程。對(duì)它們的理解和你在對(duì)象中的用法并沒(méi)有什么不同。當(dāng)一個(gè)對(duì)象被建立時(shí),構(gòu)建函數(shù)將被首先執(zhí)行,同樣,當(dāng)對(duì)象釋放后,將執(zhí)行析構(gòu)函數(shù)。下面

26、建立MyClass,屬性*初始值為0001”的全部測(cè)試代碼:類(lèi)模塊MyClass的代碼 Option E*plicit Private s$ Public Property Get *() As String   * = s End Property Public Property Let *(ByVal c As String)   s = c End Property Private Sub Class_Initialize()   s = "0001" End Sub 標(biāo)準(zhǔn)模塊1的代碼 Option E*plicit Sub aTest(

27、)   Dim mc As New MyClass   Debug.Print mc.* End Sub 隱者為你揭開(kāi)了第一層面紗,你隱約已看到她美麗的面厐,雖然還不是很清晰,但你知道,早晚會(huì)的創(chuàng)立類(lèi)方法放松一下,請(qǐng)拿出你家的紫砂壺,泡上一壺好茶,聽(tīng)我給你將類(lèi)的方法的故事,你的茶品完了,我的故事也差不多就講完了。1構(gòu)建類(lèi)的方法其實(shí)就是在類(lèi)模塊中寫(xiě)公共的Sub和Function 現(xiàn)在我們給前面提到的MyClass創(chuàng)立一個(gè)方法PutIntoActiveCell,功能是將*屬性值寫(xiě)入活動(dòng)單元格。Public *$ Sub PutIntoActiveCell()   Ac

28、tiveCell = * End Sub 在標(biāo)準(zhǔn)模塊中用下面的代碼測(cè)試一下:Sub aTest()   Dim mc As New MyClass   mc.* = "abc"   mc.PutIntoActiveCell End Sub 這是本回要告訴你的全部嗎.你還沒(méi)有開(kāi)場(chǎng)品茶吧.就這樣了完畢.這是最重要和根本的,但卻不是全部。你是否有一種感覺(jué),但你不能清楚地說(shuō)出來(lái).端起你得意的茶杯,品一口茶,我們繼續(xù)。類(lèi)的方法環(huán)境借用廣為眾知的一個(gè)名詞“數(shù)據(jù)環(huán)境,雖然不準(zhǔn)確,但我實(shí)在想不出更好的稱(chēng)謂來(lái)代替,姑且這么叫吧。稍后你就會(huì)知道它的含義。類(lèi)可以象V

29、BA提供給我們的很多標(biāo)準(zhǔn)類(lèi)一樣風(fēng)光無(wú)限,所有的程序設(shè)計(jì)者都在工程中使用它,但更多時(shí)候,我們所構(gòu)建的類(lèi)只在特定的環(huán)境下被使用,類(lèi)的方法環(huán)境是指包括類(lèi)所在工程的其它成員在的,可以調(diào)用的資源的集合。工作簿、工作表、窗體或其它,在類(lèi)模塊中,你可以象在標(biāo)準(zhǔn)模塊中一樣操作它們,千萬(wàn)不要因?yàn)閾Q成了類(lèi)模塊而產(chǎn)生任何疑慮,作為類(lèi)的創(chuàng)立者,你要讓類(lèi)模塊中的代碼象你在標(biāo)準(zhǔn)模塊中一樣親近它們,只要你認(rèn)為必要。脫離了方法環(huán)境的、謹(jǐn)小慎微的、封閉的類(lèi)實(shí)在沒(méi)有什么意義。如果你預(yù)期方法環(huán)境在運(yùn)行時(shí)可能會(huì)有變化,你要事先預(yù)知它們并象在標(biāo)準(zhǔn)模塊中一樣使用恰當(dāng)?shù)拇胧?,比方你不能確定運(yùn)行時(shí)活開(kāi)工作表的名稱(chēng)但你確定屆時(shí)會(huì)是一個(gè)工作表,

30、你可以使用ActiveSheet。我反復(fù)說(shuō)“和標(biāo)準(zhǔn)模塊一樣,就是想告訴你在類(lèi)模塊中創(chuàng)立方法時(shí),對(duì)工程中其它成員的操作,和你已經(jīng)熟悉的標(biāo)準(zhǔn)模塊中的方式的實(shí)在沒(méi)有什么不同,這一原則適用于類(lèi)模塊中所有代碼也許叫代碼環(huán)境更準(zhǔn)確些,而不僅僅是構(gòu)建方法的代碼?,F(xiàn)在,你知道了,你剛剛的感覺(jué)到的是開(kāi)放的方法環(huán)境。是的,以后你會(huì)更深地體會(huì)到,作為好的提供者,開(kāi)放的思維有多重要方法的兄弟成員事件類(lèi)方法的執(zhí)行需要在代碼中以顯性的方式指定,象上面的mc.PutIntoActiveCell,有時(shí)候,當(dāng)最終操作者觸發(fā)類(lèi)對(duì)象成員屬性的*個(gè)事件,需要在事件發(fā)生時(shí)產(chǎn)生一系列的操作,這時(shí),我們要運(yùn)用成員事件。成員事件和方法都是類(lèi)

31、提供的一系列代碼的操作,倆兄弟的區(qū)別在于,成員事件無(wú)法也不必再由代碼顯性調(diào)用。我們來(lái)看一個(gè)具有普遍意義的事例。重要例 窗體UserForm1上有5個(gè)mandButton控件名稱(chēng)分別為默認(rèn)mandButton 1- mandButton 5和1個(gè)Te*tBo*控件名稱(chēng)為T(mén)e*tBo*1。要求當(dāng)各個(gè)mandButton控件被點(diǎn)擊時(shí),它的按鈕文字Caption會(huì)寫(xiě)入Te*tBo*1。如果不用類(lèi),我們需要為5個(gè)mandButton控件分別寫(xiě)5個(gè)一樣的Click事件代碼。如: Private Sub mandButton 1_Click()   Te*tBo*1 = mandButton 1.

32、Caption End Sub 下面是用類(lèi)的成員事件方法的代碼:類(lèi)模塊Cmds的代碼Option E*plicit Public WithEvents cmd As mandButton Private Sub cmd_Click()   UserForm1.Te*tBo*1 = cmd.Caption End Sub 窗體UserForm1的代碼Option E*plicit Dim co As New Collection Private Sub UserForm_Initialize()   Dim i%   Dim myc As Cmds   F

33、or i = 1 To 5     Set myc = New Cmds     Set myc d = Me.Controls("mandButton" & i)     co.Add myc   Ne*t i   Set myc = Nothing End Sub 仔細(xì)玩味上例的每一行代碼,直至品完你壺中的茶。呵呵,因?yàn)樗鼘?shí)在很有用。最后提一下Friend關(guān)鍵字,雖然在VBA中幾乎沒(méi)有什么用,但如果有一天你要制作Active*部件,可能會(huì)用到它。之所以要

34、有Friend關(guān)鍵字,是因?yàn)轭?lèi)的私有局部在類(lèi)模塊外是不可見(jiàn)的,但有時(shí)卻需要從外面這些私有局部,這時(shí),可以使用Friend關(guān)鍵字使屬性和方法成為“友元成員。友元成員在本工程中相當(dāng)于Public,但在工程外,它仍是Private 。隱者為你揭去了第二層面紗,你幾乎已看清她美麗的面龐,她帶著甜蜜的微笑,似乎在問(wèn):什么才是最美的期待.創(chuàng)立類(lèi)事件在VBA中,因?yàn)槲覀兗仁翘峁┱撸彩鞘褂谜?,所以通過(guò)良好地構(gòu)建類(lèi)的屬性和方法,已可以滿(mǎn)足我們需要全部的要求。我不再去解釋這個(gè)觀點(diǎn),在本回后你自然會(huì)明白。從這個(gè)意義上講,創(chuàng)立類(lèi)事件實(shí)在沒(méi)有必要。唯一的遺憾是,我們沒(méi)有體會(huì)到作為創(chuàng)立者的全部樂(lè)趣,標(biāo)準(zhǔn)類(lèi)給我

35、們提供了各種事件,當(dāng)然希望自己也可以做到,想象中這應(yīng)當(dāng)是一件沖動(dòng)人心的事,所以,追求快樂(lè)是創(chuàng)立類(lèi)事件的重要理由,另一個(gè)理由,前面已經(jīng)提到?;氐角懊嫖覀兊腗yClass類(lèi),我們將*屬性改名為Value屬性,雖然對(duì)屬性、方法以及事件的命名,VBA沒(méi)有特別的限制,但建議您不要象我前面那樣,隨便取一個(gè)*,可能的話(huà),要盡量和標(biāo)準(zhǔn)類(lèi)的成員屬性、方法以及事件名稱(chēng)相一致?,F(xiàn)在我們?yōu)椤笆褂谜咛峁┮粋€(gè)“Change事件,不錯(cuò),我們給它取名為“Change,而不再是隨意的“y或其它雖然也可以,這樣,我也不用解釋這個(gè)事件的用意了,呵呵。為了做到這一點(diǎn),看看我們應(yīng)該做什么。1第一步:使用Event語(yǔ)句聲明事件看一下類(lèi)模

36、塊中現(xiàn)在的代碼:Option E*plicit Public Event Change(ByRef Cancel As Boolean) Private s$ Public Property Get Value() As String   Value = s End Property Public Property Let Value(ByVal c As String)   s = c End Property Private Sub Class_Initialize()   s = "abc"  初始值End Sub 和前面的代碼

37、比較,多出了一句:Public Event Change(ByRef Cancel As Boolean) 這就是Event語(yǔ)句,只此一句,我們已經(jīng)為我們的類(lèi)聲明我想使用“注冊(cè)一詞是不是更妥切了一個(gè)事件Change。在看Event語(yǔ)句產(chǎn)生的效果前,先來(lái)看它的特性:1為了聲明事件,Event總是Public的,這好理解吧。2事件可以不帶參數(shù),如Public Event Change(),也可以帶參數(shù),如我們上面給出的,但參數(shù)不能是命名參數(shù),可選參數(shù)或數(shù)組參數(shù)。這里我只解釋一下命名參數(shù)的含義。我們知道,事件可以因特定的用戶(hù)事件而觸發(fā),也可以在代碼中象方法一樣指定執(zhí)行,如下面的mandButton1

38、_Click:Private Sub mandButton2_Click()   mandButton1_Click End Sub 但在調(diào)用對(duì)象的方法時(shí)我們通常喜歡這樣的方式:Selection.Sort Key1:=Range("A2"), Order1:=*lAscending 這里Key1、Order1就是命名參數(shù),命名參數(shù)的好處是我們不必記住它們的次序,調(diào)用時(shí)直接以名稱(chēng)和冒號(hào)后加等于號(hào)指定它的值,但對(duì)事件的調(diào)用卻不允許這樣。3事件沒(méi)有返回值。現(xiàn)在我們看一下,Event為我們做了什么。建立一窗體UserForm1,添加一個(gè)Te*tBo*控件名稱(chēng)為T(mén)e*tB

39、o*1,兩個(gè)mandButton控件名稱(chēng)為mandButton1和mandButton2,mandButton1的Caption設(shè)置為“賦值,mandButton2的Caption設(shè)置為“讀值,窗體的代碼如下:Option E*plicit Dim WithEvents mc As MyClass Private Sub mandButton1_Click()   mc.Value = Te*tBo*1 '賦值End Sub Private Sub mandButton2_Click()   MsgBo* "mc當(dāng)前的值為" & mc.V

40、alue '讀值End Sub Private Sub UserForm_Initialize()   Set mc = New MyClass End Sub 上面這段代碼實(shí)現(xiàn)的是,當(dāng)點(diǎn)擊mandButton1時(shí)便會(huì)將Te*tBo*1的值賦給mc的Value,當(dāng)點(diǎn)擊mandButton2時(shí)便會(huì)顯示mc當(dāng)前的Value值。來(lái)運(yùn)行一下這個(gè)窗體,先點(diǎn)擊mandButton2,此時(shí)顯示“abc,是mc的初始值,然后在Te*tBo*1輸入“123,點(diǎn)擊mandButton1,再點(diǎn)擊mandButton2,顯示“123,說(shuō)明賦值成功了。呵呵,忘了,我們要做什么了!現(xiàn)在,請(qǐng)從UserFo

41、rm1代碼窗口的“通用框中選擇mc,哇!我們聲明的事件在右邊“聲明框中已經(jīng)出現(xiàn)了!此主題相關(guān)圖片如下:我們定義這個(gè)事件是希望當(dāng)mc的值改變時(shí)響應(yīng)的,現(xiàn)在就迫不及待地給它寫(xiě)一句代碼吧:Private Sub mc_Change(ByRef Cancel As Boolean)   If MsgBo*("要改變mc的值嗎?", vbYesNo) = vbNo Then Cancel = True End Sub 上面這句代碼你不會(huì)陌生吧,希望當(dāng)用戶(hù)選擇了在改變時(shí)給用戶(hù)一個(gè)確認(rèn)的時(shí)機(jī)。但是,現(xiàn)在點(diǎn)擊mandButton1,卻不會(huì)給你選擇的時(shí)機(jī),我們還有一步?jīng)]有做。第二步

42、:使用RaiseEvent語(yǔ)句引發(fā)事件聲明了事件后,我們要做的,便是找到所有與事件發(fā)生關(guān)聯(lián)的地方,使用RaiseEvent語(yǔ)句引發(fā)事件,這里引發(fā)的含義相當(dāng)于Call,就是調(diào)用用戶(hù)在事件中寫(xiě)的代碼。在本例中,只有一個(gè)地方,就是Property Let Value過(guò)程中:  Dim chyn As Boolean   RaiseEvent Change(chyn)   If chyn Then E*it Property 通過(guò)傳遞回的chyn,決定是否執(zhí)行后面的賦值語(yǔ)句。下面就是添加了RaiseEvents語(yǔ)句后的類(lèi)模塊的代碼:Option E*plicit Publ

43、ic Event Change(ByRef Cancel As Boolean) Private s$ Public Property Get Value() As String   Value = s End Property Public Property Let Value(ByVal c As String)   Dim chyn As Boolean   RaiseEvent Change(chyn)   If chyn Then E*it Property   s = c End Property Private Sub Class_Initialize()   s = "abc" End Sub 現(xiàn)

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論