Delete all rows except the ones with a specific value - excel

How, based on column values can I keep certain rows and delete the rest? Is it possible to delete everything except the value I want to keep?
Right now I repeat the values I want to delete, but this is not the best solution. Do you think it is possible to delete everything except the value I want to keep?
I would really appreciate your help. I am a beginner.
With ActiveSheet
FirstRow = 4
LastRow = 10000
For Row = LastRow To FirstRow Step -1
If .Range("A" & Row).Value = "ITT1" Then
.Range("A" & Row).EntireRow.Delete
End If
Next Row
End With

You need to negate your If statement using <> or Not:
Just use
If .Range("A" & Row).Value <> "ITT1" Then
or
If Not .Range("A" & Row).Value = "ITT1" Then
to delete all rows except the ones with ITT1 as value in column A.
Note that instead of hard coding the last row LastRow = 10000 you can determine it using something like:
LastRow = .Cells(.Rows.Count, "A").End(xlUp).Row ' get last used row in column A
So if you only have 100 rows the loop does not start at 10000 but just loops over the rows that actually have data.
So It should look something like:
With ActiveSheet
Const FirstRow As Long = 4
Dim LastRow As Long
LastRow = .Cells(.Rows.Count, "A").End(xlUp).Row ' get last used row in column A
Dim Row As Long
For Row = LastRow To FirstRow Step - 1
If Not .Range("A" & Row).Value = "ITT1" Then
.Range("A" & Row).EntireRow.Delete
End If
Next Row
End With
If it has to delete a lot of rows this might get a bit slow. So I recommend to collect the rows to delete in a variable using Union and delete them all at once in the end, which is much faster:
With ActiveSheet
Const FirstRow As Long = 4
Dim LastRow As Long
LastRow = .Cells(.Rows.Count, "A").End(xlUp).Row ' get last used row in column A
Dim RowsToDelete As Range ' here we collect which rows to delete
Dim Row As Long
For Row = LastRow To FirstRow Step - 1
If Not .Range("A" & Row).Value = "ITT1" Then
If RowsToDelete Is Nothing Then
' set first row
Set RowsToDelete = .Range("A" & Row).EntireRow
Else
' add all the other rows
Set RowsToDelete = Application.Union(RowsToDelete, .Range("A" & Row).EntireRow)
End If
End If
Next Row
If Not RowsToDelete Is Nothing Then
RowsToDelete.Delete
Else
MsgBox "No rows to delete were found."
End If
End With
If you collect all rows to delete in a variable first you even don't need to run the loop backwards Step - 1 and just use a normal forward loop if you like:
For Row = FirstRow To LastRow

Related

Using a cell in a loop to define a range in vba. I want to basically delete the row of that cell and the next 3 ones

I'm basically writing a clean up program to make it more straight forward to access data. Anywho, I ran into possibly a nomenclature error. I want to use the "current" cell in a "for" loop to delete that row and the next 3 rows. Code looks something like this:
For Each SingleCell In SingleSheet1.Range("a1:a40")
If SingleCell.Value = "S" Or SingleCell.Value = "B" Then
Range(SingleCell.Range, SingleCell.Range.Offset(4, 0)).EntireRow.Delete Shift:=xlUp
Else
End If
Next
I tried to define the range to delete as specified in the code but it gave me a runtime error
Delete backwards looping trough row number:
Sub EXAMPLE_1()
Dim i As Long
For i = 40 To 1 Step 1
If Range("A" & i).Value = "S" Or Range("A" & i).Value = "B" Then Range("A" & i & ":A" & i + 3).EntireRow.Delete Shift:=xlUp
Next i
End Sub
Sub EXAMPLE_2()
Dim i As Long
Dim LR As Long 'in case last row is not always number 40, adapt it dinamically
LR = Range("A" & Rows.Count).End(xlUp).Row
For i = LR To 1 Step 1
If Range("A" & i).Value = "S" Or Range("A" & i).Value = "B" Then Range("A" & i & ":A" & i + 3).EntireRow.Delete Shift:=xlUp
Next i
End Sub
Your code looses the reference for the deleted rows and you should iterate backwards, if you like iteration between cells (which is slow), but a better/faster solution will be to build a Union range and delete all rows at the code end, at once:
Sub testDeleteOffset()
Dim sh As Worksheet, Urng As Range, i As Long
Set sh = ActiveSheet
For i = 1 To 40
If sh.Range("A" & i).Value = "S" Or sh.Range("A" & i).Value = "B" Then
addToRange Urng, sh.Range("A" & i, "A" & i + 3)
i = i + 4
End If
Next i
If Not Urng Is Nothing Then Urng.EntireRow.Delete xlUp
End Sub
If the involved range is huge, a better solution will be to place some markers for the necessary rows (after last existing column), sort on that marker column and delete the (consecutive marked) rows. Another column with the initial order would be necessary to re-sort according to it at the end... The idea is that building a Union range having more than 1000 areas may become slow.

