VBA循环中出现Type mismatch (Error 13)错误,求排查解决
排查VBA类型不匹配错误(Error 13)
你的代码在If .Cells(i, 1).Value = .Cells(i - 1, 1).Value Then行触发类型不匹配错误(Error 13),看似逻辑没问题,但实际是代码里的几个隐性问题导致的,下面是具体排查和修复方案:
问题根源分析
- 单元格值类型冲突或存在错误值:如果A列中存在格式不一致的内容(比如一个是文本数字、一个是数值数字),或者单元格包含#N/A、#VALUE!这类错误值,直接用
=比较会触发类型不匹配。 - With块内对象未限定:代码中多个
Cells、Rows没有加上.前缀,导致它们默认指向当前活动工作表,而非With语句指定的工作簿/工作表,会造成数据读取、赋值错误,后续单元格可能混入异常值。 - 变量类型不合理:
lastrow用Integer类型,当工作表行数超过32767时会溢出,同时数组赋值时范围不匹配,导致部分单元格出现错误值。 - 数组赋值范围不匹配:
v是从外部工作簿第4行L列到lastrow的L列的数组,直接赋值到wsSheet的A2到A(lastrow)时,行数不匹配,会导致部分单元格填充错误值,后续比较时触发报错。
修复方案
1. 严格限定With块内的对象
所有在With exwb和With wsSheet范围内的Cells、Rows、Range必须加上.前缀,确保操作的是指定的工作表。
2. 统一比较时的变量类型
比较单元格值前,先转换为相同类型(比如字符串),同时先排查错误值:
If Not IsError(.Cells(i, 1).Value) And Not IsError(.Cells(i - 1, 1).Value) Then If CStr(.Cells(i, 1).Value) = CStr(.Cells(i - 1, 1).Value) Then .Rows(i).EntireRow.Delete End If End If
3. 修正变量类型
将lastrow的类型从Integer改为Long,避免行数溢出。
4. 匹配数组赋值的范围
根据数组v的实际行数调整赋值范围,避免出现错误值:
.Range(.Cells(2, 1), .Cells(2 + UBound(v, 1) - 1, 1)).Value = v
修复后的完整代码
Sub tests() Dim lastrow As Long Dim i As Long Dim orig As String Dim v As Variant Dim wbBook As Workbook Dim wsSheet As Worksheet Dim exApp As Excel.Application Dim exwb As Excel.Workbook Dim srcSheet As Worksheet Set wbBook = Workbooks("SHELF LIFE.xlsm") Set wsSheet = wbBook.Sheets("Shelf Life Data") Set exApp = CreateObject("Excel.Application") exApp.Workbooks.Open ("link.xlsm") Set exwb = exApp.Workbooks("file name.xlsm") With exwb Set srcSheet = .Sheets("SINCE 170522") lastrow = srcSheet.Cells(srcSheet.Rows.Count, "L").End(xlUp).Row v = srcSheet.Range(srcSheet.Cells(4, 12), srcSheet.Cells(lastrow, 12)).Value .Close SaveChanges:=False End With exApp.Quit Set exApp = Nothing With wsSheet ' 匹配数组行数赋值 .Range(.Cells(2, 1), .Cells(2 + UBound(v, 1) - 1, 1)).Value = v ' 排序时限定对象 .Range(.Cells(1, 1), .Cells(.Cells(.Rows.Count, "A").End(xlUp).Row, 2)).Sort _ Key1:=.Range("A1"), _ Order1:=xlAscending, _ Header:=xlYes lastrow = .Cells(.Rows.Count, "A").End(xlUp).Row ' 从后往前遍历删除重复行 For i = lastrow To 2 Step -1 If Not IsError(.Cells(i, 1).Value) And Not IsError(.Cells(i - 1, 1).Value) Then If CStr(.Cells(i, 1).Value) = CStr(.Cells(i - 1, 1).Value) Then .Rows(i).EntireRow.Delete End If End If Next i End With End Sub
内容的提问来源于stack exchange,提问作者Sosa
相关产品推荐
相关产品推荐

