Excel-事件(Workbook、Worksheet、Range、OnKey/OnTime)


  

一、Excel事件介绍

 Excel事件就是一个能被对象识别的操作。

当某个事件发生后自动运行的过程称为事件过程。事件过程也是Sub过程。

实践过程必须写在特定对象所在的模块中,而且只有过程所在的模块里的对象才能触发这个事件。

事件过程名由Excel自动设置,以“对象名称_事件名称”的形式存在,不能更改。 

二、Worksheet事件

Worksheet事件是发生在Worksheet对象里的事件。事件过程必须写在对应的Worksheet对象里,只有过程所在的Worksheet对象里的操作才能触发该事件。

1、Worksheet_Change事件:自动提示更改的内容 

Private Sub Worksheet_Change(ByVal Target As Range)    '入参中Target代表被选中的单元格
    Application.EnableEvents = False '禁用事件
    If Target.Column = 1 Then
        MsgBox Target.Address & "单元格的值被修改为:" & Target.Value
    End If
    Application.EnableEvents = True '启用事件
End Sub

2、Worksheet_SelectionChange事件:你选中了谁

 可以用此事件来记录Excel单元格修改前的旧值。

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    Dim oldvalue As String
    MsgBox "当前选中的单元格区域为:" & Target.Address
    oldvalue = Target.Value
    
    If Target.Column <> 1 Then
        Cells(Target.Row, "A").Select
    End If
End Sub

3、Worksheet_Activate事件:自动提示工作表名 

Private Sub Worksheet_Activate()
    MsgBox "当前活动工作表为:" & ActiveSheet.Name
End Sub

4、Worksheet_Deactivate事件:禁止选中其他工作表 

Private Sub Worksheet_Deactivate()
    MsgBox "不允许选中" & ActiveSheet.Name & "工作表外的其他工作表"
    Worksheets("Sheet1").Select
End Sub

5、Worksheet事件列表

Worksheet对象一共有9个事件可供使用。 

 

三、Workbook事件

 Workbook事件是发生在Workbook对象里的事件,进入VBE后可以看到ThisWorkbook模块。这个模块专门用来保存Workbook对象的事件过程,Workbook对象的事件过程只有保存在这个模板里才能被Excel识别

1、OPen事件

 Workbook_Open事件告诉Excel,当打开工作簿时自动运行程序。

Private Sub Workbook_Open()
    Worksheets(1).Select
End Sub 

2、BeforeClose事件 

每次关闭工作簿都会自动运行程序

Private Sub Workbook_BeforeClose(Cancel As Boolean)
    '判断用户单击对话框中的哪个按钮,如果按下的是【否】,则修改参数的值为True
    If MsgBox("你确定要关闭工作簿吗?", vbYesNo) = vbNo Then
        '变量Cancel是程序参数,如果为True,则取消关闭工作簿
        Cancel = True '取消关闭
    End If
End Sub 

3、Workbook_SheetChange事件

 当工作簿里任意一个单元格被更改时,自动运行程序。

Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
    '这里入参Sh代表发生更改的单元格所在的工作表,Target表示被更改的单元格
    MsgBox "当前更改的工作表为:" & Sh.Name & Chr(13) & _
            "发生更改的单元格地址为:" & Target.Address
End Sub 

4、Workbook事件列表

  

四、其他事件

1、MouseMove事件

   当鼠标指针移动到按钮上时,按钮迅速闪开。鼠标和按钮就像老鹰捉小鸡游戏,这样的效果可以用MouseMove实现。

  添加一个按钮:通过“视图”——“工具栏”——“控件工具箱”添加,或者通过“开发人员选项”——“插入”——“ActiveX控件”——“命令按钮”

  右键按钮查看代码(修改按钮上文字通过Caption属性修改),编辑按钮和完成事件逻辑

'MouseMove事件告诉Excel,当鼠标指针在cmd按钮上移动是自动运行程序
Private Sub CommandButton1_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
    Dim l As Integer, t As Integer
    l = Int(Rnd() * 10 + 125) * (Int(Rnd() * 3 + 1) - 2) '生成随机数
    t = Int(Rnd() * 10 + 30) * (Int(Rnd() * 3 + 1) - 2)
    CommandButton1.Top = CommandButton1.Top + t '重新设置改按钮的top属性值
    CommandButton1.Left = CommandButton1.Left + l '重新设置改按钮的left属性值
End Sub

如果按钮跑远了,可以通过另外按钮Click事件设置参数

Private Sub CommandButton2_Click()
    CommandButton1.Top = 15
    CommandButton1.Left = 160
End Sub

2、不是事件的事件-Application对象的OnKey方法

除了对象的事件,Application对象还有两种方法,可以像事件一样让程序自动运行,分别是OnKey和OnTime 

OnKey方法告诉Excel,当在键盘上按下指定键或组合键时自动运行程序。

运行ok过程,返回工作表按下Shift+e组合键即可自动运行Test

Sub ok()
    Application.OnKey "+e", "test" '当按下Shift+e组合键时,运行参test过程
End Sub
Sub Test()
    MsgBox "你好,我在学习OnKey方法"
End Sub

3、不是事件的事件-Application对象的OnTime方法

 OnTime方法告诉Excel,当到指定的时间时自动运行程序(可以是指定的某个时间,也可以是指定的某个时间之后)

Sub ot()
    '一个小时后,自动运行Test过程
    Application.OnTime Now() + TimeValue("01:00:00"), "test"
End Sub

Sub Test()
    MsgBox "你好,你已经连续工作一个小时了,请注意休息!"
End Sub

  无论是OnKey还是OnTime想要让指定程序自动运行,都必须先运行该方法所在的程序,如果不运行ok或ot过程,指定的Test都不会自动运行。

  如果想省去手动执行ok和ot的步骤,可以在ThisWorkbook增加如下事件过程:  

