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
Related
i am new in VBA and i am blocked on my VBA code. what i am trying to do : On my database, inside the colmun M:M, if each cell from column M:M who contain "B1", it copy the line from the Sheet "Database" into another sheet ("Work"), make a filter on the Sheet ("Alloc") on the word "B1" and copy filtered cells from Sheet ("Alloc") to the Sheet ("work")
Please find my code :
Dim r As Range
Dim rw As Long, Cell As Range
For Each Cell In Sheets("Database").Range("M:M")
rw = Cell.Row
If UCase(Cell.Value) Like UCase("*B1*") Then
Cell.EntireRow.Copy
Sheets("Work").Select
Range("A1048576").End(xlUp).Offset(1, 0).Select
Selection.PasteSpecial xlPasteValues
Sheets("Alloc").Select
Rows("1:1").Select
Selection.AutoFilter
ActiveSheet.Range("$A$1:$H$10000").AutoFilter Field:=1, Criteria1:= _
"B1"
Set r = Sheets("Alloc").Range("B2")
Do While r.Value <> ""
Range("N1048576").End(xlUp).Offset(1, 0).Value = r.Value
Set r = r.Offset(1)
Loop
Set r = Sheets("Alloc").Range("C2")
Do While r.Value <> ""
Range("O1048576").End(xlUp).Offset(1, 0).Value = r.Value
Set r = r.Offset(1)
Loop
Set r = Sheets("Alloc").Range("D2")
Do While r.Value <> ""
Range("P1048576").End(xlUp).Offset(1, 0).Value = r.Value
Set r = r.Offset(1)
Loop
Set r = Sheets("Alloc").Range("E2")
Do While r.Value <> ""
Range("Q1048576").End(xlUp).Offset(1, 0).Value = r.Value
Set r = r.Offset(1)
Loop
Sheets("Alloc").Select
Rows("1:1").Select
Selection.AutoFilter
End If
Next
My code is working, the only issue it's copy also data in sheet ("alloc") who are also fileted
do you know how i can take only the filtered data from the sheet ("Alloc") into the sheet("work") ?
Thanks a lot for your help
The following is based on your description of the problem - rather than on your code. Please try the following & let me know how it goes. Assumes both the Database and Alloc sheets have headings in row 1 starting in A1 and contiguous data.
Option Explicit
Sub CopyData()
Dim ws1 As Worksheet: Set ws1 = Sheets("Database")
Dim ws2 As Worksheet: Set ws2 = Sheets("Alloc")
Dim ws3 As Worksheet: Set ws3 = Sheets("work")
Dim PasteRow As Long
PasteRow = ws3.Cells(Rows.Count, 1).End(xlUp).Row + 1
With ws1.Cells(1, 1).CurrentRegion
.AutoFilter 13, "*B1*", 7
.Offset(1).Resize(.Rows.Count - 1).Copy ws3.Cells(PasteRow, 1)
.AutoFilter
End With
PasteRow = ws3.Cells(Rows.Count, 1).End(xlUp).Row + 1
With ws2.Cells(1, 1).CurrentRegion
.AutoFilter 1, "B1", 7
.Offset(1).Resize(.Rows.Count - 1).Copy ws3.Cells(PasteRow, 1)
.AutoFilter
End With
End Sub
I am trying to compare two columns (A and B) for duplicates. As an output I am trying to get cells that does not match (not duplicates). Column A values are coming from table 1 and Column B values are coming from table 2. Code target is basically to get to know which items were deleted from table 2 (Column B).
Data looks like:
A B
BMW PORSCHE
FIAT VOLVO
VOLVO AUDI
PORSCHE FERRARI
FERRARI TOYOTA
TOYOTA
AUDI
Output should be:
A B
BMW
FIAT
This is working for highlighting duplicates, but how to get values deleted that are duplicates? For example using .ClearContents. Then after that I have loop for deleting empty rows in range.
Sub MarkDuplicatesInCompare()
Dim ws As Worksheet
Dim cell As Range
Dim myrng As Range
Dim clr As Long
Dim lastCell As Range
Dim EntireRow As Range
Set ws = ThisWorkbook.Sheets("Compare")
Set myrng = ws.Range(ws.Cells(2, 1), ws.Cells(ws.Rows.Count, "B").End(xlUp))
With myrng
Set lastCell = .Cells(.Cells.Count)
End With
myrng.Interior.ColorIndex = xlNone
clr = 3
For Each cell In myrng
If Application.WorksheetFunction.CountIf(myrng, cell) > 1 Then
If myrng.Find(what:=cell, lookat:=xlWhole, MatchCase:=False, after:=lastCell).Address = cell.Address Then
cell.Interior.ColorIndex = clr
clr = clr
Else
cell.Interior.ColorIndex = myrng.Find(what:=cell, lookat:=xlWhole, MatchCase:=False, after:=lastCell).Interior.ColorIndex
End If
End If
Next
' Delete empty rows
For I = myrng.Rows.Count To 1 Step -1
Set EntireRow = myrng.Cells(I, 1).EntireRow
If Application.WorksheetFunction.CountA(EntireRow) = 0 Then
EntireRow.Delete
End If
Next
End Sub
Give this a try:
Sub Keanup()
Dim i As Long, j As Long, Na As Long, Nb As Long
Na = Cells(Rows.Count, "A").End(xlUp).Row
Nb = Cells(Rows.Count, "B").End(xlUp).Row
For i = Na To 1 Step -1
v = Cells(i, "A").Value
For j = Nb To 1 Step -1
If v = Cells(j, "B").Value Then
Cells(i, "A").Delete shift:=xlUp
Cells(j, "B").Delete shift:=xlUp
Exit For
End If
Next j
Next i
End Sub
Note we run the loops bottom up.
you could use AutoFilter()
With Range("A1", Cells(Rows.Count, 1).End(xlUp))
.Rows(1).EntireRow.Insert ' insert temporary row for dummy headers
With .Offset(-1).Resize(.Rows.Count + 1)
.Range("A1:B1").Value = Array("h1", "h2") ' write dummy headers
.AutoFilter field:=1, Criteria1:=Application.Transpose(Range("B1", Cells(Rows.Count, 2).End(xlUp)).Value), Operator:=xlFilterValues
.Offset(1).Resize(.Rows.Count - 1).SpecialCells(xlCellTypeVisible).ClearContents
.Parent.AutoFilterMode = False
.Rows(1).EntireRow.Delete ' remove dummy headers temporary row
End With
End With
Range("B1", Cells(Rows.Count, 2).End(xlUp)).ClearContents ' clear column B values
or with Find()
Dim cel As Range
With Range("B1", Cells(Rows.Count, 2).End(xlUp))
For Each cel In Range("A1", Cells(Rows.Count, 1).End(xlUp))
If Not .Find(what:=cel.Value, LookIn:=xlValues, lookat:=xlWhole) Is Nothing Then cel.ClearContents
Next
.ClearContents
End With
which, should keeping "surivors" at the top be an issue, becomes:
Dim cel As Range, s As String
With Range("B1", Cells(Rows.Count, 2).End(xlUp))
For Each cel In Range("A1", Cells(Rows.Count, 1).End(xlUp))
If Not .Find(what:=cel.Value, LookIn:=xlValues, lookat:=xlWhole) Is Nothing Then s = s & cel.Address(False, False) & " "
Next
.ClearContents
End With
If s <> vbNullString Then Range(Replace(Trim(s), " ", ",")).Delete xlUp
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
I am currently building a macro to format a sheet of data as well as to remove inapplicable rows of data. Specifically, I am looking to delete rows where Column L = "ABC" as well as delete rows where Column AA <> "DEF".
So far I have been able to achieve the first objective, but not the second. The existing code is:
Dim LastRow As Integer
Dim x, y, z As Integer
Dim StartRow, StopRow As Integer
For x = 0 To LastRow
If (Range("L1").Offset(x, 0) = "ABC") Then
Range("L1").Offset(x, 0).EntireRow.Delete
x = x - 1
End If
It is normally much quicker to use AutoFilter rather than loop Ranges
The code below creates a working column, then use a formula to detect delete criteria and then autofilter and delete the result records
The working column puts a formula
=OR(L1="ABC",AA1<>"DEF")
into row 1 of the first blank column then copies down as far ar the true used range. Then any TRUE records are quicklly deleted with AutoFilter
Sub QuickKill()
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
Rows(1).Insert
With rng3.Offset(-1, 1).Resize(rng3.Rows.Count + 1, 1)
.FormulaR1C1 = "=OR(RC12=""ABC"",RC27<>""DEF"")"
.AutoFilter Field:=1, Criteria1:="TRUE"
.EntireRow.Delete
On Error Resume Next
'in case all rows have been deleted
.EntireColumn.Delete
On Error GoTo 0
End With
Application.ScreenUpdating = True
End Sub
Using a loop:
Sub test()
Dim x As Long, lastrow As Long
lastrow = Cells(Rows.Count, 1).End(xlUp).Row
For x = lastrow To 1 Step -1
If Cells(x, 12).Value = "ABC" or Cells(x, 27) <> "DEF" Then
Rows(x).Delete
End If
Next x
End Sub
Using autofilter (probably faster):
Sub test2()
Range("a1").AutoFilter Field:=12, Criteria1:="ABC", Operator:=xlOr, _
Field:=28, Criteria1:="<>""DEF"""
'exclude 1st row (titles)
With Intersect(Range("a1").CurrentRegion, _
Range("2:60000")).SpecialCells(xlCellTypeVisible)
.Rows.Delete
End With
ActiveSheet.ShowAllData
End Sub
Cell with number 12 is "L" and number 27 is "AA"
Dim x As Integer
x = 1
Do While x <= ActiveSheet.Cells.SpecialCells(xlCellTypeLastCell).Row
If (Cells(x, 12) = "ABC") Then
ActiveSheet.Rows(x).Delete
Else
If (Cells(x, 27) <> "DEF") And (Cells(x, 27) <> "") Then
ActiveSheet.Rows(x).Delete
Else
x = x + 1
End If
End If
Loop
End Sub
Sub test()
Dim bUnion As Boolean
Dim i As Long, lastrow As Long
Dim r1 As Range
Dim v1 As Variant
lastrow = Cells(Rows.Count, 1).End(xlUp).Row
v1 = ActiveSheet.Range(Cells(1, 12), Cells(lastrow, 27)).Value2
bUnion = False
For i = 1 To lastrow
If v1(i, 1) = "ABC" Or v1(i, 16) <> "DEF" Then
If bUnion Then
Set r1 = Union(r1, Cells(i, 1))
Else
Set r1 = Cells(i, 1)
bUnion = True
End If
End If
Next i
r1.EntireRow.Delete
End Sub
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