【问题标题】:Run-time error '13': Type mismatch on VBA code运行时错误“13”:VBA 代码上的类型不匹配
【发布时间】:2015-08-10 19:15:17
【问题描述】:

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

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

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

运行时错误“13”:类型不匹配

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

任何帮助将不胜感激。

编辑:

抱歉,不清楚。

我在工作表“技术员报告摘要”中有一组值,占据了 C2:E8561 范围。我想过滤并复制一些错误的值,这些是“未使用”和“#N/A”错误。上面的代码复制了这些值,然后将它们粘贴到原始的未过滤值集旁边,并在 G、H 和 I 列中删除了“未使用”和“#N/A”的实例。

当我运行它时,没有任何行被突出显示为问题,错误对话框只是弹出,当我点击“确定”时没有突出显示。

编辑 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('原始数据'!$A:$A,$B2)

【问题讨论】:

  • 错误出现在哪一行?
  • 旁注:Set Source = Range(Cells(1, "C"), Cells(n, "E")) 不限定rangecells 是从哪个工作表中提取的。您需要澄清这一点才能正常工作/工作而不会出现意外的未来错误。
  • 你的问题很不清楚。一方面(正如@KFichter 提到的),您没有告诉我们错误行。其次,您还没有告诉我们代码应该如何进行正确评估。
  • Cells() 是否将字母作为参数?编辑:确实如此,我真的不知道。
  • @KFichter - 是的,第二个参数可以是数字或列字母

标签: vba excel excel-2013


【解决方案1】:

所以我不确定问题出在哪里。

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

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

唯一真正的区别是“值”与“文本”。我没有收到任何错误。唯一的问题是,它需要很长时间才能完成它应该做的事情,因为行数太多了。

现在...我建议您可以做一些不同的事情。

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

这基本上可以完成您尝试做的事情,但使用自动过滤器。它比遍历每个单元格并最终执行相同的操作要快得多。希望对您有所帮助...

【讨论】:

  • 同样的事情发生了,它被锁住了,当我按下退出键退出它时,If 的第一行被突出显示。
  • 您能否将一些引发错误的样本(非敏感)数据放在一起,以便我可以使用 VBA?我根据你提供的描述做了一些,但它的工作原理。
  • 好的,我已经按照你的建议做了。这是 Google Drive 中的链接:Tech Report - Troubleshoot
  • @nickelcap 我基本上使用更快的方法更新了所有内容。我希望这能满足您的需要。
  • 非常感谢!它现在工作得很好,但正如你所说的第一种方法要慢得多。我决定使用您建议的第二种方法,因为它可以满足我的要求,而且速度更快。
【解决方案2】:

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

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

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

这应该足以让你工作。

【讨论】:

    猜你喜欢
    • 2015-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多