VBA代码一个循环可删除行另一个报错:Range类的Delete方法失败
问题描述
- 需求:编写VBA程序,找出Sheet1中满足以下任一条件的行:AB列(第28列)包含“Cancelled”,或Z列(第26列)不为空;将这些行移动到Sheet2后,从Sheet1中删除。
- 现状:第一个处理“Cancelled”行的循环正常工作,但第二个循环执行时抛出运行时错误,提示“Delete method of range class failed”。移除第二个循环中的
myCell.EntireRow.Delete语句后,程序可正常运行(仅不会删除目标行)。 - 疑问:为何两个循环表现不同?
原代码
Sub move_rows_to_another_sheet_cust() For Each myCell In Worksheets("Sheet1").Columns(28).Cells If myCell.Value = "Cancelled" Then myCell.EntireRow.Copy Worksheets("Sheet2").Range("A" & Rows.Count).End(3)(2) myCell.EntireRow.Delete End If Next For Each myCell In Worksheets("Sheet1").Columns(26).Cells If myCell.Value <> "" Then myCell.EntireRow.Copy Worksheets("Sheet2").Range("A" & Rows.Count).End(3)(2) myCell.EntireRow.Delete End If Next End Sub
问题原因与解决方案
为啥第二个循环会报错?
两个循环表现不一样的核心问题出在遍历方式和删除行导致的单元格集合错位:
- 第一个循环遍历AB列(第28列),虽然删除行后后续行会往上挪,但AB列大部分行可能是空的,遍历到空单元格时不会触发删除,所以没立刻报错,但这种写法本身就有隐患,属于“运气好没出问题”。
- 第二个循环遍历Z列(第26列),如果Z列有不少非空单元格,删除行之后,
For Each循环依赖的单元格集合会直接乱掉——被删行的下一行会移到当前位置,但循环已经跳过这个位置了,到最后甚至会遍历到工作表最后一行之外的无效区域,自然就触发删除失败的错误。
另外,Columns(26).Cells会遍历整列所有单元格(从第1行到第1048576行),不仅效率极低,遍历到空白行时还会因为之前的行删除操作导致位置混乱,进一步增加出错概率。
怎么改才对?
正确的做法是从下往上遍历行,这样删除行不会影响还没遍历到的行;同时只遍历有数据的区域,别瞎跑整列。还可以把两个条件合并,一次遍历搞定,少写重复代码:
Sub move_rows_to_another_sheet_cust() Dim wsSource As Worksheet Dim wsTarget As Worksheet Dim lastRow As Long Dim i As Long ' 先把工作表对象存起来,写代码更省事 Set wsSource = ThisWorkbook.Worksheets("Sheet1") Set wsTarget = ThisWorkbook.Worksheets("Sheet2") ' 找到Sheet1里有数据的最后一行,别瞎遍历整列 lastRow = wsSource.Cells(wsSource.Rows.Count, "A").End(xlUp).Row ' 从最后一行往第一行倒着遍历,删行不影响前面的遍历 For i = lastRow To 1 Step -1 ' 同时判断两个条件:AB列是"Cancelled",或者Z列不为空 If wsSource.Cells(i, 28).Value = "Cancelled" Or wsSource.Cells(i, 26).Value <> "" Then ' 复制到Sheet2的最后一行下面 wsSource.Rows(i).Copy Destination:=wsTarget.Cells(wsTarget.Rows.Count, "A").End(xlUp).Offset(1) ' 删除当前行 wsSource.Rows(i).Delete End If Next i End Sub
改了啥?
- 倒序遍历:从下往上走,删行之后上面的行不会被跳过,彻底解决集合错位的问题。
- 只遍历有效行:用
lastRow找到实际有数据的行,避免遍历几十万行空白单元格,速度快很多。 - 合并条件:一次遍历处理两个判断,不用写两次循环,代码更简洁。
- 用工作表变量:不用每次都写
Worksheets("Sheet1"),代码更清晰,也不容易写错。
内容的提问来源于stack exchange,提问作者Kat Brown
相关产品推荐
相关产品推荐

