Excel VBA:必须有更好的方法使用循环根据单元格内容删除行

Excel VBA:必须有更好的方法使用循环根据单元格内容删除行,vba,excel,foreach,Vba,Excel,Foreach,报表生成的工作表如下所示: 格式从源数据继承而来,数据以列A、D和G表示,并单独合并ABC、D合并DEF和G 我只想用蓝色突出显示线条。我希望宏检查G:G的内容,如果Cell.Text=”“,则检查entirerow.delete,否则不处理它 唯一的问题是当它删除第2行时,第3行变成第2行,这意味着它不会删除它,因为它已经选中了第2行。原来的第4行现在变成第3行,这是下一个要检查的行,它看到文本在那里,没有删除,移到第4行,删除它,第5行变成第4行,保持未选中状态,移到第6行(现在是第5行)

报表生成的工作表如下所示:

格式从源数据继承而来,数据以列A、D和G表示,并单独合并ABC、D合并DEF和G

我只想用蓝色突出显示线条。我希望宏检查G:G的内容,如果Cell.Text=”“,则检查entirerow.delete,否则不处理它

唯一的问题是当它删除第2行时,第3行变成第2行,这意味着它不会删除它,因为它已经选中了第2行。原来的第4行现在变成第3行,这是下一个要检查的行,它看到文本在那里,没有删除,移到第4行,删除它,第5行变成第4行,保持未选中状态,移到第6行(现在是第5行),看到为空,删除它,但第7行现在变成第6行,没有删除。。。等等

我找到的唯一解决方法是使用GOTO重新启动循环,然后使用另一个GOTO尽早退出循环。我知道这可能不是最优雅的解决方案

iRange = Application.Workbooks(2).Worksheets(2).Cells(Rows.Count, "A").End(xlUp).Row + 1
Debug.Print (iRange)

RestartLoop:

For Each rCell In Application.Workbooks(2).Worksheets(2).Range("G2:G" & iRange)

    If Not rCell.Offset(0, -3).Value = "" Then

        If rCell.Text = "" Then
            Debug.Print (rCell.Address)
            rCell.EntireRow.Delete
            GoTo RestartLoop
        End If

    Else0

        GoTo LeaveLoop

    End If
Next rCell

LeaveLoop:
'Do the next thing
(代码是选项显式的:Dim iRange作为整数Dim rCell作为代码顶部声明中的范围)

以下是debug.print:

26 
$G$2
$G$2
$G$3
$G$3
$G$3
$G$3
$G$3
$G$3
$G$3
$G$3
$G$3
$G$4
$G$4
$G$4
$G$4
$G$4
$G$6
$G$6
$G$7
如果有人知道一个解决方案,也能向外行解释,我将不胜感激。解决方案需要是动态的,因为每次生成的原始纸张长度不同,每次有不同数量的空白单元格和蓝色单元格


我搜索了一下,但要么我没有完全理解答案,要么他们似乎给了我同样的问题

看看下面的内容,它的工作原理是从符合条件的单元格中建立一个范围,然后一次性删除所有单元格测试时,务必在原件的副本上进行,以确保结果符合预期,然后再将其永久化

Dim DeleteRng As Range

Application.ScreenUpdating = False

IRange = Application.Workbooks(2).Worksheets(2).Cells(Rows.Count, "A").End(xlUp).Row + 1

Debug.Print IRange

' This is dangerous, select workbook using ThisWorkbook, or setting the workbook to a variable
' Not just using the number, this could change when opening other workbooks as well
' Similar with above when setting IRange
For Each rcell In Application.Workbooks(2).Worksheets(2).Range("G2:G" & IRange)
    If Not rcell.Offset(0, -3).value = vbNullString And rcell.Text = vbNullString Then
        If DeleteRng Is Nothing Then
            Set DeleteRng = rcell
        Else
            Set DeleteRng = Union(DeleteRng, rcell)
        End If
    End If
Next rcell
Debug.Print DeleteRng.Address
DeleteRng.EntireRow.Delete

Application.ScreenUpdating = True

您应该在G列上使用Autofilter来选择空行,然后删除这些行,这样就可以在G列中包含文本的所有行。这将删除G列中包含空白单元格的所有行。需要添加新行,即虚拟行,以作为进一步选择和删除行的参考点。

Dim lastrow As Long
lastrow = Range("A" & Rows.Count).End(xlUp).Row
' Add dummy row
Rows("1:1").Copy
Rows("2:2").Insert shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
Rows("2:2").Paste
CutCopyMode = False

'add filter
With ActiveSheet

.AutoFilterMode = False
.Range("A2:G2").AutoFilter field:=7, Criteria1:="=", Operator:=xlOr, Criteria2:="=" & ""
End With

'delete blank rows
Range("A2:G2").Select
Range(Selection, Selection.End(xlDown)).EntireRow.Delete

希望这有帮助:)

简单的答案是使用
进行r=iRange到2步骤-1的循环。更复杂的答案是从一百个或更多类似的问题中找出一个,这样我们就可以将这个问题标记为重复问题。保持积极@YowE3K,我会找到一个好的重复:P@CallumDA-找到一个。过滤器可能会帮助删除一个简单的空单元格,过滤空白,删除选定的数据,过滤掉。我拒绝将其作为答案发布,但您的代码可能会随着应用程序的使用而变得
。工作簿(2)。工作表(2)
对于r=.Cells(.Rows.Count,“A”).End(xlUp)。Row+1到2步骤-1
如果.Cells(r,“D”).Value“”和.Cells(r,“G”).Text=”“然后。Rows(r)。删除
下一步
结束,但是从@Ralph提供的链接中得到一些提示也可以让你加快速度。所有
Select
语句是怎么回事?不要将宏记录器输出用于回答。这是草率的best@tom我是VBA新手,我知道为任何操作调用范围的唯一方法是通过
选择
,我将尝试进一步学习。感谢将
选择
选择
行组合,例如
行(1:1)。选择:选择。复制
成为
行(1:1).复制
除非您需要直观地执行某些操作,否则您应该很少使用
选择
语句感谢您的输入。为什么您要回答一个被明确标识为重复的问题,并且在其他地方有非常好的答案?我不是100%确定,但我认为比我们更高的权力会删除这样的封闭式问题,因为这些问题已经被问过了,也被回答过了,其实很简单。当我回答的时候,它没有被标记为重复的-看看时间stamps@CallumDA你愿意我把它删除吗?@CallumDA-从记忆中,我认为重复的问题通常会被留下(除非它们被标记为劣质等),因为它们可以作为搜索目标,然后让人们参考“原始”问题/答案。