最近更新:'2019-04-24'
- 工作簿事件介绍
- 工作表事件介绍
3.worksheet_SelectionChange
4.worksheet_change(Target)
1. 工作簿事件介绍
1.1常用事件简单了解
双击打开工作簿,就显示今天是谁的生日.那需要怎么样可以到达这个目的呢?

达到这个目的,需要用到事件处理,什么叫事件处理呢?

首先要搞清楚,程序代码应该写在什么地方?事件处理要写在发生地.

那么案例1是打开工作簿发生的事件.因此在工作簿写代码.


那么VBA怎么知道关联在哪件事件上?

需要知道子程序名称与工作簿事件相对应.


事件编程的总结

完整的代码如下:
Private Sub Workbook_Open()
Dim today As Date, d As Date, i As Long
today = Date
i = 6
Do While Trim(Cells(i, 2)) <> ""
d = Cells(i, 6)
If Month(d) = Month(today) And Day(d) = Day(today) Then
MsgBox "½ñÌìÊÇ" & Cells(i, 3) & Cells(i, 5) & "µÄÉúÈÕ"
End If
i = i + 1
Loop
End Sub

那么多事件编程,不需要记忆,直接在编程窗口有对应的事件,如下方法:

1.2workbook_beforeclose
在窗口关闭之前,先运行这段程序,这段程序有什么用法呢? 如下:
Private Sub Workbook_BeforeClose(Cancel As Boolean)
MsgBox "再加,别忘记备份数据!"
End Sub

代码显示的结果如下:

Cancel这个参数的作用是否取消关闭这个动作.如果是true,则取消关闭这个懂这个动作,换句话说就是禁止关闭.

把程序稍微修改一下,禁止关闭.
Private Sub Workbook_BeforeClose(Cancel As Boolean)
MsgBox "再见,别忘记备份数据!"
Cancel = True
End Sub
代码显示的最终结果如下:



1.3workbook_newsheet
即新增一个工作表的时候自动运行的事件.
里面有个参数sh代表刚刚新建的工作表对象.


2. 工作表事件介绍
2.1Worksheet_SelectionChange
这个是vba最常用的工作表事件

Worksheet_SelectionChange是做什么的呢?

Worksheet_SelectionChange有个参数叫做Target.

运用方法如下:
案例1
用鼠标或键盘选中单元格,则会显示单元格的地址.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
MsgBox Target.Address
End Sub
代码显示的结果如下:

案例2
用鼠标或键盘选中单元格,则会显示单元格的背景色是红色.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Target.Interior.Color = vbRed
End Sub

代码显示的结果如下:

案例3
只是被选中单元格高亮
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Cells.Interior.Color = xlNone
Target.Interior.Color = vbRed
End Sub

代码显示的最终结果如下:


案例4
选中的单元格行与列均有背景色
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Cells.Interior.Color = xlNone
Target.EntireRow.Interior.Color = vbRed
Target.EntireColumn.Interior.Color = vbRed
End Sub

代码显示的最终结果如下:

案例5
如何在相关的工作表的事件互相调用
首先,在工作表对应的代码只能运行当前的工作表.比如sheet1的事件代码只能运行sheet1,不能运行在sheet2.如想运行在sheet2,必须编写相关的代码.

如想调用其他工作表的代码,更简洁,需要运用模块的格式进行调用.
模块1的代码
Sub highlight(r As Range)
Cells.Interior.Color = xlNone
r.EntireRow.Interior.Color = vbRed
r.EntireColumn.Interior.Color = vbRed
End Sub

sheet2的代码如下:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Call 模块1.highlight(Target)
End Sub

可以同时在sheet3...sheetn的代码的调用,调用显示的结果如下:


变量和过程(函数)的作用域

如果将之前的案例5的模块1改成private,在调用的过程中就会报错


3.worksheet_SelectionChange
案例1
如果在E或者G列选中某个亲友,会直接显示B列(姓名)这一列相同内容的单元格.比如选择E列(亲友1)的郭靖,会在B列显示有郭靖的单元格.


注意:
如果用户选中多个单元格.一样可以引发worksheet_SelectionChange,而此时的worksheet_SelectionChange中的target参数不是代表一个单元格,而是选中的单元格构成的range区域.

为了避免选中多个单元格带来困扰,因此对选中的单元格规定为选中区域的第一行第一列(即左上角第一个单元格)

期望达到的效果是点击亲友列(即E列和G列),可以在B列显示相同内容的单元格.除了亲友列,其他单元格不应该做查找的工作.
我们可以写一个判断语句.

那么又如何查找与r内容相同的单元格并被选中


完整的代码如下:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim r As Range
Set r = Target.Cells(1, 1)
If r.Row > 3 And (r.Column = 5 Or r.Column = 7) Then
i = 4
Do While Trim(Cells(i, 2)) <> ""
If Trim(Cells(i, 2)) = Trim(r.Value) Then
Cells(i, 2).Select
Exit Do
End If
i = i + 1
Loop
End If
End Sub

代码显示的结果如下:

虽然完成了跳转,但是对亲友这两列无法对单元格的内容进行修改.方法有很多,以下方法是比较常用的方法.
在跳转之前进行咨询,确定是否跳转?


完整的代码:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim r As Range
Set r = Target.Cells(1, 1)
If r.Row > 3 And (r.Column = 5 Or r.Column = 7) Then
k = MsgBox("确定跳转?", vbYesNo)
If k = vbYes Then
i = 4
Do While Trim(Cells(i, 2)) <> ""
If Trim(Cells(i, 2)) = Trim(r.Value) Then
Cells(i, 2).Select
Exit Do
End If
i = i + 1
Loop
End If
End If
End Sub

代码显示的结果如下:

4.worksheet_change(Target)
常用于修改单元格,一离开修改好的单元格就会激活change事件,并且运行相关代码.与此同时,即便是光标在单元格在里面闪烁,哪怕没做任何修改,一离开单元格,同样会激活change事件.千万不要被chang这个名字所迷惑.
change常用于修改的单元格的数值是否符合规定.相当于数据有效性的检验.
change也有个参数,叫target,代表的是刚刚修改过的单元格.

案例1
要求武林世家社会网络分析中的武力值是0-100的数值.其他文本或者更大的数字就会出错.


完整的代码:
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Row > 3 And Target.Column = 4 Then
If Not IsNumeric(Target) Or Target > 100 Or Target < 5 Then
MsgBox "武力值必须是0到100之间的数字!"
Target.Select
End If
End If
End Sub

代码显示的最终结果如下:

change事件使用的时候要特别小心
并不是每一种单元格的修改都能激活change事件.

案例2
要求武林世家社会网络分析中的武力值是0-100的数值.其他文本或者更大的数字就会出错,并且单元格显示为"待输入"
在代码块增加一行代码:
Target.Value = "待输入"

因为在运行VBA代码时,在VBA代码中修改了单元格的内容,导致激活了change事件.msgbox界面一直是打开状态.


这种事件称为事件级联,应该要避免的一种情况.



完整的代码:
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Row > 3 And Target.Column = 4 Then
If Not IsNumeric(Target) Or Target > 100 Or Target < 5 Then
MsgBox "武力值必须是0到100之间的数字!"
Target.Select
Application.EnableEvents = False
Target.Value = "待输入"
Application.EnableEvents = True
End If
End If
End Sub

代码显示的最终结果如下:

网友评论