Insert empty rows in between fields or move entries

I have a list of items in column A (starting from A12) I want to know the best way to do this. I want there to be a 7 row gap between all the entries. These entries will have additions so some code that perhaps says if text here then add 7 rows below until no more. Or is there a way to code it so it just pushes the entries into different fields (7+ down). What would the code look like?
Basic adding row is:
Range("A13").EntireRow.Insert
So, along with #Plutian and his code to insert new rows, I edited this to filldown the new rows with data from each cell that is not blank. Hope this helps.
Sub numberf()
Application.ScreenUpdating = False
Dim lastrow As Integer
lastrow = Sheets("Sheet1").Range("A" & Rows.Count).End(xlUp).Row
Do While lastrow > 12
Range("A" & lastrow).EntireRow.Resize(7).Insert
lastrow = lastrow - 1
Debug.Print lastrow
Loop
lastrow = Sheets("Sheet1").Range("A" & Rows.Count).End(xlUp).Row
Dim i As Long
i = 1
For i = 12 To lastrow Step 8
If Cells(i, 1).Value <> "" Then
Range("A" & i).Resize(8).EntireRow.FillDown
End If
Next i
Application.ScreenUpdating = True
End Sub
Sub numberf()
Application.ScreenUpdating = False
Dim lastrow As Integer
lastrow = Sheets("Sheet1").Range("A" & Rows.Count).End(xlUp).Row
Do While lastrow > 2
Range("A" & lastrow).EntireRow.Resize(7).Insert
lastrow = lastrow - 1
Loop
Application.ScreenUpdating = True
End Sub
As I suggested, a reverse loop that does the trick. Props to #MilesFett with the resize option, as my first idea was to loop 7 times inserting a row. This is much cleaner.

How to delete the rows based in excel sheet using column values

I have excel with 5 different sheets.
sheet3 and sheet4 i want delete rows based on the single column cell value.
in sheet 3 i want to delete rows based on H column cell values if H2="#N/A" and H503="#N/A" then delete entire rows.
in sheet 4 i want to delete rows based on b column cell values if B2="320857876",B3="32085678",B4="12133435" the delete the entire rows where B column cell values starts with 302.
and i want to delete all Data from 'C' column
My excel sheet is like this
Using excel file
Sub Create()
Dim LastRow As Long
Dim i As Long
LastRow = Range("B10000").End(xlUp).Row
For i = LastRow To 1 Step -1
If Range("B" & i) = "#N/A" Then
Range("B" & i).EntireRow.Delete
End If
Next
End Sub
You've got a few requirements there and your code is fairly light but regarding the #N/A part of it, you can't just test for that text using the value approach, which is the default property returned for a range object.
Sub Create()
Dim LastRow As Long, i As Long
LastRow = Range("B10000").End(xlUp).Row
For i = LastRow To 1 Step -1
If Range("B" & i).Text = "#N/A" Then
Range("B" & i).EntireRow.Delete
End If
Next
End Sub
... you need to use .Text to get that to work, or, If IsError(Range("B" & i)) Then is another approach.
The rest of your requirements is just logic. The rest of your code is relatively sound so you just need to work through it.
I hope that helps.
Sub delete_rows()
Dim sheet As Worksheet, cell As Range
Count = 1
For Each sheet In ThisWorkbook.Worksheets
If Count = 3 Then
lastrow = sheet.Cells(sheet.Rows.Count, "H").End(xlUp).Row
Set Rng = sheet.Range("H1:H" & lastrow)
For i = Rng.Cells.Count To 1 Step -1
If Application.WorksheetFunction.IsNA(Rng(i).Value) Then
Rng(i).EntireRow.Delete
ElseIf Rng(i).Value = "#NA" Then
Rng(i).EntireRow.Delete
End If
Next
ElseIf Count = 4 Then
lastrow = sheet.Cells(sheet.Rows.Count, "B").End(xlUp).Row
Set Rng = sheet.Range("B1:B" & lastrow)
Debug.Print (Rng(4).Text)
If Rng(2).Value = "320857876" And Rng(3).Value = "32085678" And Rng(4).Value = "12133435" Then
For i = Rng.Cells.Count To 1 Step -1
If Left(Rng(i).Value, 3) = "302" Then
Rng(i).EntireRow.Delete
End If
Next
End If
lastrow = sheet.Cells(sheet.Rows.Count, "C").End(xlUp).Row
Set Rng = sheet.Range("C1:C" & lastrow)
For Each cell In Rng
cell.Value = ""
Next cell
End If
Count = Count + 1
Next
End Sub

