运行-时间错误“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
这应该足以让你工作。
我在我正在处理的项目中使用以下代码:
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
这应该足以让你工作。