Reputation: 41
I'm trying to make a button macro that deletes rows based on their true/false value in the 'b' column. the issue with deleting is once it's gone, the 'for _ do' skips the one after cause the cell in the range bellow becomes the current. I came up with this alternative but it's super laggy when done in large quantities. any suggestions. also, im trying to keep the code as simple and clean as possible, I don't like too many vars because it becomes confusing when I have to review and adjust in the future. thanx
Dim inps As Integer
Sub delline()
inps = MsgBox("Are you sure you wish to delete the selected rows?", vbYesNo, "Point Of No Return")
If inps = vbYes Then
For Each b In Range("B12", Range("B12").End(xlDown))
For Each a In Range("B12", Range("B12").End(xlDown))
If a.Value = True Then
a.EntireRow.Delete
End If
Next a
Next b
End If
End Sub
Upvotes: 0
Views: 981
Reputation: 2233
delete from last to first. for RowIndex = RowIndexMax to RowIndexMin Step -1
Sub delline() 'Using Max-Min-Rows
Const RowIndexMin As Long = 12 'first row at the top. B12 => row 12.
Const ColumnB_Index As Long = 2
Dim UserDecision As Long
Dim RowIndexMax As Long 'last row at the bottom
Dim RowIndex As Long 'changed in every loop
On Error GoTo Reset
UserDecision = MsgBox("Are you sure you wish to delete the selected rows?", vbYesNo + vbQuestion, "Point Of No Return") 'you can combine vb- enumerations ;)
If UserDecision <> vbYes Then
Exit Sub 'just my way of avoiding unnecessary nesting.
End If
'Some of speet boosting settings
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Application.EnableEvents = False
RowIndexMax = Cells(RowIndexMin, ColumnB_Index).End(xlDown).Row
For RowIndex = RowIndexMax To RowIndexMin Step -1 'Step -1 decreases the RowIndex every loop by 1
If Cells(RowIndex, ColumnB_Index).Value2 = True Then
Debug.Print "Deleting row: " & RowIndex
Rows(RowIndex).Delete
End If
Next
'True's should be gone. Falses should bubbled to the top.
Reset:
Application.EnableEvents = True
Application.Calculation = xlCalculationAutomatic 'assuming it was automatic at the beginning
Application.ScreenUpdating = True
End Sub
Upvotes: 1
Reputation: 1104
In your code you should set Application.ScreenUpdating
to False
, this makes a HUGE impact on performance, but be sure to set it back to True
when you're done!
Sub delline()
Application.ScreenUpdating = False
If (MsgBox("Are you sure you wish to delete the selected rows?", _
vbYesNo, "Point Of No Return") = vbYes) Then
For Each b In Range("B12", Range("B12").End(xlDown))
For Each a In Range("B12", Range("B12").End(xlDown))
If a.Value = True Then
a.EntireRow.Delete
End If
Next a
Next b
End If
Application.ScreenUpdating = True
End Sub
EDIT
If all you're trying to do is strictly delete the row where in Column B has a value = FALSE, you can use the below code. I've test it and it works fine. It will delete all rows UP TO (and including) B12
Sub test1()
Dim LastRow As Long
Application.ScreenUpdating = False
If (MsgBox("Are you sure you wish to delete the selected rows?", _
vbYesNo, "Point Of No Return") = vbYes) Then
With ActiveSheet
LastRow = .Cells(.Rows.Count, "B").End(xlUp).Row
For i = LastRow To 12 Step -1
If (.Cells(i, "B").Value = True) Then
.Cells(i, "B").EntireRow.Delete
End If
Next i
End With
End If
Application.ScreenUpdating = True
End Sub
EDIT 2
This is using the direct value copy method, and it's very fast compared to all the above
Sub test1()
Dim LastRow As Long
Dim LastRow2 As Long
Application.ScreenUpdating = False
With ActiveSheet
LastRow = .Cells(.Rows.Count, "B").End(xlUp).Row
For i = LastRow To 12 Step -1
If (.Range("B" & i).Value = False) Then
LastRow2 = Sheets("Sheet2").Cells(.Rows.Count, "B").End(xlUp).Row + 1
Sheets("Sheet2").Range("B" & LastRow2).Value = .Range("B" & i).Value
' .Range("B" & i).EntireRow.Delete
End If
Next i
End With
Application.ScreenUpdating = True
End Sub
Unless you need all the data from the rows, I'd suggest using this one; Or you can add the other data from those rows to the loop as well. Which still will be much faster
Upvotes: 0