Excel 如果有两个连续的空行,则删除行
如果有两个连续的空行,我要做的是删除行,并且在标题和要删除的第一组数据行之间也要有空行。这是我的原稿 我想要的是。我试着在这里和那里找到一些代码,并提出了这个代码Excel 如果有两个连续的空行,则删除行,excel,vba,Excel,Vba,如果有两个连续的空行,我要做的是删除行,并且在标题和要删除的第一组数据行之间也要有空行。这是我的原稿 我想要的是。我试着在这里和那里找到一些代码,并提出了这个代码 Sub Testing() Dim i As Long , lRow As Long Dim ws As Worksheet Set ws = Activesheet With ws With .Range("C:C") fr = .Find(what:="*"
Sub Testing()
Dim i As Long , lRow As Long
Dim ws As Worksheet
Set ws = Activesheet
With ws
With .Range("C:C")
fr = .Find(what:="*", after:=.Cells(1, 1), LookIn:=xlValues).row
If fr > 2 Then
.Rows("2:" & fr - 1).EntireRow.Delete
End If
End With
i = 1
For i = 1 To lRow
If IsEmpty(Cells(i, 3)) And IsEmpty(Cells(i + 1, 3)) Then
.Rows(i).EntireRow.Delete
End If
Next i
End With
End Sub
但是,在数据集中的中间仍然有一些连续的空行。我知道这是因为我正在增加
I
,它将查看下一个单元格,但我不确定如何解决它。我是vba新手,甚至比SO帖子更新,所以如果我有什么地方做错了,请告诉我,并感谢您的帮助。我认为删除一行后您需要减少I
For i = 1 To lRow
If IsEmpty(Cells(i, 3)) And IsEmpty(Cells(i + 1, 3)) Then
.Rows(i).EntireRow.Delete
i = i - 1
lRow = lRow - 1
End If
If i > lRow Then Exit For
Next i
你唯一需要做的就是向后循环。而不是
For i = 1 To lRow
做
这是因为从底部循环不会对尚未处理行的行计数产生任何影响,但从顶部循环到底部会产生影响
此外,您还可以在For
之前跳过i=1
,因为For
以指定为下限的任何i
开头,因此它没有任何影响
我认为您的代码只是一个示例,但只是以防万一。请注意,lRow
从未设置为代码中的值,因此是0
请注意,在这一行中
If IsEmpty(Cells(i, 3)) And IsEmpty(Cells(i + 1, 3)) Then
您的单元格
对象没有引用到With
语句的工作表,因为您在开始时忘记了
。应该是
If IsEmpty(.Cells(i, 3)) And IsEmpty(.Cells(i + 1, 3)) Then
此外,我强烈建议如果您使用 始终将
LookAt
参数指定为xlother
或xlPart
(请参阅)。因为LookAt
参数没有默认值(很遗憾),如果您不指定它,VBA将使用xlother
或xlPart
用户界面或VBA上次使用的任何内容。因此,您无法知道以前使用过哪一个,它将变得非常随机(或者您的代码有时可以工作,有时不能)
替代(更快)方法… …是保持正向循环,并在变量
RowsToDelete
中收集所有要删除的行,以便在最后立即删除它们。它的速度要快得多,因为每个删除操作都需要时间,在这种方法中,您只有一个删除操作……而在另一种方法中,每行只有一个删除操作
Dim RowsToDelete As Range
For i = 1 To lRow 'forward loop is no issue here because we just collect
If IsEmpty(.Cells(i, 3)) And IsEmpty(.Cells(i + 1, 3)) Then
If RowsToDelete Is Nothing Then 'first row
Set RowsToDelete = .Rows(i).EntireRow
Else 'append more rows with union
Set RowsToDelete = Application.Union(RowsToDelete, .Rows(i).EntireRow)
End If
End If
Next i
'delete all collected rows (after the loop, so delete doesn't affect row counting of the loop)
If Not RowsToDelete Is Nothing Then
RowsToDelete.Delete
End If
当删除行时,你想从下向上工作。哦,我需要使用<代码>为i= LROW到1步-1 <代码>吗?没错,你要考虑的不是一个一个删除,而是在一个GOHI中,我在尝试周围的时候尝试了这一点,这将使程序循环永远像你删除整个行一样。我的实际最后一行将减少,但
lRow
仍将保持不变。这将使程序永远循环,因为当我不断减少i
时,i
将永远不会达到lRow
。如果由For
循环处理i
,请不要手动处理i
。这是一个非常糟糕的方法。相反,使用Step-1
egFor i=l到1 Step-1
向后循环。因此,不会发生错误计数(因为删除了行)您可以在do
循环中执行您在i
不由循环处理的操作,但不要在For
循环中执行。抱歉,我只是再次可用。你可以添加If i>lRow然后退出For.hmm这终究是可行的,很高兴知道这是可行的,我会将它标记为答案,因为它确实有效,但正如Peh所提到的,这是一个糟糕的方法。@adhywijaya请注意,你现在完全搞乱了For
循环的目的。这是一个非常糟糕的方法。将其更改为Do
循环,或使用For i=l进入1步-1
。不要使用此代码,与其说是出于目的,不如说是出于偶然。您好,欢迎来到stackoverflow,谢谢您的回答。你能不能简单地解释一下你解决了什么问题以及你是如何解决的,而不是仅仅发布一段代码?这将帮助将来发现这个问题的人更好地理解这个问题以及如何处理它。哦,哇,这真是一个更好的方法,我从中学到了很多,谢谢!
If IsEmpty(.Cells(i, 3)) And IsEmpty(.Cells(i + 1, 3)) Then
fr = .Find(what:="*", after:=.Cells(1, 1), LookIn:=xlValues).row
Dim RowsToDelete As Range
For i = 1 To lRow 'forward loop is no issue here because we just collect
If IsEmpty(.Cells(i, 3)) And IsEmpty(.Cells(i + 1, 3)) Then
If RowsToDelete Is Nothing Then 'first row
Set RowsToDelete = .Rows(i).EntireRow
Else 'append more rows with union
Set RowsToDelete = Application.Union(RowsToDelete, .Rows(i).EntireRow)
End If
End If
Next i
'delete all collected rows (after the loop, so delete doesn't affect row counting of the loop)
If Not RowsToDelete Is Nothing Then
RowsToDelete.Delete
End If