Deleting Duplicates while ignoring blank cells in VBA

I have some code in VBA that is attempting to delete duplicate transaction IDs. However, i'd like to ammend the code to only delete duplicates that have a transaction ID - so, if there is no transaction ID, i'd like that row to be left alone. Here is my code below:
With MySheet
newLastRow = .Range("A" & .Rows.Count).End(xlUp).Row
newLastCol = .Cells(5 & .Columns.Count).End(xlToLeft).Column
Set Newrange = .Range(.Cells(5, 1), .Cells(newLastRow, newLastCol))
Newrange.RemoveDuplicates Columns:=32, Header:= _
xlYes
End With
I was also wondering - in the remove.duplicates command - is there a way where I can have the column I want looked at to be named rather than have it be 32 in case I add or remove columns at a later date?
Here is an image of the data: I'd like the ExchTransID column that have those 3 blank spaces to be left alone.
Modify and try the below:
Option Explicit
Sub test()
Dim Lastrow As Long, Times As Long, i As Long
Dim rng As Range
Dim str As String
'Indicate the sheet your want to work with
With ThisWorkbook.Worksheets("Sheet1")
'Find the last row with IDs
Lastrow = .Cells(.Rows.Count, "A").End(xlUp).Row
'Set the range with all IDS
Set rng = .Range("A1:A" & Lastrow)
'Loop column from buttom to top
For i = Lastrow To 1 Step -1
str = .Range("A" & i).Value
If str <> "" Then
Times = Application.WorksheetFunction.CountIf(rng, str)
If Times > 1 Then
.Rows(i).EntireRow.Delete
End If
End If
Next i
End With
End Sub

How to fill in from dynamic last row in one column to the last row in adjacent column?

I have been trying some time now with the following problem: First code (not listed here) drops data in sheet EDD in column B (B45 to be precise), then each cell in col A is populated with number 1 (from A45 to the bottom of column B) - as the code below shows.
Now the problem is that I will be adding another set of data in column B (to the bottom of what has already been added) but this time this new data will have number 2 in each cell of the column A (ps. I cannot overwrite number 1's that I have already entered) - the issue is that the data is dynamic. I do not know how to identify the last row in column A (populated it with value = 2 and autofill it to the bottom of this new data in column B).
Dim EDDx As Worksheet
Dim lastrow As Long
Set EDDx = Sheets("EDD")
lastrow = EDDx.Cells(Rows.Count, "C").End(xlUp).Row
With EDDx
.Range("B45:B" & lastrow).Value = 1
End With
End Sub
Thanks
Try,
with workSheets("EDD")
.range(.cells(.rows.count, "B").end(xlup), _
.cells(.rows.count, "C").end(xlup).offset(0, -1)).filldown
end with
Try:
Option Explicit
Sub Test()
Dim LastrowC As Long
Dim LastrowB As Long
With wsTest
LastrowB = .Range("B" & Rows.Count).End(xlUp).Row
LastrowC = .Range("C" & Rows.Count).End(xlUp).Row
.Range("B" & Lastrow + 1 & ":C" & LastrowC).Value = "2"
End With
End Sub

Resources