主要内容:
- Excel事件的类别
- 编写事件处理程序代码
- 启用和禁用事件
- 工作簿、工作表和应用程序级事件
- 如何使用与对象无关的事件
事件是Excel编程的重要组成部分。在第20课中对事件进行过介绍,涉及到用户窗体控件以及他们可以响应的一些事件。理解和使用Excel事件是创建易于使用的响应式应用程序的重要工具。
事件类别
Excel程序可以响应的事件能够通过两种方式进行分类。一种方式是根据接收事件的对象来组织事件,如下所示:
- 应用程序事件
- 工作簿事件
- 工作表事件
- 用户窗体和控件事件
- 非对象事件
非对象事件是一个特殊类别,其中包含不与特定对象关联的事件。
对事件进行分类的另一种方式是通过事件本身,例如发生什么来触发事件。有三类事件:
- 事件始终是用户操作的结果,例如单击用户窗体上的控件或按某个键
- 用户操作或VBA代码可能引起的事件,例如打开工作簿或激活图表
- 与用户操作无关的事件,例如一天中的特定时间的发生
总体而言,Excel提供的各种事件应该几乎满足任何编程需求。
事件处理程序代码
你的程序通过将代码放置在事件处理程序中来响应事件。事件处理程序是一种特殊的VBA过程,当相关事件发生时会自动执行。命名这些过程时必须遵守严格的规则;名称必须采用objectname_eventname的形式。例如,文本框控件具有Click事件,对于名称为txtAddress的文本框,事件处理程序过程必须命名为txtAddress_Click。这是必不可少的,因为过程名称将过程连接到事件。
在大多数情况下,VBA编辑器会为你创建事件过程的框架(第一行和最后一行)。打开代码编辑窗口后,该窗口顶部将显示两个下拉列表(参见图22-1)。左上方的对象列表显示了可以在当前窗口中放置事件处理代码的那些对象,右上方的事件列表列出了第一个列表中所选对象的事件。当选择事件时,编辑器会在窗口中自动输入该过程的框架。你可以手动输入事件过程,但是这样自动输入功能可以节省时间并减少错误。
注意:如果你没有为事件创建事件过程,或者该事件过程不包含任何代码,则Excel将忽略该事件。
应该在工程的什么位置放置事件处理过程呢?如果该过程放置在错误的位置,即使它的名称正确,也不会响应其事件。随后的内容将提供了有关事件放置的一些具体建议,这里是一些准则:
- 用户窗体(及其控件)的事件过程应始终放在用户窗体模块本身中。
- 工作簿、工作表或图表的事件过程应始终放置在与该工作簿关联的工程中。
- 如果可以在编辑窗口顶部的对象和事件列表中找到对象和事件,则将过程放置在当前模块中。
- 切勿在代码模块(这些项目模块在“工程”窗口的“模块”节点下列出)中放置事件过程。
图22-1:在代码编辑窗口输入事件过程
事件顺序
处理事件时,你需要了解某些操作会导致触发Excel中的多个事件。在这些情况下,多个事件以特定顺序发生。在某些情形下,确定用于代码的事件过程时,需要注意这个顺序。下面是一个示例:将在工作簿中添加新工作表时,将按以下顺序触发下列三个应用程序级事件:
- 当添加新的工作表时,将发生WorkbookNewSheet。
- 当停用先前处于活动状态的工作表时,将发生SheetDeactivate。
- 当激活新工作表时,将发生SheetActivate。
当用户单击用户窗体上的控件时,也会出现类似情况:MouseDown、MouseUp和Click事件依次发生。
在事件过程中使用Debug.Print语句,你可以确定发生哪些事件以及它们发生的顺序。
启用和禁用事件
Excel的默认启用所有事件。你可以通过将Application对象的EnableEvents属性设置为False来禁用大多数事件。这样做会禁用除用户窗体和控件外的所有事件。何时需要禁用事件?当事件过程中的代码直接或间接导致再次触发同一事件时。
下面是一个例子。
只要修改工作表中的数据,就会触发Worksheet_Change事件。你可以将此事件用于数据验证,例如验证在特定单元格中输入的值始终在指定范围内。如果数据不在此范围内,代码将显示一条消息并清除单元格,以便用户可以重新输入数据。问题在于清除单元格的行为会再次触发Worksheet_Change事件,从而导致Worksheet_Change事件永无止境的循环。为避免此问题,更改事件过程中的代码,以便该代码执行以下操作:
1.设置EnableEvents属性为False。
2.清除工作表单元格中的内容。
3.设置EnableEvents属性为True。
注意:因为EnableEvents属性是Application对象的属性,所以它适用于所有打开的工作簿。你不能有选择地禁用某个工作簿的事件。
下面将分别讲解Workbook事件、Worksheet事件、Application事件、以及OnTime事件和OnKey事件。
......
注:本文是在知识星球App的完美Excel社群中发表的Excel VBA编程系列文章《Excel编程周末速成班第22课:使用事件》中的一部分内容。