Delete Rows in Excel Based on Criteria - excel

I'm close to figuring out the correct way to do this but I'm all searched out. I'm trying to search a column (Asset Tag) that holds various garbage but want to keep entire rows that start with AA as this confirms the row is actually an Asset Tag.
The code below gives me an "Object Required" error, and I believe I might not be correctly telling it to look at cell values with the"If rng.Cells(i) <> Left(cell.Value, 2) = "AA" Then" statement. Can someone point me in the right direction of what I need to do?
Sub DeleteRows()
Dim rng As Range
Dim i As Double, counter As Double
Set rng = Range("C:C")
i = 1
For counter = 1 To rng.Rows.count
If rng.Cells(i) <> Left(cell.Value, 2) = "AA" Then
rng.Cells(i).EntireRow.Delete
Else
i = i + 1
End If
Next
End Sub
Thanks!

If you're deleting rows then you should always work from the bottom up:
Sub DeleteRows()
Dim rng As Range
Dim counter As Long, numRows as long
With ActiveSheet
Set rng = Application.Intersect(.UsedRange, .Range("C:C"))
End With
numRows = rng.Rows.Count
For counter = numRows to 1 Step -1
If Not rng.Cells(counter) Like "AA*" Then
rng.Cells(counter).EntireRow.Delete
End If
Next
End Sub

Given your code took 5 minutes I suggest you try this AutoFilter approach. It uses a working column (the first unused column part the usedrange) to run a case sensitive text for the first two letters of column C cells being "AA". If not an autofilter deletes these rows.
Sub KillnonAA()
Dim ws As Worksheet
Dim rng1 As Range
Dim lRow As Long
Dim lCol As Long
Set ws = ActiveSheet
'in case the sheet is blank
On Error Resume Next
lRow = ws.Cells.Find("*", , xlValues, , xlByRows, xlPrevious).Row
lCol = ws.Cells.Find("*", , xlValues, , xlByColumns, xlPrevious).Column
On Error GoTo 0
If lRow = 0 Then Exit Sub
Set rng1 = ws.Range(ws.Cells(1, lCol + 1), ws.Cells(lRow, lCol + 1))
Application.ScreenUpdating = False
Rows(1).Insert
With rng1.Offset(0, 1)
.FormulaR1C1 = "=EXACT(LEFT(RC3,2),""AA"")"
.AutoFilter Field:=1, Criteria1:="FALSE"
.EntireRow.Delete
'in case all records were deleted
On Error Resume Next
.EntireColumn.Delete
On Error GoTo 0
End With
Application.ScreenUpdating = True
End Sub

Related

How to sort column2 only but separated by Space and Remove Duplicates

Thus anyone have idea on how to resolved this,
I have many Data to Sort, I want to Sort only Column 2 but separated by Space and also I want to delete duplicate values,
Is there any formula to fix this?
Please see Picture Below
I found this Answer on Google, And it Helps me to fix the Problem
Sub SortAndRemoveDuplicates()
Dim Rng As Range
Dim RngArea As Range
Dim sortRng As Range
Dim lr As Long
Dim i As Long
Dim startRow As Long
If Selection.Columns.Count > 1 Or Selection.Column <> 2 Then
MsgBox "Please select data in column B only and then try again...", vbExclamation
Exit Sub
End If
On Error Resume Next
Set Rng = Selection.SpecialCells(xlCellTypeConstants, 1)
On Error GoTo 0
If Rng Is Nothing Then Exit Sub
Application.ScreenUpdating = False
startRow = Selection.Cells(1).Row
lr = startRow + Selection.Rows.Count - 1
For Each RngArea In Rng.Areas
Set sortRng = RngArea.Resize(, 2)
sortRng.Sort key1:=sortRng.Cells(1), order1:=xlAscending, Header:=xlNo
Next RngArea
For i = lr To startRow Step -1
If Cells(i, 2) = Cells(i - 1, 2) Then
Rows(i).Delete
End If
Next i
Application.ScreenUpdating = True
End Sub

xlup is looking for text, but finding formulas that are "", how to convert to look for non-'"/blank cells?

Counter = Cells(Rows.Count, 4).End(xlUp).Row - 1
So I'm using this to look up occupied cells, but it's finding cells that have formulas that are IF's that end as "".
Can I convert this to look up visible text?
Thank you in advance
Last Row Excluding Cells Containing Formulas Evaluating to ""
Using the Find method
Here is a link to see what Microsoft states about the Find method.
Here is a link to Siddharth Rout's legendary post about using the Find method to find the last cell (row).
Note that Counter is 'pointing' one row above the Last Row.
The Code
Sub testGetLastRowInColumn()
Dim LastRow As Long
Dim Counter As Long
' Simple, for the ActiveSheet:
LastRow = getLastRowInColumn("A") ' 1 or "A", both are allowed.
Debug.Print LastRow
' Proper, for a certain sheet:
Dim wb As Workbook
Set wb = ThisWorkbook ' The workbook containing this code.
Dim ws As Worksheet
Set ws = wb.Worksheets("Sheet1")
LastRow = getLastRowInColumn("A", ws)
Debug.Print LastRow
' In your case
LastRow = getLastRowInColumn(4)
If LastRow > 0 Then
Counter = LastRow - 1
End If
Debug.Print LastRow, Counter
' In your case without the function:
LastRow = Columns(4).Find(What:="*", _
LookIn:=xlValues, _
SearchDirection:=xlPrevious).Row
If LastRow > 0 Then
Counter = LastRow - 1
End If
Debug.Print LastRow, Counter
' Or simplified:
LastRow = Columns(4).Find("*", , xlValues, , , xlPrevious).Row
If LastRow > 0 Then
Counter = LastRow - 1
End If
Debug.Print LastRow, Counter
' Or just (if you're sure that there is data in column 4):
Counter = Columns(4).Find("*", , xlValues, , , xlPrevious).Row - 1
Debug.Print LastRow, Counter
End Sub
Function getLastRowInColumn(ColumnIndex As Variant, _
Optional Sheet As Worksheet = Nothing, _
Optional includeEmpties As Boolean = False)
If Sheet Is Nothing Then
Set Sheet = ActiveSheet
End If
Dim FormVal As XlFindLookIn
If includeEmpties Then
FormVal = xlFormulas
Else
FormVal = xlValues
End If
Dim rng As Range
Set rng = Sheet.Columns(ColumnIndex).Find(What:="*", _
LookIn:=FormVal, _
SearchDirection:=xlPrevious)
If Not rng Is Nothing Then
getLastRowInColumn = rng.Row
Else
getLastRowInColumn = 0
End If
End Function

How to delete rows that contains value "Invoiced" in whole worksheet

I have a lot of Excels from different modules with different column layouts (purchase orders, Sales orders, Production orders, etc.).
I want to delete every row that contains value "Invoiced".
I was able to create simple code where only one column ("J") is checked, but I need whole worksheet to be checked.
Private Sub BoomShakalaka_Click()
Application.ScreenUpdating = False
ow = Cells(Rows.Count, "J").End(xlUp).Row
For r = ow To 1 Step -1
If Cells(r, "J") = "Invoiced" Then Rows(r).Delete
Next
Application.ScreenUpdating = True
End Sub
I expect that after I run this function, it will check the whole workbook and delete every row which contains the value "Invoiced".
I want to add here my idea of using arrays instead, so you only access the worksheet when you read the data, and then when you delete the rows.
Option Explicit
Sub deleteInvoiced()
With Application
.ScreenUpdating = False
.DisplayAlerts = False
End With
Dim wb As Workbook: Set wb = ActiveWorkbook 'or ThisWorkbook, or the name of the workbook where data is
Dim ws As Worksheet
Dim R As Long, C As Long, X As Long
Dim lRow As Long, lCol As Long
Dim arrData
For Each ws In wb.Worksheets
lRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).row 'Get the last row in the current sheet
lCol = ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column 'Get the last column in the current sheet
arrData = ws.Range(ws.Cells(1, 1), ws.Cells(lRow, lCol))
For R = UBound(arrData) To LBound(arrData) Step -1
For C = UBound(arrData, 2) To LBound(arrData, 2) Step -1
If arrData(R, C) = "Invoiced" Or arrData(R, C) = "Delivered" Then
'Now delete the rows
ws.Cells(R, C).EntireRow.Delete
Exit For 'Exit here in case multiple "Invoice" or "Delivered" in the same row (WHY?!!). Thanks #Brian.
End If
Next C
Next R
Next ws
With Application
.ScreenUpdating = True
.DisplayAlerts = True
End With
End Sub
PS: There is no error handling, but i leave that to you.
Loop through every cell within every row within activesheet.usedrange:
Private Sub BoomShakalaka_Click()
For r = ActiveSheet.UsedRange.Rows.Count To 1 Step -1
For Each c In ActiveSheet.UsedRange.Rows(r).Cells
If c.Value = "Invoiced" Then
c.EntireRow.Delete
Exit For
End If
Next c
Next r
End Sub
Alternatively, you could do it by using find. This will be faster than my other answer if there is a lot of data:
sub BoomShakalaka_Click()
screenupdating = false
On Error GoTo exitSub
ActiveSheet.UsedRange.SpecialCells(xlLastCell).select
do while true
Cells.Find(What:="Invoiced", After:=ActiveCell, LookIn:=xlFormulas, LookAt:= _
xlPart, SearchOrder:=xlByRows, SearchDirection:=xlPrevious, MatchCase:=False _
, SearchFormat:=False).Activate
Selection.EntireRow.Delete
Loop
exitSub:
screenupdating = True
Exit Sub
end sub
Here's another interesting way. It assumes your data starts in cell A1 and is contiguous.
Option Explicit
Public Sub TestDeleteInvoiced()
Dim wb As Workbook
Dim ws As Worksheet
Dim arr As Variant
Dim arr1() As Variant
Dim row As Long
Dim col As Long
Dim i As Long
Set wb = ActiveWorkbook
i = 1
ReDim arr1(1 To 14)
For Each ws In wb.Worksheets
arr = ws.Range("A1").CurrentRegion
For row = UBound(arr, 1) To LBound(arr, 1) Step -1
For col = UBound(arr, 2) To LBound(arr, 2) Step -1
If arr(row, col) = "Invoiced" Then
arr1(i) = row & ":" & row
i = i + 1
'This If statement ensures that the Join function is less than 255 characters.
If i = 15 Then
ws.Range(Join(arr1, ", ")).EntireRow.Delete
ReDim arr1(1 To 14)
i = 1
End If
Exit For
End If
Next col
Next row
ReDim Preserve arr1(1 To i - 1)
ws.Range(Join(arr1, ", ")).EntireRow.Delete
Next ws
End Sub
Note: Deleting a range of non-contiguous rows cannot exceed a 255 character parameter. Link

My code won’t delete lines of unnecessary data under the data I’m trying to keep

Sub DeleteExtraValues ()
Dim I as Integer, strValueToFind As String, lngRows As Long, she As Worksheet
Set an = ThisWorkbook.ActiveSheet
LngRows = sh.Range(“A1048576”).End(xlUp).Row
strValueToFind = “DCAP”
For I = 1 To lngRows
If InStr(Cells(I,1).Value, strValueToFind) = 0 Then
If Cells(I,1).Value = “” Then
Else
Rows(I).Delete
I = I-1
End If
End If
Next I
End Sub
When running this, it will delete the cells above the data I want to keep and then will stop once it gets to the first cell that contains “DCAP”. I need it also to delete any unnecessary information after the last cell that contains “DCAP”.
Try this code. It removes every row that doesn't contain DCAP in the first column.
Dim r As Long
Dim LastRow As Long
r = 1
LastRow = Cells.Find("*", [A1], , , xlByRows, xlPrevious).Row
Do Until r > LastRow
DoEvents
If InStr(1, Cells(r, 1), "DCAP") > 0 Then
r = r + 1
Else
Cells(r, 1).EntireRow.Delete
LastRow = LastRow - 1
End If
Loop
MsgBox
"done"
Try this...
Dim rng As Range
Set rng = ActiveSheet.Range("A1").CurrentRegion 'depending on your data you may have to change to a specific range using last row and column
' change the `Field` to the column that contains "DCAP"
With rng
.AutoFilter Field:=9, Criteria1:="<>DCAP", Operator:=xlAnd 'select all cells that are not "DCAP"
.Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow.Delete 'don't delete the header row
.AutoFilterMode = False
End With

Delete specifics rows in a sheet with more than 60000 rows

I need to delete the rows that:
- Does not have the Word "Get" into Column A, example: if A1 is Configuration Get, I should not delete; but if it is nFormat or anything else, I should delete.
- And for the rows which has the word "get" I also need to check if in Column C the value is 0, if it is not 0 I also should delete.
My function is working for sheet with a small number of rows, but the problem is, I really need to run it for a large number, let's say for 60000 rows. Could someone help me?
My function is:
Sub DeleteRows()
Dim c As Range
Dim ColumnA
Dim Lrow As Long
Dim Lastrow As Long
With Sheets("Sheet1") 'I'm using the Sheet1
.Select
Set ColumnA = ActiveSheet.UsedRange
Lastrow = .UsedRange.Rows(.UsedRange.Rows.Count).Row
For Lrow = Lastrow To 1 Step -1
Set ColumnA = Cells(Lrow, "A") 'I'm looking just in Column "A" for a Get
Set c = ColumnA.Find("Get", LookIn:=xlValues)
If Not c Is Nothing Then
' If the cell has a Get, it will look for a 0 in Column "C"
With .Cells(Lrow, "C")
If Not IsError(.Value) Then
' If the Value is not 0 the row will be delete.
If Not (.Value = 0) Then .EntireRow.Delete
End If
End With
Else
'If didn't find a "Get", it will delete the row
ColumnA.EntireRow.Delete
End If
Next Lrow
End With
End Sub
Try something like this which uses AutoFilter instead
It is the VBA equivalent of:
finding the first blank column
entering =OR(ISERROR(FIND("Get",$A1)),AND(NOT(ISERROR(FIND("Get",$A1))),$C1<>0)) in row 1 and copying down
deleting and TRUE results
cleaning up the working column
code
Sub KillEm()
Dim rng1 As Range, rng2 As Range, rng3 As Range
Set rng1 = Cells.Find("*", , xlValues, , xlByColumns, xlPrevious)
Set rng2 = Cells.Find("*", , xlValues, , xlByRows, xlPrevious)
Set rng3 = Range(Cells(rng2.Row, rng1.Column), Cells(1, rng1.Column))
Application.ScreenUpdating = False
With rng3.Offset(0, 1)
.FormulaR1C1 = "=OR(ISERROR(FIND(""Get"",RC1)),AND(NOT(ISERROR(FIND(""Get"",RC1))),RC3<>0))"
.AutoFilter Field:=1, Criteria1:="TRUE"
.Offset(1, 0).Resize(rng3.Rows.Count - 1, 1).EntireRow.Delete
.EntireColumn.Delete
End With
Application.ScreenUpdating = True
End Sub
I did like this for, in this case sheet7, and it worked:
Application.ScreenUpdating = False
With Sheet7
r = 1
Do While r <= LastRow
If IsError(.Cells(r, 1)) Then
.Rows(r).Delete
LastRow = LastRow - 1
Else
If InStr(.Cells(r, 1), "Get") = 0 Then
.Rows(r).Delete
LastRow = LastRow - 1
Else
r = r + 1
End If
End If
Loop
End With
Application.ScreenUpdating = True

Resources