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
eg
For 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