Deleting All Rows That Have an Empty "B" Column Using VBA - vba

I'm looking to create a macro that deletes all rows that don't contain any data in Column B. Any help would be appreciated. This is all I got for now.
Sub DeleteAllEmptyBRows()
Dim lr As Long
lr = Cells(Rows.Count, "B").End(xlUp).Row
For Each cell In Range("B1:B" & lr)
If cell.Value = "" Then
cell.Row.Delete
Exit Sub
End If
Next cell
End Sub

You can use SpecialCells to do this in one quick line:
Range("B:B").SpecialCells(xlCellTypeBlanks).EntireRow.Delete
I'd use the above, but also for your own knowledge, here's how you could do it following your code:
Sub DeleteAllEmptyBRows()
Dim lr As Long, i&
lr = Cells(Rows.Count, "B").End(xlUp).Row
For i = lr To 1 Step -1 'Since you're deleting rows, start at the end, and work upwards
If Cells(i, 2).Value = "" Then
Cells(i, 2).EntireRow.Delete
End If
Next i
End Sub
Note that you have an Exit Sub in yours, after the first time a row is deleted. I removed that, since you want to loop through all cells in the range. Again, this is a loop so will take longer, and has more room for errors, than the simple one liner above.

You are missing some parameters:
Cells(cell.Row, 2).Delete Shift:=xlUp
If you need the entire row, just change to:
cell.Row.EntireRow.Delete

Related

Excel VBA Delete Row based on column value

I wanted to write a Excel Macro that goes though K1--->K(lastrow) and looks for the value "OptedOut", and if it finds that value then it deletes that row. I appreciate the help guys. The only part that is wrong is the For Each C part, because I don't understand arrays, and possibly "c.Value = "OptedOut" Then Rows(c).Delete" kinda pulled that out of my ass.
Thanks all!
Sub DuplicateDelete()
Sheets("ALL CLIENTS").Range("A1:J10000").Copy Destination:=Sheets("ClientsAndEmailsThatAreOK").Range("A1:J10000")
With ActiveSheet
LastRow = .Cells(.Rows.Count, "K").End(xlUp).Row
MsgBox LastRow
End With
'Dim c As Range
For Each c In Range(Range(Cells("K1"), Cells(LastRow, "K")))
If c.Value = "OptedOut" Then Rows(c).Delete
Next c
End Sub
Loop backwards when deleting rows (or other objects).
Also, instead of using ActiveSheet try to fully qualify your Worksheet object, such as Sheets("ClientsAndEmailsThatAreOK").
Try the code below, explanation inside the code's comments:
Option Explicit
Sub DuplicateDelete()
Dim C As Range
Dim i As Long, LastRow As Long
Sheets("ALL CLIENTS").Range("A1:J10000").Copy Destination:=Sheets("ClientsAndEmailsThatAreOK").Range("A1:J10000")
' I'm assuming you want to work with sheet "ClientsAndEmailsThatAreOK" (if not then switch it)
With Sheets("ClientsAndEmailsThatAreOK")
LastRow = .Cells(.Rows.Count, "K").End(xlUp).Row
MsgBox LastRow
' always loop backwards when deleting rows
For i = LastRow To 1 Step -1
If .Range("K" & i).Value2 = "OptedOut" Then .Rows(i).Delete
Next i
End With
End Sub

VBA Function - Argument Not Optional (Separating Blocks of Text)

Sub Macro6()
Dim rngW As Range
Dim cell As Range
Set rngW = Range("W1", Range("W65536").End(xlUp))
For Each cell In rngW
If cell.Value = "Y" Then
Rows.Select
Range.Activate
Selection.Insert Shift:=xlDown
End Sub
I want to put add a blank row above each "Y" in column W that I find in my entire excel sheet. This will help me separate chunks of data. I keep getting "Compile Error: Argument not Optional". What gives?
As Scott Craner points out you are missing closing statements for If and Next.
Also, when inserting or deleting rows, you will need to loop backwards through the row set.
See code below:
Sub Macro6()
Dim lRow as Long
lRow = Range("W" & Rows.Count).End(xlUp).Row
Dim i as Long
For i = lRow to 1 Step -1
if Range("W" & i).Value = "Y" Then Range("W" & i).EntireRow.Insert Shift:=xlDown
Next
End Sub

VBA - Delete Adjacent row in For loop

I have two problems:
1)
I am running a for loop in vba that will search rows for a specific condition. If that condition is met, it will copy the value of a cell from the row above (using the offset function) and paste it in the cell below.
Then I want it to delete the entire row above. I am having trouble combining the offset function with
entirerow.delete
The error i get is just "Syntax error"
Here is the code:
Sub rowdelete()
maxrow = ActiveSheet.UsedRange.Rows.Count
For Each rcell In Range("A2:A" & maxrow)
If rcell.Value = "--" Then
rcell.offset(-1,).EntireRow.Delete
End If
Next rcell
End Sub
2) In playing around with syntax to troubleshoot, i tried just running
rcell.entirerow.delete
this worked, but I realized if there are two adjacent rows which should be both deleted, only the first will be deleted. I presume this is because the second row becomes the first row after deletion and is skipped as an iteration in the loop.
Are there easy ways to get around this? It is important that the rows preserve the sort order they are in before the loop starts.
Thanks!
Use a standard for loop that loops backwards.
Sub rowdelete()
dim maxrow as long
dim i as long
maxrow = ActiveSheet.UsedRange.Rows.Count
For i = maxrow To 2 Step -1
If Cells(i, 1).Value = "--" Then
Rows(i - 1).Delete
End If
Next i
End Sub
another method is to put all the rows into one range and delete it once:
Sub rowdelete()
Dim maxrow As Long
Dim i As Long
Dim rng As Range
maxrow = ActiveSheet.UsedRange.Rows.Count
For i = maxrow To 2 Step -1
If Cells(i, 1).Value = "--" Then
Set rng = Union(rng, Rows(i - 1))
End If
Next i
rng.Delete xlShiftUp
End Sub

VBA get rid of full row if one specific column repeats a word in next row

I am trying to write a vba code to get rid of a row if any word is immediately repeated in same column (column E) but in other row. If that happens, the row to be deleted is the one more on top. Follow an example below. In this case, the row to be dropped are: E6, E10 and E15.
Name of the sheet is test. Columns and F and G are not relevant.
Thanks a lot!
Edit to add code from comments:
Sub delete_duplicates_column_E()
With Sheets("test").Range("A:E")
.Value = .Value
.RemoveDuplicates Columns:=5, Header:=xlYes
End With
End Sub
Just whipped this up, try it:
Sub removeDuplicates()
Range("E2").Select
Do Until ActiveCell.Value = ""
If ActiveCell.Value = ActiveCell.Offset(1).Value Then
ActiveCell.EntireRow.Delete (xlShiftUp)
End If
ActiveCell.Offset(1).Select
Loop
End Sub
When deleting rows it is better to loop back wards:
Sub delete_duplicates_column_E()
Dim ws As Worksheet
Dim lastrow As Long
Dim i As Long
Set ws = Sheets("test")
With ws
lastrow = .Range("E" & .Rows.Count).End(xlUp).Row
For i = lastrow To 2 Step -1
If .Cells(i, 5) = .Cells(i + 1, 5) Then
.Rows(i).Delete
End If
Next i
End With
End Sub

Macro - delete rows based on date

