第41章 初識VBA
VBA全稱為Visual Basic for Application,它是Visual Basic的應(yīng)用程序版本。作為功能強(qiáng)大的工具,VBA使Excel形成了獨立的編程環(huán)境。本章將簡要介紹什么是VBA以及如何學(xué)習(xí)Excel VBA。
41.1 什么是宏
在很多應(yīng)用軟件中都有宏的應(yīng)用。什么是宏呢?計算機(jī)詞典中有多種對于宏的定義。在此無需花費大量時間去研究那些拗口的定義哪個更準(zhǔn)確。本書中討論的宏僅限于微軟Office軟件包設(shè)計的一個特殊功能,目的是讓用戶的一些任務(wù)實現(xiàn)自動化。
與其他用于軟件開發(fā)的單獨編程語言不同,宏代碼只能“寄生”于Excel文件之中,并且宏代碼不能編譯為可執(zhí)行文件。
41.2 VBA的應(yīng)用場景
Excel VBA作為一種擴(kuò)展工具,得到了越來越廣泛的應(yīng)用,原因在于,很多實際應(yīng)用中復(fù)雜的Excel操作都可以利用Excel VBA得到簡化。一般來說,Excel VBA可以應(yīng)用在如下幾個方面:
自動執(zhí)行重復(fù)的操作
進(jìn)行復(fù)雜的數(shù)據(jù)分析對比
生成報表和圖表
個性化用戶界面
Offic組件的協(xié)同工作
Excel二次開發(fā)
41.3 在Excel 中錄制宏代碼
41.3.1 錄制宏是最好的學(xué)習(xí)工具
錄制宏不僅是Excel 中一個非常實用的功能,而且是學(xué)習(xí) VBA的好幫手。在 Excel 中,有兩種方法可以開始錄制一個宏。
1.利用Excel菜單:“工具”——宏——錄制新宏,在“錄制新宏”對話框中,設(shè)置宏的名稱、保存位置以及快捷鍵,再單擊“確定”按鈕,就可以開始錄制一個新的宏。
系統(tǒng)默認(rèn)錄制新宏的名稱為“Macro”加數(shù)字序號的形式,例如Macro1、Macro2等等,建議用戶使用能夠代表代碼功能的宏名稱。宏名稱可以包含字母、數(shù)字和下劃線,但第一個字符必須是字母或中文字符,不能是數(shù)字,也就是“1Macro”不可以作為宏名稱。建議在宏名稱中不要使用中文字符,否則在非中文版的Excel中使用該宏時可能會出現(xiàn)兼容性問題。
2.利用Visual Basic工具欄
步驟1:單擊視圖——工具欄——Visual Basec,將顯示工具欄。
步驟2:單擊第二個按鈕“錄制宏”,同樣會出現(xiàn)“錄制新宏”對話框。
步驟3:單擊“錄制新宏”對話框的“確定”按鈕,系統(tǒng)將開始錄制宏,Visual Basic工具欄的第二個按鈕將變?yōu)?#8220;停止錄制”。
開始錄制宏后,Excel中絕大部分操作將被記錄為宏代碼,此時可以開始在Excel 中進(jìn)行相關(guān)的操作。操作結(jié)束后,單擊Visual Basic工具欄的“停止錄制”按鈕,將停止本次錄制宏。單擊“查看代碼”按鈕或按<Alt+F11>組合鍵就可以打開VBE(V
isual Basic Editor,即VBA集成開發(fā)環(huán)境)窗口,在代碼窗口中將看到剛才錄制的宏代碼,下一章中將講述VBE中主要窗口的功能。
對于VBA的初學(xué)者,最困難的事情就是想要實現(xiàn)一個功能,卻不知道代碼從何寫起,錄制宏可以很好地幫助大家。在Excel中進(jìn)行操作的同時錄制宏,就可以看到整個操作過程的代碼,請注意這只是一個“半成品”,經(jīng)過必要的修改才能得到更高效更智的代碼。
41.3.2 錄制宏的局限性
錄制宏可以忠誠地記錄Excel 操作,但也有其本身的局限性,主要表現(xiàn)在以下幾個方面:
1、錄制宏產(chǎn)生的代碼不一定完全等同于用戶的操作,例如用戶設(shè)置保護(hù)工作表時輸入的密碼就無法記錄在代碼中,設(shè)置工作表控件的屬性也無法產(chǎn)生相關(guān)的代碼。
2.錄制宏產(chǎn)生的代碼執(zhí)行效率不高,因為代碼中大量使用Activate和Select等方法,影響了代碼的執(zhí)行效率,在實際應(yīng)用中需要進(jìn)行相應(yīng)的優(yōu)化。
第42章 VBA的組裝工廠——Visual Basic Editor
Visual Basic Editor(以下簡稱VBE),是指Excel及其他Office組件中集成的VBA編輯器,本章將介紹VBE中主要功能窗口的功能。
42.1VBE窗口介紹
42.1.1 VBE窗口介紹
在VBE界面中,除了和一般Windows應(yīng)用程序類似的菜單和工具欄外,其工作區(qū)中還提供了多個功能窗口供用戶選擇。單擊VBE“視圖”菜單,將顯示菜單項,用戶可根據(jù)需要和使用習(xí)慣選擇在VBE中顯示的功能窗口。
42.1.2 工程窗口
工程窗口以樹形結(jié)構(gòu)顯示Excel中的所有工程,即Excel中所有已經(jīng)打開的工作簿,包含隱藏工作簿的加載宏。每個工程作為一個樹結(jié)構(gòu)的根結(jié)點,一般顯示為“VBAProject(Book1.xls)”的形式。
42.1.3 屬性窗口
屬性窗口會列出選取對象的屬性,用戶可以修改這些屬性的值。當(dāng)選取了多個控件時,屬性窗口會列出所有控件所共有的屬性;如果此時更改某個屬性的值,那么被選中的多個控件的相應(yīng)屬性會同時被修改。屬性窗口所示分為兩部分:對象框和屬性列表。
42.1.4 代碼窗口
代碼窗口用來輸入、顯示以及編輯VBA代碼。打開對象的代碼窗口后,可以查看模塊或?qū)ο笾械拇a和在它們之間進(jìn)行復(fù)制和粘貼。
42.1.5 立即窗口
在立即窗口中鍵入或粘貼一行代碼,然后按<Enter>鍵可以執(zhí)行該代碼。在代碼中使用Debug.Print可將內(nèi)容輸出到立即窗口中。
注意:立即窗口中的代碼是不能被保存的,關(guān)閉Excel后,立即窗口中的內(nèi)容將丟失。
第43章 VBA語言基礎(chǔ)
VBA作為一種編程語言,具有其自身特有的語法規(guī)則。本章將介紹VBA編程的基礎(chǔ)知識,包括變量與常量、過程、程序結(jié)構(gòu)以及對象的屬性、方法和事件。
43.1 變量與常量
43.1.1 數(shù)據(jù)類型
數(shù)據(jù)類型用來決定可保存何種數(shù)據(jù)。VBA中的數(shù)據(jù)類型包括Byte,Boolean,Integer,Long,Currency,Decimal,Single,Double,Date,Stri
ng,Object,Variant(默認(rèn))和用戶定義類型等。不同數(shù)據(jù)類型所需要的存儲空間并不相同。
數(shù)據(jù)類型 關(guān)鍵字 類型標(biāo)識符 字節(jié)數(shù)
字節(jié)型 Byte 無
1
布爾型 Boolean 無 2
整數(shù)型 Integer % 2
長整數(shù)型 Long & 4
貨幣型 Currcncy @ 8
小數(shù)點型 Decimal 無 14
單精度型 Single ! 4
雙精度型 Double # 8
日期型 Date 無 8
字符串型(定長) String $ 字符長度(1~65 400)
字符串型(變長) String $ 字符長度+10
對象型 Object 無 4
變體型 Variant 無 以上任意類型,可變
43.1.2 變量
變量用于保存在程序運行過程中需要臨時保存的值或?qū)ο螅诔绦蜻\行過程中其值可以發(fā)生改變。
在VBA中,變量無需聲明就可以直接使用,此時該變量為變體變量。但使用之前聲明變量是一個良好的編程習(xí)慣,同時也可以提高程序的運行效率。
在VBA中用Dim語句聲明變量。下述代碼聲明局部變量a為整數(shù)型變量。
Dim a as Integer
使用類型標(biāo)識符可以簡化為:
Dim a%
注意:如果在同一個語句中同時聲明多個變量,如下面的Dim語句中聲明了兩個變量,其中的變量a實際聲明為Variant變量,則應(yīng)該使用如下代碼:
Dim a as Integer,b as Integer
變量賦值使用等號,等號右側(cè)可以是表達(dá)式。如下代碼是為變量a賦值。
a = 128+56
43.1.3 常量
常量用于存儲固定信息,其值不會發(fā)生改變,使用常量可以增加程序的可讀性。例如VBA中的常量vbGreen,其值為65 280,在代碼中設(shè)置綠色時使用常量vbGreen,使得代碼更具可讀性。
在VBA中用Const語句聲明常量。如下代碼聲明字符型常量ClubName。
Const clubName As String = "ExcelHome"
43.2 運算符
VBA中有如下4種運算符:
1.算術(shù)運算符:用來進(jìn)行數(shù)學(xué)計算的運算符。
2.比較運算符:用來進(jìn)行比較的運算符。
3.連接運算符:用來合并字符串的運算任。
4.邏輯運算符:用來執(zhí)行邏輯運算的運算符。
連接運算符包括"&"運算符和"+"運算符兩種。
43.3 過程 過程(Procedure)是可以執(zhí)行的語句序列單元,所有可執(zhí)行的代碼必須包含在某個過程內(nèi),任何過程都不能嵌套在其他過程中。過程的名稱只能在模塊級別進(jìn)行定義。
VBA中有3種過程,即Sub過程、Function過程和Property過程。
1.Sub過程執(zhí)行指定的操作,但不返回運行結(jié)果,以關(guān)鍵Sub開關(guān)和關(guān)鍵字End Sub結(jié)束。可以通過錄制宏生成Sub過程或在VBE窗口里直接編寫。
2.Function過程執(zhí)行指定的操作,可以返回運行結(jié)果,以關(guān)鍵字Function開關(guān)和關(guān)鍵字End Function結(jié)束。Function過程可以在其他過程中調(diào)用,也可以在工作表的公式中使用,就像Excel的內(nèi)置函數(shù)一樣。
3.Property過程用于設(shè)置和獲取自定義對象屬性的值,或者用來設(shè)置對另外一個對象的引用。
43.4 程序結(jié)構(gòu)
VBA中的程序結(jié)構(gòu)與控制和大多數(shù)編程語言相同,下面介紹最基本的幾種程序結(jié)構(gòu)。
43.4.1 條件語句
程序代碼經(jīng)常用到條件判斷,并且根據(jù)結(jié)果執(zhí)行不同的代碼。在VBA中有If/Then語句和Select Case語句兩種條件語句。
下面的If/Then語句判斷活動單元格的內(nèi)容,如果是“Excelhome”則將其字號設(shè)置為10,否則將字號設(shè)置為9。
If ActiveCell.Value = "ExcelHome" Then ActiveCell.Font.Size = 10 Else ActiveCell.Font.Size=9
43.4.2 循環(huán)語句
對程序中多次重復(fù)執(zhí)行的某段代碼就可以使用循環(huán)語句。在VBA中循環(huán)語句有多種形式,包括For循環(huán)、Do循環(huán)和While循環(huán)。下面的For循環(huán)實現(xiàn)1~10的累加功能。
Sub ForLoop()
Dim i As Integer, iSum As Integer
iSum = 0
For i = 1 To 10
iSum = iSum + i
Next
MsoBox iSum,,"ForLoop"
End Sub
43.4.3 With語句
With語句可以在一個單一對象或一個用戶定義類型上執(zhí)行一系列的語句。使用With語句不僅可以簡化程序代碼,而且可以提高代碼的運行效率。With/End With結(jié)構(gòu)中以“.”開頭的語句相當(dāng)于引用了With語句中指定的對象。當(dāng)程序一旦進(jìn)入With/End 結(jié)構(gòu),With語句指定的對象就不能改變。因此不能用一個With語句來設(shè)置多個不同的對象。如下代碼是使用With語句設(shè)置活動工作表的相關(guān)屬性。
With ActiveSheet
.Visible = True
.Cells(1,1 ) = "ExcelHome"
.Name = .Cells(1,1)
End With
43.5 對象
對象代表應(yīng)用程序中的元素,例如工作表、單元格、圖表或窗體等。應(yīng)用程序提供的對象按照層次關(guān)系進(jìn)行排列管理。Excel應(yīng)用程序中的頂級對象是Application對象的子對象,反之,Application對象是這些對象的的父對象。
許多子對象都有自己的子對象。例如Workbook對象包含Worksheets對象,或者說,Workbook對象是Worksheets對象的父對象。Worksheets對象是一種稱為集合中的單個Worksheet對象。
43.5.1 屬性
屬性是指對象的特征、如大小、顏色或屏幕位置,也可指某一方面的行為,諸如對象是否被激活或是否可見。通過修改對象的屬性值可以改變對象的特性。如下代碼是設(shè)置活動工作表的名稱為“ExcelHome”。
ActiveSheet.Name = “ExcelHome”
43.5.2 方法
方法指對象能執(zhí)行的動作。例如使用Worksheets對象的Add方法可以添加一個新的工作表,代碼如下:
Worksheets.Add
在代碼中,屬性和方法都是通過連接符“.”來和對象連接的。
43.5.3 事件
事件是一個對象可以辨認(rèn)的動作,像單擊鼠標(biāo)或按下某鍵等,并且可以指定代碼針對此動作來做出響應(yīng)。用戶操作、程序代碼的執(zhí)行和系統(tǒng)本身都可以觸發(fā)相關(guān)的事件。
第44章 與Excel進(jìn)行交互
在Excel中,系統(tǒng)提供了各式各樣的對話框與用戶進(jìn)行交互;在使用VBA編寫程序時,為了提高代碼的靈活性和程序的友好度,也經(jīng)常需要實現(xiàn)用戶與Excel的交互功能。本章將介紹如何InputBox和MsgBox實現(xiàn)輸入和輸出信息,以及如何調(diào)用Excel的內(nèi)置對話框。
44.1使用MsgBox輸出信息
MsgBox函數(shù)通常應(yīng)用于如下幾種情況:
1.輸出代碼最終運行結(jié)果
2.產(chǎn)生一個消息框用于提醒用戶
3.在代碼運行過程中顯示某個變量的值,用于調(diào)試代碼
MsgBox函數(shù)的語法格式如下:
MsgBox(prompt[,buttons][,title] [,helpfile,context])
prompt參數(shù)用于設(shè)置消息框的提示文本信息,最大長度為1 023個字符。顯然這么多的字符無法顯示在同一行,如果代碼中沒有使用強(qiáng)制換行,系統(tǒng)將按照每行102個字符進(jìn)行自動換行處理,多數(shù)情況下這并不符合用戶的使用習(xí)慣。
在文本信息中使用vbCrLf或 vbNewLine常量可以進(jìn)行強(qiáng)制換行。
示例44.1 顯示多行文本信息
步驟1:打開一個新的工作簿文件,按Alt+F11組合鍵切換到VBE窗口。
步驟2.在工程窗口中插入“模塊”,修改其名稱為“MsgBoxDemo”。
步驟3.在模塊MsgBoxDemo中寫入如下代碼。
Sub MultiLineDemo()
'定義變量
Dim MsgStr As String
'生成提示信息
MsgStr = "歡迎加入Excel Home論壇!"&vbCrLf
MsgStr =MsgStr & "Excel Home 是微軟技術(shù)社區(qū)聰明成員" & vbCrLf
MsgStr = MsgStr & "Let's do it better!"
'顯示消息框
MsgBox MsgStr,,"歡迎"
End Sub
步驟4.返回Excel界面,運行宏MultiLineDemo,將顯示消息框。
buttons參數(shù)用于指定消息框顯示按鈕的數(shù)目及形式、圖標(biāo)樣式和缺少按鈕等。組合使用參數(shù)值可以顯示多種不同風(fēng)格的消息框;省略buttons參數(shù)時,消息框只顯示一個確定按鈕。
44.2 如何利用InpuitBox輸入
程序中往往需要用戶輸入很多內(nèi)容,例如數(shù)字、日期或文本等,這就需要使用InpuitBox獲取用戶輸入。
使用VBA提供的InpuitBox函數(shù)可以實現(xiàn)用戶輸入,其語法格式為:
InpuBox(prompt[, title] [, default] [,xpos] [, helpfile, context])
輸入框中必須顯示相關(guān)的提示信息,即prompt參數(shù),否則用戶無法知道需要輸入什么樣的內(nèi)容。設(shè)置輸入框的標(biāo)題,即title參數(shù),使得輸入框更接近Excel的內(nèi)置對話框風(fēng)格;如果省略該參數(shù),則輸入框的標(biāo)題為“Micrlsoft Excel”。
注意:用戶在輸入框中輸入的內(nèi)容是否滿足要求,需要在代碼中進(jìn)行相應(yīng)判斷,以保證后續(xù)程序可以正確地執(zhí)行。
除了InputBox函數(shù)之外,Excel VBA的InpuBox方法(Application.InputBox)也可用于接收用戶輸入的信息,二者的用法基本相同。區(qū)別在于InpuBox方法可以指定返回值的數(shù)據(jù)類型。其語法格式為:
InpuBox(Prompt,Title,Default, Left, Top, HelpFile, HelpContextId, Type)
示例44.2 利用InpuBox方法輸入員工號信息
步驟1.打開—個新的工作簿文件,按Alt+F11組合鍵切換到VBE窗口。
步驟2.在工程窗口中插入“模塊”,修改其名為“InputBoxDemo”。
步驟3.在模塊InputBoxDemo中寫入如下代碼。
Sub ExcelInputBoxDemo()
'定義變量
Dim newID As Integer
Do
'提示用戶輸入員工號
newID = Application.InputBox("請輸入員工號(四位數(shù)字):", "員工信息管理系統(tǒng)", Type:=1)
'如果輸入的是四位員工號就退出循環(huán)
Loop Until Len(CStr(newID)) = 4
'顯示信息框
MsgBox "您輸入的員工號為 " & newID, vbInformation, "提示信息"
End Sub
步驟4.返回Excel界面,運行宏ExcekInputBoxDemo,將顯示輸入框;如果輸入“abcd”后單擊“確定”,將顯示消息框。由此可以看出,使用InputBox方法,系統(tǒng)將根據(jù)Type參數(shù)判斷輸入的數(shù)據(jù)類型是否符號要求。
注意:在VBA代碼中直接使用InputBox相當(dāng)于調(diào)用VBA的InputBox函數(shù)。
44.3 Excel內(nèi)置對話框
用戶使用Excel時,系統(tǒng)出現(xiàn)的對話框統(tǒng)稱為Excel內(nèi)置對話框,例如單擊“文件”——“打開”將顯示“打開”對話框。VBA程序與用戶之間的交互也可以借助這些內(nèi)置對話框來實現(xiàn)。
Application對象的Dialogs集合中包含大部分Excel內(nèi)置對話框,每種對話框?qū)?yīng)一個VBA常量。在VBA幫助中搜索“內(nèi)置對話框參數(shù)列表”;可以查看所有的內(nèi)置對話框參數(shù)列表。
使用Show方法可以顯示一個內(nèi)置對話框,下面代碼將顯示“打開”對話框。
Application.Dialogs(xlDialogOpen).Show
第45章 自定義函數(shù)
自定義函數(shù)與Excel工作表函數(shù)相比具有更強(qiáng)大、更靈活的功能。自定義函數(shù)可以用來簡化公式,也可以用來完成Excel工作表函數(shù)無法完成的功能。
45.1 什么是自定義函數(shù)
自定義函數(shù)(User-defined Worksheet Functions 簡稱UDF)就是用戶創(chuàng)建的用于滿足特定需求的函數(shù),是對于Excel內(nèi)置工作表函數(shù)的一個補(bǔ)充。Excel已經(jīng)提供了數(shù)百個工作表函數(shù)可供選擇使用,有必要創(chuàng)建自定義函數(shù)嗎?答案是肯定的。自定義函數(shù)的優(yōu)勢在于:
1.自定義函數(shù)可以簡化公式。一般情況下,組合使用Excel工作表函數(shù)完全可以滿足絕大多數(shù)應(yīng)用,但是復(fù)雜的公式有可能太冗長和繁瑣,其可讀性非常差,不易于修改,除了公式的作者之外,公式的使用者可能很難理解公式的含義。此時就可以通過使用自定義函數(shù)來進(jìn)行簡化。
2.自定義函數(shù)與Excel工作函數(shù)相比具有更強(qiáng)大和更靈活的功能。Excel實際應(yīng)用中,要求是千變?nèi)f化的,僅僅使用Excel工作表函數(shù)常常不能圓滿地解決問題。此時就可以考慮使用自定義函數(shù)來滿足實際工作中的個性化需求。
與Excel工作表函數(shù)相比,自定義函數(shù)的弱點也是顯而易見的,就是自定義函數(shù)的效率要遠(yuǎn)遠(yuǎn)低于Excel工作表函數(shù)功能,應(yīng)該使用45.3節(jié)中講述的方法進(jìn)行引用。
45.2 函數(shù)的參數(shù)與返回值
VBA中參數(shù)有兩種傳遞方式:按值傳遞(關(guān)鍵字ByVal)和按地址傳遞(ByRef)。參數(shù)的默認(rèn)傳遞方式為按地址傳遞,因此如果希望使用這種方式傳遞參數(shù),可以省略參數(shù)前的關(guān)鍵字。
這兩種傳遞方式的區(qū)別在于,按值傳遞只是將參數(shù)值的副本傳遞到調(diào)用過程中,在過程中對于參數(shù)的修改,并不改變參數(shù)的原始值;按地址傳遞是將該參數(shù)的引用傳遞到調(diào)用過程中,在過程中任何對于參數(shù)的修改都將改變參數(shù)的原始值。
注意:由于按地址傳遞方式會修改參數(shù)的原始值,所以需要謹(jǐn)慎使用。
函數(shù)屬于Function過程,其區(qū)別于Sub過程之處在于,F(xiàn)unction過程可以提供返回值。函數(shù)可以返回一個單一值或數(shù)組。如下面的自定義函數(shù)TaxRate根據(jù)工資數(shù)返回相應(yīng)的稅費稅率,如果在工作表中使用公式實現(xiàn)則需要多層If結(jié)構(gòu)嵌套。
Function TaxRate(Salary)
Select Case Salary - 1000
Case Is <0
TaxRate = 0
Case Is <=500
TaxRate = 0.05
Case Is <= 2000
TaxRate = 0.1
Case Is <= 5000
TaxRate = 0.15
Case Else
TaxRate =0.2
End Select
End Function
45.3 如何在VBA中引用工作表函數(shù)
由于工作表函數(shù)的效率遠(yuǎn)遠(yuǎn)高于自定義函數(shù),因此對于工作表函數(shù)已經(jīng)實現(xiàn)的功能,可以在VBA代碼中直接引用工作表函數(shù),其語法格式為:
Application.WorksheetFunction.工作表函數(shù)名稱
WorksheetFunction.工作表函數(shù)名稱
Application.工作表函數(shù)名稱
在VBA中Application對象可以省略,所以第二種語法格式實際上是第一種語法格式的簡化。為了方便讀者識別,本書后續(xù)章節(jié)中所有對于工作表的函數(shù)的引用都將采用第一種格式。
在VBA代碼中調(diào)用工作表函數(shù)時,函數(shù)參數(shù)的順序與在工作表單元格公式中相同,但是具體表示方法會略有不同,例如在工作表中使用公式示A1和A2單元格的和,公式為:
=SUM(A1,A2)
其中參數(shù)為兩個單元格的引用A1和A2。而在VBA代碼中調(diào)用工作表函數(shù)SUM時,需要使用VBA中單元格的引用方法,如下所示:
Application.WorksheetFunction.Sum(Cells(1,1),Cells(2,1))
45.4 在VBA中引用自定義函數(shù)
除非自定義函數(shù)不使用任何參數(shù),否則自定義函數(shù)不能通過單擊VBE菜單“運行”——“運行子過程/窗體”來運行自定義函數(shù)過程。在VBA代碼中,只能在另一個過程里調(diào)用該自定義函數(shù)。
45.5 在工作表中引用自定義函數(shù)
在工作表單元格公式引用自定義函數(shù)的方法和引用普通Excel工作表函數(shù)的方法基本相同。
步驟1.單擊選中目標(biāo)單元格。
步驟2.單擊菜單“工具”——選項,在“視圖”選項卡中,確認(rèn)已經(jīng)選中“編輯欄”。
步驟3.單擊“編輯欄”的“插入函數(shù)”按鈕,或單擊菜單“插入”——“公式”。
步驟4.在“插入函數(shù)”對話框中選擇類別“用戶定義”,在“選擇函數(shù)”列表框中將顯示可供選擇的全部自定義函數(shù)名稱。
注意:使用關(guān)鍵字Private聲明的私有自定義函數(shù)不會出現(xiàn)在“插入函數(shù)”對話框中,私有自定義函數(shù)不能用于公式里,只能在另外一個VBA過程里調(diào)用這些私有的自定義函數(shù)。
步驟5.單擊自定義函數(shù)名稱,然后單擊“確定”,假設(shè)選定的函數(shù)為TaxRate。
步驟6.在“函數(shù)參數(shù)”對話框中輸入相關(guān)參數(shù),單擊“確定”,單元格中將出現(xiàn)相應(yīng)的計算結(jié)果。
45.6 自定義函數(shù)的限制
并非所有的功能都可以在自定義函數(shù)中實現(xiàn)。在工作表單元格公式中引用自定義函數(shù)時,不能更改Microsoft Excel的環(huán)境,這意味著自定義函數(shù)不能執(zhí)行以下任何操作:
1.在工作表中插入、刪除單元格或設(shè)置單元格格式。
2.更改其他單元格中的值。
3.在工作簿中移動、重命名、刪除或添加工作表。
4.更改任何環(huán)境選項,例如計算模式或屏幕視圖。
5.向工作簿中添加名稱。
6.設(shè)置屬性或執(zhí)行大多數(shù)方法。
其實,Excel中的內(nèi)置工作表函數(shù)同樣也不能更改Microsoft Excel的環(huán)境,函數(shù)只能執(zhí)行計算以在輸入它們的單元格中返回某個值或文本。
如果在其他過程中調(diào)用自定義函數(shù)就不存在上述限制。盡管如此,為了規(guī)范代碼,建議所有上述需要更改Microsoft Excel環(huán)境功能的代碼在Sub過程中實現(xiàn)。
45.7如何制作加載宏
加載宏(英文名稱為Add-in)是一類程序的統(tǒng)稱,它們可以為Microsoft Excel添加可選的命令和功能。例如,“分析工具庫”加載宏程序提供了一套數(shù)據(jù)分析工具,在進(jìn)行復(fù)雜統(tǒng)計或工程分析時,可以節(jié)省操作步驟,提高分析效率。
Microsoft Excel有三種類型的加載宏程序:Excel加載宏、自定義的組件對象模型(COM)加載宏和自動化加載宏。本節(jié)討論的加載宏特批Excel加載宏。
理論上來說,任何一個工作簿可以制作成為加載宏,但是某些工作簿不適合制作成為加載宏,例如一個包含圖表的工作簿,如果該工作簿轉(zhuǎn)換為加載宏,那么就無法查看該圖表,除非利用VBA代碼將圖表所在的工作表拷貝成為一個新的工作簿。
制作加載宏的步驟非常簡單,一般來說有兩種方法可以將普通工作簿轉(zhuǎn)換為加載宏。
1.在VBE的工程窗口中雙擊ThisWorkBook,按F4顯示屬性窗口,在其中修改IsAddin屬性的值為True。
2.另存為加載宏。
步驟1.在Excel窗口中單擊菜單“文件”——“另存為”。
步驟2.在“另存為”對話框中,單擊保存類型下拉列表框,選擇“Microsoft Office Excel加載宏(*.xla)”。
步驟3.選擇保存位置,加載宏的缺省目錄為“c:\Documents and Settings\<用戶登錄名>\Application Data\Microslft\Addlns\”。
步驟4.單擊“確定”按鈕。
系統(tǒng)默認(rèn)的加載宏擴(kuò)展名為XLA,但并非一定要用XLA作為加載宏的擴(kuò)展名,使用任意的擴(kuò)展名都不會影響加載宏的功能。為了便于識別,建議使用XLA作為加載宏的擴(kuò)展名。
第46章 如何操作工作簿、工作表和單元格
在Excel中,對工作簿、工作表和單元格的操作,多數(shù)都可以利用VBA代碼實現(xiàn)兩樣的效果。本章介紹了工作簿對象的Workshee
t對象的引用方法以及添加刪除對象的方法。Range對象是Excel最基本也是最常用的對象之一,對于Rabge對象處理的方法也有多種,本章將進(jìn)行詳細(xì)的介紹。
46.1 Workbook對象
Workbook對象代表Microsoft Excel工作簿,也就是通常據(jù)說的Excel文件,每個Excel文件都是一個Workbook對象。Workbook集合代表所有已經(jīng)打開的工作簿,加載宏除外。
在代碼中經(jīng)常用的Workbook對象是ThisWorkbook和ActiveWorkbook。
1.ThisWorkbook對象指代碼所在的Workbook對象。
2.ActiveWorkbook對象指Excel中活動窗口中的Workbook對象。
46.1.1 引用Workbook對象
使用Workbooks屬性引用工作簿有如下兩種方法。
1.使用工作簿序號引用Workbook對象,語法格式為:
Workbooks.Item(工作簿序號)
工作簿序號是指創(chuàng)建或打開工作簿的順序號,Workbooks(1)代表Excel應(yīng)用程序中創(chuàng)建或打開的第一個工作簿,而Workbook(
Workbooks.Count)為最后一個工作簿,其中Workbooks.Count返回Workbooks集合中包含的Workbook對象的個數(shù)。即便是隱藏工作簿也包括在序號計數(shù)中,也就是說可以使用工作簿序號引用隱藏的Workbook對象。
Item屬性是大多數(shù)對象集合的默認(rèn)屬性,因此可以省略Item關(guān)鍵字,簡化為下面的語法形式:
Workbooks(工作簿序號)
2.使用工作簿(或加載宏)名稱引用Workbook對象,語法格式為:
Workbooks(工作簿名稱)
利用Workbook對象的Name屬性可以返回工作簿名稱,但是Name為只讀性,不能利用Name屬性修改工作簿名稱;如果需要更改工作簿名稱,應(yīng)使用Workbook對象的SaveAs方法以其他名稱保存工作簿。下面代碼將工作簿Book1.xls另存到C:\temp目錄,文件名稱為ExcelHome.xls,如果不指定目錄,則新的工作簿保存在與原來工作簿相同的目錄中。
Workbooks("Book1.xls").SaveAs"c:\temp\ExcelHome.xls"
46.1.2 打開一個已經(jīng)存在的工作簿
使用Workbooks對象的Open方法可以打開一個已經(jīng)存在的工作簿,其語法格式如下:
Workbooks.Open FileName:="c:\temp\ExcelHome.xls"
注意:參數(shù)名和參數(shù)值之間應(yīng)該使用“:=”符號,而不是等號。
參數(shù)名稱可以省略,代碼簡化為:
Workbooks.Open"c:\temp\ExcelHome.xls"
46.1.3 遍歷工作簿
對于兩種不同的引用工作簿的方法,分別可以使用For Each循環(huán)和For/Next循環(huán)遍歷Workbooks集合中的Workbook對象。
示例46.1 遍歷工作簿名稱
步驟1.在工程中插入模塊,并修改其名稱為“AllWorkBook"。
步驟2.在模塊AllWorkBook中寫入如下代碼。
Sub AllWorkBook1()
'聲明變量
Dim WK As Workbook, iRow As Integer
ActiveSheet.Cells(1, 1) = "AllWorkBook1 運行結(jié)果"
iRow = 2
'循環(huán)取得WorkBooks集合中的所有WorkBook對象
For Each WK In Application.Workbooks
'將工作簿的名稱寫入工作表第一列
ActiveSheet.Cells(iRow, 1) = WK.Name
'行號遞增
iRow = iRow + 1
Next
End Sub
Sub AllWorkBook2()
'聲明變量
Dim i As Integer, iRow As Integer
ActiveSheet.Cells(1, 2) = "AllWorkBook2 運行結(jié)果"
iRow = 2
'設(shè)置循環(huán)變量的初值和終止值
For i = 1 To Application.Workbooks.Count
'將工作簿的名稱寫入工作表第二列
ActiveSheet.Cells(iRow, 2) = Workbooks(i).Name
'行號遞增
iRow = iRow + 1
Next
End Sub
步驟3.運行宏AllWorkBook1。
步驟4.運行宏AllWorkBook2。
運行結(jié)果,兩個過程的結(jié)果分別顯示在第一列和第二列,內(nèi)容完全相同,實際應(yīng)用中可以根據(jù)需要選擇任何一種遍歷方法。這兩種遍歷方法適用于多數(shù)對集合,如遍歷Worksheets集合中的Worksheet對象。
46.1.4 添加一個新的工作簿
在Excel中單擊菜單“文件”——新建,然后單擊新建工作簿窗口的“空白工作簿”;或單擊標(biāo)準(zhǔn)工具欄的“新建”按鈕,可以在Excel中產(chǎn)生一個新的工作簿。利用WorkBook對象的Add方法也可以實現(xiàn)添加一個新的工作簿,其語法格式為:
Wo(hù)rkbooks.Add
46.1.5 保護(hù)工作簿
從安全角度考慮,可以為工作簿設(shè)置密碼。下面代碼設(shè)置活動工作簿的保密密碼為“abc”。
ActiveWorkbook.Protect Password:="abc"
如果需要修改工作簿,可以利用Unprotect方法取消工作簿的保護(hù)。
ActiveWorkbook.Unprotect Password:="abc"
46.1.6 關(guān)閉工作簿
使用WorkBook對象的Close方法可以關(guān)閉打開的工作簿。如果該工作簿有更改,Excel將顯示對話框,詢問是否保存更改。
關(guān)閉工作簿時設(shè)置SaveChanges參數(shù)值為False,將放棄所有對該工作簿的更改,并且不會出現(xiàn)保存提示框。
ActiveWorbook.Close SaveChanges:=False
46.2 Worksheet對象
Worksheet對象代表一張工作表。Worksheet對象既是Worksheets集合的成員,同時又是Sheets集合的成員。Worksheets集合包含工作簿中所有的Worksheet對象。Sheets集合除了包含工作簿中所有的Worksheet對象外,還包含工作簿中所有的圖表工作表(Chart)對象和宏表對象。
ActiveSheet對象可用來引用處于活動狀態(tài)的工作表。
46.2.1 引用Worksheet對象
對于Worksheet對象,有如下3種引用方法。
1.使用工作表序號引用Worksheet對象,語法格式為:
Worksheets(工作表序號)
工作表序號是按照工作表的排列順序依次編號的,Worksheets(1)代表工作簿中的第一個工作表,而Worksheets(Worksheets.Co
unt)代表最后一個工作表,其中Worksheets.Count返回Worksheets集合中包含的Worksheet對象的個數(shù)。隱藏工作表也包括在序號計數(shù)中,也就是說可以使用工作表序號引用隱藏的Worksheet對象。
2.使用工作表名稱引用Worksheet對象,語法格式為:
Worksheets(工作表名稱)
使用工作表名稱引用Workbook對象時,工作表的名稱不區(qū)分大小寫字母,因此Worksheets(“sheet1”)引用的是同一個工作表,但是Worksheet對象的Name屬性返回值是工作表的實際名稱,可能和引用工作表時的名稱有大小寫區(qū)別。
3.使用工作表的代碼名(Codename)引用Worksheet對象。假設(shè)工作簿中有3個工作表。
在VBE窗口中查看工程窗口和屬性窗口。在工程窗口中Worksheet對象顯示為“工作表代碼名(工作表名稱)”的形式,對應(yīng)在屬性窗口中,“名稱”欄為代碼名,“Name”欄為工作表名稱。使用代碼名Sheet1等同于Worksheets(Sht3)。工作表的名稱和其代碼名也可以相同。
46.2.2 遍歷工作簿中的所有工作表
遍歷工作表的方法與遍歷工作簿的方法完全相同,可以使用For Each循環(huán)或For/Next循環(huán),具體請參閱46.1.3小節(jié)。
46.2.3 添加新的工作表
在Excel單擊菜單“插入”——“工作表”可以在當(dāng)前工作簿中插入一個新的工作表。使用Add方法也可以在工作簿中插入一個新的工作表,其語法格式為:
Sheets.Add
提示:插入指定名稱的工作表可以使用代碼Sheets.Add.Name = "newSheet",雖然在VBA幫助中沒有說明Add方法具有Name屬性,但上述代碼是可以運行。需要注意的是,采用這個簡化方式時,無法使用Add方法的參數(shù)。
46.2.4 拷貝和移動工作表
Worksheet對象的Copy方法和Move方法可以實現(xiàn)工作表的拷貝和移動。其語法格式為:
Copy(Befor,After)
Move(Before,After)
Before和After均為可選參數(shù),二者只能選擇一個。Copy和Move方法不僅可以實現(xiàn)同一個工作簿之內(nèi)的工作表的拷貝和移動,也可以實現(xiàn)工作簿之間的工作表拷貝和移動。下面的代碼可以將工作簿Book1.XLS中的工作表Sheet1拷貝到工作簿Book2.XLS中,并放置在原有的第3個工作表之前。
Workbooks("Book1.xls").Sheets("Sheet1").Copy Before:=Workbooks("Book2.xls").Sheets(3)
46.2.5 如何保護(hù)工作表
為了防止工作表被意外修改可以設(shè)置工作表保護(hù)密碼。Worksheet對象Protect方法有很多可選參數(shù),其中Password參數(shù)用于設(shè)置保護(hù)密碼。
ActiveSheet.Protect "ExcelHome"
46.2.6 刪除工作表
使用Worksheet對象的Delete方法刪除工作表時,將會出現(xiàn)提示框,單擊“刪除”完成刪除工作表。
如果不希望在刪除工作表時出現(xiàn)這個提示框,可以使用DisplayAlerts禁止提示框的顯示。
Application.DisplayAlerts = False
Worksheets("Sheet1").Delete
Application.DisplayAlerts = True
注意:代碼中如果使用了Application.DisplayAlerts=False, 在使用Application.DisplayAlerts=True恢復(fù)之前,所有的系統(tǒng)提示信息都是將被屏蔽。如果沒有使用代碼進(jìn)行恢復(fù),則在代碼運行結(jié)束后,Micorosoft Excel將該屬性設(shè)置為True。
46.3 Range對象
Range對象代表工作表中的單個單元格或多個單元格組成的區(qū)域,該區(qū)域可以是連續(xù)的也可以是非連續(xù)的。雖然單元格是Excel操作的基本單位,但是Excel中不存在單元格對象。
46.3.1 引用單個單元格
在VBA代碼中有多種方法可以用來引用單個單元格。
1.使用“[單元格名稱]”的形式:這是在寫法上最簡單的一種引用方式。其中單元格名稱與在工作表單元格公式中使用的A1樣式單元格名稱完全相同,如[C5]代表工作表中的C5單元格。在這種引用方式中,單元格名稱不能使用變量。
2.使用Cells屬性:Cells屬性返回一個Rabge對象。其語法格式為:
Cells(RowIndex,ColumnIndex)
Cells屬性的參數(shù)為行號和列號。行號是一個數(shù)值,其范圍為1~65 536。列號可以是數(shù)值,其范圍為1~256;也可以是字母形式的列標(biāo),其范圍為“A”~“IV”。工作表所支持的列數(shù)量為256,其列標(biāo)為“IV”。同樣是引用C5單元格,可以有兩種寫法:
Cells(5,3)
Cells(5,"c")
2.使用Range(單元格名稱)形式:其中單元格名稱可以使用變量或表達(dá)式。在參數(shù)名稱的表達(dá)式中可以使用"&"連接符,連接兩個字符串。
Range(“C5”)
46.3.2 單元格格式的常用屬性
常用的單元格格式有字體大小、字體顏色、背景色以及邊框等,下面的代碼將設(shè)置“A1:D10”區(qū)域的格式為:紅色11號字,背景色為青色,并添加邊框。
Sub CellFormat()
With Range("A1:D10")
With .Font
'設(shè)置字號
'Size = 11
'設(shè)置字體顏色為紅色
'Color = vbRed
End With
'設(shè)置單元格邊框線
Borders.LineStyle = xlContinuous
'設(shè)置單元格背景色為青色
.Interior.Color = vbCyan
End With
End Sub
46.3.3 添加批注
Comment對象代表單元格的批注,是Comments集合的成員。Comment對象并沒有Add方法,添加批注需要使用Range對象的AddCo
mment方法。下述代碼在活動單元格添加批注,內(nèi)容為“ExcelHome”。
Activecell.AddComment "ExcelHome"
利用For Each循環(huán)可以遍歷Comments集合中的所有Comment對象。
46.3.4 如何表示一個區(qū)域
Range屬性除了可以返回單個單元格,也可以返回單元格區(qū)域。Range的語法格式如下:
Range(cell1,cell2)
參數(shù)Cell必須為A1樣式引用,是一個單元格或區(qū)域的名稱字符串。參數(shù)Cell2,可以是一個包含單個單元格、整列或整行的Range對象,也可以是一個單元格或區(qū)域的名稱字符串。
如果引用以A3單元格和C6單元格之間所包含的單元格區(qū)域?qū)ο螅梢允褂萌缦聨追N方法:
Range(“A3:C6”)
Range([A3],[C6])
Range(Cells(3,1),Cells(6,3))
Range(Range("A3"),Range("C6"))
第一種Range(“A3,C6”)引用方式是最常用的方式,其中的冒號是區(qū)域操作符,其含義是以兩個A1樣式單元格為頂點的矩形單元格區(qū)域。
46.3.5 如何定義名稱
在工作表公式中,經(jīng)常通過定義名稱來簡化工作表單元格公式。本節(jié)所批的名稱是單元格區(qū)域的定義名。Workbook對象的Names集合代表工作簿中所有名稱組成的集合。Add方法用于指定新的名稱,參數(shù)RefersToR1C1用于指定單元格區(qū)域,格式為R1C1引用方式。利用Range對象的Name屬性,指定名稱的代碼為:
Range("A3:D6").Name = "data"
46.3.6 選中工作表的指定區(qū)域
在VBA代碼中經(jīng)常要引用某些特定區(qū)域,CurrentRegion屬性和UsedRange屬性是兩個最常用的屬性。
CurrentRegion屬性返回Range對象,就是通常據(jù)說的當(dāng)前區(qū)域。當(dāng)前區(qū)域是一個由任意空行和空列包圍的最小矩形單元格區(qū)域。按Ctrl+Shift+8組合鍵可以選中當(dāng)前區(qū)域,選中著色區(qū)域內(nèi)的任意單元格時,即使該單元格沒有內(nèi)容,按Ctrl+Shift+8組合鍵,同樣會選中相應(yīng)的著色區(qū)域。
UsedRange屬性返回Range對象,代表指定工作表上的已使用區(qū)域,該區(qū)域是由工作表中已經(jīng)被使用的單元格組成的矩形單元格區(qū)域。這里的“使用”與單元格是否有內(nèi)容無關(guān),即使只是改變了單元格的格式,這個單元格也是已經(jīng)被告使用,它將被包括在UsedR
ange屬性返回的Range對象中。
可以使用Rabge對象的Select方法或Activate方法來檢查相應(yīng)區(qū)域的范圍。
Activate.UsedRange.Select
Activate.UsedRange.Activate
46.3.7 特殊區(qū)域——行與列
行與列是工作表中經(jīng)常用到的兩個Range對象,對于行與列的引用既可以使用Rows屬性和Columns屬性,也可以使用Range屬性。
引用第1行至第5行的區(qū)域可以使用如下幾種形式:
Rows(“1:5”)
Range(“A1:IV5”)
Range(“1:5”)
列的引用方法與上述行的引用方式類似。例如引用A列~E列的區(qū)域可以使用如下幾種形式:
Colums("A:E")
Range("A1:E65536")
Range("A:E")
46.3.8 刪除單元格
Range對象的Delete方法可刪除一個單元格或單元格區(qū)域。下面代碼將刪除C3:F5單元格區(qū)域,其下的替補(bǔ)單元格向上移動,也就是原來C6:F8單元格區(qū)域?qū)⑾蛏弦苿拥奖粍h除的區(qū)域。
Range("C3:F5").Delete Shift:=xlShiftUp
46.3.9 插入單元格
Range對象的Insert方法可在工作表中插入一個單元格或單元格區(qū)域,其他單元格作相應(yīng)移動以騰出空間。下面代碼在工作表的第2行插入單元格,原工作表的第2行單元格將占據(jù)第3行的位置。
Rows(2).Insert
46.3.10 合并區(qū)域與相交區(qū)域
Union方法返回Range對象,代表兩個或多個區(qū)域的合并區(qū)域,其參數(shù)為Range類型。
Application.Union(Range("A3:D6"),Range("C5:F8"))
Intersect方法返回Range對象,代表兩個或多個單元格區(qū)域重疊的矩形區(qū)域,其參數(shù)為Range類型,如果參數(shù)單元格區(qū)域沒有重疊區(qū)域,那么結(jié)果為Nothing。
Application.Intersect(Range("A3:D6"),Range("C5:F8"))
利用 Intersect方法可以判斷某個單元格區(qū)域是否完全包含在另一個單元格區(qū)域中。
第47章 事件的應(yīng)用
在Excel VBA中,事件是指對象可以辨認(rèn)的動作。用戶可以指定VBA代碼來對這些動作做出響應(yīng)。Excel可以監(jiān)視多種不同類型的事件,Excel中的工作表、工作簿、應(yīng)用程序、圖表工作表、查詢表和控件等不同對象都有不同的事件,而且每個對象都有多種相關(guān)的事件,本章將主要介紹工作表和工作簿的常用事件。
47.1 事件過程
事件過程作為一種特殊的Sub過程,在事件被觸發(fā)時執(zhí)行,如果事件過程包含參數(shù),系統(tǒng)會為相關(guān)參數(shù)賦值。事件過程必須寫入相應(yīng)的模塊中才能發(fā)揮作用,工作簿事件過程須寫入Thisworkbook模塊中,工作表事件過程則須寫入相應(yīng)的工作表模塊中;且只有過程所在工作表的行為可以觸發(fā)該事件。
47.2 工作表事件
工作表事件發(fā)生在特定的Worksheet對象中。Worksheet對象也是Excel最常用的對象之一,因此實際應(yīng)用中經(jīng)常會用到Worksheet對象事件。
47.2.1 Change事件
工作表中的單元格被用戶手工修改或被VBA代碼修改時,將觸發(fā)工作表Change事件。值得注意的是,雖然事件的名稱是Change
但是并非工作表中單元格的任何變化都能觸發(fā)該事件。
Change事件的參數(shù)Target是Change變量,代表工作表中發(fā)生變化的區(qū)域,它可以是一個單元格也可以攻玉是多個單元格組成的區(qū)域。在實際應(yīng)用中,用戶通常希望只有工作表中的某些特定單元格區(qū)域發(fā)生變化時,才激活Change事件,這就需要在Change事件中對Target參數(shù)進(jìn)行判斷。
示例47.1 自動記錄數(shù)據(jù)錄入日期
在工作表ChangDemo的代碼窗口中寫入如下代碼:
Private Sub Worksheet_Change(ByVal Target As Range)
With Target
'判斷是否選中了單個單元格
If .Count = 1 Then
'判斷單元格是否在第一列
If .Column = 1 Then
'禁止事件激活
Application.EnableEvents = False
'在相應(yīng)行的第二列輸入當(dāng)前日期
Target.Offset(0, 1) = Date
'恢復(fù)事件激活
Application.EnableEvents = True
End If
End If
End With
End Sub
返回Excel界面,在工作表ChangDemo中的A列中輸入備忘內(nèi)容,Change事件將自動在B列的相應(yīng)行寫入當(dāng)前日期。修改工作表中其他列的單元格(如C列),工作表的Change事件同樣會被觸發(fā),但是因為不滿足代碼中的判斷條件,所以不會執(zhí)行寫入日期的代碼。
如何禁止事件的激活
上述代碼使用Application.EnableEvents=False為防止事件被意外多次激活。Application對象的EnableEvents屬性可以設(shè)置是否允許對象的事件被激活。上述代碼中如果沒有禁止事件激活的代碼,在寫入當(dāng)前日期的代碼執(zhí)行后,工作表的Change事件被再次激活,事件代碼被再次執(zhí)行。某些情況下,這種事件的意外激活會重復(fù)多次發(fā)生,甚至造成死循環(huán)導(dǎo)致事件代碼重復(fù)調(diào)用,無法結(jié)束運行。因此在可能意外觸發(fā)事件的時候,需要設(shè)置Application.EnableEvents=False禁止事件激活。但這個設(shè)置并不能限制控件的事件被激活。
EnableEvents屬性的值不會隨著事件過程的執(zhí)行結(jié)束而自動恢復(fù)為True,也就是說需要在代碼運行結(jié)束之前進(jìn)行恢復(fù)。如果代碼被異常終止,而EnableEvents屬性的值仍然為False,則相關(guān)的事件都無法激活。恢復(fù)辦法是在VBE的立即窗口中執(zhí)行Application.EnableEven
ts=True。
47.2.2 SelectionChange事件
工作表中選定區(qū)域的范圍發(fā)生變化將觸發(fā)工作表的SelectionChange事件。SelectionChange事件的參數(shù)Target是Range變量,代表工作青史被選中的區(qū)域,相當(dāng)于Selection屬性返回的Range對象。
示例47.2 高亮顯示工作表中選定區(qū)域所在的行和列
在工作表SelectionChangeDemo中寫入如下的SelectionChange事件代碼。
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
With Target
'清除工作表單元格的背景色
.Parent.Cells.Interior.ColorIndex = xlNone
'設(shè)置選中區(qū)域所在行的背景色
.EntireRow.Interior.Color = vbCyan
'設(shè)置選中區(qū)域所在列的背景色
.EntireColumn.Interior.Color = vbCyan
End With
End Sub
返回Excel界面,在工作表SelectionChangeDemo中選中一個單元格區(qū)域C10:C14,顯示效果,第10行至第14行以及第3列單元格高亮顯示。
47.3 工作簿事件
工作簿事件發(fā)生在特定的Workbook對象中。
47.3.1 Open事件
Open事件是Workbook對象最常用的事件之一,它發(fā)生于用戶打開工作簿之時。
注意:在如下兩種情況下,打開工作簿不會觸發(fā)Open事件。
1.在按住<Shift>鍵的同時打開工作簿。
2.在打開文件時的宏安全警告提示框里,選擇了“禁用宏”。
Open事件經(jīng)常被用來自動設(shè)置用戶界面,這樣的好處在于,無論工作簿關(guān)閉時的狀態(tài)如何,再次打開時都可以按照某個特定風(fēng)格呈現(xiàn)在用戶面前。
示例47.3 自動設(shè)置工作簿打開時的界面風(fēng)格
步驟1.在Thisworkbook模塊中寫入如下的Open事件代碼。
Private Sub Workbook_Open()
'Excel窗口最大化
Application.WindowState = xlMaximized
With ActiveWindow
'工作表窗口最大化
.WindowState = xlMaximized
'禁止顯示行標(biāo)和列標(biāo)
.DisplayHeadings = False
End With
'激活Welcome工作表
Sheets("Welcome").Select
End Sub
步驟2.返回Excel界面,選中Sheet1工作表。
步驟3.單擊Excel窗口右上角的向下還原按鈕,取消窗體最大化。
步驟4.單擊“文件”——“保存”。
步驟5.單擊“文件”——“退出”關(guān)閉工作簿。
步驟6.單擊“文件”——“打開”,再次打開剛才保存的工作簿。
步驟7.單擊安全警告提示框的“啟用宏”按鈕。
工作簿打開后,Excel窗口是最大化的,Welcome工作表成為活動工作表,而不是關(guān)閉工作簿時的Sheet1工作表。
47.3.2 BeforeClose事件
工作簿被關(guān)閉之前BeforeClose事件被激活。BeforeClose事件經(jīng)常和Open事件配合使用,在Open事件中修改的Excel設(shè)置和用戶界面,可以在BeforeClose事件中進(jìn)行恢復(fù)。
示例47.4 關(guān)閉工作簿時自動恢復(fù)Excel默認(rèn)界面風(fēng)格
在Thisworkbook模塊中寫入如下的代碼:
Private Sub Workbook_Open()
With Application
'隱藏公式編輯欄
.DisplayFormulaBar = False
'設(shè)置鼠標(biāo)指針為沙漏型
.Cursor = xlWait
End With
End Sub
Private Sub Workbook_BeforeClose(Cancel As Boolean)
With Application
'顯示公式編輯欄
.DisplayFormulaBar = True
'恢復(fù)系統(tǒng)默認(rèn)鼠標(biāo)指針
.Cursor = xlDefault
End With
End Sub
保存并關(guān)閉工作簿,然后再次打開工作簿,公式編輯欄已經(jīng)隱藏且鼠標(biāo)指針改為沙漏形。而在BeforeClose事件中,對相應(yīng)的設(shè)置進(jìn)行了恢復(fù),所以工作簿關(guān)閉后,Excel將恢復(fù)默認(rèn)的系統(tǒng)設(shè)置。
47.3.3 全部工作表使用相同的事件代碼
工作簿事件有幾個名稱是以“Sheet”開頭的,這些事件的一個共同特點是,工作簿內(nèi)的任意工作表的行為都將觸發(fā)事件代碼的執(zhí)行。
如果希望所有的工作表都相應(yīng)相同的工作表事件代碼,有兩種實現(xiàn)方法:
1.在每個工作表代碼模塊中寫入相同的事件代碼。
2.使用相應(yīng)的工作簿事件代碼。
毫無疑問,第二種方法是最簡潔的實現(xiàn)方法。
示例47.5 高亮顯示任意工作表中選定區(qū)域所在的行和列
與示例47.2相對應(yīng),如果希望在工作簿中的任意工作表都擁有這種高亮顯示的效果,可以在Thisworkbook模塊中寫入如下事件代碼:
Private Sub Workbook_SheetSelectionChange(ByVal Sh As Object, ByVal Target As Range)
With Target
'清除工作表單元格的背景色
.Parent.Cells.Interior.ColorIndex = xlNone
'設(shè)置選中區(qū)域所在行的背景色
.EntireRow.Interior.Color = vbCyan
'設(shè)置選中區(qū)域所在列的背景色
.EntireColumn.Interior.Color = vbCyan
End With
End Sub
與示例47.2相比,這種方法不必在每個工作表代碼模塊中寫入相同的事件代碼,而且當(dāng)工作簿中新增工作表時,也無需為新建工作表添加Change事件代碼。
47.4 非對象事件
Excel提供了兩種不與對象關(guān)聯(lián)的特殊事件,利用Application對象的相應(yīng)方法可以設(shè)置這些特殊事件。
47.4.1 OnTime事件
OnTime事件指定一個過程在將來的特定時間運行,此處的特定事件既可以是具體指定的某個時間點,也可以是指定的一段時間之后。
示例47.6 文件保存提醒
步驟1.在工作簿中插入標(biāo)準(zhǔn)模塊,并在其中寫入如下代碼。
'定義全局變量
Public iTime As Date
Sub SaveReminder()
'判斷當(dāng)前工作簿是否被修改
If ThisWorkbook.Saved = False Then
'顯示消息框
If MsgBox("為了防止數(shù)據(jù)丟失請保存文件" & _
vbCrLf & "點擊<是>進(jìn)行保存", vbYesNo, "OnTimeDemo") = vbYes Then
'如果用戶選擇<是>,則保存當(dāng)前工作簿
ThisWorkbook.Save
End If
End If
'記錄下次運行的時間點
iTime = Now + TimeValue("0:0:10")
'設(shè)置10秒后再次運行SaveReminder過程
Application.OnTime iTime, "SaveReminder"
End Sub
步驟2.在Thisworkbook中寫入如下代碼。
Private Sub Workbook_Open()
'記錄下次運行的時間點
iTime = Now + TimeValue("0:0:10")
'設(shè)置10秒后再次運行SaveReminder過程
Application.OnTime iTime, "SaveReminder"
End Sub
Private Sub Workbook_BeforeClose(Cancel As Boolean)
'取消設(shè)置的自動運行
Application.OnTime iTime, "SaveReminder", Schedule:=False
End Sub
步驟3.保存并關(guān)閉工作簿。
重新打開工作簿,在10秒鐘之后將看到工作簿保存提醒消息框。
Now函數(shù)返回當(dāng)前計算機(jī)系統(tǒng)設(shè)置的日期和時間:TimeValue("0:0:10")函數(shù)返回一個Date類型數(shù)據(jù),相當(dāng)于10秒;SaveReminder是標(biāo)準(zhǔn)模塊中在指定時間執(zhí)行的過程的名稱。為了演示方便,示例中設(shè)定的較短的代碼執(zhí)行時間間隔。
首先在工作簿打開時會觸發(fā)工作簿的Open事件,其中的OnTime設(shè)置10秒后運行SaveReminder過程。
在SaveReminder過程中,判斷工作簿的Saved屬性的值,如果為False說明工作簿已經(jīng)被修改,進(jìn)而提示用戶進(jìn)行保存,如果用戶單擊“是”按鈕,就保存當(dāng)前工作簿。在過程的最后,設(shè)置10秒后再次執(zhí)行SaveReminder過程代碼。
在工作簿的BeforClose事件中,利用Onkey方法的Schedule參數(shù)清除已經(jīng)設(shè)置的定時運行過程,如果省略此代碼,即使工作簿已經(jīng)關(guān)閉,到達(dá)指定時間時,Excel將再次打開工作簿運行SaveReminder過程代碼。
47.4.2 OnKey
使用OnKey方法可以設(shè)置按下特定的鍵或組合鍵時運行指定的過程代碼。Excel會一直監(jiān)視著用戶的任何鍵盤操作,因此理論上可設(shè)置任何一個鍵或組合鍵來運行指定的過程代碼。
注意:在工作表中輸入公式或在對話框中時,OnKey設(shè)置的組合鍵無效。
示例47.7 為Excel設(shè)置自定義快捷鍵
步驟1.在工作簿中插入標(biāo)準(zhǔn)模塊,在模塊中寫入如下代碼。
Sub OnKeyDemo()
Application.OnKey"^a","CtrlA"
End Sub
Sub CtrlA()
MsgBox "您按下了Ctrl+A組合鍵"
End Sub
步驟2.返回Excel界面,按<Ctrl+A>組合鍵,將出現(xiàn)消息框。
OnKey方法的參數(shù)"^a"中的"^"代表<Ctrl>鍵,關(guān)于其他功能鍵的表示方法請參考VBA幫助。
默認(rèn)情況下,Excel中<Ctrl+A>組合鍵為選中工作表中的全部單元格。運行OnKeyDemo過程之后,按<Ctrl+A>組合鍵將執(zhí)行CtrlA過程代碼顯示消息框。這也就是說,OnKey方法設(shè)置的組合鍵與系統(tǒng)默認(rèn)的組合鍵相比有更高的優(yōu)先級。
使用如下的代碼可以恢復(fù)<Ctrl+A>組合鍵的默認(rèn)設(shè)置功能。
Application.OnKey"^a"
第48章 控件在工作表中的應(yīng)
在工作表中可以使用兩種控件:窗體控件和ActiveX控件,二者既有聯(lián)系又有明顯的區(qū)別。
48.1 在工作表中插入控件
控件是在Excel與用戶交互時,用于輸入數(shù)據(jù)或操作數(shù)據(jù)的對象。在工作表中使用控件將為用戶提供更加友好的操作界面。控件具有豐富的屬性,并且可以被不同的事件激活以執(zhí)行相關(guān)代碼。
示例48.1 在工作表中使用按鈕控件
下面介紹如何在工作表中插入按鈕控件。
步驟1.打開一個新的工作簿。
步驟2.單擊菜單“視圖”——“工具欄”——“控件工具箱”;或者單擊Visual Basic工具欄上的“控件工具箱”按鈕,將顯示控件工具箱工具欄。
步驟3.單擊“命令按鈕”。
步驟4.移動鼠標(biāo)至工作表的任意區(qū)域,光標(biāo)變?yōu)槭中巍?div style="height:15px;">
步驟5.按住鼠標(biāo)左鍵,在工作表中拖動;至適當(dāng)位置再釋放鼠標(biāo),工作表中將添加一個名稱為CommandButton1的按鈕。
步驟6.如下4種方法可以為新的命令按鈕控件添加事件代碼。
1.雙擊命令按鈕控件。
2.在命令按鈕上右鍵單擊選擇“查看代碼”。
3.單擊控件工具箱工具欄上查看代碼按鈕。
4.切換到VBE窗口,在代碼中選擇CommandButton1對象和相應(yīng)的事件。
步驟7.代碼窗口中將自動添加了按鈕控件的Click事件模塊框架。
步驟8.在模塊框架中寫入如下事件代碼。
Private Sub CommandButton1_Click()
MsgBox "歡迎加入Excel Home"
End Sub
步驟9.返回Excel界面,單擊控件工具箱工具欄或Visual Basic工具欄的退出編輯模式按鈕。
步驟10.單擊工作表中的按鈕,將看到歡迎消息框。
48.2 窗體控件和工具箱控件
在Excel中有兩種控件,分別是窗體控件和控件工具箱控件,后者也被成為ActiveX控件。
單擊菜單“視圖”——“工具欄”——“窗體”,將顯示窗體工具伴。窗體控件是Excel 5和Excel 95完全兼容的,可以用于普通工作表和MS Excel 5.0對話框工作表中。部分工具欄按鈕處于禁用狀態(tài),這些窗體控件只能用于MS Excel 5.0對話框工作表中,在普通的工作表中無法使用。
控件工具箱控件為ActiveX控件,是用戶窗體上的控件子集,這些控件只能用于Excel 97或更高版本的Excel中。對比不難看出,其中部分控件從外觀上看是相同的,其功能也非常相似,如按鈕,組合框和列表框等,但ActiveX控件擁有豐富的屬性,支持多種事件。正是由于ActiveX控件具有的如上這些優(yōu)勢,使得ActiveX控件在Excel中得到比窗體控件更為廣泛的應(yīng)用。本章后續(xù)章節(jié)中所涉及的控件勻指ActiveX控件。
48.3 控件的屬性
每種控件都有多種屬性,這些屬性是對控件某些特征的描述。ActiveX控件的一個最重要的優(yōu)勢在于擁有豐富的屬性,在不同的應(yīng)用中需要設(shè)置不同的屬性值。以命令按鈕控件為例,更改其屬性值的步驟如下。
步驟1.單擊控件工具箱工具欄上或Visual Basic工具欄上的編輯模式按鈕,進(jìn)入編輯模式。
步驟2.在控件上右鍵單擊,在彈出的快捷菜單上選擇“屬性”。
步驟3.在屬性窗口中,設(shè)置命令按鈕的屬性值,Caption屬性為"Excel Home";AutoSize屬性為True。命令按鈕控件的尺寸自動調(diào)整以適應(yīng)新設(shè)置的Caption。
如果需要,還可以再繼續(xù)設(shè)置其他的屬性。全部設(shè)置完成后,切換回工作表窗口,退出控件的編輯模式即可。
48.4 認(rèn)識常用控件
本節(jié)將介紹控件工具箱工具欄所包含的基本控件。
48.4.1 最常用的控件——命令按鈕(CommandButton)
命令按鈕是最常用的ActiveX控件,一般用來執(zhí)行指定的代碼。鼠標(biāo)單擊命令按鈕將觸發(fā)其Click事件,在Click事件代碼中,可以顯示消息框,也可以完成操作工作表單元格等任務(wù)。
示例48.2 使用命令按鈕控件設(shè)置單元格格式
如果需要多次執(zhí)行錄制的宏,利用命令按鈕執(zhí)行宏代碼,是最方便快捷的方法。
步驟1.在工作表中設(shè)置活動單元格背景色為紅色,錄制宏產(chǎn)生相應(yīng)的代碼如下,該代碼已經(jīng)保存在工作簿的“模塊1”中。
Sub Macro1()
'Macro1 Macro
'宏由 Taller 錄制,時間:2007-5-26
With Selection.Interior
.ColorIndex = 3
.Pattern = xlSolid
End With
End Sub
步驟2.在工作表中添加命令按鈕控件。
步驟3.雙擊處于編輯模式的命令按鈕,在VBE的代碼窗口中將自動添加Click事件的代碼框架。
步驟4.使用如下兩種方法,可以實現(xiàn)單擊命令按鈕運行相應(yīng)的代碼。
1.將錄制宏產(chǎn)生的代碼寫入Click事件的代碼框架。
Private Sub CommandButton1_Click()
With Selection.Interior
.ColeorIndex = 3
.Pattern = xlSolid
End With
End Sub
2.在Click事件的代碼中調(diào)用錄制宏Macro1。
Private Sub CommandButton1_Click()
Call Macro1
End Sub
如果錄制宏的代碼需要被多個不同的過程引用,或者Click事件中的代碼較多時,方法二使得代碼更具有可讀性,也便于日后的代碼維護(hù)和修改。
步驟5.返回Excel界面,退出編輯模式。
步驟6.在工作表中單擊選中任意單元格,單擊命令按鈕將設(shè)置活動單元格的背景色為紅色。
48.4.2 復(fù)選框(CheckBox)
復(fù)選框控件用于二元選擇,控件的返回值為True或False。利用復(fù)選框控件的LinkCell屬性還可以在單元格中得到控件的返回值。
示例48.3 使用復(fù)選框控件制作多選調(diào)查問卷
步驟1.在工作表中添加一個復(fù)選框,修改其屬性。
1.Caption屬性為“Excel基礎(chǔ)應(yīng)用”。
2.LinkCell屬性為C3。
步驟2.調(diào)整控件位置,使其位于A3單元格內(nèi),退出編輯模式。
步驟3.在B3單元格輸入公式“=IF(C3,“經(jīng)常”,“偶爾”)”。
步驟4.使用類似方法添加另外3個復(fù)選框控件并修改其屬性。
1.CheckBox2的Caption屬性值為“Excel VBA程序開發(fā)”。
2.CheckBox3的Caption屬性值為“Excel 函數(shù)和公式”。
3.CheckBox4的Caption屬性值為“Excel 圖表與圖形”。
4.CheckBox2的LinkCell屬性值為“C4”。
5.CheckBox3的LinkCell屬性值為“C5”。
6.CheckBox4的LinkCell屬性值為“C6”。
無需使用VBA代碼也可以實現(xiàn)二選一的效果。選中復(fù)選框控件時,相應(yīng)行的第2列結(jié)果為“經(jīng)常”,否則為“偶爾”,用戶通過單擊控件可以切換第2列的值。為了便于用戶理解控件值變化對最終結(jié)果的影響,將首復(fù)選框控件的值顯示在第3列中。實際應(yīng)用中,可以設(shè)置該列的字體顏色為白色或隱藏第3列,這樣可以使得用戶界面更加簡潔。
48.4.3 選項按鈕(OptionButton)
選項按鈕控件同樣用于進(jìn)行二元選擇,控件的返回值為True或False。與復(fù)選框控件的不同之處在于,選項按鈕控件用于單項選擇,在多個選項按鈕成為一組時,選中其中某個選項按鈕后,同組的其余選項按鈕的值自動設(shè)置為False。而復(fù)選框控件用于多項選擇,單個復(fù)選框控件是否被選中,并不影響其他的復(fù)選框控件。
示例48.4 使用選項按鈕控件制作單項調(diào)查問卷
步驟1.在工作表中添加一個選項按鈕,修改其Caption屬性為“Excel基礎(chǔ)應(yīng)用”。
步驟2.雙擊控件,在代碼窗口中寫入如下的Click事件代碼。
Private Sub OptionButton1_Click()
Cells(12,"D").Value = OptionButtonl.Caption
End Sub
步驟3.使用類似方法添加另外3個選項按鈕控件并修改其Caption屬性。
1. OptionButton2的Caption屬性值為“Excel VBA程序開發(fā)”。
2.CheckBox3的Caption屬性值為“Excel 函數(shù)和公式”。
3.CheckBox4的Caption屬性值為“Excel 圖表與圖形”。
步驟4.在代碼窗口中添加如下Click事件代碼。
將錄制宏產(chǎn)生的代碼寫入Click事件的代碼框架中。
Private Sub CommandButton1_Click()
With Selection.Interior
.ColorIndes = 3
.Pattern = xlSolik
End Sub
在Click事件代碼中調(diào)用錄制的宏Macro1.
Private Sub CommandButton1_Click()
Call Macro1
End Sub
如果錄制宏的代碼需要被多個不同的過程引用,或者Click事件中的代碼較多時,方法二使得代碼更具有可讀性,也便于日后的代碼維護(hù)和修改。
步驟5.返回Excel界面,退出編輯模式。
步驟6.在工作表中單擊選中任意單元格,單擊命令按鈕將設(shè)置活動單元格的背景色為紅色。
48.4.2 復(fù)選框(CheckBox)
復(fù)選框控件用于二元選擇,控件的返回值為True或False。利用復(fù)選框控件的LinkCell屬性還可以在單元格中得到控件的返回值。
示例48.3 使用復(fù)選框控件制作多選調(diào)查問卷
步驟1.在工作表中添加一個復(fù)選框,修改其屬性。
Caption屬性為“Excel 基礎(chǔ)應(yīng)用”。
LinkCell屬為C3。
步驟2.調(diào)整控件位置,使其位于A3單元格內(nèi),退出編輯模式。
步驟3.在B3單元格輸入公式“=IF(C3,“經(jīng)常”,“偶爾”)”。
步驟4.使用類似方法添加另外3個復(fù)選框控件并修改其屬性。
1.CheckBox2的 Caption屬性值為“ Excel VBA程序開發(fā)”。
2.CheckBox3的 Caption屬性值為“ Excel 函數(shù)和公式”。
3.CheckBox4的 Caption屬性值為 “Excel 圖表與圖形”。
4.CheckBox2的 Caption屬性值為“C4”。
5.CheckBox3的 Caption屬性值為“C5”。
6.CheckBox4的 Caption屬性值為“C6”。
無需使用VBA代碼也可以實現(xiàn)二選一的效果。選中復(fù)選框控件時,相應(yīng)行的第2列結(jié)果為“經(jīng)常”,融為“偶爾”,用戶通過單擊控件可以切換第2列的值。為了便于用戶理解控件值變化對最終結(jié)果的影響,將復(fù)選框控件的值顯示在第3列中。實際應(yīng)用中,可以設(shè)置該列的字體顏色為白色或隱藏第3列,這樣可以使得用戶界面更加簡潔。
48.4.3 選項按鈕(OptionButton)
選項按鈕控件同樣用于進(jìn)行二元選擇,控件的返回值為True或 False。與復(fù)選框控件的不同之處在于,選項按鈕控件用于單項選擇,在多個選項按鈕成為一組時,選中其中某個選項按鈕后,同組的其余選項按鈕的值自動設(shè)置為 False。而復(fù)選框控件用于多項選擇,單個復(fù)選框控件是否被選中,并不影響其他的復(fù)選框控件。
示例48.4 使用選項按鈕控件制作單項調(diào)查問卷
步驟1.在工作表中添加一個選項按鈕,修改其Capion屬性為“ Excel 基礎(chǔ)應(yīng)用”。
步驟2.雙擊控件,在代碼窗口中寫入如下Click事件代碼。
Private Sub OptionButton1_Click()
Cells(12,"D"),Valeu = OptionButton1.Caption
End Sub
步驟3.使用類似方法添加另外3個選項按鈕控件并修改其Caption屬性。
1.OptionButton2的 Caption屬性值為 “Excel VBA程序開發(fā)”。
2.OptionButton3的 Caption屬性值為“ Excel 函數(shù)和公式”。
3.OptionButton4的 Caption屬性值為 “Excel 圖表與圖形”。
步驟4.在代碼窗口中添加如下Click事件代碼。
Private Sub OptionButton2_Click()
Cells(12,"D").Value = OptionButton2.Caption
End Sub
Private Sub OptionButton3_Click()
Cells(12,"D").Value = OptionButton3.Caption
End Sub
Private Sub OptionButton4_Click()
Cells(12,"D").Value = OptionButton4.Caption
End Sub
步驟5.退出編輯模式,在工作表中單擊任意一個OptionButton控件,在D12單元格中將顯示選擇的結(jié)果。
實際應(yīng)用中,往往需要在多個類別的項目中實現(xiàn)多選一功能。以示例48.4為例,如果除了上述4個選項外,還有另外一組選項,最終希望用戶在每組中選擇一個項目,這就需要利用屬性對選項按鈕控件進(jìn)行分組。分組后,改變某個選項按鈕的值,不影響其他組中的選項按鈕。
步驟6.進(jìn)入編輯模式,依次設(shè)置OptionButton1,OptionButton2,OptionButton3和 OptionButton4控件的GroupaName屬性值為“Excel”
步驟7.添加4個選項按鈕,設(shè)置其GroupaName屬性值為“NonExcel”,并修改其Caption屬性。
OptionButton5的 Caption屬性值為“會員廣場”。
OptionButton6的 Caption屬性值為“電腦網(wǎng)絡(luò)”。
OptionButton7的 Caption屬性值為“休閑吧”。
OptionButton8的 Caption屬性值為“MS Office Word”。
步驟8.在代碼窗口中寫入如下Click事件代碼。
Private Sub OptionButton5_Click()
Cells(13,"D").Value = OptionButton5.Caption
End Sub
Private Sub OptionButton6_Click()
Cells(13,"D").Value = OptionButton6.Caption
End Sub
Private Sub OptionButton7_Click()
Cells(13,"D").Value = OptionButton7.Caption
End Sub
Private Sub OptionButton8_Click()
Cells(13,"D").Value = OptionButton8.Caption
End Sub
步驟9.退出設(shè)計模式。用戶可以分別選中左右兩組控件中的某個選項按鈕,選擇的結(jié)果顯示在D12和D13單元格中。
48.4.4 列表框(ListBox)和組合框( ComboBox)
組合框控件與列表框控件非常相似,兩種控件都可以在一組列表中進(jìn)行選擇;二者的區(qū)別在于列表框控件可以選中一個或多個條目,而組合框控件只能選中單個條目。組合框的優(yōu)點在于控件占用面積小,除了可以在預(yù)置選項中進(jìn)行選擇外還可以輸入其他數(shù)據(jù)。
下面介紹組合框控件的幾個常用屬性。
1.ListFillRange屬性可以指定列表來自于工作表中的某個區(qū)域。
2.ListRows屬性指定下拉過猶不及顯示的行數(shù)。
3.Style屬性指定是否允許輸入列表中不存在的值。
示例48.5 使用組合框控件制作調(diào)查問卷
利用組合框控件可以實現(xiàn)與示例48.4相同的效果。
步驟1.在工作表中插入組合框控件,并修改其屬性如下。
1.設(shè)置ListFillRange屬性值為G1:G4。
2.設(shè)置ListRows屬性值為D14。
3.設(shè)置Style屬性值為“2-fmStyleDropDownList”,即只允許用戶在列表中選擇項目。
步驟2.在工作表中插入第二個組合框控件,并修改其屬性如下。
1.設(shè)置ListFillRange屬性值為H1:H4。
2.設(shè)置ListRows屬性值為H15。
3.設(shè)置Style屬性值為“2-fmStyleDropDownList”,即只允許用戶在列表中選擇項目。
步驟3.退出設(shè)計模式,單擊組合框控件,將出現(xiàn)下拉列表,選中某個項目后將更新D15單元格。
48.4.5 文本框(TextBox)
文本框控件主要用于接受用戶的輸入。一般情況下,用戶會在工作表的單元格中直接輸入數(shù)據(jù),但當(dāng)單元條處于編輯狀態(tài)時,E
xcel應(yīng)用程序則無法運行任何代碼,借助文本框控件,就可以實現(xiàn)對用戶鍵盤輸入的控制。
示例48.6 快速錄入3數(shù)字
在單元格中錄入數(shù)據(jù)時,需要按<Enter>鍵才能完成輸入。如果需要錄入大量的數(shù)據(jù)時,每個單元格都按<Enter>鍵將會影響錄入的效率。假設(shè)錄入的數(shù)據(jù)為3位數(shù)字,依次放置于第一列單元格,借助文本框控件可以實現(xiàn)快速錄入,并防止意外輸入非數(shù)字字符。
步驟1.在工作表添加文本框控件。
步驟2.雙擊控件,在VBE代碼窗口中寫入如下事件代碼。
Private Sub TextBox1_Change()
'判斷文本框內(nèi)字符的個數(shù)
In Len(TextBox1.Value) = 3 Then
'將文本框的內(nèi)容寫入A列第一個非空單元格
[a65536].End{xlUp}.Offset(1,0) = TextBox1.Value
'清空文本框
TextBox1.Text = ""
End If
End Sub
Private Sub TextBox1_KeyPress(ByBal KeyAscii As MSForms.ReturnInteger)
'判斷鍵盤輸入的字符是否為數(shù)字
If KeyAscii <Asc("c") Or KeyAscii > Asc("9") Then
'清空鍵盤輸入
KeyAscii = 0
End If
End Sub
步驟3.返回Excel界面,退出編輯模式。
步驟4.單元文本框控件,在文本框中輸入數(shù)字,3個數(shù)字輸入完成后,自動填充到A列的第一個非空單元格,并清空文本框,此時可以開始錄入下一數(shù)據(jù)。
48.4.6 切換按鈕(ToggleButton)
切換按鈕控件也被稱作開頭按鈕,單擊該擦傷可以在“開”和“關(guān)”兩種狀態(tài)之間進(jìn)行切換,其外觀也隨之變化。切換按鈕的返回值為True(按下狀態(tài))或 False(彈起狀態(tài))。
48.4.7 數(shù)值調(diào)節(jié)鈕(SpinButton)
數(shù)值調(diào)節(jié)鈕控件可以實現(xiàn)用戶單擊控件中的箭頭來選擇一個值。控件具有兩個箭頭,一個箭頭用于增加值,一個用于減少值;增加或減少以SamllChange屬性值為步長。
48.4.8 流動條(ScrollBar)
滾動條控件與數(shù)值調(diào)節(jié)鈕控件非常類似,區(qū)別在于滾動條控件可按照兩種不同的步長(SmallChange屬性值和 LargeChange屬性值)改變控件的值,而且用戶可以拖放滾動條按鈕,大幅度改變控件的值。
單擊控件兩端按鈕以SmallChange屬性值為步長修改控件的值
單擊控件以LargeChange屬性值為步長修改控件的值
48.4.9 標(biāo)簽控件(Label)
標(biāo)簽控件主要用于顯示文本信息,除非需要使用標(biāo)簽控件的事件代碼,否則在工作表中完全可以使用文本框自選圖形替代標(biāo)簽控件。
48.4.10 圖像控件(Image)
圖像控件用于顯示一張圖片。使用圖像控件可能會使工作簿文件的大小猛增。利用圖像控件的Picture屬性可以選擇需要加載的圖片文件。
第49章 窗體在EXCEL中的應(yīng)用
在VBA代碼中使用InputBox和 MsgBox,可以滿足大多數(shù)交互應(yīng)用的需要,但這些對話框并非適合所有的應(yīng)用場景,其明顯的弱點在于缺乏靈活性。例如,除了窗口的顯示位置和幾種預(yù)先定義的按鈕組合外,無法按照實際需要添加更多的控件,利用用戶窗體則可以實現(xiàn)各種用戶定制的對話框。本章將介紹如何插入窗體、修改窗體屬性、窗體事件的應(yīng)用和在窗體中使用控件。
49.1 創(chuàng)建自己的第一個窗體
在示例44.2中,利用了InpuBox框輸入員工號,如果除了員工號還有很多信息需要錄入,這就需要多次調(diào)用InpuBox逐項輸入。使用用戶窗體就可以實現(xiàn)在一個窗體中輸入某個員工的全部信息。
49.1.1 插入用戶窗體
步驟1.打開一個新的工作簿文件,按<Alt+F11>組合鍵切換到VBE窗口。
步驟2.單擊VBE菜單“插入”——“用戶窗體”,系統(tǒng)將添加名稱為Userform1 用戶窗體。
步驟3.按<F4>鍵顯示屬性窗口,修改用戶窗體的Capiton屬性為“員工信息管理系統(tǒng)”。
步驟4.單擊VBE菜單“插入”——“模塊”,在模塊1中寫入如下代碼。
Sub ShowFrm()
UserForm1.Show
End Sub
Show方法用于顯示 UserForm對象。
步驟5.返回Excel界面,運行宏 ShowFrm,將顯示用戶窗體。
步驟6.單擊用戶窗體右上角的紅色“X”按鈕,可以關(guān)閉窗體。
49.1.2 關(guān)閉窗體
使用如下代碼將關(guān)閉UserForm1窗體,代碼執(zhí)行后UserForm對象將從內(nèi)存中刪除,此后無法訪問窗體和其中的控件。
Unload UserForm1
49.2 窗體中使用控件
上面設(shè)置中顯示的用戶窗體只是一個空白窗體,其中沒有任何控件,因此也就無法進(jìn)行用戶交互。本節(jié)將講解如何在用戶窗體中使用控件。
49.2.1 在窗體中插入控件
示例49.2 在用戶窗體中插入控件
步驟1.打開示例49.1的工作簿,另存為新工作簿,按<Alt+F11>組合鍵切換到VBE窗口。
步驟2.在工程窗口中雙擊UserForm1,對象窗口中將顯示UserForm對象。
步驟3.單擊VBE菜單“視圖”——“工具箱”,顯示工具箱窗口。
步驟4.單擊標(biāo)簽控件的按鈕A
步驟5.拽住鼠標(biāo)左鍵,在UserForm1控件上拖動至適當(dāng)位置,再釋放鼠標(biāo),將添加一個標(biāo)簽控件。
步驟6.按<F4>鍵,在屬性窗口中調(diào)整標(biāo)簽控件的屬性值。
AutoSize屬性值為“True”。
Caption屬性值為“員工號”。
步驟7.使用類似的方法添加另外兩個標(biāo)簽控件,并設(shè)置控件的屬性值。
AutoSize屬性值為“True”。
Label2控件的Captio屬性值為“性別”。
Label3控件的Caption屬性值為“部門”。
步驟8.在UserForm1控件上右鍵單擊,選擇“全選”,選中全部控件。
步驟9.在選中的控件上右鍵單擊,選擇“對齊”——“左對齊”。
步驟10.在用戶窗體中插入TextBox控件,并調(diào)整其屬性。
MaxLength屬性值為4,即控件中最多可輸入4個字符。
步驟11.在用戶窗體中插入兩個ComboBox控件,并調(diào)整其屬性。
Style屬性值為 "2-fmStyleDropDownList",即用戶只能在下拉列表中選擇條目,不能輸入新的值。
步驟12.在用戶窗體中插入兩個CommandButton控件,并調(diào)整其屬性。
CommandButton1控件Caption屬性設(shè)置為“添加數(shù)據(jù)”。
CommandButton2控件Caption屬性設(shè)置為“退出”。
步驟13.調(diào)整控件的大小及其位置。
步驟14.返回Excel界面,運行宏ShowFrm,將顯示用戶窗體。
步驟15.單擊用戶窗體右上角的紅色“X”按鈕,可以關(guān)閉窗體。
49.2.2 指定控件代碼
上面設(shè)置的用戶窗體中,如果單擊“性別”旁邊的下拉箭頭,會發(fā)現(xiàn)下拉列表是空白的,單擊“添加數(shù)據(jù)”按鈕也沒有任何反應(yīng),其原因在于尚未添加各控件相關(guān)的事件代碼。下面來為控件添加事件代碼。
示例49-3 為窗體控件添加事件代碼
步驟1.打開示例49-2的工作簿,另存為新工作簿,按<Alr+F11>組合鍵切換到VBE窗口。
步驟2.在工程窗口中UserForm1上右鍵單擊,選擇“查看代碼”。
步驟3.在代碼窗口上部的對象下拉列表中選擇"TextBox1",在事件下拉列表中選擇"KeyPress",系統(tǒng)將自動添加KeyPress事件模塊框架,在其中寫入如下代碼,用于防止用戶意外輸入非數(shù)字字符。
Private Sub TextBox1_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
'判斷鍵盤輸入的字符是否為數(shù)字
If keyAscii <Asc("0") Or KeyAscii > Asc("9") Then
'清空鍵盤輸入
KeyAscii = 0
End If
End Sub
步驟4.在代碼窗口上部的對象下拉列表中選擇“Userform”,在事件下拉列表中選擇"Initialize",系統(tǒng)將自動添加Initialize事件模塊框架,在其中寫入如下代碼,用于添加ComboBox控件的下拉列表。
Private Sub UserForm_Initialize()
With Me.ComboBox1
.AddItem "男"
.AddItem "女"
End With
With Me.ComboBox2
.AddItem "計劃部"
.AddItem "建設(shè)部"
.AddItem "網(wǎng)絡(luò)部"
.AddItem "財務(wù)部"
End With
End Sub
步驟5.在代碼窗口上部的對象下拉列表中選擇“CommandButton1”,在事件下拉列表中選擇"Click",系統(tǒng)將自動添加Click事件模塊框架,在其中寫入如下代碼。
Private Sub CommandButton1_Click()
Dim iRow As Integer
'定位工作表中A列第一個空白單元格
iRow = [A65536].End(xlUp).Row + 1
'將數(shù)據(jù)寫入工作表中
'員工號
Cells(iRow, 1) = Me.TextBox1.Value
'性別
Cells(iRow, 2) = Me.ComboBox1.Value
'部門
Cells(iRow, 3) = Me.ComboBox2.Value
'清空用戶窗體中輸入的內(nèi)容
Me.TextBox1.Value = ""
Me.ComboBox1.Value = ""
Me.ComboBox2.Value = ""
End Sub
步驟6.在代碼窗口上部的對象下拉列表中選擇"CommandButton2",在事件下拉列表中選擇"Click",系統(tǒng)將自動添加Click事件模塊框架,在其中寫入如下代碼。
Private Sub CommandButton2_Click()
'卸載窗體
Unload UserForm1
End Sub
步驟7.返回Excel界面,運行宏ShowFrm。
步驟8.在用戶窗體的文本框中輸入員工“7009”,如果按鍵為非數(shù)字鍵,將被忽略,并且文本框中最多只能輸入4個數(shù)字;單擊“性別”組合框,選擇“男”;單擊“部門”組合框,選擇“網(wǎng)絡(luò)部”。
步驟9.單擊“添加數(shù)據(jù)”按鈕,新輸入數(shù)據(jù)添加到工作表中,同時用戶窗體將清空,用戶可以開始輸入下一組數(shù)據(jù)。
步驟10.單擊“退出”按鈕,關(guān)閉用戶窗體。
49.3窗體的常用事件
用戶窗體作為一個控件的容器,本身也是一個對象,因此用戶窗體同樣支持多種事件。本節(jié)將介紹窗體的幾個常用事件。
49.3.1 Initialize事件
使用UserForm對象的Show方法顯示用戶窗體時將觸發(fā)Initialize事件,也就是說Initialize事件代碼運行之后才會顯示用戶窗體,因此對用戶窗體或窗體中的初始化工作可以在Initialize事件代碼中完成。如示例49.3中用Initialize事件代碼添加ComboBox控件的下拉列表。
49.3.2 QueryClose事件和Terminate事件
QueryClose事件和Terminate事件都是和關(guān)閉窗體相關(guān)的事件。關(guān)閉窗體時首先激活QueryClose事件,系統(tǒng)將窗體從屏幕上刪除后,在內(nèi)存中制裁窗體之前將激活Terminate事件,也就是說Terminate事件代碼中仍然可以訪問用戶窗體及窗體上的控件。
示例49-4 用戶窗體QueryClose事件和Terminate事件
步驟1.打開—個新的工作簿文件,按<Alt+F11>組合鍵切換到VBE窗口。
步驟2.單擊VBE菜單“插入”——“用戶窗體”,系統(tǒng)將添加名稱Userrorm1的用戶窗體。
步驟3.在窗體中添加一個TextBox控件。
步驟4.雙擊窗體,在代碼窗口中寫入如下事件代碼。
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
MsgBox Me.Visible & vbTab & TextBox1.Value, , "QueryClose"
End Sub
Private Sub UserForm_Terminate()
MsgBox Me.Visible & vbTab & TextBox1.Value, , "Terminate"
End Sub
步驟5.單擊VBE菜單“插入”——“模塊”,在模塊1中寫入如下代碼。
Sub CloseEventDemo()
UserForm1.Show
End Sub
步驟6.返回Excel界面,運行宏CloseEventDemo,在用TextBox控件中輸入"ExcelHome"。
步驟7.單擊用戶窗體右上角的紅色“X”按鈕,關(guān)閉用戶窗體,將出現(xiàn)消息框,由消息框的標(biāo)題可以得知QueryClose事件被激活。
步驟8.單擊“確定”,將出現(xiàn)消息框,由消息框的標(biāo)題可以得知Terminate事件被激活,此時屏幕中已經(jīng)不再顯示用戶窗體,因此用戶窗體的Visible屬性值為False,但是代碼可以讀取用戶窗體中TextBox控件的值。
步驟9.單擊“確定”,將關(guān)閉消息框。