




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、Excel VBA類模塊入門教程示例一示例二集合示例VBA類:隱者的秘密刖言寫下這個(gè)題目,可能會(huì)讓很多朋友疑惑,筆者先埋下一個(gè) 關(guān)子,很快我會(huì)讓您知道這個(gè)標(biāo)題的寓意。這份禮物送給現(xiàn)在想學(xué)習(xí)類知識(shí)或曾經(jīng)學(xué)過(guò)但因?yàn)楦鞣N 原因沒(méi)有“修成正果”的朋友,我期望的結(jié)果是這篇文章后, 您可以在類模塊中像在標(biāo)準(zhǔn)模塊中寫代碼一樣熟練,我也期 望不至于太乏味而使您沒(méi)有耐心看完整篇文章,或者說(shuō)期望 您學(xué)習(xí)的過(guò)程是輕松愉悅的,但愿我可以做到。文章構(gòu)劃為 8部分:1 .什么是類2. 為什么要學(xué)習(xí)類3. 類的預(yù)備知識(shí)4. 創(chuàng)建類屬性5. 創(chuàng)建類方法6. 創(chuàng)建類事件7. 個(gè)完整的類實(shí)例&未完的結(jié)尾什么是類在我們身邊
2、,相同或相似的物品無(wú)處不在,從生活用品,到工業(yè)產(chǎn)品,通常它們都是由同一個(gè)可以稱為“模具”的 東西生產(chǎn)出來(lái)。理解類,一般要先從對(duì)象談起,但由于從不同的角度,有不 同的理解,從而也有不同的關(guān)于類的定義,本文不去探討一 個(gè)完整并且公認(rèn)的類概念,在這一部分后,只要你有一個(gè)基 本的判斷并且在遇到時(shí)知道是類就可以了。在上面的這個(gè)例 子中,一個(gè)“模具”就是一個(gè)“類”,而由它生產(chǎn)出的每一 個(gè)產(chǎn)品,就是一個(gè)“對(duì)象”??聪旅娴?VBA 語(yǔ)句: Dim tx1 As Textbox 不用解釋它的意思吧,這里我們用到一個(gè)類 Textbox 定義了 一個(gè)對(duì)象 tx1 ,再來(lái)看:Dim tx1 As TextboxDim
3、 tx2 As Textbox又定義了一個(gè)對(duì)象tx2,如果你不嫌煩,我還可以繼續(xù)下去。 對(duì)象增加了,但As后的Textbox沒(méi)有變,它可以無(wú)限制的使 用下去。類是一個(gè)隱者, 上面 Textbox 是 VBA 已經(jīng)給我們準(zhǔn)備好的一 個(gè)類,我們無(wú)法知道 VBA 是怎么準(zhǔn)備的(它的真身被隱藏 了),但我們可以知道對(duì)象 tx1 怎么用。 VBA 把對(duì)對(duì)象的使用劃分為三種, 屬性、方法和事件 (后面預(yù)備知識(shí)我們?cè)偬幔?然而, Textbox 是一個(gè)類,仍然不是本文要說(shuō)的類,因?yàn)樗?是 VBA 已經(jīng)給我們準(zhǔn)備好了的,我們要做的,只是知道如 何使用它而已。本文要介紹的,是利用 VBA 已經(jīng)給我們提 供的資源
4、,來(lái)構(gòu)建我們自己的類,姑且可稱之為自定義類。 這需要在 VBE 下,通過(guò)插入類模塊,然后向類模塊中寫入 代碼來(lái)完成。這就是你常常聽說(shuō)的類,本文的主題就是這個(gè) 包含代碼的模塊!通過(guò)這個(gè)模塊,可以提供給我們一個(gè)和 V BA 提供給我們的諸如 Textbox 功能性質(zhì)完全相同的類,然 后,再由我們自己象使用 Textbox 一樣使用! 類是一個(gè)隱者,她把自己藏在所有模塊的最后,甚至在多數(shù) 情況,她從不出場(chǎng)?,F(xiàn)在,她掛著神秘的微笑,向你走來(lái), 你要拒絕嗎為什么要學(xué)習(xí)類模塊類通常被認(rèn)為是學(xué)習(xí) VBA 的難點(diǎn)之一,之所以如此,因?yàn)?相對(duì)于制造一個(gè)標(biāo)準(zhǔn)模塊或用戶窗體,我們可以找到的類的 學(xué)習(xí)資源少之又少,
5、甚至很多 VB 的書籍也只有繆繆字語(yǔ) (在 后面的預(yù)備知識(shí),我們?cè)偬崃硪粋€(gè)重要的原因)。從技術(shù)角 度上看, 類的構(gòu)建, 不象窗體, VBA 的類也不象有些語(yǔ)言提供了可視的設(shè)計(jì)界面,感性上那樣直接,隱者!她是不可視 的設(shè)計(jì),所有的構(gòu)建都是通過(guò)在類模塊中寫代碼來(lái)實(shí)現(xiàn)的。1學(xué)習(xí)是一種興趣的追求俗語(yǔ)云: 學(xué)的千千萬(wàn), 用的有幾何?又曰: 書到用時(shí)方恨少。 林語(yǔ)堂先生將做學(xué)問(wèn)劃分為三重境界,第二重說(shuō)“為伊消得 人憔悴,衣帶漸寬終不悔”,大多數(shù)朋友,包括本人,都不 是專業(yè)程序員,學(xué)習(xí)程序只是一種興趣和愛(ài)好,就好象有人 喜歡修煉網(wǎng)游一樣,對(duì)喜歡程序的人,不斷地學(xué)習(xí)和提高, 也是一種追求優(yōu)秀的態(tài)度,并且樂(lè)意享
6、受這個(gè)追求的過(guò)程。 模塊、控件、鏈接庫(kù)和類構(gòu)成軟件工程開發(fā)的四大技術(shù),而 類技術(shù)是控件和鏈接庫(kù)技術(shù)的基礎(chǔ),我們不得不學(xué)。2類有什么用 如你前面看到的我們使用 Textbox 類,類可以創(chuàng)建大量性質(zhì) 相近的對(duì)象,減輕我們的程序量,簡(jiǎn)潔代碼并提高效率。 類定義后,在其它模塊中使用時(shí),我們就可以暫時(shí)忘記或不 必考慮它內(nèi)部復(fù)雜的細(xì)節(jié), 讓我們變得輕松, VBA 雖然不能 真正封裝類的形式,但在這里,我們可以封裝它的概念。 這并不是類的全部好處,其它的,留著朋友們用的時(shí)候慢慢 體會(huì)吧。類掛著神秘的微笑,已經(jīng)走到你的大門口,開門迎接她吧, 你還等什么?類的預(yù)備知識(shí)廣義上講,所有 VBA 的知識(shí),包括語(yǔ)句、
7、函數(shù)以及為我們 提供的標(biāo)準(zhǔn)類甚至第三方的資源都可以在類中被使用。本文 無(wú)法也不準(zhǔn)備逐一探討,這里只說(shuō)一些最密切最基本的,但 即使這樣,筆者仍然不能把這些點(diǎn)的知識(shí)都寫到,甚至因?yàn)?對(duì)問(wèn)題解釋清晰或符合邏輯的需要,采用非規(guī)范的表述,對(duì) 專門問(wèn)題的全面理解,請(qǐng)讀者注意參考有關(guān)標(biāo)準(zhǔn)幫助文檔并 加以甄別。1從構(gòu)建者的角度理解對(duì)象 上一回我們提到,類被認(rèn)為是 VBA 難點(diǎn)還有一個(gè)原因,這 就是我們的思想! VBA 提供了大量的現(xiàn)成的類, 我們幾乎不 再需要去構(gòu)建自己的類,這種結(jié)果,我們熟練地習(xí)慣了從使 用者的角度去理解類 的實(shí)例:對(duì)象,包括它的屬性、方法 和事件。但是,現(xiàn)在你還要嘗試做一個(gè)提供者,這和你作
8、為 使用者時(shí)的思考方法是完全不同的,甚至是革命性的。這種 角色的轉(zhuǎn)位是痛苦的,它需要你放棄你原本可以自豪地解釋 出對(duì)象以及它的屬性、方法、事件的定義,它們?cè)臼侨绱?邏輯地被劃分,如此清晰,但現(xiàn)在,類模塊中的一切,彼此 交織,你會(huì)發(fā)現(xiàn)它們都模糊了! 是需要你忘掉所有固執(zhí)的 “招 勢(shì)”的時(shí)候了,當(dāng)你心中無(wú)劍時(shí),轉(zhuǎn)位也就完成了,隱者變 得清晰了,她是如此美麗。且慢,在你完全忘掉前,讓我們 最后再看一眼它們的樣子,呵呵,如果你實(shí)在忘不掉,你就 提醒一下自己構(gòu)建者的身份吧。下面是通常情況下關(guān)于對(duì) 象、屬性、方法、事件的基本表述,如果你以前沒(méi)了解過(guò), 則應(yīng)當(dāng)找些資料先認(rèn)真地理解它們,然后再按照上面的提示
9、 去做。對(duì)象是由類創(chuàng)建的一個(gè)實(shí)例,它是類的實(shí)體化。 對(duì)象的引用和操作被邏輯上劃分為不重疊的三個(gè)部分: 屬性是指對(duì)象的特性。以前面的 Textbox 為例,有長(zhǎng)度,高 度,框中顯示的文字等等。方法是指對(duì)象的某個(gè)操作。 如讓 Textbox 成為當(dāng)前的焦點(diǎn) (即 光標(biāo)移動(dòng)到它上面)。事件是指對(duì)象對(duì)外部動(dòng)作的響應(yīng)。 如我們用鼠標(biāo)點(diǎn)擊 Textbo x 時(shí),會(huì)產(chǎn)生一個(gè) Click 事件,改變它的值,則產(chǎn)生一個(gè) Ch ange 事件變量的作用域變量因?yàn)槁暶鞯奈恢煤头绞讲煌?,從而有不同的作用域。?用域是指變量在多大范圍內(nèi)能被代碼識(shí)別??梢詣澐譃檫^(guò)程 級(jí)、模塊級(jí)和全局變量。過(guò)程級(jí)變量在過(guò)程中聲明,這里過(guò)程
10、指的是一個(gè)Sub 或 Function ,也包括后面提到到屬性過(guò)程。通常用 Dim 或 Static 進(jìn) 行聲明。 Dim 聲明的變量,只在該過(guò)程執(zhí)行時(shí)存在,過(guò)程結(jié)束,變量的值也就消失了。 Static 聲明的變量稱為靜態(tài)變量, 這個(gè)值在整個(gè)程序運(yùn)行期間都存在。 模塊級(jí)變量對(duì)整個(gè)模塊的所有過(guò)程都有效,但對(duì)其它模塊不 可用??梢栽谀K頂部聲明。 聲明模塊級(jí)變量用 Private 關(guān)鍵 字和直接使用 Dim 沒(méi)有區(qū)別。 但推薦使用 Private 進(jìn)行聲明, 因?yàn)檫@樣可以方便地與后面的全局變量區(qū)分開來(lái)。 全局變量是對(duì)整個(gè) VBA 工程的所有過(guò)程都有效的變量,使 用 Public 關(guān)鍵字在標(biāo)準(zhǔn)模塊的
11、頂部來(lái)聲明。 在類模塊中,對(duì)變量作用域的理解要注意下面兩點(diǎn):(a) 由于類是生成對(duì)象的模具,每生成一個(gè)對(duì)象,相當(dāng)于產(chǎn) 生了一個(gè)副本,這個(gè)副本就是對(duì)象的“真身”,副本間是相 互獨(dú)立的,從而,模塊級(jí)的變量只作用于副本自身。(b)類模塊中使用Public關(guān)鍵字,只有當(dāng)對(duì)象變量是這個(gè) 類的實(shí)例時(shí),才能被訪問(wèn)。過(guò)程和函數(shù)變量、過(guò)程(Sub)、函數(shù)(Function)是我們?cè)跇?biāo)準(zhǔn)模塊中使用的最基本的構(gòu)件,在類摸塊中,它們?nèi)匀皇亲罨竞椭?要的角色。對(duì)于它們,你已經(jīng)再熟悉不過(guò),之所以前面還要 花這么多文字, 是為了突出它的重要, 也是想讓你放松一下, 哦,我花了很短的時(shí)間已經(jīng)看了這么多 (我也寫了這么多!
12、)。過(guò)程和函數(shù)并無(wú)實(shí)質(zhì)的區(qū)別,當(dāng)需要返回值時(shí),就使用 Fun ction ,如果不需要返回任何結(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è)工程有效。同變量一樣,在類模塊中使用 Public 關(guān)鍵字,只有當(dāng)引用對(duì) 象變量是這個(gè)類的實(shí)例時(shí),才能被訪問(wèn)通用內(nèi)部控件 Control ( s)VBA 提供 Control 類作為一般內(nèi)部控件類型,
13、當(dāng)使用Dim Ct As Control 聲明了一個(gè)變量后,就可以將任何控件賦給該變量,而不管 具體的類型,因?yàn)樵陬惖氖褂猛ǔJ翘幚泶罅肯嘟膶?duì)象, 所以這種特性非常有用。在實(shí)際使用時(shí),我們多是通過(guò)容器 控件的 Controls 屬性來(lái)返回一個(gè) Control 的集合對(duì)象。Dim Ct As ControlFor Each Ct In Me.ControlsIf TypeName(Ct) = "CommandButton" Then MsgBox Ct. CaptionNext 上面這段代碼可以遍歷窗體的所有控件并報(bào)告找到的命令 按鈕。集合 CollectionCollec
14、tion 是我們?cè)谑褂妙悤r(shí)最常用到的對(duì)象。一個(gè) Collecti on 對(duì)象代表一組相關(guān)的項(xiàng)目, 雖然它的成員并不被強(qiáng)制要求 是同一類型的的,但請(qǐng)記住,這通常并不能給我們帶來(lái)額外 的方便,相反,我們通常是用來(lái)收集同一類型的數(shù)據(jù)。 建立集合的方法和建立其它對(duì)象一樣,如:Dim col As New Collection 集合建立后,可以使用 Add 方法添加成員,用 Remove 方法 刪除成員,用 Item 方法從集合中返回特定成員。Private Sub CommandButton1_Click()Dim col As New CollectionDim i%Dim ct As Contro
15、lFor Each ct In Me.ControlsIf Left(ct.Name, 7) = "TextBox" Then col.Add ctNext ctFor i = col.Count To 1 Step -1MsgBox " 下面刪除成員 " & col.Item(i).Name col.Remove iNext iEnd Sub 上面的代碼先將窗體上所有的 TextBox 加入到集合中,然后 再刪除掉。 Count 屬性返回集合的成員數(shù)量, Remove 方法后 面的參數(shù)是集合成員的索引號(hào)。成員的索引號(hào)通常是按照加 入的順序自然編
16、號(hào), 從1開始,但可以在加入時(shí)使用 Add 方 法的參數(shù)進(jìn)行改變。 Add 方法的完整語(yǔ)法是: object .Add item , key , before , afteritem 必需的。 任意類型的表達(dá)式, 指定要添加到集合中的成 員。key 可選的。 唯一字符串表達(dá)式, 指定可以使用的鍵字符串, 代替位置索引來(lái)訪問(wèn)集合中的成員。before/after 可選的。表達(dá)式,指定集合中的相對(duì)位置。 下面語(yǔ)句向集合增加一個(gè)對(duì)象 TextBox1 ,并定義該成員的關(guān) 鍵字為 tx1 。col.Add TextBox1, "tx1" 然后,下面兩句都可以向集合中增加一個(gè) Tex
17、tBox2 ,并把它 放在成員 TextBox1 的前面。col.Add TextBox2, , col.Count col.Add TextBox2, , "tx1" 第一句中,因?yàn)橹挥幸粋€(gè)成員,所以 col.Count 也是索引號(hào)使用事件的WithEvents 變量WithEvents不是一個(gè)單獨(dú)的語(yǔ)句,為了使用對(duì)象的事件,需 要在聲明該對(duì)象時(shí)使用WithEvents關(guān)鍵字。例如:Dim WithEvents app As Application將上面的語(yǔ)句寫入ThisWorkBook的模塊,可以看到在通用 框中出現(xiàn)了一個(gè)變量 app:外接程序)電t*i行卄列1此主題相
18、關(guān)圖片如下:么 Microsoft Visual Basic - Bookl - | ThisWorkbook (代巧)橢 文件怨)編輯 視窗 插入 格式辺 調(diào)試 運(yùn)行® 工具j-a Jt電齟勺小丨壬三卜占醸倉(cāng)1謝轉(zhuǎn)S 縣 ¥BJlFr*j ec t 白 Bicrosoft(Baakl)Entel刑象(Sheetl)13 2 匚|GM3卡WappSheetlShestE (SkeetS)Sheets (Sheets)Thi stfcrkbook白自模塊 戰(zhàn)複塊1:"類梗塊芒類1Option ExplicitDim WitKEvftiits 電pp As Appli
19、nation在通用框選擇app后,左邊的聲明框便會(huì)顯示 app的事件。此主題相關(guān)圖片如下:£3按字母序I按分類序I囲稱)JJS p w迅就|題廚瞥洪砲用m列i肉文件世編輯(1)視圉迪插入格式辺調(diào)試 運(yùn)行 工具(1)外接程序 奮VBATrflject.(Bookl)&-3 Microsoft Jscel 對(duì)象S Sheetl Gheetl)Sj Sheets (5h eet2)O sheeta和 Thi sWorkbook 自-b模塊我模塊1-l 出類模塊類1TLi sVorkbovT Workbook |A.cceptLbelzI FalseAutoUpdateFr e 0C
20、han尊皀Hi story 0S "e "litf I * t r需要注意的是,使用WithEvents只是聲明了對(duì)象變量,而并不實(shí)際生成對(duì)象,為了生成真實(shí)的對(duì)象,你仍然需要在聲明后向生成其它對(duì)象一樣,使用Set語(yǔ)句進(jìn)行指定。此外,WithEvents變量不能是通用類變量如Object,而必須指定類名,也不能把 WithEvents變量聲明為 As New。不能在標(biāo)準(zhǔn)模塊 中使用 WithEvents初識(shí)類模塊現(xiàn)在,請(qǐng)打開你的 VBE,主菜單-插入-類模塊。插入了一個(gè)類模塊,也就建立了一個(gè)類。類模塊的名字就是類的名字。你現(xiàn)在看到的,她的名字叫“類1”,這是VBA按她姐妹排行
21、給她取的的, 是的,VBA 一貫如此,你早就熟悉了這種規(guī)則,現(xiàn)在,在標(biāo)準(zhǔn)模塊或其它模塊中輸入 Dim As的時(shí)候,提示框中她已經(jīng)出現(xiàn)了。 但我知道,有件事你正 耿耿于懷,“類1”,太沒(méi)個(gè)性了,想改成自己要的名字吧。 很容易,和你改標(biāo)準(zhǔn)模塊的名字一樣,打開屬性窗口,看到 了吧,第一行就是她的名字,隨你的意愿修改吧。此主題相關(guān)圖片如下:駕 文件便)漏輯© 視閣 插入 格式調(diào)試1運(yùn)行® 工具外接程序®転M A ilU呂冒 =Microsoft Visual Bask: - Bookl -類I (代碼)' VBAProjectm mi口-VBAProjectCBn
22、okl-< < Mi crosoft Si cel 對(duì)象 0 Shetl (SheHl) 辱SheetE (SheetE) 園 1 Sheet3 (Sheets) © ThisWorkbook 曰曰複塊隣模塊1-勺類橈塊Opti on Ex:pli ci tdim xx魚呂 XnnlMap sXmlHwneEpjie® XmlNamespaces 思I XmlSchemaXmlSchemasthzi1饕1類模炊捲字母序丨松44舉字(名稱)類1ilnstarLCing I " Frivat e你或許已經(jīng)注意到,在名字下面,只有一個(gè)屬性:Instancin
23、g,其值也只有兩個(gè)選項(xiàng):Private 和PublicNotCreatable。事實(shí)上,你完全可以忽略這個(gè)Instancing ,就象你完全忽略條件編譯指令一樣,因?yàn)樵?VBA中我們幾乎用不到它 們,而只需維持她的默認(rèn)值即可。至少我是這樣認(rèn)為的,但 我給不了您充足的理由,而只是個(gè)人的一種狹隘經(jīng)歷。既然 提到了,就簡(jiǎn)單說(shuō)明一下:Instancing 屬性決定該“類”在其它工程中是否可以被使 用。我們知道,標(biāo)準(zhǔn)模塊中的 Public 過(guò)程,可以保存在宏工 作簿甚至直接被另一工作簿的工程調(diào)用,但類中的代碼是不 可分割的整體,所以必須整體決定是否允許外用。當(dāng) Insta ncing 屬性設(shè)為 Priv
24、ate (默認(rèn))時(shí),不允許其它工程訪問(wèn)。 當(dāng)設(shè)置為 PublicNotCreatable 時(shí),只有在自己的工程創(chuàng)建 了該類的對(duì)象時(shí),其它工程才允許使用這個(gè)對(duì)象,注意,僅 僅是在本工程中創(chuàng)建的對(duì)象,而不能用她在其它工程中創(chuàng)建 對(duì)象。 隱者已經(jīng)來(lái)到你的身邊,透過(guò)薄薄的面紗,你似乎已看到她 神秘的微笑。站起身來(lái),走過(guò)去吧!創(chuàng)建類屬性讓我們想一下作為類的使用者時(shí),我們是如何操作對(duì)象的屬 性的,對(duì)象屬性的操作不外乎讀和寫兩種。當(dāng)我們要給對(duì)象 的某個(gè)屬性賦值時(shí),我們會(huì):TextBox1.Text= ”abc” 當(dāng)我們要讀取對(duì)象的屬性時(shí),S= TextBox1.Text 現(xiàn)在,看看作為類的提供者需要怎樣做。
25、我們將“類 1”改名為“ MyClass ”并為它創(chuàng)建一個(gè)名稱為 x 的字符型屬性。1使用 Public 變量創(chuàng)建類屬性 在類模塊中寫下行代碼:Public x$ 是的,就這么簡(jiǎn)單,通常情況下,只需要這么簡(jiǎn)單使用 Property 過(guò)程創(chuàng)建類屬性Private s$Public Property Get x() As Stringx = sEnd PropertyPublic Property Let x(ByVal c As String)s = cEnd Property 我們可以省去上面默認(rèn)的 Public 。但看上去還是有點(diǎn)麻煩哦, 不僅需要兩個(gè)公共過(guò)程,而且還要一個(gè)輔助的私有變量 s
26、 和 一個(gè)參數(shù)c。在類模塊中,Property過(guò)程把對(duì)屬性的讀寫分開 了,說(shuō)一下 Property 過(guò)程的工作機(jī)制,當(dāng)標(biāo)準(zhǔn)模塊中的代碼 讀取對(duì)象的屬性時(shí),便會(huì)觸發(fā)存在的 Property Get 過(guò)程,或 者說(shuō) Property Get 過(guò)程提供了屬性的讀功能,同樣, Propert y Let 過(guò)程提供了寫屬性。這樣,上面的兩個(gè)過(guò)程(當(dāng)然在 模塊中沒(méi)有先后的要求),可以只有一個(gè),或者雖然兩個(gè)都 有,但卻不全是 Public ,從而提供出去的屬性是只讀或只寫 (呵呵,沒(méi)見過(guò)只寫哈)。僅僅是為了提供只讀或只寫的屬 性,代碼就從一行變成了七行?! 這樣的理由, 你不會(huì)信服,VBA 中的類通常是提供
27、給我們自己使用的!如果它確實(shí)是 只讀的,我們自覺(jué)地去只讀就是了!我們使用 Property 過(guò)程 還有其它理由,最基本的一條,我們可以利用這個(gè)“過(guò)程” 來(lái)做我們想做的事??匆豢矗篜ublic Property Let x(ByVal c As String)s = Format(c, "0000")End Property 這里我們只是簡(jiǎn)單的利用了一下,更多的在后面你會(huì)看到。 此外,誰(shuí)會(huì)保證有一天你不使用 VB 給別人提供類呢,這個(gè) 技術(shù)可是通用的。提供一段標(biāo)準(zhǔn)模塊的測(cè)試代碼,來(lái)看看我 們上面構(gòu)建的類屬性,你自己試試吧。Sub aTest()Dim mc As New My
28、Classmc.x = "123"Debug.Print mc.xEnd Sub 就象我們給普通變量和對(duì)象變量賦值的方式不同一樣,對(duì)象 變量是使用 Set 賦值的。對(duì)“對(duì)象”屬性, VBA 提供了 Property Set來(lái)代替構(gòu)建“普通”屬性使用的Property Let。來(lái)看一段代碼:Private tx As ObjectProperty Get x() As ObjectSet x = txEnd PropertyProperty Set x(ByVal o As Object)Set tx = oEnd Property和前面的比較一下,除了多一個(gè)Set,實(shí)在沒(méi)有
29、什么不同。告訴你一個(gè)小秘訣,你可以按照 Function 去記住 Property G et 的用法,按照 Sub 去記住 Property Let /Set。屬性的初始值我們常常希望,當(dāng)一個(gè)對(duì)象建立的時(shí)候,它的某些屬性會(huì)被 自動(dòng)賦予一個(gè)初始值,這樣,對(duì)具有最常見的屬性值的對(duì)象 可以減少重復(fù)性的賦值工作。這需要借助于類的構(gòu)建函數(shù)來(lái) 完成。在類模塊代碼窗口的“通用”框中點(diǎn)擊向下的小三角箭頭, 選擇“ Class”,右面聲明框中可以看到兩個(gè)選項(xiàng),“Initialize”和“ Terminate ”,我們對(duì)它們應(yīng)該不陌生,很多對(duì)象都 有這兩個(gè)事件, Initialize 事件當(dāng)對(duì)象建立時(shí)發(fā)生, Te
30、rminate 事件在對(duì)象對(duì)釋放時(shí)發(fā)生。由于類是靜態(tài)存在的,它并不是真正的對(duì)象,所以在類模塊中,它們通常被稱為構(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ù)。下面建立MyClass ,屬性x初始值為” 0001的全部測(cè)試代碼:類模塊 MyClass 的代碼 Option ExplicitPrivate s$Public Property Get x() As Stringx = sEnd PropertyPublic Property Let x(ByVal c As Str
31、ing)s = cEnd PropertyPrivate Sub Class_Initialize()s = "0001"End Sub 標(biāo)準(zhǔn)模塊 1 的代碼 Option ExplicitSub aTest()Dim mc As New MyClassDebug.Print mc.xEnd Sub 隱者為你揭開了第一層面紗,你隱約已看到她美麗的面厐, 雖然還不是很清晰,但你知道,早晚會(huì)的創(chuàng)建類方法放松一下,請(qǐng)拿出你家的紫砂壺,泡上一壺好茶,聽我給你 將類的方法的故事,你的茶品完了,我的故事也差不多就講 完了。1構(gòu)建類的方法其實(shí)就是在類模塊中寫公共的Sub 和 Functi
32、on現(xiàn)在我們給前面提到的 MyClass 創(chuàng)建一個(gè)方法 PutIntoActive Cell ,功能是將 x 屬性值寫入活動(dòng)單元格。Public x$Sub PutIntoActiveCell()ActiveCell = xEnd Sub在標(biāo)準(zhǔn)模塊中用下面的代碼測(cè)試一下:Sub aTest()Dim mc As New MyClassmc.x"abc"mc.PutIntoActiveCellEnd Sub 這是本回要告訴你的全部嗎?你還沒(méi)有開始品茶吧?就這 樣了結(jié)束?這是最重要和基本的,但卻不是全部。 你是否有一種感覺(jué),但你不能清楚地說(shuō)出來(lái)? 端起你可愛(ài) 的茶杯,品一口茶,
33、我們繼續(xù)。類的方法環(huán)境借用廣為眾知的一個(gè)名詞“數(shù)據(jù)環(huán)境”,雖然不準(zhǔn)確,但我 實(shí)在想不出更好的稱謂來(lái)代替,姑且這么叫吧。稍后你就會(huì) 知道它的含義。類可以象 VBA 提供給我們的很多標(biāo)準(zhǔn)類一樣風(fēng)光無(wú)限,所 有的程序設(shè)計(jì)者都在工程中使用它,但更多時(shí)候,我們所構(gòu) 建的類只在特定的環(huán)境下被使用,類的方法環(huán)境是指包括類 所在工程的其它成員在內(nèi)的,可以調(diào)用的資源的集合。工作 簿、工作表、窗體或其它,在類模塊中,你可以象在標(biāo)準(zhǔn)模 塊中一樣操作它們,千萬(wàn)不要因?yàn)閾Q成了類模塊而產(chǎn)生任何 疑慮,作為類的創(chuàng)建者,你要讓類模塊中的代碼象你在標(biāo)準(zhǔn) 模塊中一樣親近它們, 只要你認(rèn)為必要。 脫離了方法環(huán)境的、 謹(jǐn)小慎微的、封
34、閉的類實(shí)在沒(méi)有什么意義。如果你預(yù)期方法 環(huán)境在運(yùn)行時(shí)可能會(huì)有變化,你要事先預(yù)知它們并象在標(biāo)準(zhǔn)模塊中一樣使用恰當(dāng)?shù)拇胧?,比如你不能確定運(yùn)行時(shí)活動(dòng)工 作表的名稱(但你確定屆時(shí)會(huì)是一個(gè)工作表),你可以使用 ActiveSheet 。我反復(fù)說(shuō)“和標(biāo)準(zhǔn)模塊一樣”,就是想告訴你在類模塊中創(chuàng) 建方法時(shí),對(duì)工程中其它成員的操作,和你已經(jīng)熟悉的標(biāo)準(zhǔn) 模塊中的方式的實(shí)在沒(méi)有什么不同,這一原則適用于類模塊 中所有代碼(也許叫代碼環(huán)境更準(zhǔn)確些),而不僅僅是構(gòu)建 方法的代碼?,F(xiàn)在,你知道了,你剛才的感覺(jué)到的是開放的方法環(huán)境。是 的,以后你會(huì)更深地體會(huì)到,作為好的提供者,開放的思維 有多重方法的兄弟 成員事件類方法的執(zhí)行
35、需要在代碼中以顯性的方式指定,象上面的 c.PutIntoActiveCell ,有時(shí)候,當(dāng)最終操作者觸發(fā)類對(duì)象成員 (屬性) 的某個(gè)事件, 需要在事件發(fā)生時(shí)產(chǎn)生一系列的操作, 這時(shí),我們要運(yùn)用成員事件。成員事件和方法都是類提供的 一系列代碼的操作,倆兄弟的區(qū)別在于,成員事件無(wú)法也不 必再由代碼顯性調(diào)用。我們來(lái)看一個(gè)具有普遍意義的事例。 重要例 窗體 UserForm1 上有 5 個(gè) CommandButton 控件(名稱分別為 默認(rèn) CommandButton 1- CommandButton 5)和 1 個(gè) TextBo x 控件(名稱為 TextBox1 )。要求當(dāng)各個(gè) CommandB
36、utton 控件被點(diǎn)擊時(shí),它的按鈕文字( Caption )會(huì)寫入 TextBox1 。如果不用類, 我們需要為 5 個(gè) CommandButton 控件分別寫 5 個(gè)相同的 Click 事件代碼。如 :Private Sub CommandButton 1_Click()TextBox1 = CommandButton 1.CaptionEnd Sub下面是用類的成員事件方法的代碼:類模塊 Cmds 的代碼Option ExplicitPublic WithEvents cmd As CommandButtonPrivate Sub cmd_Click()UserForm1.TextBox1
37、 = cmd.CaptionEnd Sub窗體 UserForm1 的代碼Option ExplicitDim co As New CollectionPrivate Sub UserForm_Initialize()Dim i%Dim myc As CmdsFor i = 1 To 5Set myc = New CmdsSet myc.cmd = Me.Controls("CommandButton" & i) co.Add mycNext iSet myc = NothingEnd Sub 仔細(xì)玩味上例的每一行代碼,直至品完你壺中的茶。呵呵, 因?yàn)樗鼘?shí)在很有用。
38、最后提一下 Friend 關(guān)鍵字,雖然在 VB A 中幾乎沒(méi)有什么用, 但如果有一天你要制作 ActiveX 部件, 可能會(huì)用到它。之所以要有 Friend 關(guān)鍵字,是因?yàn)轭惖乃接?部分在類模塊外是不可見的,但有時(shí)卻需要從外面訪問(wèn)這些 私有部分,這時(shí),可以使用 Friend 關(guān)鍵字使屬性和方法成為 “友元成員”。友元成員在本工程中相當(dāng)于Public ,但在工程外,它仍是 Private 。 隱者為你揭去了第二層面紗,你幾乎已看清她美麗的面龐, 她帶著甜蜜的微笑,似乎在問(wèn):什么才是最美的期待?創(chuàng)建類事件在 VBA 中,因?yàn)槲覀兗仁翘峁┱?,也是使用者,所以通過(guò) 良好地構(gòu)建類的屬性和方法,已可以滿足
39、我們需要全部的要 求。我不再去解釋這個(gè)觀點(diǎn),在本回后你自然會(huì)明白。從這個(gè)意義上講,創(chuàng)建類事件實(shí)在沒(méi)有必要。唯一的遺憾是,我們沒(méi)有體會(huì)到作為創(chuàng)建者的全部樂(lè)趣,標(biāo)準(zhǔn)類給我們提供了各種事件,當(dāng)然希望自己也可以做到,想象中這應(yīng)當(dāng)是一件 激動(dòng)人心的事,所以,追求快樂(lè)是創(chuàng)建類事件的重要理由, 另一個(gè)理由,前面已經(jīng)提到?;氐角懊嫖覀兊?MyClass 類,我們將 x 屬性改名為 Value 屬 性,雖然對(duì)屬性、 方法以及事件的命名, VBA 沒(méi)有特別的限 制,但建議您不要象我前面那樣,隨便取一個(gè)x,可能的話,要盡量和標(biāo)準(zhǔn)類的成員 (屬性、 方法以及事件) 名稱相一致?,F(xiàn)在我們?yōu)椤笆褂谩闭咛峁┮粋€(gè)“Chang
40、e ”事件,不錯(cuò),我們給它取名為“ Change”,而不再是隨意的“ y”或其它(雖 然也可以) ,這樣, 我也不用解釋這個(gè)事件的用意了, 呵呵。 為了做到這一點(diǎn),看看我們應(yīng)該做什么。1第一步:使用 Event 語(yǔ)句聲明事件 看一下類模塊中現(xiàn)在的代碼:Option ExplicitPublic Event Change(ByRef Cancel As Boolean)Private s$Public Property Get Value() As StringValue = sEnd PropertyPublic Property Let Value(ByVal c As String)s =
41、 cEnd PropertyPrivate Sub Class_Initialize()s = "abc" 初始值End Sub和前面的代碼比較,多出了一句:Public Event Change(ByRef Cancel As Boolean) 這就是 Event 語(yǔ)句,只此一句, 我們已經(jīng)為我們的類聲明 (我 想使用“注冊(cè)” 一詞是不是更妥切)了一個(gè)事件Changeo在看 Event 語(yǔ)句產(chǎn)生的效果前,先來(lái)看它的特性:(1 )為了聲明事件,Event總是Public的,這好理解吧。(2)事件可以不帶參數(shù),女口 Public Event Change。,也可以 帶參數(shù),如
42、我們上面給出的,但參數(shù)不能是命名參數(shù),可選 參數(shù)或數(shù)組參數(shù)。這里我只解釋一下命名參數(shù)的含義。我們 知道,事件可以因特定的用戶事件而觸發(fā),也可以在代碼中 象方法一樣指定執(zhí)行,如下面的 CommandButton1_Click :Private Sub CommandButton2_Click()CommandButton1_ClickEnd Sub但在調(diào)用對(duì)象的方法時(shí)我們通常喜歡這樣的方式: Selection.Sort Key1:=Range("A2"), Order1:=xlAscending 這里 Key1 、 Order1 就是命名參數(shù),命名參數(shù)的好處是我們 不必記住
43、它們的次序,調(diào)用時(shí)直接以名稱和冒號(hào)后加等于號(hào) 指定它的值,但對(duì)事件的調(diào)用卻不允許這樣。(3)事件沒(méi)有返回值?,F(xiàn)在我們看一下, Event 為我們做了什么。 建立一窗體 UserForm1 ,添加一個(gè) TextBox 控件(名稱為 Te xtBox1 ),兩個(gè) CommandButton 控件(名稱為 CommandBut ton1 和 CommandButton2 ), CommandButton1 的 Caption 設(shè) 置為“賦值” ,CommandButton2 的 Caption 設(shè)置為“讀值” , 窗體的代碼如下:Option ExplicitDim WithEvents mc As
44、 MyClassPrivate Sub CommandButton1_Click()mc.Value = TextBox1 '賦值End SubPrivate Sub CommandButton2_Click()MsgBox "mc 當(dāng)前的值為 " & mc.Value '讀值End SubPrivate Sub UserForm_Initialize()Set mc = New MyClass End Sub上面這段代碼實(shí)現(xiàn)的是,當(dāng)點(diǎn)擊 CommandButtonl時(shí)便會(huì)將TextBoxI 的值賦給 me 的 Value,當(dāng)點(diǎn)擊 CommandBu
45、tton2 時(shí)便會(huì)顯示 me當(dāng)前的Value值。來(lái)運(yùn)行一下這個(gè)窗體,先點(diǎn)擊CommandButton2,此時(shí)顯示“abc”,是me的初始值,然后在 TextBoxI輸入“ 123”, 點(diǎn)擊 CommandButtonl,再點(diǎn)擊 CommandButton2,顯示 “ 1 23”,說(shuō)明賦值成功了。呵呵,忘了,我們要做什么了!現(xiàn)在,請(qǐng)從 UserForml代碼 窗口的“通用”框中選擇me,哇!我們聲明的事件在右邊“聲明”框中已經(jīng)出現(xiàn)了!此主題相關(guān)圖片如下:MicrosoFt Visual Basic = Bookl.xls - UserForml垮文件 編輯觀圖世)插入格式迫)調(diào)試運(yùn)行®
46、 工具外按程序翅23 Ji Y IS 麹 3-VBAPrajecI色3 .0(Bdokl. xls)-Microsoft Ek cel 對(duì)隊(duì) 題 Sheetl (Sheetl) S侶h昵坨)適 ShetS (ShetS) 罰 ThisWorkbookS-曰窗體a UserForml El -舊類模塊NlyClas:E二CWge二Qptxcn Explicit 11 . 1 SIl le ll a 1 wILIWI -Ikllilll. 1N觀爭(zhēng)弓 妙行1列Din Hi tU/vivts; mu 人百 MtCIe倉(cāng)百Fr ivete Sub CommaiidBu11on 1 Cl i ek 0m
47、e. Value 二 TextBoxIEnd EiAFyivata Sub CommuidButtoi£_Cli ck0"mu當(dāng)前的值北T" & me. Value,讀值End SubFrivate Sub UerForrn_Initi sli re ()Set me - New MyClasEnd SubPrivets SubCancel Aw Bociean)End SubILUfllEIHEIi我們定義這個(gè)事件是希望當(dāng)me的值改變時(shí)響應(yīng)的,現(xiàn)在就迫不及待地給它寫一句代碼吧:Private Sub mc_Change(ByRef Cancel As B
48、oolean)If MsgBox(" 要改變 mc 的值嗎 ?", vbYesNo) = vbNo ThenCancel = TrueEnd Sub 上面這句代碼你不會(huì)陌生吧,希望當(dāng)用戶選擇了在改變時(shí)給 用戶一個(gè)確認(rèn)的機(jī)會(huì)。但是,現(xiàn)在點(diǎn)擊 CommandButton1 ,卻不會(huì)給你選擇的機(jī)會(huì), 我們還有一步?jīng)]有做。使用 RaiseEvent 語(yǔ)句引發(fā)事件第二步:使用 RaiseEvent 語(yǔ)句引發(fā)事件 聲明了事件后,我們要做的,便是找到所有與事件發(fā)生關(guān)聯(lián) 的地方,使用 RaiseEvent 語(yǔ)句引發(fā)事件,這里引發(fā)的含義相 當(dāng)于 Call ,就是調(diào)用用戶在事件中寫的代碼。在本
49、例中,只 有一個(gè)地方,就是 Property Let Value 過(guò)程中:Dim chyn As BooleanRaiseEvent Change(chyn)If chyn Then Exit Property通過(guò)傳遞回的chyn,決定是否執(zhí)行后面的賦值語(yǔ)句。下面就是添加了 RaiseEvents 語(yǔ)句后的類模塊的代碼:Option ExplicitPublic Event Change(ByRef Cancel As Boolean)Private s$Public Property Get Value() As StringValue = sEnd PropertyPublic Property Let Value(ByVal c As String)Dim chyn As BooleanRaiseEvent Change(chyn)If chyn Then Exit Propertys = cEnd PropertyPrivate Sub Class_Initialize()s = "abc"End Sub 現(xiàn)在你可以去運(yùn)行你的窗體了,我們要的效果應(yīng)該是達(dá)到了 吧。為了便于你
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 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ì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年中考物理二輪復(fù)習(xí):電與磁 信息 能源 尖子生測(cè)試卷(含答案解析)
- 第五單元 第1章 第1節(jié) 腔腸動(dòng)物和扁形動(dòng)物(新教學(xué)設(shè)計(jì))2023-2024學(xué)年八年級(jí)上冊(cè)生物(人教版)
- 借款房屋轉(zhuǎn)讓合同范例
- 產(chǎn)品采購(gòu)合同范例加工商
- 主體裝修合同范本
- 互聯(lián)網(wǎng)醫(yī)療行業(yè)月度個(gè)人工作計(jì)劃
- 農(nóng)村安裝光伏合同范例
- 眼科相關(guān)治療
- 班級(jí)工作計(jì)劃執(zhí)行效率總結(jié)
- 學(xué)校學(xué)期校園文明創(chuàng)建計(jì)劃
- 2025年中考百日誓師活動(dòng)教師代表發(fā)言(三)
- 中國(guó)家用通風(fēng)電器具制造行業(yè)分析報(bào)告
- 2024年山東省濟(jì)南市中考英語(yǔ)試題卷(含答案解析)
- 汽車坡道玻璃雨棚施工方案
- 新高考英語(yǔ)讀后續(xù)寫——人物描寫高級(jí)表達(dá)素材
- EN10204-2004中文版
- 二年級(jí)美術(shù)下冊(cè)第3課田園風(fēng)光1浙美版
- 教育研究方法PPT課件
- 芳草湖農(nóng)場(chǎng)醫(yī)院臥床病人翻身卡
- 財(cái)稅2016年第36號(hào)文[共94頁(yè)]
- 新課程高考化學(xué)考題命題原則與要求
評(píng)論
0/150
提交評(píng)論