1.让Excel自动响应你的行为
Excel VBA有一系列预定义的事件,Workbook_Open()就是其中之一,把以下代码写入到ThisWorkbook模块,每次打开Excel文件都会弹出消息框
写入到Sheet模块无效,因为Workbook_Open()是一个工作簿级别的事件过程,Sheet1只能响应工作表级别的事件,工作表模块不能包含Workbook_开头的过程名
Private Sub Workbook_Open()
MsgBox "欢迎使用本工作簿!"
End Sub
如果想在每次点开某个工作表都弹出提示,可以在对应的工作表模块中写入以下代码:
Private Sub Worksheet_Activate()
MsgBox "欢迎来到Sheet1!"
End Sub
其他常见的预定义事件还有:
Workbook_BeforeClose():工作簿关闭前触发
Worksheet_Change():工作表内容改变时触发
Worksheet_SelectionChange():选择单元格改变时触发
事件,VBA里的自动开关
事件时Excel中发生的特定动作或情况,它们可以触发我们预现编写的代码
事件包括但不限于:
工作簿事件:如打开工作簿(Open)、保存工作簿(BeforeSave)、关闭工作簿(BeforeClose)等。
工作表事件:如激活工作表(Activate)、更改单元格(Change)、选择单元格(SelectionChange)等。
应用程序事件:如新建工作簿(NewWorkbook)、工作簿计算完成(WorkbookCalculate)等。
事件的作用:
自动化:用户无需手动触发,代码可以在特定情况下自动执行
交互性:可以根据用户的操作做出及时响应
数据验证:可以在数据输入或更改时进行检查和炎症
事件过程
当某个事件发生后自动运行的过程称为事件过程,事件过程也是Sub过程。
事件过程必须写在特定对象所在的模块中,而且只有过程所在的模块里的对象才能触发这个事件(每种事件都与特定的对象(如工作簿、工作表)相关联,因此必须放在正确的模块中)
编写事件过程
事件过程的过程名由Excel自动设置,以【对象名称_事件名称】的形式存在,不能更改。
想编写关于哪个对象的事件过程,就在【工程资源管理器】中双击该对象所在的模块【代码窗口】
如果想写这样一个程序,当激活Sheet1时,自动完成某些操作或计算,就双击进入Sheet1模块,在代码窗口上方,左边的下拉菜单栏选择Sheet1,右边的下拉菜单选择Active事件,希望程序完成什么操作或计算,就把响应的代码写在Sub与End Sub之间,之后每次切换大该工作表,都会执行设置的代码。
2.Worksheet事件
Worksheet事件是发生在Worksheet对象里的事件,Worksheet事件过程必须写在相应的Worksheet对象里,只有过程所在的Worksheet对象里的操作才能触发该时间。
常用的Worksheet事件
Worksheet_Change 工作表中的单元格内容发生变化
Worksheet_Change告诉Excel,当过程所在的工作表的单元格发生更改时自动运行程序过程,程序必须写在相应的工作表对象里
用途:数据验证、动态更新、记录修改等
变量Target是程序运行的参数,代表工作表中被更改的但愿那个
' 用途:数据验证 - 确保第一列只输入数字
' 这个事件可以用于实时数据验证,防止用户输入错误的数据类型
Private Sub Worksheet_Change(ByVal Target As Range)
' 检查是否更改的是第一列的单元格
If Target.Column = 1 Then
' 检查输入的值是否为数字
If Not IsNumeric(Target.Value) Then
' 如果不是数字,显示警告消息
MsgBox "请输入数字!"
' 清空单元格内容
Target.Value = ""
End If
End If
End Sub
Worksheet_SelectionChange 用户改变选定的单元格或区域
当工作表选中的单元格或区域发生改变时触发
' 用途:动态信息显示 - 实时显示用户当前选中的单元格
' 这个事件可以用于创建交互式工作表,帮助用户追踪他们在工作表中的位置
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
' 在A1单元格显示当前选中的单元格地址
Me.Range("A1").Value = "当前选中: " & Target.Address
' 注:Me 表示当前工作表,可以省略
End Sub
Worksheet_Activate 工作表被激活(切换到该工作表)
用途:欢迎信息、初始化设置、更新数据等
' 用途:初始化和欢迎信息 - 当用户进入工作表时执行必要的设置和更新
' 这个事件可以用于显示欢迎信息,更新数据,或执行其他必要的初始化操作
Private Sub Worksheet_Activate()
' 显示欢迎消息,包含当前工作表的名称
MsgBox "欢迎来到" & ActiveSheet.Name & "工作表!"
End Sub
Worksheet_Deactivate 当用户离开工作表
当活动工作表转为非活动工作表(用户离开该工作表)时触发
用途:保存更改、清理临时数据、显示提醒等
' 用途:保存提醒 - 在用户离开工作表时提醒保存更改
' 这个事件可以用于防止用户无意中丢失重要的更改
Private Sub Worksheet_Deactivate()
' 检查A1单元格是否有内容
If Range("A1").Value <> "" Then
' 如果A1不为空,提醒用户保存更改
MsgBox "请记得保存您的更改!"
End If
End Sub
Worksheet_Calculate 当工作表完成计算
用途:在复杂计算后更新图表、触发其他操作等
Private Sub Worksheet_Calculate()
Application.StatusBar = "计算完成于 " & Now
End Sub
Worksheet_BeforeDoubleClick 在用户双击工作表的单元格之前
用途:自定义双击行为、阻止默认的双击编辑等
' 用途:自定义双击行为 - 为特定区域的双击操作定义特殊行为
' 这个事件可以用于创建自定义的交互功能,如显示额外信息或触发特定操作
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
' 检查双击的是否是第一列的单元格
If Target.Column = 1 Then
' 显示被双击的单元格地址
MsgBox "你双击了第一列的单元格:" & Target.Address
' 设置 Cancel 为 True 以阻止默认的双击编辑行为
Cancel = True
End If
End Sub
Worksheet_BeforeRightClick 在用户右键单击工作表的单元格之前
用途:自定义右键菜单、阻止默认的右键菜单等
Private Sub Worksheet_BeforeRightClick(ByVal Target As Range, Cancel As Boolean)
If Target.Row = 1 Then
MsgBox "请不要对标题行使用右键菜单"
Cancel = True ' 阻止默认的右键菜单
End If
End Sub
Worksheet事件列表
Worksheet对象一共有9个事件可使用:
事件名称 | 触发条件 | 常见用途 |
Activate | 工作表被激活时 | 初始化设置,显示欢迎信息,更新数据 |
BeforeDoubleClick | 用户双击单元格之前 | 自定义双击行为,显示额外信息,触发特定操作 |
BeforeRightClick | 用户右键单击单元格之前 | 自定义右键菜单,保护特定区域 |
Calculate | 工作表完成计算时 | 更新依赖于计算结果的内容,通知用户计算完成 |
Change | 工作表中的单元格内容发生变化时 | 数据验证,动态更新,记录修改 |
Deactivate | 用户离开该工作表时 | 保存更改,清理临时数据,显示提醒 |
FollowHyperlink | 用户点击工作表中的超链接时 | 记录链接点击,执行自定义操作 |
PivotTableUpdate | 数据透视表更新完成后 | 格式化数据透视表,更新相关图表 |
SelectionChange | 用户改变选定的单元格或区域时 | 动态显示信息,更新状态栏,控制其他单元格的显示 |
3.Workbook事件
Workbook事件是发生在Workbook对象里的事件,必须在ThisWorkbook模块中定义,使用【Workbook_】前缀命名。
Workbook_Open 工作簿被打开
用途:初始化设置、显示欢迎信息、加载数据等
' 用途:在工作簿打开时执行初始化操作
Private Sub Workbook_Open()
' 显示欢迎信息
MsgBox "欢迎使用本工作簿!"
' 初始化设置,例如设置特定单元格的值
ThisWorkbook.Sheets("Sheet1").Range("A1").Value = "上次打开时间:" & Now()
' 调用自定义函数加载数据
Call LoadData
End Sub
Workbook_BeforeClose 工作簿即将关闭时
用途:保存更改、清理临时文件、显示提醒等
' 用途:在工作簿关闭前执行清理操作
Private Sub Workbook_BeforeClose(Cancel As Boolean)
' 询问用户是否确定要关闭
Dim response As Integer
response = MsgBox("确定要关闭工作簿吗?", vbYesNo + vbQuestion, "确认关闭")
If response = vbNo Then
Cancel = True ' 取消关闭操作
Else
' 执行清理操作
Call CleanupTempFiles
ThisWorkbook.Save ' 保存工作簿
End If
End Sub
Workbook_SheetActivate 工作簿中的任何工作表被激活
用途:更新UI,执行特定于该工作表的操作等
' 用途:响应工作表激活事件
Private Sub Workbook_SheetActivate(ByVal Sh As Object)
' 更新状态栏显示当前激活的工作表名称
Application.StatusBar = "当前工作表: " & Sh.Name
' 如果激活的是特定工作表,执行额外操作
If Sh.Name = "数据表" Then
Call RefreshData
End If
End Sub
Workbook_SheetChange 工作簿中任何工作表的内容发生变化时
用途:跟踪更改,更新相关数据等
‘ 用途:响应工作表内容变化
' ====================================================================================================
' 模块名称:ThisWorkbook
'
' 功能描述:
' 这个模块包含了工作簿级别的事件处理程序,主要用于跟踪和记录工作表的变更。
' 主要功能包括:
' 1. 监听工作表内容的变化
' 2. 将变更信息记录到专门的日志工作表中
' 3. 防止事件循环和重复触发
' 4. 提供调试信息输出
' 5. 包含一个手动测试过程以验证功能
'
' 注意事项:
' - 本代码应放在ThisWorkbook模块中
' - 需要注意事件循环和性能问题
' - 使用Debug.Print输出有助于排查问题
' ====================================================================================================
Option Explicit ' 强制声明所有变量
' 用于防止事件循环的标志
Private isRunning As Boolean
' 用途:响应工作表内容变化
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
' 防止事件循环
If isRunning Then Exit Sub ' 如果已经在运行,则退出
isRunning = True ' 设置运行标志
On Error GoTo ErrorHandler ' 设置错误处理
' 暂时禁用事件,防止在处理过程中触发其他事件
Application.EnableEvents = False
' 输出调试信息:事件触发时间
Debug.Print "Workbook_SheetChange triggered: " & Now()
' 输出调试信息:变更的工作表和单元格范围
Debug.Print "Sheet: " & Sh.Name & ", Range: " & Target.Address
' 声明日志工作表对象
Dim logSheet As Worksheet
On Error Resume Next ' 临时忽略错误
Set logSheet = ThisWorkbook.Sheets("变更日志") ' 尝试获取日志工作表
On Error GoTo ErrorHandler ' 恢复错误处理
' 如果日志工作表不存在,则创建一个新的
If logSheet Is Nothing Then
Set logSheet = ThisWorkbook.Sheets.Add ' 添加新工作表
logSheet.Name = "变更日志" ' 设置工作表名称
' 添加表头
logSheet.Range("A1:C1").Value = Array("时间", "工作表", "单元格地址")
End If
' 记录日志
With logSheet
Dim nextRow As Long
' 找到下一个空行
nextRow = .Cells(.Rows.Count, 1).End(xlUp).Row + 1
' 记录时间
.Cells(nextRow, 1).Value = Now()
' 记录工作表名称
.Cells(nextRow, 2).Value = Sh.Name
' 记录变更的单元格地址
.Cells(nextRow, 3).Value = Target.Address
End With
' 输出调试信息:确认日志已添加
Debug.Print "Log entry added successfully"
CleanExit:
' 重新启用事件
Application.EnableEvents = True
' 重置运行标志
isRunning = False
Exit Sub
ErrorHandler:
' 输出错误信息
Debug.Print "Error in Workbook_SheetChange: " & Err.Description
Resume CleanExit ' 跳转到清理代码
End Sub
' 手动触发测试过程
Public Sub TestSheetChange()
' 修改第一个工作表的A1单元格,触发SheetChange事件
ThisWorkbook.Sheets(1).Range("A1").Value = "测试 " & Now()
' 显示测试完成消息
MsgBox "测试完成。请检查'变更日志'工作表和即时窗口。", vbInformation
End Sub
Workbook_NewSheet 当新工作表被添加到工作簿
用途:初始化新工作表、应用标准格式等
' 用途:为新添加的工作表应用标准格式
Private Sub Workbook_NewSheet(ByVal Sh As Object)
' 设置标准标题
Sh.Range("A1:D1").Value = Array("日期", "描述", "金额", "类别")
Sh.Range("A1:D1").Font.Bold = True
' 应用标准格式
Sh.Columns("A:D").AutoFit
Sh.Range("C:C").NumberFormat = "$#,##0.00"
End Sub
Workbook事件列表
事件名称 | 触发条件 | 常见用途 |
Activate | 工作簿被激活时 | 更新界面,刷新数据 |
AddinInstall | 工作簿作为加载项安装时 | 初始化加载项设置 |
AddinUninstall | 工作簿作为加载项卸载时 | 清理加载项相关数据 |
AfterSave | 工作簿保存后 | 记录日志,同步数据 |
AfterXmlExport | XML数据导出后 | 处理导出后的操作 |
AfterXmlImport | XML数据导入后 | 处理导入的数据 |
BeforeClose | 工作簿关闭前 | 保存设置,清理资源 |
BeforePrint | 打印前 | 设置打印区域,调整格式 |
BeforeSave | 工作簿保存前 | 执行数据验证,更新计算 |
BeforeXmlExport | XML数据导出前 | 准备要导出的数据 |
BeforeXmlImport | XML数据导入前 | 准备导入操作 |
Deactivate | 工作簿取消激活时 | 保存临时状态 |
NewChart | 新建图表时 | 设置图表属性 |
NewSheet | 新建工作表时 | 设置新表格式,添加默认内容 |
Open | 工作簿被打开时 | 初始化设置,加载数据 |
PivotTableCloseConnection | 数据透视表关闭连接时 | 清理资源 |
PivotTableOpenConnection | 数据透视表打开连接时 | 刷新数据 |
RowsetComplete | 查询完成时 | 处理查询结果 |
SheetActivate | 工作表被激活时 | 更新界面,刷新数据 |
SheetBeforeDoubleClick | 工作表单元格被双击前 | 自定义双击行为 |
SheetBeforeRightClick | 工作表单元格被右击前 | 自定义右键菜单 |
SheetCalculate | 工作表重新计算时 | 执行自定义计算 |
SheetChange | 工作表内容改变时 | 记录变更,触发计算 |
SheetDeactivate | 工作表取消激活时 | 保存临时数据 |
SheetFollowHyperlink | 单击超链接时 | 记录访问历史 |
SheetPivotTableAfterValueChange | 数据透视表值更改后 | 更新相关数据 |
SheetPivotTableBeforeAllocateChanges | 数据透视表分配更改前 | 准备数据更新 |
SheetPivotTableBeforeCommitChanges | 数据透视表提交更改前 | 验证更改 |
SheetPivotTableBeforeDiscardChanges | 数据透视表放弃更改前 | 确认操作 |
SheetPivotTableChangeSync | 数据透视表同步更改时 | 同步相关数据 |
SheetPivotTableUpdate | 数据透视表更新时 | 刷新关联图表或数据 |
SheetSelectionChange | 选中单元格改变时 | 动态显示信息 |
Sync | 工作簿同步时 | 处理同步相关操作 |
WindowActivate | 工作簿窗口激活时 | 更新状态栏 |
WindowDeactivate | 工作簿窗口取消激活时 | 暂停实时更新 |
WindowResize | 工作簿窗口大小改变时 | 调整界面布局 |
4.别样的自动化
MouseMove事件
在【开发工具-插入】中,拖入ActiveX类的按钮,右键该按钮,可以设置该按钮的属性,包括名称(重要)、字体、大小、背景图等
将该按钮的名称改为【cmd】,右键该按钮选择“查看代码”,在代码窗口中为该按钮添加MouseMove事件,完成后,退出设计模式即可运行代码
' MouseMove 事件处理程序
' 当鼠标在控件上移动时触发
Private Sub cmd_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal x As Single, ByVal y As Single)
Dim l As Integer, t As Integer ' 声明变量用于存储随机生成的位置偏移量
' 生成随机数来计算新的左侧位置
' Rnd() 生成 0 到 1 之间的随机小数
' 公式解释:(0~1 * 10 + 125) * (0~1 * 3 + 1) - 2 生成一个 123 到 405 之间的随机数
l = Int(Rnd() * 10 + 125) * (Int(Rnd() * 3 + 1) - 2)
' 生成随机数来计算新的顶部位置
' 公式解释:(0~1 * 10 + 30) * (0~1 * 3 + 1) - 2 生成一个 28 到 120 之间的随机数
t = Int(Rnd() * 10 + 30) * (Int(Rnd() * 3 + 1) - 2)
' 更新控件的垂直位置(Top属性)
cmd.Top = cmd.Top + t
' 更新控件的水平位置(Left属性)
cmd.Left = cmd.Left + l
End Sub
不是事件的事件
除了对象的事件,Application对象还有两种方法,可以像事件一样让程序自动运行
Application对象的OnKey方法
OnKey方法告诉Excel,当在键盘上按下指定键或组合键时自动运行程序
语法:Application.OnKey(Key, [Procedure])
key是一个字符串,表示要补货的按键或按键组合
Procedure是个可选参数,也是一个字符串,表示要执行的宏名称,如果省略,则取消之前设置的按键关联
按F5运行便可以启用代码,代码需要放入某个模块中
Sub SetupHotkey()
Application.OnKey "^q", "QuickSave" ' Ctrl+Q 触发 QuickSave 宏
End Sub
Sub QuickSave()
ActiveWorkbook.Save
MsgBox "文件已保存!", vbInformation
End Sub
禁用某个按键
Sub DisableF1()
Application.OnKey "{F1}", "" ' 禁用 F1 键
End Sub
恢复某个按键:
Sub RestoreF1()
Application.OnKey "{F1}" ' 恢复 F1 键的默认功能
End Sub
使用多个按键组合
Sub SetupMultipleHotkeys()
Application.OnKey "^+s", "SpecialSave" ' Ctrl+Shift+S
Application.OnKey "%{F2}", "CustomRename" ' Alt+F2
End Sub
按键符号:
控制键:
^ 表示 Ctrl 键
替代键:
% 表示 Alt 键
Shift 键:
表示 Shift 键
特殊键(用花括号包围):
{F1} 到 {F15} 表示功能键
{ENTER} 表示回车键
{ESC} 表示 Esc 键
{HOME} 表示 Home 键
{END} 表示 End 键
{LEFT} 表示左箭头键
{RIGHT} 表示右箭头键
{UP} 表示上箭头键
{DOWN} 表示下箭头键
{PGUP} 表示 Page Up 键
{PGDN} 表示 Page Down 键
{TAB} 表示 Tab 键
{BACKSPACE} 或 {BS} 表示退格键
{DELETE} 或 {DEL} 表示删除键
{INSERT} 或 {INS} 表示插入键
{CAPSLOCK} 表示大写锁定键
{NUMLOCK} 表示数字锁定键
{SCROLLLOCK} 表示滚动锁定键
{BREAK} 表示 Break 键
{PRINTSCREEN} 表示 Print Screen 键
组合键示例:
^c 表示 Ctrl+C
%F 表示 Alt+F
+{F1} 表示 Shift+F1
^%{F5} 表示 Ctrl+Alt+F5
Application的OnTime方法
OnTime方法告诉Excel,当到指定的事件时自动运行程序(可以是指定的某个事件,也可以是指定的一段时间之后)
语法:
Application.OnTime EarliestTime, Procedure, [LatestTime], [Schedule]
EarliestTime:指定过程运行的时间(日期和时间)
Procedure:要运行的过程名称(字符串)
LasteTime(可选):如果错过了EarliestTime,过程最晚应该运行的时间
Schedule(可选):布尔值,如果为False,则取消先前安排的过程
Sub ScheduleReport()
Application.OnTime TimeValue("7:37:00"), "GenerateDailyReport"
End Sub
Sub GenerateDailyReport()
' 生成报告的代码
MsgBox "日报已生成!", vbInformation
End Sub
1 thought on “4.Excel事件”