第15單 Excel事件
15.1 了解事件
事件是一個(gè)對(duì)象可以辯認(rèn)的動(dòng)作,像單擊鼠標(biāo)或按下某鍵等,并且可以編寫某些代碼針對(duì)此動(dòng)作做出響應(yīng)。用戶做動(dòng)作或程序代碼的結(jié)果都可能導(dǎo)致事件的發(fā)生,事件還可由系統(tǒng)引發(fā)。在VBA中,可以激發(fā)事件的用戶動(dòng)作包括切換工作表、選擇單元格和單擊鼠標(biāo)等幾十種。當(dāng)事件發(fā)生時(shí),將執(zhí)行包含在事件過(guò)程中的代碼。如果用戶沒(méi)有定義某事件所調(diào)用的過(guò)程,那么當(dāng)發(fā)生該事件時(shí),就不會(huì)產(chǎn)生任何反應(yīng)。
15.1.1事件分類
Excel提供了非常多的事件,主要可以分為以下幾類。
1、工作簿事件
工作簿事件發(fā)生在特定的工作簿中,如Open(打開(kāi)工作簿)、BeforeClose(關(guān)閉工作簿之前)和SheetActivate(激活任何一張表)等。工作簿事件的代碼必須在ThisWork對(duì)象代碼模塊中編寫。
2、工作表事件
工作表事件發(fā)生在特定的工作表中,如Activate(激活工作表)、Change(更改工作表中的單元格)和SelectionChange(工作表上的選定區(qū)域發(fā)生改變)等。工作表帶今年年底代碼必須在對(duì)應(yīng)工作表的代碼模塊中編寫。
3、窗體、控件事件
新建的用戶窗體及窗體上的控件也可響應(yīng)很多事件,如Click(單擊)、Change(控件內(nèi)容更改)等,這類事件的代碼必須編寫在相應(yīng)的用戶窗體代碼模塊中。
4、圖表事件
圖表事件針對(duì)某個(gè)特殊的圖表產(chǎn)生,例如Select(選中了圖表中的某個(gè)對(duì)象)和SeriesChange(改變了系列中的某個(gè)數(shù)據(jù)點(diǎn)的值)。
5.不與對(duì)象關(guān)聯(lián)的事件
這類事件只有兩個(gè),分別是OnTime和OnKey,根據(jù)時(shí)間和按鈕來(lái)產(chǎn)生兩個(gè)事件。
15.1.2 編寫事件程序
如果要對(duì)某個(gè)事件進(jìn)行響應(yīng),就必須編寫對(duì)應(yīng)的事件處理程序,并將這些程序放置在規(guī)定的位置上,并且每個(gè)事件處理程序都必須使用系統(tǒng)事先定義好的名稱。例如,需要對(duì)工作簿的Open事件編寫處理代碼,其操作步驟如下。
步驟1 在Excel環(huán)境下按Alt+F11組合鍵打開(kāi)VisualBasic編輯器。
步驟2 在左側(cè)的“工程資源管理器”窗口中列出了當(dāng)前工程項(xiàng)目中的Excel對(duì)象,雙擊其中的“ThisWorkbook”對(duì)象,將在右側(cè)打開(kāi)代碼編輯器。
步驟3 在代碼窗口左側(cè)對(duì)象下拉列表框中選擇對(duì)象。
步驟4 選擇好對(duì)象“Workbook”后,在代碼窗口右側(cè)的事件下拉列表框中可看到出該對(duì)象的事件列表。
步驟5 選擇好對(duì)象和事件后,系統(tǒng)自動(dòng)生成事件過(guò)程的外部結(jié)構(gòu)。在事件過(guò)程結(jié)構(gòu)中編寫響應(yīng)該事件的代碼即可。
15.2 工作簿事件
當(dāng)工作簿更改、工作簿中的任何工作表更改、加載宏更改或數(shù)據(jù)透視表更改時(shí),都將引發(fā)工作簿事件。合理地使用各個(gè)事件可以避免一些意料不到的錯(cuò)誤,以及提高代碼的可讀性,同時(shí)也可以提高代碼的執(zhí)行效率。
15.2.1 工作簿事件簡(jiǎn)介
若要查看工作簿的事件過(guò)程,可以雙擊“工程資源管理器”窗口中的“ThisWorkbook”對(duì)象,打開(kāi)“代碼編輯器”窗口,在“過(guò)程”下拉列表框內(nèi)選擇事件名稱。Excel 2007的工作簿事件如表15-1所示。
表15-1 工作簿事件及其觸發(fā)時(shí)間
表中可以看出,Excel工作簿事件非常多,但有一部分事件幾乎很難用到。
工作簿事件代碼必須位于“ThisWorkbook”對(duì)象的代碼模塊中,如果放于其他代碼模塊中,將不會(huì)被執(zhí)行。
15.2.2 Open事件
打開(kāi)工作簿時(shí),將產(chǎn)生此事件。Workbook_Open事件只在工作簿打開(kāi)時(shí)產(chǎn)生,在下一次打開(kāi)之前不再發(fā)生此事件。此事件中可以寫入一些只需執(zhí)行一次的代碼,比如如果需要在每次打開(kāi)文件時(shí)在“Sheet1”工作表的A列記錄文件打開(kāi)的時(shí)間,則應(yīng)該使用此事件,代碼如下:
Private Sub Workbook_Open()
Worksheets("Sheet1").Range("A1048576").End(xlUp).Offset(1,0).Value = VBA.Now
End Sub
對(duì)系統(tǒng)設(shè)置進(jìn)行修改的代碼不應(yīng)編寫在這個(gè)事件過(guò)程中,而應(yīng)寫入Workbook_Activate事件中,Workbook_Activate事件緊隨在Workbook_Open事件后面發(fā)生。
注意:Workbook_Open事件代碼有可能不被執(zhí)行,例如在打開(kāi)工作簿時(shí)用戶按住“Shift”鍵可跳過(guò)該事件代碼。
15.2.3 BeforeClose事件 在關(guān)閉工作簿之前,先產(chǎn)生此事件。如果該工作簿已經(jīng)更改過(guò),則本事件在詢問(wèn)用戶是否保存更改之前產(chǎn)生。其事件處理代碼格式如下: Private Sub Workbook_BeforeClose(Cancel As Boolean) 當(dāng)事件產(chǎn)生時(shí),參數(shù)Cancel為False。如果該事件將Cancel設(shè)為True,則停止對(duì)工作簿的關(guān)閉操作,工作簿仍處于打開(kāi)狀態(tài)。 一般情況下,只應(yīng)在該事件中加上以下功能,而不應(yīng)將對(duì)系統(tǒng)的設(shè)置或者恢復(fù)代碼放在此處。 ?。保┎伙@示是否保存修改對(duì)話框而保存工作簿的任何更改。 ?。玻┓艞壉4婀ぷ鞑镜娜魏胃?,直接退出,代碼如下: Private Sub Workbook_BeforeClose(Cancel as Boolean) Me.Saved = True End Sub ?。常┏绦蛑性O(shè)置標(biāo)志變量,控制用戶直接按窗口上的“關(guān)閉”按鈕退出系統(tǒng)。只有通過(guò)代碼設(shè)置標(biāo)志變量為對(duì)應(yīng)值時(shí)才允許退出系統(tǒng),具體代碼如下: Private Sub Workbook_BeforeClose(Cancel As Boolean) If bFlag=False then Cancel=True 'bFlag為標(biāo)志變量 End Sub 15.2.4 Activate事件 激活一個(gè)工作簿時(shí)將產(chǎn)生該事件。所謂工作簿激活,包括以下兩種情況: 1)工作簿打開(kāi)時(shí),在Open事件之后發(fā)生該事件; ?。玻牧硪还ぷ鞑厩袚Q到本工作簿時(shí),發(fā)生該事件。 工作簿的Open事件有可能被用戶跳過(guò),所以應(yīng)該將系統(tǒng)設(shè)置之類的初始化代碼放在Activate事件中。 下例通過(guò)工作簿的Activate事件完成調(diào)用自定義菜單、隱藏工具欄等設(shè)置,其代碼如下: Private Sub Workbook_Activate() Application.ScreenUpdatin = False '關(guān)閉屏幕更新 Application.Cursor = xlDefault '設(shè)置光標(biāo)為默認(rèn)圖標(biāo) Application.Caption = "學(xué)生成績(jī)管理系統(tǒng)" '設(shè)置應(yīng)用程序標(biāo)題 Application.Caption = "" Application.CommandBars("Toolbar list").Enabled = False '屏蔽右鍵工具欄 Application.CommandBars("Standard").Visible = False '隱藏標(biāo)準(zhǔn)工具欄 Application.CommandBars("Formatting").Visible = False '隱藏格式工具欄 Application.DisplayFormulaBar = False ’隱藏編輯欄 Application.DisplayStatusBar= True '顯示狀態(tài)欄 ActiveWindow.DisplayWorkbookTabs= False ’隱藏工作表標(biāo)簽 HideBar '調(diào)用子過(guò)程,隱藏工具欄 MyBar_Menu ’調(diào)用子過(guò)程,顯示自定義菜單 Sheets("主界面").ScrollArea = "A1:M38" '設(shè)置主界面的滾動(dòng)區(qū)域 Application.ScreenUpdatin = True '打開(kāi)屏幕更新 End Sub 15.2.5 Deactivate事件 當(dāng)工作簿從活動(dòng)狀態(tài)轉(zhuǎn)為非活動(dòng)狀態(tài)時(shí)產(chǎn)生此事件。以下情況將產(chǎn)生該事件: ●工作簿從活動(dòng)狀態(tài)轉(zhuǎn)為非活動(dòng)狀態(tài)時(shí); ●關(guān)閉工作簿時(shí),在Workbook_BeforClose事件之后發(fā)生此事件。 一些恢復(fù)系統(tǒng)設(shè)置之類的代碼可放在此事件中。例如對(duì)上例中Activate事件所做設(shè)置進(jìn)行清理,恢復(fù)Excel初始設(shè)置,具體代碼如下: Private Sub Workbook_Deactivate() Application.Caption = “Microsoft Excel” '設(shè)置應(yīng)用程序的標(biāo)題為默認(rèn)值 MyBarDelete ’刪除自定義菜單 ShowBar ’顯示各工具欄 Application.CommandBars("Toolbar list").Enabled = True '顯示默認(rèn)工具欄 Me.save ’保存工作簿 End Sub 15.2.6 SheetActivate事件 激活任何一張表時(shí)產(chǎn)生此事件。例如,下面的代碼將顯示被激活工作表的名稱: Private Sub Workbook_SheetActivate(ByVal Sh As Object) MsgBox Sh.Name End Sub 如果激活工作簿中的任何一張工作表,那么將活動(dòng)單元格定位到A1單元格的代碼如下: Private Sub Workbook_SheetActivate(ByVal Sh As Object) MsgBox Sh.Name End Sub 如果激活工作簿中的任何一張工作表,那么將活動(dòng)單元格定位到A1單元格的代碼如下: Private Sub Workbook_SheetActivate(ByVal Sh As Object) On Error Resume Next Range("A1").Select End Sub 當(dāng)打開(kāi)一張圖表時(shí),執(zhí)行Range("A1").Select語(yǔ)句時(shí)將會(huì)出現(xiàn)錯(cuò)誤提示,為了防止錯(cuò)誤提示出現(xiàn),在過(guò)程最前面使用On Error語(yǔ)句。 15.2.7 NewSheet事件 在工作簿中新建工作表時(shí)產(chǎn)生此事件,其事件處理代碼格式如下: Private Sub Workbook_NewSheet(ByVal Sh As Object) 例如,在Excel中新建工作表時(shí)默認(rèn)取名為Sheet后面加上一個(gè)數(shù)字,使用以下代碼可以為新建的工作表生成中文名稱。 Private Sub Workbook_NewSheet(ByVal Sh As Object) n = Worksheets.Count If TypeName(Sh) = "Worksheet" Then Sh.Name = "工作表" & n End If End Sub 程序通過(guò)Worksheets.Count獲取當(dāng)前工作表的數(shù)量,然后判斷新建表的類型。如果是工作表,則對(duì)新建的工作表進(jìn)行命名。 15.2.8 BeforeSave事件 保存工作簿之前產(chǎn)生此事件,其事件處理代碼格式如下: Private Sub Workbook_BeforSave(ByVal SaveAsUi As Boolean,Cancel As Boolean) 事件過(guò)程中有兩個(gè)參數(shù),如果顯示“另存為”對(duì)話框,則參數(shù)SaveAsUi為True。參數(shù)Cancel的值當(dāng)事件產(chǎn)生時(shí)為False,如果該事件過(guò)程將本參數(shù)設(shè)為True,則該過(guò)程執(zhí)行結(jié)束之后不保存工作簿,針對(duì)該事件的兩個(gè)參數(shù),該事件一般可以完成以下功能: ●禁止文件另存,但可對(duì)原文件的修改進(jìn)行保存; ●禁止保存修改,使保存與另存為功能都失效。 例如,以下代碼在保存工作簿之前詢問(wèn)用戶是否保存文件。在保存工作簿之前產(chǎn)生此事件,那么只要在該事件寫入一行代碼就完全可以禁止文件被另存,而且連另存為對(duì)話框也不顯示。 Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean,Cancel As Boolean) If SaveAsUI = True Then Cancel=True '禁止另存為 End Sub Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean,Cancel As Boolean) Cancel = True ’禁止保存修改 End Sub 在禁止保存修改時(shí)應(yīng)配合在BeforeClose事件中寫入代碼才能達(dá)到完美效果。 Private Sub Workbook_BeforeClose(Cancel As Boolean) Me.Saved=True End Sub 15.2.9 BeforePrint事件 當(dāng)進(jìn)行打印或者打印預(yù)覽時(shí),在打印或打印預(yù)覽實(shí)際發(fā)生之前將產(chǎn)生BeforePrint事件。該事件處理代碼格式如下: Private Sub Workbook_BeforePrint(Cancel As Boolean) 當(dāng)事件發(fā)生時(shí)參數(shù)Cancel為False,如果該事件過(guò)程將此參數(shù)設(shè)置為True,則該過(guò)程完成后將不打印工作簿。例如,以下代碼在打印之前對(duì)活動(dòng)工作簿的所有工作表重新計(jì)算。 Private Sub Workbook_BeforePrint(Cancel As Boolean) Dim wk As Worksheet For Each wk in Worksheets wk.Calculate Next End Sub 15.3 工作表事件 在Excel應(yīng)用程序中,要控制用戶在工作表中的操作,就需要為工作表事件編寫代碼。工作表事件是開(kāi)發(fā)Excel應(yīng)用程序時(shí)使用最多的。 15.3.1 工作表事件簡(jiǎn)介 若要查看工作表的事件過(guò)程,可以雙擊“工程資源管理器”窗口中的一個(gè)工作表對(duì)象(例如“Sheet1”),打開(kāi)“代碼編輯器”窗口,在“過(guò)程”下拉列表框內(nèi)選擇事件名稱。Excel2007的工作表事件如表15-2所示。 表15-2 工作表事件及其激發(fā)時(shí)間
工作表事件發(fā)生在工作表被激活、用戶修改,以及更新工作表上的單元格或數(shù)據(jù)透視表時(shí)。例如,以下代碼將在工作表重新計(jì)算后將A列到H列的大小調(diào)整到合適狀態(tài):
Private Sub Worksheet_Calculate()
Columns("A:H").AutoFit
End Sub
注意:在一個(gè)工作簿中,一般都有多張工作表。工作表事件必須編寫在對(duì)應(yīng)的工作表對(duì)象中。操作該工作表時(shí)才會(huì)執(zhí)行對(duì)應(yīng)的事件代碼。例如在“Sheet1”工作表的代碼模塊中編寫的事件代碼不會(huì)在操作“Sheet2”工作表時(shí)執(zhí)行。
15.3.2 Activate事件
激活工作表、圖表工作表或嵌入式圖表時(shí)發(fā)生此事件。例如,以下代碼將在工作表被激活時(shí)對(duì)區(qū)域A1:A20進(jìn)行排序。
Private Sub Worksheet_Activate()
Range("a1:a20").Sort Key1:=Range("a1"),Order:=xlAscending
End Sub
15.3.3 BeroreRightClick事件
在工作表上單擊鼠標(biāo)右鍵時(shí)發(fā)生此事件,此事件先于默認(rèn)的單擊右鍵操作。該事件的代碼格式如下:
Private Sub Worksheet_BeforeRightClick(ByVal Target As Range,Cancel As Boolean)
其中的參數(shù)含義如下:
●Target表示一個(gè)Range對(duì)象,為單擊右鍵發(fā)生時(shí)最靠近鼠標(biāo)指針的單元格.
●Cancel事件發(fā)生時(shí)為False.如果事件過(guò)程將此參數(shù)設(shè)為True,則在完成此過(guò)程后,不執(zhí)行默認(rèn)的單擊右鍵操作.
注意:當(dāng)指針在形狀或命令欄(工具欄或菜單欄)上時(shí),單擊右鍵不觸發(fā)此事件。
BeforeRightClick事件可用于取代默認(rèn)的右鍵快捷菜單操作,或?qū)δJ(rèn)操作進(jìn)行一些小改動(dòng)。例如,以下代碼捕獲了單擊右鍵事件,并在單元格區(qū)域“B1:B10”的快捷菜單中添加了新的菜單項(xiàng)。
Private Sub Worksheet_BeforeRightClick(ByVal Target As Range,Cancel As Boolean)
|
|