你真的知道如何使用Target.Count吗?

工作表的Change和SelectChange事件是VBA开发中最常用的事件。

Private Sub Worksheet_Change(ByVal Target As Range)

End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Range)

End Sub

两个过程的参数都有Range类型的对象变量Target,为了确保用户在Excel操作时只选中了单个单元格,经常会使用如下代码。这句代码已经是简单得不能再简单的语句了,它会有什么问题吗?

If Target.Count > 1 Then

我们来做个试验,新建一个Excel文件,在工作表模块中添加如下事件代码,如果用户选中多个单元格就在立即窗口中输入选中区域的地址。

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    If Target.Count > 1 Then
        Debug.Print Target.Address
    End If
End Sub

单击工作表左上角选中全部单元格,立刻出现如下图所示的错误提示。
你真的知道如何使用Target.Count吗?_第1张图片
单击【调试】按钮将打开VBE窗口,定位到出错的代码,如下图所示,这句简单的代码出什么幺蛾子呢?
你真的知道如何使用Target.Count吗?_第2张图片

查阅一下关于Range对象的Count属性帮助文档,Count属性返回值为Long,查阅一下帮助可以得知Long类型数据的范围是:-2,147,483,648至2,147,483,647。从Excel 2007开始,一个工作表中的单元格数量为 1048576(行) * 16384 (列)= 17,179,869,184,这个数远远超过了Long类型数据的范围。
你真的知道如何使用Target.Count吗?_第3张图片
这个问题的解决方法其实很简单,只需要使用CountLarge属性替代Count属性就可以了,CountLarge属性返回值为Variant 类型,可以处理工作表中全部单元格区域。代码更新如下。

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    If Target.CountLarge > 1 Then
        Debug.Print Target.Address
    End If
End Sub

如果不使用CountLarge属性,使用其他的方法也可以实现相同的功能。我们首先来分析一下用户选中单元格的行为的几个不同类型。

选中类型 选中区域地址
单个单元格 $AA$188
多个单元格连续区域 $AA$188:$BB$199
多个单元格非连续区域 $A$88,$AA$188:$BB$199

如果希望只处理用户选中单个单元格的场景,那么Target.Address属性返回值加可以进行判断,如果返回值中包含冒号或者逗号,那么一定是选中了多个单元格,无论是连续区域还是非连续区域。
示例代码如下。

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    If Target.Address Like "*[:,]*" Then
        Debug.Print "选中了多个单元格"
    Else
        Debug.Print "选中了单个单元格"
    End If
End Sub

大家可以测试一下,即使选中全部工作表单元格,此代码过程也不会报错。

你可能感兴趣的:(VBA,Excel,事件)