Vba 根据单元格删除行(动态金额)';内容

Vba 根据单元格删除行(动态金额)';内容,vba,loops,excel,range,Vba,Loops,Excel,Range,很抱歉,如果这很简单,这是我第一次尝试VBA 所以我想让这个宏去掉我不需要的行,对于每个实体,它都有一个总字段(大约每20条记录),我制作了这个脚本: Dim i As Integer Dim LastRow As Integer LastRow = Range("A65536").End(xlUp).Row For i = 3 To LastRow If Range("C" & i) = "Result" Then Rows(i & ":" &

很抱歉,如果这很简单,这是我第一次尝试VBA

所以我想让这个宏去掉我不需要的行,对于每个实体,它都有一个总字段(大约每20条记录),我制作了这个脚本:

Dim i As Integer
Dim LastRow As Integer
LastRow = Range("A65536").End(xlUp).Row

For i = 3 To LastRow
    If Range("C" & i) = "Result" Then
        Rows(i & ":" & i).Select
        Selection.Delete Shift:=x1Up
    End If
Next
而且效果很好!然后我试着做一件类似的事情。。我试图遍历数据集中的每一行(记录),如果某个字段不包含字符串“INVOICE”,那么我不需要该行,我可以将其删除。所以我刚刚添加到我当前的循环中(为什么循环两次?),所以现在看起来是这样的:

Dim i As Integer
Dim LastRow As Integer
LastRow = Range("A65536").End(xlUp).Row

For i = 3 To LastRow
    If Range("C" & i) = "Result" Then
        Rows(i & ":" & i).Select
        Selection.Delete Shift:=x1Up
    End If
    If Not InStr(1, Range("Q" & i), "INVOICE") Then
        Rows(i & ":" & i).Select
        Selection.Delete Shift:=x1Up
    End If
Next

就我所知,第二位只是随机开始删除行,没有押韵或理由。Q字段不包含发票的行有时保留,有时保留,如果它确实包含发票,则相同。你知道我做错了什么吗?

你应该把你的条件放在一起,这样如果任何一个原因存在,那行就会被删除。否则,由于删除预设范围内的行,最终跳过的行数将超过当前的行数。目前,每次删除一行时,似乎都会跳过一行,因此会丢失任何连续的案例。蒂姆从最后一排开始工作的建议是正确的

For i = LastRow to 3 Step -1
  If Range("C" & i) = "Result" OR Not InStr(1, Range("Q" & i), "INVOICE") Then
    Rows(i & ":" i).Delete Shift:=x1Up
  End If
Next i

实际上有两种方法:
AutoFilter
For Loop
。在这两种方法中,
AutoFilter
速度要快得多,尤其是对于大型数据集,但它通常需要非常好的设置。循环的
For
很简单,但它的回报微乎其微,尤其是当您的数据开始达到10万行或更多行时

另外,
而不是InStr(1,范围(“Q”和“i”),“INVOICE”)
似乎是最好的方法,但事实并非如此
InStr
返回一个数字,因此如果您做进一步的比较,例如
而不是InStr(1,范围(“Q”&i),“发票”)>0
或者只是
InStr(1,范围(“Q”&i),“发票”)=0
。无论如何,我在下面的第二个代码中使用了前者

以下是两种方法。它们是在简单的数据上测试的。代码可能看起来有点笨重,但逻辑是合理的。有关其他事项,请参阅评论

自动筛选方法:

Sub RemoveViaFilter()

    Dim WS As Worksheet: Set WS = ThisWorkbook.Sheets("ModifyMe")
    Dim LastRow As Long

    Application.ScreenUpdating = False
    With WS
        '--For condition "Result"
        .AutoFilterMode = False
        LastRow = .Cells(Rows.Count, 1).End(xlUp).row '--Compatible if there are more rows.
        With Range("A2:Q" & LastRow) '--Assuming your header is in Row 2 and records start at Row 3.
            .AutoFilter Field:=3, Criteria1:="Result" '--Field:=3 is Column C if data starts at A
            .Cells.Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow.Delete '--Delete the visible ones.
        End With
        '--For condition "<>*INVOICE*"
        .AutoFilterMode = False
        LastRow = .Cells(Rows.Count, 1).End(xlUp).row
        With Range("A2:Q" & LastRow)
            .AutoFilter Field:=17, Criteria1:="<>*INVOICE*" '--Field:=17 is Column Q if data starts at A
            .Cells.Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow.Delete
        End With
        .AutoFilterMode = False
    End With
    Application.ScreenUpdating = True

End Sub
Sub RemoveViaLoop()

    Dim WS As Worksheet: Set WS = ThisWorkbook.Sheets("Sheet6")
    Dim LastRow As Long: LastRow = WS.Cells(Rows.Count, 1).End(xlUp).row
    Dim Iter As Long

    Application.ScreenUpdating = False
    With WS
        For Iter = LastRow To 3 Step -1 '--Move through the rows from bottom to up by 1 step (row) at a time.
            If .Range("C" & Iter) = "Result" Or Not InStr(1, .Range("Q" & Iter).Value, "Invoice") > 0 Then
                .Rows(Iter).EntireRow.Delete
            End If
        Next Iter
    End With
    Application.ScreenUpdating = True

End Sub

让我们知道这是否有用。

不要循环。使用自动筛选:)请参阅…或者如果要循环,请从最后一行开始,然后向上操作(
For i=LastRow to 3 Step-1
),这样在删除行时就不会踩到循环索引(从而向上移动下面的行…),这很有意义,感谢您的帮助!我想我要切换到autofilter选项,因为它速度更快,而且我的数据集相当大。谢谢,我今天要用auto filter试试,因为我的数据集可能会变得很大,这是一台我不想停滞不前的后台机器。