Private Sub Workbook_Open()
    Call ok '运行ok过程
    Call ot '运行ot过程
End Sub

五、事件实例

1、一举多得,快速录入数据

逻辑说明:
1、通过工作表的Change事件触发
2、如果C3:C65536为空,或者修改单元格数量大于1,则退出事件
3、读取“I”列数据,从第3行开始循环,读取非空数值
4、如果输入的值等于I列里的值,则进入处理逻辑
5、禁止事件,防止将字母更改为商品名称时,再次执行程序
6、目标单元格写入“产品名称”
7、目标单元格向左移动一格,写入“销售日期”
8、目标单元格向右移动一格,写入“商品代码”
9、目标单元格向右移动二格,写入“商品单价”
10、目标单元格向右移动三个,获取焦点(选中),等待输入“销售数量”
11、重启事件并退出事件
12、循环递增

Private Sub Worksheet_Change(ByVal Target As Range)
    '如果更改的单元格不是C列第3行以下的单元格或更改的单元格个数大于1时退出程序
    If Application.Intersect(Target, Range("C3:C65536")) Is Nothing Or Target.Count > 1 Then
        Exit Sub
    End If
    Dim i As Integer
    i = 3 '参照表中第1条记录在第3行,所以初始值设置为3
    Do While Cells(i, "I").Value <> ""
        If UCase(Target.Value) = Cells(i, "I").Value Then
            Application.EnableEvents = False '禁用事件,防止将字母改为商品名称时,再次执行程序
            Target.Value = Cells(i, "i").Offset(0, 1).Value '写入产品名称
            Target.Offset(0, -1).Value = Date '设置销售日期
            Target.Offset(0, 1) = Cells(i, "I").Offset(0, 2).Value '写入商品代码
            Target.Offset(0, 2) = Cells(i, "I").Offset(0, 3).Value '写入商品单价
            Target.Offset(0, 3).Select '选中销售数量列,等待输入销售数量
            Application.EnableEvents = True '重新启用事件
            Exit Sub
        End If
        i = i + 1
    Loop
End Sub

功能:在C列录入内容对应I列内容时,自动匹配其相关信息,更新销售日期,并把光标选中F列,等待输入销售数量。

2、我该监考哪一场

逻辑说明:
1、使用SelectionChange事件。
2、清除B3:Q22区域内所有单元格底纹颜色。
3、如果同时选中多个单元格,将选中区域内的第一个单元格赋值给Targer。
4、当选中的单元格不在区域B3:Q22时,退出事件。
5、遍历区域B3:Q22如果有值等于选中的单元格值,则突出显示。

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    Range("B3:Q22").Interior.ColorIndex = xlNone '清除单元格里原有底纹颜色
    '当选中的单元格个数大于1时,重新给Target赋值
    If Target.Count > 1 Then
        Set Target = Target.Cells(1)
    End If
    '当选中的单元格不包含指定区域的单元格时,退出程序
    'Intersect方法返回参数指定的多个单元格的公共区域。参数至少是两个Range对象
    If Application.Intersect(Target, Range("B3:Q22")) Is Nothing Then
        Exit Sub
    End If
    Dim rng As Range
    For Each rng In Range("B3:Q22")
        If rng.Value = Target.Value Then
            rng.Interior.ColorIndex = 39
        End If
    Next
End Sub

功能:光标选中单元格时,区域内跟单元格值一样的都会突出显示。

  

逻辑说明:
1、使用SelectionChange事件。
2、清除B3:Q22区域内所有单元格底纹颜色。
3、如果同时选中多个单元格,将选中区域内的第一个单元格赋值给Targer。
4、当选中的单元格不在区域B3:Q22时,退出事件。
5、突出(底纹)标志选中的单元格的行和列

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    Range("B3:Q22").Interior.ColorIndex = xlNone '清除单元格里原有底纹颜色
    '当选中的单元格个数大于1时,重新给Target赋值
    If Target.Count > 1 Then
        Set Target = Target.Cells(1)
    End If
    '当选中的单元格不包含指定区域的单元格时,退出程序
    'Intersect方法返回参数指定的多个单元格的公共区域。参数至少是两个Range对象
    If Application.Intersect(Target, Range("B3:Q22")) Is Nothing Then
        Exit Sub
    End If
'    Dim rng As Range
'    For Each rng In Range("B3:Q22")
'        If rng.Value = Target.Value Then
'            rng.Interior.ColorIndex = 39
'        End If
'    Next
    '添加底纹颜色
    Range(Cells(Target.Row, "B"), Cells(Target.Row, "Q")).Interior.ColorIndex = 39
    Range(Cells(3, Target.Column), Cells(22, Target.Column)).Interior.ColorIndex = 39
End Sub

功能:

选中单元格时,会自动表示对应的行和列。

3、让文件每个一分钟自动保存一次

新增模块并写入如下程序 

Sub otime()
    '一分钟后自动运行WbSave过程
    Application.OnTime Now() + TimeValue("00:01:00"), "WbSave"
End Sub
Sub WbSave()
    ThisWorkbook.Save '保存本工作簿
    Call otime  '再次运行otime过程
End Sub

为了在打开工作簿时就运行如上程序,需要增加Workbook事件(在ThisWorkbook中)

Private Sub Workbook_Open()
    Call otime '打开工作簿后自动运行otime过程
End Sub

 

六、Interior.ColorIndex说明

使用.Range("").Interior.ColorIndex的方法获取对应单元格的ColorIndex值,参照下表。

'用代码就可以获取颜色列表了
Sub 颜色代码()
    For i = 1 To 56
    Cells(i, 1) = i
    Cells(i, 1).Interior.ColorIndex = i
    Next
End Sub

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM