运行-时间错误“13”:VBA 代码类型不匹配

Run-time error '13': Type mismatch on VBA code

我在我正在处理的项目中使用以下代码:

Sub test()
    Application.ScreenUpdating = False
    Worksheets("Technician Report Summary").Range("G2:I8561").ClearContents
    Dim Source As Range, Target As Range
    Dim n As Long, i As Long
    n = Range("C:C").Cells.Count
    i = Cells(n, "C").End(xlUp).Row
    Set Source = Range(Cells(1, "C"), Cells(n, "E"))
    Set Target = Range("G2:I2")

    For i = 2 To n
        If Source.Cells(i, 1).Value <> "Not Used" And Not Application.WorksheetFunction.IsNA(Source.Cells(i, 3).Value) Then
            Source.Rows(i).Copy
            Target.PasteSpecial xlPasteValues
            Set Target = Target.Offset(1)
        End If
    Next i

    Application.CutCopyMode = False
    Application.ScreenUpdating = True
End Sub

当我 运行 代码似乎可以正常运行时,它会按照代码中设置的条件将过滤值列表复制到同一工作表中的另一个位置。问题是我也收到以下错误:

Run-time error '13': Type mismatch

我做错了什么?我认为我在声明变量时犯了某种错误或类似的错误,但我对 VBA 不够熟悉,无法确定问题所在。

如有任何帮助,我们将不胜感激。

编辑:

抱歉没说清楚。

我在工作表 'Technician Report Summary' 中有一组值占据范围 C2:E8561。有一些我想过滤掉并复制的错误值,这些是 "Not Used" 和 '#N/A' 错误。上面的代码复制值,然后将它们粘贴到原始的、未过滤的值集旁边,并删除 G、H 和 I 列中的 "Not Used" 和“#N/A”实例。

当我 运行 时,没有任何行被突出显示为问题,错误对话框弹出,当我点击 "OK" 时,没有任何突出显示。

编辑 2:

我按照@KFitchter 的建议进行了更改,现在它似乎锁定了。我按了转义键,下面一行被高亮显示:

If Source.Cells(i, 1).Text <> "Not Used" And Not Application.WorksheetFunction.IsNA(Source.Cells(i, 3).Value) Then

编辑 3:

只是想到了其他可能会扰乱它的事情。 C、D 和 E 列中的值实际上是从工作簿其他地方提取值的函数。这是其中一个函数的示例。

=INDEX('RAW DATA'!$A:$A,$B2)

所以我不太确定是什么问题。

我稍微修改了你的代码(使用我最初的猜测):

Sub test()
    Application.ScreenUpdating = False
    Worksheets("Technician Report Summary").Range("G2:I8561").ClearContents
    Dim Source As Range, Target As Range
    Dim n As Long, i As Long
    n = Range("C:C").Cells.Count
    i = Cells(n, "C").End(xlUp).Row
    Set Source = Range(Cells(1, "C"), Cells(n, "E"))
    Set Target = Range("G2:I2")

    For i = 2 To n
        If Source.Cells(i, 1).Text <> "Not Used" And Not Application.WorksheetFunction.IsNA(Source.Cells(i, 3).Value) Then
            Source.Rows(i).Copy
            Target.PasteSpecial xlPasteValues
            Set Target = Target.Offset(1)
        End If
    Next i

    Application.CutCopyMode = False
    Application.ScreenUpdating = True
End Sub

唯一真正的区别是 "Value" 到 "Text"。我没有收到任何错误。唯一的问题是它需要很长时间才能完成它应该做的事情,因为有太多的线路。

现在... 我建议您可以稍微改变一下您正在做的事情。

Sub test()
    Application.ScreenUpdating = False

    Worksheets("Technician Report Summary").Range("G2:I8561").ClearContents

    Dim Source As Range, Target As Range
    Dim n As Long

    ActiveSheet.Range("C:E").AutoFilter Field:=1, Criteria1:= _
        Array("<>#N/A", "<>Not Used"), Operator:=xlAnd
    ActiveSheet.Range("C:E").AutoFilter Field:=3, Criteria1:= _
        "<>#N/A", Operator:=xlAnd

    n = ActiveSheet.Cells(Rows.Count, "C").End(xlUp).Row

    Set Source = Range("C2:E" & n).SpecialCells(xlCellTypeVisible)
    Set Target = Range("G2")

    Source.Copy
    Target.PasteSpecial (xlPasteValues)

    Application.CutCopyMode = False
    Application.ScreenUpdating = True

    Range("C:E").AutoFilter
End Sub

这基本上完成了您想要做的事情,但使用了自动过滤器。它比遍历每个单元格并最终做同样的事情要快得多。希望对您有所帮助...

首先指定所有区域和单元格引用的父级。

不要将错误检查与其他字符串比较或布尔检查结合起来。首先检查错误,然后在新代码行上处理其他布尔检查。

n = .Range("C:C").Cells.Count 将 1,048,576 放入 n。你真的想要 Set src = .Range("C1:E1048576)For i = 2 To 1048576 吗?

直接文本比较通常区分大小写。

尽可能使用直接值传输而不是复制、选择性粘贴、值。

将所有这些点放在一起:

Sub test()
    Dim src As Range, trgt As Range, nas As Range
    Dim n As Long, i As Long, bERR As Boolean

    Application.ScreenUpdating = False

    With Worksheets("Technician Report Summary")
        .Range("G2:I8561").ClearContents
        n = .Cells(Rows.Count, "C").End(xlUp).Row
        Set src = .Range(.Cells(1, "C"), .Cells(n, "E"))
        Set trgt = .Range("G2:I2")
    End With

    For i = 2 To n
        If Not IsError(src.Cells(i, 3)) Then
            Debug.Print src.Cells(i, 3).Text
            If LCase(src.Cells(i, 1).Value2) <> "not used" Then
                trgt = src.Rows(i).Value
                Set trgt = trgt.Offset(1)
            End If
        End If
    Next i

    Application.ScreenUpdating = True
End Sub

这应该足以让你工作。