关于vba:为什么我在这里遇到类型不匹配错误?

Why am I getting a type mismatch error here?

我创建一个新模块并插入以下代码:

1
2
3
4
5
Sub test()
   Set wsData = ThisWorkbook.Worksheets("Data")
   sCount = wsData.Columns(14).SpecialCells(xlCellTypeBlanks).Count
   msgbox sCount
End Sub

在工作表" Data "中,我有以下代码:

1
2
3
4
5
6
7
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    If Selection.CountLarge = 1 Then
        If Not Intersect(Target, Range("K:M")) Is Nothing And Target.Value <>"" Then
            'code
        End if
    End if
End Sub

运行test()子时,在If Not Intersect(Target, Range("K:M")) Is Nothing上收到类型不匹配错误,作为目标错误类型。

为什么会这样?

为什么测试会触发更改事件?
如果手动过滤数据表的第14列以仅保留空白单元格,我不会出现相同的错误!


类型不匹配的问题是Target.Cells超过一个单元格。因此,Target.Value <>""引发类型不匹配,因为无法将多个单元格与""进行比较。请参见MsgbBox以及单元格数量:

1
2
3
4
5
6
7
8
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    If Selection.CountLarge = 1 Then
        If Target.Cells.CountLarge > 1 Then MsgBox Target.Cells.CountLarge
        If Not Intersect(Target, Range("K:M")) Is Nothing And Target.Value <>"" Then
            'code
        End If
    End If
End Sub

根据业务逻辑,可能有几种解决方案。

  • 最容易的是写
    _SelectionChange事件中的If Target.Cells.CountLarge > 1 Then Exit Sub

  • 另一种方法是禁用

    附近的事件

sCount = wsData.Columns(14).SpecialCells(xlCellTypeBlanks).Count像这样:

1
2
3
4
5
6
7
Sub TestMe()
   Set wsData = ThisWorkbook.Worksheets("Data")
   Application.EnableEvents = False
   sCount = wsData.Columns(14).SpecialCells(xlCellTypeBlanks).Count
   Application.EnableEvents = True
   msgbox sCount
End Sub


我几乎以重复的形式结束了这个问题。

我将按照相反的顺序回答您的两个问题,以便您更好地理解它。

Why is test triggering the Change Event?

我已经在导致Excel 2010中的SheetSelectionChange事件的SpecialCells中对此进行了解释

When I run the test() sub, I get a type mismatch error on If Not Intersect(Target, Range("K:M")) Is Nothing, as Target wrong type.
Why this is happening?

当过程Test触发Worksheet_SelectionChange事件时,您的代码将在该行上失败

1
If Not Intersect(Target, Range("K:M")) Is Nothing And Target.Value <>"" Then

这是因为Target.Value <>""是元凶,因为SpecialCells(xlCellTypeBlanks).Count可能返回多个单元格。

如果将上述行分成两行,则不会出现错误

1
2
3
4
5
6
7
8
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    If Target.Cells.CountLarge > 1 Then Exit Sub
    If Not Intersect(Target, Range("K:M")) Is Nothing Then
        If Target.Value <>"" Then
             'code
        End If
    End If
End Sub