第15单 Excel事件
15.1 了解事件
事件是一个对象可以辩认的动作,像单击鼠标或按下某键等,并且可以编写某些代码针对此动作做出响应。用户做动作或程序代码的结果都可能导致事件的发生,事件还可由系统引发。在VBA中,可以激发事件的用户动作包括切换工作表、选择单元格和单击鼠标等几十种。当事件发生时,将执行包含在事件过程中的代码。如果用户没有定义某事件所调用的过程,那么当发生该事件时,就不会产生任何反应。
15.1.1事件分类
Excel提供了非常多的事件,主要可以分为以下几类。
1、工作簿事件
工作簿事件发生在特定的工作簿中,如Open(打开工作簿)、BeforeClose(关闭工作簿之前)和SheetActivate(激活任何一张表)等。工作簿事件的代码必须在ThisWork对象代码模块中编写。
2、工作表事件
工作表事件发生在特定的工作表中,如Activate(激活工作表)、Change(更改工作表中的单元格)和SelectionChange(工作表上的选定区域发生改变)等。工作表带今年年底代码必须在对应工作表的代码模块中编写。
3、窗体、控件事件
新建的用户窗体及窗体上的控件也可响应很多事件,如Click(单击)、Change(控件内容更改)等,这类事件的代码必须编写在相应的用户窗体代码模块中。
4、图表事件
图表事件针对某个特殊的图表产生,例如Select(选中了图表中的某个对象)和SeriesChange(改变了系列中的某个数据点的值)。
5.不与对象关联的事件
这类事件只有两个,分别是OnTime和OnKey,根据时间和按钮来产生两个事件。
15.1.2 编写事件程序
如果要对某个事件进行响应,就必须编写对应的事件处理程序,并将这些程序放置在规定的位置上,并且每个事件处理程序都必须使用系统事先定义好的名称。例如,需要对工作簿的Open事件编写处理代码,其操作步骤如下。
步骤1 在Excel环境下按Alt+F11组合键打开VisualBasic编辑器。
步骤2 在左侧的“工程资源管理器”窗口中列出了当前工程项目中的Excel对象,双击其中的“ThisWorkbook”对象,将在右侧打开代码编辑器。
步骤3 在代码窗口左侧对象下拉列表框中选择对象。
步骤4 选择好对象“Workbook”后,在代码窗口右侧的事件下拉列表框中可看到出该对象的事件列表。
步骤5 选择好对象和事件后,系统自动生成事件过程的外部结构。在事件过程结构中编写响应该事件的代码即可。
15.2 工作簿事件
当工作簿更改、工作簿中的任何工作表更改、加载宏更改或数据透视表更改时,都将引发工作簿事件。合理地使用各个事件可以避免一些意料不到的错误,以及提高代码的可读性,同时也可以提高代码的执行效率。
15.2.1 工作簿事件简介
若要查看工作簿的事件过程,可以双击“工程资源管理器”窗口中的“ThisWorkbook”对象,打开“代码编辑器”窗口,在“过程”下拉列表框内选择事件名称。Excel 2007的工作簿事件如表15-1所示。
表15-1 工作簿事件及其触发时间
表中可以看出,Excel工作簿事件非常多,但有一部分事件几乎很难用到。
工作簿事件代码必须位于“ThisWorkbook”对象的代码模块中,如果放于其他代码模块中,将不会被执行。
15.2.2 Open事件
打开工作簿时,将产生此事件。Workbook_Open事件只在工作簿打开时产生,在下一次打开之前不再发生此事件。此事件中可以写入一些只需执行一次的代码,比如如果需要在每次打开文件时在“Sheet1”工作表的A列记录文件打开的时间,则应该使用此事件,代码如下:
Private Sub Workbook_Open()
Worksheets("Sheet1").Range("A1048576").End(xlUp).Offset(1,0).Value = VBA.Now
End Sub
对系统设置进行修改的代码不应编写在这个事件过程中,而应写入Workbook_Activate事件中,Workbook_Activate事件紧随在Workbook_Open事件后面发生。
注意:Workbook_Open事件代码有可能不被执行,例如在打开工作簿时用户按住“Shift”键可跳过该事件代码。
15.2.3 BeforeClose事件 在关闭工作簿之前,先产生此事件。如果该工作簿已经更改过,则本事件在询问用户是否保存更改之前产生。其事件处理代码格式如下: Private Sub Workbook_BeforeClose(Cancel As Boolean) 当事件产生时,参数Cancel为False。如果该事件将Cancel设为True,则停止对工作簿的关闭操作,工作簿仍处于打开状态。 一般情况下,只应在该事件中加上以下功能,而不应将对系统的设置或者恢复代码放在此处。 1)不显示是否保存修改对话框而保存工作簿的任何更改。 2)放弃保存工作簿的任何更改,直接退出,代码如下: Private Sub Workbook_BeforeClose(Cancel as Boolean) Me.Saved = True End Sub 3)程序中设置标志变量,控制用户直接按窗口上的“关闭”按钮退出系统。只有通过代码设置标志变量为对应值时才允许退出系统,具体代码如下: Private Sub Workbook_BeforeClose(Cancel As Boolean) If bFlag=False then Cancel=True 'bFlag为标志变量 End Sub 15.2.4 Activate事件 激活一个工作簿时将产生该事件。所谓工作簿激活,包括以下两种情况: 1)工作簿打开时,在Open事件之后发生该事件; 2)从另一工作簿切换到本工作簿时,发生该事件。 工作簿的Open事件有可能被用户跳过,所以应该将系统设置之类的初始化代码放在Activate事件中。 下例通过工作簿的Activate事件完成调用自定义菜单、隐藏工具栏等设置,其代码如下: Private Sub Workbook_Activate() Application.ScreenUpdatin = False '关闭屏幕更新 Application.Cursor = xlDefault '设置光标为默认图标 Application.Caption = "学生成绩管理系统" '设置应用程序标题 Application.Caption = "" Application.CommandBars("Toolbar list").Enabled = False '屏蔽右键工具栏 Application.CommandBars("Standard").Visible = False '隐藏标准工具栏 Application.CommandBars("Formatting").Visible = False '隐藏格式工具栏 Application.DisplayFormulaBar = False ’隐藏编辑栏 Application.DisplayStatusBar= True '显示状态栏 ActiveWindow.DisplayWorkbookTabs= False ’隐藏工作表标签 HideBar '调用子过程,隐藏工具栏 MyBar_Menu ’调用子过程,显示自定义菜单 Sheets("主界面").ScrollArea = "A1:M38" '设置主界面的滚动区域 Application.ScreenUpdatin = True '打开屏幕更新 End Sub 15.2.5 Deactivate事件 当工作簿从活动状态转为非活动状态时产生此事件。以下情况将产生该事件: ●工作簿从活动状态转为非活动状态时; ●关闭工作簿时,在Workbook_BeforClose事件之后发生此事件。 一些恢复系统设置之类的代码可放在此事件中。例如对上例中Activate事件所做设置进行清理,恢复Excel初始设置,具体代码如下: Private Sub Workbook_Deactivate() Application.Caption = “Microsoft Excel” '设置应用程序的标题为默认值 MyBarDelete ’删除自定义菜单 ShowBar ’显示各工具栏 Application.CommandBars("Toolbar list").Enabled = True '显示默认工具栏 Me.save ’保存工作簿 End Sub 15.2.6 SheetActivate事件 激活任何一张表时产生此事件。例如,下面的代码将显示被激活工作表的名称: Private Sub Workbook_SheetActivate(ByVal Sh As Object) MsgBox Sh.Name End Sub 如果激活工作簿中的任何一张工作表,那么将活动单元格定位到A1单元格的代码如下: Private Sub Workbook_SheetActivate(ByVal Sh As Object) MsgBox Sh.Name End Sub 如果激活工作簿中的任何一张工作表,那么将活动单元格定位到A1单元格的代码如下: Private Sub Workbook_SheetActivate(ByVal Sh As Object) On Error Resume Next Range("A1").Select End Sub 当打开一张图表时,执行Range("A1").Select语句时将会出现错误提示,为了防止错误提示出现,在过程最前面使用On Error语句。 15.2.7 NewSheet事件 在工作簿中新建工作表时产生此事件,其事件处理代码格式如下: Private Sub Workbook_NewSheet(ByVal Sh As Object) 例如,在Excel中新建工作表时默认取名为Sheet后面加上一个数字,使用以下代码可以为新建的工作表生成中文名称。 Private Sub Workbook_NewSheet(ByVal Sh As Object) n = Worksheets.Count If TypeName(Sh) = "Worksheet" Then Sh.Name = "工作表" & n End If End Sub 程序通过Worksheets.Count获取当前工作表的数量,然后判断新建表的类型。如果是工作表,则对新建的工作表进行命名。 15.2.8 BeforeSave事件 保存工作簿之前产生此事件,其事件处理代码格式如下: Private Sub Workbook_BeforSave(ByVal SaveAsUi As Boolean,Cancel As Boolean) 事件过程中有两个参数,如果显示“另存为”对话框,则参数SaveAsUi为True。参数Cancel的值当事件产生时为False,如果该事件过程将本参数设为True,则该过程执行结束之后不保存工作簿,针对该事件的两个参数,该事件一般可以完成以下功能: ●禁止文件另存,但可对原文件的修改进行保存; ●禁止保存修改,使保存与另存为功能都失效。 例如,以下代码在保存工作簿之前询问用户是否保存文件。在保存工作簿之前产生此事件,那么只要在该事件写入一行代码就完全可以禁止文件被另存,而且连另存为对话框也不显示。 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 在禁止保存修改时应配合在BeforeClose事件中写入代码才能达到完美效果。 Private Sub Workbook_BeforeClose(Cancel As Boolean) Me.Saved=True End Sub 15.2.9 BeforePrint事件 当进行打印或者打印预览时,在打印或打印预览实际发生之前将产生BeforePrint事件。该事件处理代码格式如下: Private Sub Workbook_BeforePrint(Cancel As Boolean) 当事件发生时参数Cancel为False,如果该事件过程将此参数设置为True,则该过程完成后将不打印工作簿。例如,以下代码在打印之前对活动工作簿的所有工作表重新计算。 Private Sub Workbook_BeforePrint(Cancel As Boolean) Dim wk As Worksheet For Each wk in Worksheets wk.Calculate Next End Sub 15.3 工作表事件 在Excel应用程序中,要控制用户在工作表中的操作,就需要为工作表事件编写代码。工作表事件是开发Excel应用程序时使用最多的。 15.3.1 工作表事件简介 若要查看工作表的事件过程,可以双击“工程资源管理器”窗口中的一个工作表对象(例如“Sheet1”),打开“代码编辑器”窗口,在“过程”下拉列表框内选择事件名称。Excel2007的工作表事件如表15-2所示。 表15-2 工作表事件及其激发时间
工作表事件发生在工作表被激活、用户修改,以及更新工作表上的单元格或数据透视表时。例如,以下代码将在工作表重新计算后将A列到H列的大小调整到合适状态:
Private Sub Worksheet_Calculate()
Columns("A:H").AutoFit
End Sub
注意:在一个工作簿中,一般都有多张工作表。工作表事件必须编写在对应的工作表对象中。操作该工作表时才会执行对应的事件代码。例如在“Sheet1”工作表的代码模块中编写的事件代码不会在操作“Sheet2”工作表时执行。
15.3.2 Activate事件
激活工作表、图表工作表或嵌入式图表时发生此事件。例如,以下代码将在工作表被激活时对区域A1:A20进行排序。
Private Sub Worksheet_Activate()
Range("a1:a20").Sort Key1:=Range("a1"),Order:=xlAscending
End Sub
15.3.3 BeroreRightClick事件
在工作表上单击鼠标右键时发生此事件,此事件先于默认的单击右键操作。该事件的代码格式如下:
Private Sub Worksheet_BeforeRightClick(ByVal Target As Range,Cancel As Boolean)
其中的参数含义如下:
●Target表示一个Range对象,为单击右键发生时最靠近鼠标指针的单元格.
●Cancel事件发生时为False.如果事件过程将此参数设为True,则在完成此过程后,不执行默认的单击右键操作.
注意:当指针在形状或命令栏(工具栏或菜单栏)上时,单击右键不触发此事件。
BeforeRightClick事件可用于取代默认的右键快捷菜单操作,或对默认操作进行一些小改动。例如,以下代码捕获了单击右键事件,并在单元格区域“B1:B10”的快捷菜单中添加了新的菜单项。
Private Sub Worksheet_BeforeRightClick(ByVal Target As Range,Cancel As Boolean)
|
|