I am very new to VBA and macros in Excel. I have a very large excel spreadsheet in which column A holds dates. I am trying to delete the rows which have a value smaller than a certain date and this is what I have come up with till now..
Sub DELETEDATE()
Dim x As Long
For x = 1 To Cells.SpecialCells(xlCellTypeLastCell).Row
Debug.Print Cells(x, "A").Value
If CDate(Cells(x, "A")) < CDate("01/01/2013") Then
Cells(i, "A").EntireRow.Delete
End If
Next x
Next i
End Sub
I am receiving a Next without For error... can somebody help please?
This lends itself well to using the .AutoFilter property of a Range. The script below contains a comment for each step taken:
Option Explicit
Sub DeleteDateWithAutoFilter()
Dim MySheet As Worksheet, MyRange As Range
Dim LastRow As Long, LastCol As Long
'turn off alerts
Application.DisplayAlerts = False
'set references up-front
Set MySheet = ThisWorkbook.Worksheets("Sheet1")
'identify the last row in column A and the last col in row 1
'then assign a range to contain the full data "block"
With MySheet
LastRow = .Range("A" & .Rows.Count).End(xlUp).Row
LastCol = .Range("A" & .Columns.Count).End(xlToLeft).Column
Set MyRange = .Range(.Cells(1, 1), .Cells(LastRow, LastCol))
End With
'apply autofilter to the range showing only dates
'older than january 1st, 2013, then deleting
'all the visible rows except the header
With MyRange
.AutoFilter Field:=1, Criteria1:="<1/1/2013"
.SpecialCells(xlCellTypeVisible).Offset(1, 0).Resize(.Rows.Count).Rows.Delete
End With
'turn off autofilter safely
With MySheet
.AutoFilterMode = False
If .FilterMode = True Then
.ShowAllData
End If
End With
'turn alerts back on
Application.DisplayAlerts = True
End Sub
Running this code on a simple example (on "Sheet1" in this picture) that looks like this:
Will delete all rows with a date older than 1/1/2013, giving you this result:
To answer your question
I am receiving a Next without For error
The problem is you are trying to loop on i but you haven't opened a For i loop. When you indent the code below any code that invokes a Loop or condition (i.e. If) it becomes obvious
Sub DELETEDATE()
Dim x As Long
For x = 1 To Cells.SpecialCells(xlCellTypeLastCell).Row
Debug.Print Cells(x, "A").Value
If CDate(Cells(x, "A")) < CDate("01/01/2013") Then
Cells(i, "A").EntireRow.Delete 'i has no value so Cells(0, "A") is ??
End If
Next x
Next i 'where is the For i = ... in this code?
End Sub
When writing code I try to:
Enter the end command immediately if it's needed. So type If...Then, hit [ENTER], type End If, hit [HOME], hit [ENTER], hit [UP ARROW] then [TAB] to the right place to write the conditional code so that anyone will be able to read and understand it easily.
Always use Option Explicit at the top of every module to force variable declarations.
a tip about deleting rows based on a condition
If you start at the top and work down, every time you delete a row your counter will effectively move to the cell two rows below the row you deleted because the row immediately below the deleted row moves up (i.e. it is not tested at all).
The most efficient way is to loop up from the bottom or your rows:
Sub DELETEDATE()
Dim x As Long
For x = [a1].SpecialCells(xlCellTypeLastCell).Row To 1 Step -1
Debug.Print Cells(x, "A").Value
If CDate(Cells(x, "A")) < CDate("01/01/2013") Then
Cells(x, "A").EntireRow.Delete 'changed i to x
End If
Next x
End Sub
This way, the next row you want to test has been preserved - you've only moved the row below up by 1 and you've tested that row earlier.
Please try with this
Sub DELETEDATE()
Dim x As Long
last = Range("A65536").End(xlUp).Row
For x = 1 To last
Debug.Print Cells(x, "A").Value
check:
If x <= last Then
If Trim(CDate(Cells(x, "A"))) <= Trim(CDate("7/29/2013")) Then
last = last - 1
Cells(x, "A").EntireRow.Delete
GoTo check
End If
End If
Next x
End Sub
You have an additional Next i for some reason in your code as highlighted by the debugger. Try the below:
Sub DELETEDATE()
Dim x As Long
For x = 1 To Cells.SpecialCells(xlCellTypeLastCell).Row
Debug.Print Cells(x, "A").Value
If CDate(Cells(x, "A")) < CDate("01/01/2013") Then
Cells(i, "A").EntireRow.Delete
End If
Next x
End Sub