VBA-TG第5节|事件编程

2019-04-24  本文已影响0人  努力奋斗的durian

最近更新:'2019-04-24'

  1. 工作簿事件介绍
  2. 工作表事件介绍
    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内容相同的单元格并被选中

image.png

完整的代码如下:

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

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


上一篇 下一篇

猜你喜欢

热点阅读