简体   繁体   中英

How do I write a loop in VBA that will delete a row if a cell in a range and the cell next to it both equal a constant?

[This is in Excel 2007]

In other words, the loop will cycle through all the active cells in a one-column range (rngAddressName) and, if the cell in the range AND the cell directly to the left of it contain the string "#N/A", then it will delete that row.

Unfortunately, nothing I have tried has had any actual effect. Here is my best go at it:

i = 1
For counter = 1 To rngSC2A.Rows.Count
Contents = rngSC2A.Cells(i).Value
If Contents = "#N/A" Then
If rngAddressName.Cells(i).CellOffset(0, -1).Value = "#N/A" Then
rngAddressName.Cells(i).EntireRow.Delete
Else
End If
Else
i = i + 1
End If
Next

But this doesn't seem to find any rows with the conditions satisfied (even though such rows exist in the worksheet). I think it might have something to do with the fact that I am looking in the Cell.Value, but I am not sure.

You can autofilter your range, delete any rows that meet your criteria, then turn the autofilter off. This is a much more efficient approach than looping.

The example below works on columns A and B in Sheet1. Modify the variables to reference the range and sheet in your workbook.

Sub DeleteDoubleNA()
    Dim ws As Worksheet
    Dim rng As Range
    Dim lastRow As Long

    Set ws = ThisWorkbook.Sheets("Sheet1")

    lastRow = ws.Range("A" & ws.Rows.Count).End(xlUp).Row

    Set rng = ws.Range("A1:B" & lastRow)

    ' filter and delete all but header row
    With rng
        .AutoFilter field:=1, Criteria1:="#N/A"
        .AutoFilter field:=2, Criteria1:="#N/A"
        .Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow.Delete
    End With

    ' turn off the filters
    ws.AutoFilterMode = False
End Sub

This is a different take on on the excellent answer posted by @Jon Crowell.

If you use an Excel table, you can use the table's ListObject to get the data range which automatically excludes the header and footer rows.

This avoids the sometimes incorrect calculation search for a last row.

You also want to clear any pre-existing filters on the data so that you don't overlook any rows.

Dim myTable As Object
Set myTable = ActiveSheet.ListObjects(1) ' Works if worksheet contains only one table

' Clear pre-existing filters on the table
myTable.AutoFilter.ShowAllData

' Filter the table
With myTable.DataBodyRange
    .AutoFilter field:=1, Criteria1:="#N/A"
    .AutoFilter field:=2, Criteria1:="#N/A"
End With

' Delete visible cells in the filtered table
myTable.DataBodyRange.SpecialCells(xlCellTypeVisible).EntireRow.Delete

' Clear filters on the table
myTable.AutoFilter.ShowAllData

The (1) in ListObjects(1) is the first (in my case only) table in the worksheet. DataBodyRange refers to the data range of that table excluding header and footer rows.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM