Trying to delete a row if no data in row A:J - excel

I am trying to delete a row if there is no data from A:J
I have found this code and been trying to edit it, but this is deleting the whole sheet's data eventually.
Any help would be greatly appreciated
Sub DeleteRows()
Dim rngBlanks As Range
Dim i As Integer
For i = 1 To 10
On Error Resume Next
Set rngBlanks = Columns(i).SpecialCells(xlCellTypeBlanks)
On Error GoTo 0
If Not rngBlanks Is Nothing Then
rngBlanks.EntireRow.Delete
End If
Next
End Sub

Trying to delete a row if no data in row A:J
What code is doing is individually checking the columns and not the range A:J as your title suggests. It is very much possible that your entire data is getting deleted because of this. Lets say A1 has some data but B1 doesn't. So your code will delete Row 1. What you have to do is to check if say A1:J1 is blank.
I think this is what you are trying?
Option Explicit
Sub Sample()
Dim ws As Worksheet
Dim rngBlanks As Range
Dim i As Long, lRow As Long, Ret As Long
'~~> Set this to the relevant worksheet
Set ws = ThisWorkbook.Sheets("Sheet2")
With ws
'~~> Get the last row in that sheet
If Application.WorksheetFunction.CountA(.Cells) <> 0 Then
lRow = .Cells.Find(What:="*", _
After:=.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
Else
lRow = 1
End If
'~~> Loop through the rows to find which range is blank
For i = 1 To lRow
Ret = Application.Evaluate("=COUNTA(A" & i & ":J" & i & ")")
If Ret = 0 Then
If rngBlanks Is Nothing Then
Set rngBlanks = .Rows(i)
Else
Set rngBlanks = Union(rngBlanks, .Rows(i))
End If
End If
Next i
End With
'~~~> Delete the range
If Not rngBlanks Is Nothing Then rngBlanks.Delete
End Sub
Another way would be to use Autofilter to delete those ranges

I stepped through your code with a sheet having some non-blank cells in columns A:J down to row 15. Rows 16:18 were entirely blank and D19=1. You want to delete rows that have blanks in every cell from A:J.
On the first iteration of your For..Next loop rngBlanks was not Nothing because typing
?rngBlanks.address
returned $A$1,$A$5:$A$19. A2:A4 were not blank. When you execute
Set rngBlanks = Columns(i).SpecialCells(xlCellTypeBlanks)
it looks for any blanks in column A which is not what you wanted to test. You want to test each row, probably within your ActiveSheet.UsedRange to see if columns A:J are all blank. So you need to define a variable
Dim Rw as Range
and iterate through each Rw in UsedRange
For Each Rw in ActiveSheet.UsedRange
If WorksheetFunction.CountBlank(range(cells(Rw,1),cells(Rw,10))) =0 Then
Rw.EntireRow.Delete
I could post the entire code here but what I've given should put you on the right track.

Related

Get the last column number while the column is hidden

I need to get the last column number on the second row, while the cited column is hidden.
The below code outputs wrong result if the last column is hidden.
Sub Last_column_number_even_is_hidden()
Dim ws As Worksheet, lastCol_n As Long
Set ws = ActiveSheet
lastCol_n = ws.Cells(2, ws.Columns.Count).End(xlToLeft).Column
MsgBox ("Last column number is " & lastCol_n)
End Sub
It looks that only Find does not care about the hidden cells in a range...
Please, try the next way:
Sub testLastColEvenHidded()
Dim ws As Worksheet, lastCol_n As Long, rng2 As Range
Set ws = ActiveSheet
Set rng2 = ws.UsedRange.rows(2)
lastCol_n = rng2.Find(What:="*", After:=rng2.cells(1), Lookat:=xlPart, LookIn:=xlFormulas, _
SearchOrder:=xlByColumns, SearchDirection:=xlPrevious).column
Debug.Print lastCol_n
End Sub
UsedRange may be not reliable, but only adding to the range... So, using it you can extract a full slice of a specific row to process it using Find, which does not care about not visible cells.

Deleting Preceding Blank Columns and Rows

I am trying to write a VBA code to cycle through each sheet in the active workbook and delete all blank columns and rows leading up to the first cell with data. For example, if the first cell with data is D5, columns A-C and Rows 1-4 would be deleted leaving the data starting in A1. I have the code below which works for the active sheet but I can't figure out how to get it to loop through the other sheets.
Sub DeleteRowsColumns()
' This will delete all Blank Columns and Rows before any data
Dim ColCounter As Long
Dim RowCounter As Long
Dim SafeCount As Integer
Dim ws As Worksheet
SafeCount = 0
' Check Column A is empty if Yes then Delete till A is populated
For Each ws In ActiveWorkbook.Worksheets
Do While ColCounter = 0
SafeCount = SafeCount + 1
ColCounter = Application.CountA(Columns(1).EntireColumn)
If ColCounter = 0 Then
Columns(1).EntireColumn.Delete
End If
If SafeCount = 50 Then
Exit Do
End If
Loop
Next ws
' Check Row 1 is empty if Yes then Delete till 1 is populated
For Each ws In ActiveWorkbook.Worksheets
SafeCount = 0
Do While RowCounter = 0
SafeCount = SafeCount + 1
RowCounter = Application.CountA(Rows(1).EntireRow)
If RowCounter = 0 Then
Rows(1).EntireRow.Delete
End If
If SafeCount = 50 Then
Exit Do
End If
'Loop
Next ws
MsgBox "Removed Preceding Blank Rows and Columns"
End Sub
Within each loop you need to specify which worksheet you are performing the operations on. Just looping through doesn't solve the problem. For instance:
ColCounter = Application.CountA(ws.Columns(1).EntireColumn)
If ColCounter = 0 Then
ws.Columns(1).EntireColumn.Delete
This ensures you are working in the correct worksheet.
Add it to a loop.
For X = 1 To 50
For i = 1 To 50
ColCounter = Application.CountA(ws.Columns(i).EntireColumn)
If ColCounter = 0 Then
ws.Columns(i).EntireColumn.Delete
End If
rowCounter = Application.CountA(ws.Rows(i).EntireRow)
If rowCounter = 0 Then
ws.Rows(i).EntireRow.Delete
End If
Next i
Next X
You could avoid any looping by first finding where the content starts (by row and then by column)
Sub RemoveEmpties()
Dim f As Range, f2 As Range, ws As Worksheet
For Each ws In ActiveWorkbook.Worksheets
'first occupied cell on sheet (by row)
Set f = ws.Cells.Find(What:="*", After:=ws.Cells(ws.Rows.Count, ws.Columns.Count), _
LookAt:=xlPart, LookIn:=xlFormulas, SearchOrder:=xlByRows, _
SearchDirection:=xlNext, MatchCase:=False)
If Not f Is Nothing Then
'have content, so find first-occupied column
Set f2 = ws.Cells.Find(What:="*", After:=ws.Cells(ws.Rows.Count, ws.Columns.Count), _
LookAt:=xlPart, LookIn:=xlFormulas, SearchOrder:=xlByColumns, _
SearchDirection:=xlNext, MatchCase:=False)
'remove rows/columns as required
If f.Row > 1 Then ws.Cells(1, 1).Resize(f.Row - 1).EntireRow.Delete
If f2.Column > 1 Then ws.Cells(1, 1).Resize(, f2.Column - 1).EntireColumn.Delete
End If
Next ws
End Sub
Alternatively (again only max of two deletes):
Sub RemoveEmpties2()
Dim ws As Worksheet, r As Long, c As Long
For Each ws In ActiveWorkbook.Worksheets
'first make sure there's some content on the sheet...
If Application.CountA(ws.Cells) > 0 Then
r = 1: c = 1
Do While Application.CountA(ws.Rows(r)) = 0
r = r + 1
Loop
If r > 1 Then ws.Rows(1).Resize(r - 1).Delete
Do While Application.CountA(ws.Columns(c)) = 0
c = c + 1
Loop
If c > 1 Then ws.Columns(1).Resize(, c - 1).Delete
End If
Next ws
End Sub
Using the Find Method
The Flow
In the procedure delFirstBlank the workbook is defined. A worksheet variable is declared. In the following For Each Next loop, for each worksheet in the workbook, the procedure deleteFirstBlank is called. When the loop exits, by a message box, the user is informed that the code has finished.
In the deleteFirstBlank procedure, the result of the function getFirstRow is written to a variable. The variable is then tested if it is equal to 0 i.e. the worksheet is blank. If so, then the procedure is exited. If not, the variable is tested if it is greater than 1 i.e. if at least the first row is empty. If so, the rows from the first row to the row defined by the variable decreased by one are deleted. Then the result of the function getFirstRow is written to a variable which is tested if it is greater than 1 i.e. if at least the first column is empty. If so, the columns from the first column to the column defined by the variable decreased by one are deleted.
In the getFirstRow procedure (function) a range variable is declared. Using the Find method, searching by rows, the first found non-blank cell (range) in the supplied worksheet, is assigned to the range variable. If the result of the Find method was a cell range, its row is written as the result of the function. If not, 0 is written as the result i.e. the worksheet is blank.
In the getFirstColumn procedure (function) a range variable is declared. Using the Find method, searching by columns, the first found non-blank cell (range) in the supplied worksheet, is assigned to the range variable. If the result of the Find method was a cell range, its column is written as the result of the function. If not, 0 is written as the result i.e. the worksheet is blank (the latter will never happen, because the worksheet was already tested if it is blank in the 'getFirstRow' procedure).
The Code
Option Explicit
Sub delFirstBlank()
Dim wb As Workbook
Set wb = ActiveWorkbook
Dim ws As Worksheet
For Each ws In wb.Worksheets
deleteFirstBlank ws
Next ws
MsgBox "Removed first blank rows and columns.", vbInformation, "Success"
End Sub
Sub deleteFirstBlank(Sheet As Worksheet)
Dim Current As Long
Current = getFirstRow(Sheet)
If Current = 0 Then GoTo ProcExit ' Blank sheet.
If Current > 1 Then
Sheet.Range(Sheet.Rows(1), Sheet.Rows(CLng(Current) - 1)).Delete
End If
Current = getFirstColumn(Sheet)
If Current > 1 Then
Sheet.Range(Sheet.Columns(1), Sheet.Columns(CLng(Current) - 1)).Delete
End If
ProcExit:
End Sub
Function getFirstRow(Sheet As Worksheet) As Long
Dim rng As Range
Set rng = Sheet.Cells.Find(What:="*", _
After:=Sheet.Cells(Sheet.Rows.Count, _
Sheet.Columns.Count), _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows)
If Not rng Is Nothing Then
getFirstRow = rng.Row
Else
getFirstRow = 0 ' Blank Sheet
End If
End Function
Function getFirstColumn(Sheet As Worksheet) As Long
Dim rng As Range
Set rng = Sheet.Cells.Find(What:="*", _
After:=Sheet.Cells(Sheet.Rows.Count, _
Sheet.Columns.Count), _
LookIn:=xlFormulas, _
SearchOrder:=xlByColumns)
If Not rng Is Nothing Then
getFirstColumn = rng.Column
Else
getFirstColumn = 0 ' Blank Sheet
End If
End Function

Find total description and copy paste values 4 rows down

Does anyone know what other command I need to use to copy the row label "Total WI Expenses" down 4 rows below?
The following code will find the "Total WI Expenses" and copy it to a range, however, I just want to find the total and copy the data to the 4 rows down. They need to be copied and pasted as values.
Sub Test()
Dim ws As Worksheet
Set ws = ActiveSheet
Dim rw As Long, Cell As Range
For Each Cell In ActiveSheet.Range("B:B")
If Cell.Value = "Total WI Expenses" Then
Cell.EntireRow.copy
Range("A71").PasteSpecial (xlPasteValues)
Application.CutCopyMode = False
End If
Next
End Sub
I sincerely appreciate your assistance.
Instead of running a For loop over the whole(!) column you may check first, if something is in the column, and then .Find the wanted value. If you found a result, then you may use it's row number.
Instead of Copy/Paste you may just assign the Range.Value to get the values without formatting.
This code copies the whole row's values four rows below.
Sub Test()
Dim ws As Worksheet
Dim c As Range
Set ws = ActiveSheet
If WorksheetFunction.CountA(ws.Columns(2)) > 0 Then
Set c = ws.Columns(2).Find( _
What:="Total WI Expenses", _
After:=ws.Cells(1, 2), _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext)
If Not c Is Nothing Then
ws.Rows(c.Row + 4).Value = ws.Rows(c.Row).Value
End If
Set c = Nothing
End If
Set ws = Nothing
End Sub

Selecting Range between two words then based on a different column deleting them

I made an original post (Selecting a Range depended on two Key Words). My code was correct however it doesn't do what I needed it to do. I need help/ guidance to manipulate the code so that between Revenue and total revenue we look at column J if it is empty the entire row is deleted. I tried my best but as I am currently learning VBA I am struggling to find even how to approach it.
Code thus far:
Dim rngFirst As Range
Dim rngLast As Range
Dim rngUnion As Range
Application.ScreenUpdating = False
With Sheets("Input")
'Find the start and stop
Set rngFirst = .Cells.Find(what:="Performance Income", lookat:=xlWhole, _
LookIn:=xlValues, MatchCase:=False)
Set rngLast = .Cells.Find(what:="Miscellaneous Income", _
lookat:=xlWhole, LookIn:=xlValues, MatchCase:=False)
Set rngUnion = Range(rngFirst.Address, rngLast.Address)
rngUnion.SpecialCells(xlCellTypeBlanks).EntireRow.Delete
End With
Application.ScreenUpdating = True
I appreciate all the help thus far and any help given. Thank you.
I recommend to use Match to find the rows where "Revenue" and "Total Revenue" are. Then check between these rows if there are blanks in column J .SpecialCells(xlCellTypeBlanks) and delete the EntireRow.
Option Explicit
Public Sub DeleteEmpty()
Dim wsInput As Worksheet 'define worksheet
Set wsInput = ThisWorkbook.Worksheets("Input")
Dim FirstRow As Long, LastRow As Long
On Error Resume Next 'Next line throws error if "Revenue" or "Total Revenue" is not found
FirstRow = Application.WorksheetFunction.Match("Revenue", wsInput.Range("A:A"), False) + 1
LastRow = Application.WorksheetFunction.Match("Total Revenue", wsInput.Range("A:A"), False) - 1
On Error GoTo 0 'Always re-activate error handling!
'Check if both "Revenue" and "Total Revenue" were found
If FirstRow = 0 Or LastRow = 0 Then
MsgBox "Revenue or Total Revenue not found"
Exit Sub
End If
'Find empty cells in column J between FirstRow (Revenue) and LastRow (Total Revenue)
Dim EmptyCellsInJ As Range
On Error Resume Next
Set EmptyCellsInJ = wsInput.Range(wsInput.Cells(FirstRow, "J"), wsInput.Cells(LastRow, "J")).SpecialCells(xlCellTypeBlanks)
On Error GoTo 0
'If there are empty cells delete their rows
If Not EmptyCellsInJ Is Nothing Then
EmptyCellsInJ.EntireRow.Delete
Else
MsgBox "nothing to delete"
End If
End Sub

How to delete blank rows?

I have a macro inherited from my coworker who left.
I have a sheet created from a source sheet, consisting of 30000 rows. Including the main data, over a million blank rows are created.
There are no blank rows between. It is 30k+ rows of data without a break.
I made a separate macro that deletes the blank rows after the fact.
I have to run the macro twice.
The first time, the black borders (carried over from the first sheet) are deleted, leaving a million borderless rows.
I run it a second time, which leaves the last used cell.
Sub DeleteUnused()
Dim myLastRow As Long
Dim myLastCol As Long
Dim wks As Worksheet
Dim dummyRng As Range
For Each wks In ActiveWorkbook.Worksheets
With wks
myLastRow = 0
myLastCol = 0
Set dummyRng = .UsedRange
On Error Resume Next
myLastRow = _
.Cells.Find("*", after:=.Cells(1), _
LookIn:=xlFormulas, lookat:=xlWhole, _
searchdirection:=xlPrevious, _
searchorder:=xlByRows).Row
myLastCol = _
.Cells.Find("*", after:=.Cells(1), _
LookIn:=xlFormulas, lookat:=xlWhole, _
searchdirection:=xlPrevious, _
searchorder:=xlByColumns).Column
On Error GoTo 0
If myLastRow * myLastCol = 0 Then
.Columns.Delete
Else
.Range(.Cells(myLastRow + 1, 1), _
.Cells(.Rows.Count, 1)).EntireRow.Delete
.Range(.Cells(1, myLastCol + 1), _
.Cells(1, .Columns.Count)).EntireColumn.Delete
End If
End With
Next wks
End Sub
Here is the macro I use to clean-up all blank rows as well as blank columns.
You can decide if you only want to remove empty rows, and keep empty columns.
Sub Remove_Empty_Rows_And_Columns()
Dim wks As Worksheet
Dim row_rng As Range 'All empty rows will be collected here
Dim col_rng As Range 'All empty columns will be collected here
Dim last_row As Long 'points to the last row in the used range
Dim last_column As Long 'points to the last column in the used range
Dim i As Long 'iterator
Set wks = ActiveSheet
With wks
'finding last row in used range
last_row = .UsedRange.Rows(.UsedRange.Rows.Count).Row
'finding last column
last_column = .UsedRange.Columns(.UsedRange.Columns.Count).Column
'loop through all rows in the used range and
'find if current row is blank or not
For i = 1 To last_row
If Application.WorksheetFunction.CountA(.Rows(i)) = 0 Then
'current row is blank..
If row_rng Is Nothing Then
'this is the first blank row. Lets create a new range for it
Set row_rng = .Rows(i)
Else
'this is not the first. Let's add it to the previous others
Set row_rng = Excel.Union(row_rng, .Rows(i))
End If
End If
Next
'same logic applies for empty rows
For i = 1 To last_column
If Application.WorksheetFunction.CountA(.Columns(i)) = 0 Then
If col_rng Is Nothing Then
Set col_rng = .Columns(i)
Else
Set col_rng = Excel.Union(col_rng, .Columns(i))
End If
End If
Next
End With
'lets check if we managed to find any blank rows
If Not row_rng Is Nothing Then
row_rng.EntireRow.Delete
Else
MsgBox "no rows to delete"
End If
'checking if we found any empty columns
If Not col_rng Is Nothing Then
col_rng.EntireColumn.Delete
Else
MsgBox "no columns to delete"
End If
End Sub
Per my comment this will delete blank rows. Just put this as the last line of the macro that created the blank rows.
Columns("A").SpecialCells(xlCellTypeBlanks).EntireRow.Delete

Resources