hiding blank columns on multiple sheets - excel

I want to hide the blank columns on multiple sheets. I can do it on just the active sheet but when I try to make it so it applies to all sheets with a month in the name it doesn't work. This is what I have so far:
Sub CommandButton1_Click()
Dim col As Range
Dim sheetsArray As Sheets
Set sheetsArray = ActiveWorkbook.Sheets(Array("*Jan*", "*Feb*", "*Mar*", "*Apr*", "*May*", "*Jun*", "*Jul*", "*Aug*", "*Sep*", "*Oct*", "*Nov*", "*Dec*"))
Dim sheet As Worksheet
Application.ScreenUpdating = False
For Each sheet In sheetsArray
sheet.Columns.Hidden = False
For Each col In sheet.UsedRange.Columns
col.Hidden = sheet.col.Cells(Rows.Count, 1).End(xlUp).Row = 1
Next col
Next sheet
Application.ScreenUpdating = True
End Sub
It's also now giving me a "Method or Data member not found error"

The Worksheet class does not have a method or data member named col. You can remove sheet. in front of col. Also, at the top of your module, add Option Explicit; then, before running your code, click the Debug menu and then Compile in order to catch such issues early on.
Other than that, you will have to check each sheet name against your name filters; the ActiveWorkbook.Sheets collection unfortunately won't magically interpret the filters in your array. In the end, you can go along those lines:
Option Explicit
Sub CommandButton1_Click()
Dim sheet As Worksheet
Dim col As Range
Dim sheetNameFilters As Variant
Dim filter As Variant
sheetNameFilters = Array("*Jan*", "*Feb*", "*Mar*", "*Apr*", "*May*", "*Jun*", "*Jul*", "*Aug*", "*Sep*", "*Oct*", "*Nov*", "*Dec*")
Application.ScreenUpdating = False
For Each sheet In ThisWorkbook.Worksheets
For Each filter In sheetNameFilters
If sheet.Name Like filter Then
sheet.Columns.Hidden = False
For Each col In sheet.UsedRange.Columns
col.Hidden = (col.Cells(Rows.Count, 1).End(xlUp).Row = 1)
Next
Exit For
End If
Next
Next
Application.ScreenUpdating = True
End Sub

I'm not sure if Array can perform the wild card search as you intended to. Like is a function that can be used as shown in the code below. Hope it meets your needs
Sub HideColumns()
Dim col As Range
Dim sheet As Worksheet
Application.ScreenUpdating = False
For Each sheet In ThisWorkbook.Worksheets
'check if worksheet name as month in it
If sheet.Name Like "*Jan*" Or sheet.Name Like "*Feb*" Or sheet.Name Like "*Mar*" Then 'add for rest of the months
sheet.Columns.Hidden = False 'make all columns visible
DoEvents
'reset the user range
sheet.UsedRange.Calculate 'if you are using usedrange recommend using this as sometimes usedrange behaves erratically
For Each col In sheet.UsedRange.Columns
'check if there are no entries and first row is also blank - make blank if both conditions are met
col.Hidden = IIf(col.Cells(1048576, 1).End(xlUp).Row = 1 And col.Cells(1, 1).Value = "", True, False)
DoEvents
Next col
End If
Next sheet
Application.ScreenUpdating = True
End Sub

Hide or Delete Blank Columns in Real Used Range
(Usually) Standard Module (Often 'Module1')
Option Explicit
'*******************************************************************************
' Purpose: Hides or deletes all blank columns in the Real Used Range
' of worksheets specified by a name pattern list.
' Remarks: The Real Used Range is calculated by using the Find method which
' avoids any possible 'errors' occuring when using the UsedRange
' property.
'*******************************************************************************
Sub HideDeleteColumnsOfRUR(Optional HideFalse_DeleteTrue As Boolean = False)
' Worksheet Name Pattern List
Const cSheets As String = "*Jan*,*Feb*,*Mar*,*Apr*,*May*,*Jun*,*Jul*," _
& "*Aug*,*Sep*,*Oct*,*Nov*,*Dec*"
' If a cell contains a formula that evaluates to "" and if cLookIn is
' equal to xlValues (-4163), it will not be found (Not blank).
Const cLookIn As Variant = -4123 ' -4163 Value, -4123 Formula, -4144 Comment
Dim ws As Worksheet ' (Current) Worksheet
Dim RUR As Range ' (Current) Real Used Range
Dim rngU As Range ' (Current) Union Range
Dim vntSheets As Variant ' Sheet Array
Dim i As Long ' Sheet Array Row Counter
Dim j As Long ' Used Range Column Counter
Application.ScreenUpdating = False
On Error GoTo ProcedureExit ' Enable ScreenUpdating if error occurs.
' Write Worksheet Name Pattern List to Sheet Array.
vntSheets = Split(cSheets, ",")
' Remove possible occurrences of leading and trailing spaces in
' Sheet Array.
'For i = 1 To UBound(vntSheets): vntSheets(i) = Trim(vntSheets(i)): Next
For Each ws In ThisWorkbook.Worksheets ' Loop through worksheets.
For i = 0 To UBound(vntSheets) ' Loop through Worksheet Name Patterns.
If ws.Name Like vntSheets(i) Then ' Worksheet Name Pattern found.
' Unhide all columns, calculate Real Used Range and Union Range.
GoSub RangeAccumulator
Exit For ' Stop checking for (Current) Worksheet Name Patterns.
End If
Next
Next
ProcedureExit:
Application.ScreenUpdating = True
Exit Sub
RangeAccumulator:
With ws
' Unhide all columns in (Current) Worksheet.
.Columns.Hidden = False
' Calculate Real Used Range.
If Not .Cells.Find("*", .Cells(.Rows.Count, .Columns _
.Count), -4123, , 1) Is Nothing Then ' Is not empty sheet.
Set RUR = .Range(.Cells(.Cells.Find("*", .Cells(.Rows.Count, _
.Columns.Count)).Row, .Cells.Find("*", .Cells(.Rows.Count, _
.Columns.Count), , , 2).Column), .Cells(.Cells _
.Find("*", , , , 1, 2).Row, .Cells.Find("*", , , , 2, 2) _
.Column))
Else ' Is empty sheet.
'MsgBox "Worksheet '" & ws.Name & "' is an empty sheet."
Return
End If
End With
' Accumulate Union Range using only Real Used Range's first-row cells (1).
With RUR
For j = 1 To .Columns.Count
If .Columns(j).Find("*", , cLookIn, , 2, 2) Is Nothing Then
If Not rngU Is Nothing Then
Set rngU = Union(rngU, .Cells(1, j))
Else
Set rngU = .Cells(1, j)
End If
End If
Next
End With
' Hide or Delete Union Range's columns.
If Not rngU Is Nothing Then
With rngU.EntireColumn
If Not HideFalse_DeleteTrue Then
.Hidden = True
Else
.Delete
End If
End With
Set rngU = Nothing
End If
Return
End Sub
'*******************************************************************************
'*******************************************************************************
' Purpose: Shows (unhides) all blank columns in worksheets specified by
' a name pattern list.
'*******************************************************************************
Sub ShowAllColumns()
' Worksheet Name Pattern List
Const cSheets As String = "*Jan*,*Feb*,*Mar*,*Apr*,*May*,*Jun*,*Jul*," _
& "*Aug*,*Sep*,*Oct*,*Nov*,*Dec*"
Dim ws As Worksheet ' (Current) Worksheet
Dim vntSheets As Variant ' Sheet Array
Dim i As Long ' Sheet Array Row Counter
Application.ScreenUpdating = False
On Error GoTo ProcedureExit ' Enable ScreenUpdating if error occurs.
' Write Worksheet Name Pattern List to Sheet Array.
vntSheets = Split(cSheets, ",")
' Remove possible occurrences of leading and trailing spaces in
' Sheet Array.
'For i = 1 To UBound(vntSheets): vntSheets(i) = Trim(vntSheets(i)): Next
For Each ws In ThisWorkbook.Worksheets ' Loop through worksheets.
For i = 0 To UBound(vntSheets) ' Loop through Worksheet Name Patterns.
If ws.Name Like vntSheets(i) Then ' Worksheet Name Pattern found.
' Unhide all columns in (Current) Worksheet.
ws.Columns.Hidden = False
Exit For ' Stop checking for (Current) Worksheet Name Patterns.
End If
Next
Next
ProcedureExit:
Application.ScreenUpdating = True
End Sub
'*******************************************************************************
(Usually) Sheet Module (Often 'Sheet1', 'Sheet2' or...)
Option Explicit
'*******************************************************************************
Sub CommandButton1_Click()
' HIDES columns in Real Used Range.
HideDeleteColumnsOfRUR
End Sub
'*******************************************************************************
Sub CommandButton2_Click()
' Shows (unhides) columns.
ShowAllColumns
End Sub
'*******************************************************************************
'Sub CommandButton3_Click()
' ' DELETES columns in Real Used Range.
' HideDeleteColumnsOfRUR True ' (or probably any number different than 0.)
'End Sub
'*******************************************************************************

Related

Excel VBA Hiding Rows

In the picture below, I'm trying to hide the rows that are empty in a certain cells (e.g. Row 39 to Row 48). Is is possible to do it in one click? I'm planning of doing it with VBA.
This is the formula that I'm currently using but the thing is the cells that I want to hide may not start at row 39 or ends at row 48, it depends on the data.
Sub HideRows()
Dim ws As Worksheet
For Each ws In Worksheets(Array("NAMES", "AUGUST"))
'ws.Rows("39:48").Hidden = True
Next
End Sub
Hide 'Empty' Rows
This is a slightly different approach:
uses Option Explicit
uses constants and variables
uses For Each...Next loops for both, worksheets and cells
qualifies all objects (e.g. ws.Cells or rg.Cells, not just Cells)
combines empty cells into a range
unhides all rows in one go, then hides the 'empty' rows in another (go)
Option Explicit
Sub HideRows()
Const StartRow As Long = 9
Const EndRow As Long = 89
Const ColNum As Long = 3
Dim WorksheetNames As Variant
WorksheetNames = Array("NAMES", "AUGUST") ' add more
Dim ws As Worksheet ' Current Worksheet
Dim rg As Range ' Current Range
Dim hrg As Range ' Current Hide Range
Dim cCell As Range ' Current Cell in Range
' Loop through the worksheets in the workbook containing this code.
For Each ws In ThisWorkbook.Worksheets(WorksheetNames)
' Create a reference to the range of the current worksheet.
Set rg = ws.Range(ws.Cells(StartRow, ColNum), ws.Cells(EndRow, ColNum))
' or using resize:
'Set rg = ws.Cells(StartRow, ColNum).Resize(EndRow - StartRow + 1)
' Loop through the cells of the current range.
For Each cCell In rg.Cells
If IsEmpty(cCell) Then ' cell is empty
' Combine ('add') the current cell into the hide range.
If Not hrg Is Nothing Then ' for all except the first
Set hrg = Union(hrg, cCell)
Else ' for the first
Set hrg = cCell
End If
'Else ' cell is not empty - do nothing
End If
Next cCell
' Unhide all rows of the current range of the current worksheet.
rg.EntireRow.Hidden = False
If Not hrg Is Nothing Then ' there are combined cells
' Hide the rows of the hide range.
hrg.EntireRow.Hidden = True
' Reset the hide range variable for the next worksheet.
' Also, note that 'Union' works only with ranges from one worksheet.
Set hrg = Nothing
'Else ' there are no combined cells - do nothing
End If
Next ws
End Sub
I already made it. Below is the script that I used.
Sub HideRows()
Dim ws As Worksheet
For Each ws In Worksheets(Array("NAMES", "AUGUST"))
StartRow = 9
EndRow = 89
ColNum = 3
For i = StartRow To EndRow
If Not IsEmpty(Cells(i, ColNum).Value) Then
ws.Cells(i, ColNum).EntireRow.Hidden = False
Else
ws.Cells(i, ColNum).EntireRow.Hidden = True
End If
Next i
Next
End Sub

Add Error Message If Criteria Doesn't Match

Look for (HERE) in below code for line I'm talking about.
Is it possible to setup an error message if it doesn't find any criteria "Active" in Column D?
I tried inputting an on error goto but it gave the msgbox when there were no "Active" projects in column D. But as soon as there was an "Active" Cell it would error out and not finish the code.
I did use a Exit Sub and Resume but still didn't work.
Const cCrit As Variant = "D" ' Criteria Column Letter/Number
Const cCols As String = "C:J" ' Source/Target Data Columns
Const cFRsrc As Long = 15 ' Source First Row
Dim ws1 As Worksheet ' Source Workbook
Dim ws2 As Worksheet ' Target Workbook
Dim rng As Range ' Filter Range, Copy Range
Dim lRow As Long ' Last Row Number
Dim FRtgt As Long ' Target First Row
Dim Answer As VbMsgBoxResult ' Message Box
Dim Error1 As VbMsgBoxResult ' Message Box for Errors
' Create references to worksheets.
With ThisWorkbook
Set ws1 = .Worksheets("Future Project Hopper")
Set ws2 = .Worksheets("CPD-Carryover,Complete&Active")
End With
Answer = MsgBox("Do you want to run the Macro?", vbYesNo, "Run Macro")
If Answer <> vbYes Then Exit Sub
' In Source Worksheet
With ws1
' Clear any filters.
.AutoFilterMode = False
' Calculate Last Row.
lRow = .Cells(.Rows.Count, cCrit).End(xlUp).row
' Calculate Filter Column Range.
Set rng = .Cells(cFRsrc, cCrit).Resize(lRow - cFRsrc + 1)
' Make an offset for the filter to start a row before (above) and
' end a row after (below).
With rng.Offset(-1).Resize(lRow - cFRsrc + 3)
' Filter data in Criteria Column.
.AutoFilter Field:=1, Criteria1:="Active"
End With
' Create a reference to the Copy Range.
**(HERE)** Set rng = .Columns(cCols).Resize(rng.Rows.Count).Offset(cFRsrc - 1) _
.SpecialCells(xlCellTypeVisible)
' Clear remaining filters.
.AutoFilterMode = False
End With
' Calculate Target First Row.
FRtgt = ws2.Cells(ws2.Rows.Count, cCrit).End(xlUp).row + 1
' Copy Range and paste to Target Worksheet and clear contents of future project hopper
rng.Copy
ws2.Columns(cCols).Resize(1).Offset(FRtgt - 1).PasteSpecial xlPasteValues
rng.Rows.ClearContents
Application.CutCopyMode = False
Give this a shot:
On Error Resume Next
Set Rng = .Columns(cCols).Resize(Rng.Rows.Count).Offset(cFRsrc - 1).SpecialCells(xlCellTypeVisible)
On Error GoTo 0
If Rng Is Nothing Then
MsgBox "No criteria found! Exiting sub"
Exit Sub
End If

VBA broken copy paste loop

I had been using this code for a little while in a workbook, left and come back to revisit and found the code is no longer functioning as it once was. I cannot see any obvious mistakes and wondered if anyone could spot what perhaps would be stopping it running?
Page names and locations remain the same.
The purpose was to take results in Sheet 4 (CAL) and copy each row into a new empty line in RRR. No errors are displaying. Just nothing happens at all.
Sub ca_act()
Dim nextrow As Long
nextrow = Sheet4.Cells(4, "A").End(xlUp).Row + 1
Dim src As Worksheet
Set src = Sheets("CAL")
Dim trgt As Worksheet
Set trgt = Sheets("RRR")
Dim i As Long
For i = 1 To src.Range("y" & Rows.Count).End(xlUp).Row
If src.Range("y" & i) = 1 Then
' calling the copy paste procedure
CopyPaste src, i, trgt
End If
Next i
Application.ScreenUpdating = True
End Sub
' this sub copies and pastes the entire row into a different sheet
' below the last used row
Private Sub CopyPaste(ByRef src As Worksheet, ByVal i As Long, ByRef trgt As Worksheet)
src.Activate
src.Rows(i & ":" & i).Copy
trgt.Activate
Dim nxtRow As Long
nxtRow = trgt.Range("y" & Rows.Count).End(xlUp).Row + 1
trgt.Rows(nxtRow & ":" & nxtRow).PasteSpecial _
Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
End Sub
Wrong Sheet or Column
Some Guess Work
The following line means that you will check values in column "A"
Dim nextrow As Long
nextrow = Sheet4.Cells(4, "A").End(xlUp).Row + 1
which was probably your first idea. BTW you should comment it out because it's useless.
Later you write
For i = 1 To src.Range("Y" & Rows.Count).End(xlUp).Row
which means you're checking column 'Y'. Are you sure about that?
I would consider the following:
You're checking for values in the wrong column.
Your sheets CAL and RRR might be wrong, maybe you have moved the name CAL e.g. to Sheet2 where there is no data.
In sheet 'RRR', you might have some unwanted data below in column 'Y' i.e. if you have accidentally put some data in a cell when it goes up it will stop at that cell and go one row down and write from there and you're not seeing it.
This is happening in different workbooks.
What's this all about
Application.ScreenUpdating = True
when
Application.ScreenUpdating = False
is nowhere to be found.
Here is the simplification of your second sub:
Private Sub CopyPaste(src As Worksheet, i As Long, trgt As Worksheet)
src.Rows(i).Copy (trgt.Rows(trgt.Range("Y" & Rows.Count).End(xlUp).Row + 1))
End Sub
Simplification
Constants at the beginning of the code are lifesavers as you will probably see soon.
It is customary to release object variables when they're not needed anymore or at least at the end of the code. The following codes don't use any object variables which is achieved using the Parent property.
'*******************************************************************************
' Checks a column for a specified value, and each time it is found copies
' the entire current row to another worksheet below its last used row, using
' the CopyPaste_Simple Sub.
'*******************************************************************************
Sub ca_act_Simple()
Application.ScreenUpdating = False
Const strSource As Variant = "CAL" ' Source Worksheet Name/Index
Const strTarget As Variant = "RRR" ' Target Worksheet Name/Index
Const vntSourceCol As Variant = "Y" ' Source Column Letter/Number
Const lngSourceRow As Long = 1 ' Source First Row
Const vntSearch as Variant = 1 ' Search Value
Dim intRow As Long ' Row Counter
With ThisWorkbook.Worksheets(strSource)
For intRow = lngSourceRow To _
.Cells(.Rows.Count, vntSourceCol).End(xlUp).Row
If .Cells(intRow, vntSourceCol) = vntSearch Then
' calling the copy paste procedure
CopyPaste_Simple .Parent.Worksheets(strSource), intRow, _
.Parent.Worksheets(strTarget)
End If
Next
End With
Application.ScreenUpdating = True
End Sub
'*******************************************************************************
'*******************************************************************************
' Copies the entire row to another worksheet below its last used row calculated
' from a specified column.
'*******************************************************************************
Sub CopyPaste_Simple(Source As Worksheet, SourceRowNumber As Long, _
Target As Worksheet)
' It is assumed that the Target Worksheet has headers i.e. its first row
' will never be populated.
Const vntTargetCol As Variant = "Y" ' Target Column Letter/Number
With Target
Source.Rows(SourceRowNumber).Copy (.Rows(.Cells(.Rows.Count, _
vntTargetCol).End(xlUp).Row + 1))
End With
End Sub
'*******************************************************************************
Improvement
To improve we will get rid of the second sub:
'*******************************************************************************
' Checks a column for a specified value, and each time it is found copies
' the entire current row to another worksheet below its last used row
' calculated from a specified column.
'*******************************************************************************
Sub ca_act_Improve()
Application.ScreenUpdating = False
Const strSource As Variant = "CAL" ' Source Worksheet Name/Index
Const strTarget As Variant = "RRR" ' Target Worksheet Name/Index
Const vntSourceCol As Variant = "Y" ' Source Column Letter/Number
Const vntTargetCol As Variant = "Y" ' Target Column Letter/Number
Const lngSourceRow As Long = 1 ' Source First Row
Const vntSearch as Variant = 1 ' Search Value
Dim intRow As Long ' Row Counter
With ThisWorkbook.Worksheets(strSource)
For intRow = lngSourceRow To _
.Cells(.Rows.Count, vntSourceCol).End(xlUp).Row
If .Cells(intRow, vntSourceCol) = vntSearch Then
With .Parent.Worksheets(strTarget)
.Parent.Worksheets(strSource).Rows(intRow).Copy _
(.Rows(.Cells(.Rows.Count, vntTargetCol).End(xlUp).Row + 1))
End With
End If
Next
End With
Application.ScreenUpdating = True
End Sub
'*******************************************************************************
In this improved version it is best visible that you are using column 'Y' in both worksheets, which might be the cause of your trouble.
The Second Sub
I think it's better to add the fourth argument:
'*******************************************************************************
' Copies an entire row to another worksheet below its last used row.
'*******************************************************************************
Sub CopyPaste_Improve(Source As Worksheet, SourceRowNumber As Long, _
Target As Worksheet, TargetColumnLetterNumber As Variant)
' It is assumed that the Target Worksheet has headers i.e. its first row
' will never be populated.
With Target
Source.Rows(SourceRowNumber).Copy (.Rows(.Cells(.Rows.Count, _
TargetColumnLetterNumber).End(xlUp).Row + 1))
End With
End Sub
'*******************************************************************************

Advanced Filter - exclude headers

I have a macro that does an Advanced Filter. How can I exclude the headers from this? I tried changing C:C to C2:C but it's not working.
Sub extractuniquevalues2()
Dim wks As Excel.Worksheet
Dim wksSummary As Excel.Worksheet
'----------------------------------------------------------------------------------
'edited so it shows in the 3rd column row +1. Add the header and sheet name macro to this
On Error Resume Next
Set wksSummary = Excel.ThisWorkbook.Worksheets("Unique data")
On Error GoTo 0
If wksSummary Is Nothing Then
Set wksSummary = Excel.ThisWorkbook.Worksheets.Add
wksSummary.Name = "Unique data"
End If
'Iterate through all the worksheets, but skip [Summary] worksheet.
For Each wks In Excel.ActiveWorkbook.Worksheets
With wksSummary
If wks.Name <> .Name Then
If Application.WorksheetFunction.CountA(wks.Range("C:C")) Then
Call wks.Range("C:C").AdvancedFilter(xlFilterCopy, , .Cells(.Cells(.Rows.Count, 3).End(xlUp).Row + 1, 3), True)
End If
End If
End With
Next wks
End Sub
To show you a visual check my image: [img]http://i.imgur.com/xGcAZMj.jpg[/img]
Would like to get rid of the headers and have the names row-by-row without spaces between.
EDIT------------------------------------------------------------------------
So i'm doing it like so, getting errors:
Sub testage()
Dim wks As Excel.Worksheet
Dim wksSummary As Excel.Worksheet
'----------------------------------------------------------------------------------
'edited so it shows in the 3rd column row +1. Add the header and sheet name macro to this
On Error Resume Next
Set wksSummary = Excel.ThisWorkbook.Worksheets("Unique data")
On Error GoTo 0
If wksSummary Is Nothing Then
Set wksSummary = Excel.ThisWorkbook.Worksheets.Add
wksSummary.Name = "Unique data"
End If
'Iterate through all the worksheets, but skip [Summary] worksheet.
For Each wks In Excel.ActiveWorkbook.Worksheets
Dim r As Range
' Get the first cell of our destination range...
Set r = .Cells(.Cells(.Rows.Count, 3).End(xlUp).Row + 1, 3)
' Perform the unique copy...
wks.Range("C:C").AdvancedFilter xlFilterCopy, , r, True
'Remove the first cell at the destination range...
r.Delete xlShiftUp
Next wks
End Sub
Unfortunately, no. All of the filter functions work with headers, even the ones where you copy to a new destination, such as in your case. But you can just follow-up with a Delete xlShiftUp to remove the first cell at your destination range and shift everything up a spot:
Dim r As Range
' Get the first cell of our destination range...
Set r = .Cells(.Cells(.Rows.Count, 3).End(xlUp).Row + 1, 3)
' Perform the unique copy...
wks.Range("C:C").AdvancedFilter xlFilterCopy, , r, True
' Remove the first cell at the destination range...
r.Delete xlShiftUp

Remove all completely blank rows

I have a couple thousand rows in a workbook.
There are several hundred rows that are blank.
How can I remove every entirely blank row?
There are two ways to do that:
1. With VBA:
There is a VBA script here in this link. Use the first script, I mean DeleteBlankRows.
You can also copy the same code from here.
How to use:
Copy the code.
In Excel press Alt + F11 to enter the VBE.
Press Ctrl + R to show the Project Explorer.
Insert -> Module.
Paste code.
Save and Exit VBE.
Run the code:
Select the column with blank rows.
Press Alt + F8 to open the macro dialog box.
Select DeleteBlankRows
Click Run.
2. Without VBA:
Just check the link here. It is easy so no need to explain again here.
I'll paste the code here just in case the link dies in the future.
Just a note, the second part "Without VBA" will NOT meet the requirements of the original questions because it will delete rows that contain blank cells, but are not COMPLETELY blank.
Here's the code from the first link of the accepted answer.
Sub DeleteBlankRows(Optional WorksheetName As Variant)
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' DeleteBlankRows
' This function will delete all blank rows on the worksheet
' named by WorksheetName. This will delete rows that are
' completely blank (every cell = vbNullString) or that have
' cells that contain only an apostrophe (special Text control
' character).
' The code will look at each cell that contains a formula,
' then look at the precedents of that formula, and will not
' delete rows that are a precedent to a formula. This will
' prevent deleting precedents of a formula where those
' precedents are in lower numbered rows than the formula
' (e.g., formula in A10 references A1:A5). If a formula
' references cell that are below (higher row number) the
' last used row (e.g, formula in A10 reference A20:A30 and
' last used row is A15), the refences in the formula will
' be changed due to the deletion of rows above the formula.
'
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Dim RefColl As Collection
Dim RowNum As Long
Dim Prec As Range
Dim Rng As Range
Dim DeleteRange As Range
Dim LastRow As Long
Dim FormulaCells As Range
Dim Test As Long
Dim WS As Worksheet
Dim PrecCell As Range
If IsMissing(WorksheetName) = True Then
Set WS = ActiveSheet
Else
On Error Resume Next
Set WS = ActiveWorkbook.Worksheets(WorksheetName)
If Err.Number <> 0 Then
'''''''''''''''''''''''''''''''
' Invalid worksheet name.
'''''''''''''''''''''''''''''''
Exit Sub
End If
End If
If Application.WorksheetFunction.CountA(WS.UsedRange.Cells) = 0 Then
''''''''''''''''''''''''''''''
' Worksheet is blank. Get Out.
''''''''''''''''''''''''''''''
Exit Sub
End If
''''''''''''''''''''''''''''''''''''''
' Find the last used cell on the
' worksheet.
''''''''''''''''''''''''''''''''''''''
Set Rng = WS.Cells.Find(what:="*", after:=WS.Cells(WS.Rows.Count, WS.Columns.Count), lookat:=xlPart, _
searchorder:=xlByColumns, searchdirection:=xlPrevious, MatchCase:=False)
LastRow = Rng.Row
Set RefColl = New Collection
'''''''''''''''''''''''''''''''''''''
' We go from bottom to top to keep
' the references intact, preventing
' #REF errors.
'''''''''''''''''''''''''''''''''''''
For RowNum = LastRow To 1 Step -1
Set FormulaCells = Nothing
If Application.WorksheetFunction.CountA(WS.Rows(RowNum)) = 0 Then
''''''''''''''''''''''''''''''''''''
' There are no non-blank cells in
' row R. See if R is in the RefColl
' reference Collection. If not,
' add row R to the DeleteRange.
''''''''''''''''''''''''''''''''''''
On Error Resume Next
Test = RefColl(CStr(RowNum))
If Err.Number <> 0 Then
''''''''''''''''''''''''''
' R is not in the RefColl
' collection. Add it to
' the DeleteRange variable.
''''''''''''''''''''''''''
If DeleteRange Is Nothing Then
Set DeleteRange = WS.Rows(RowNum)
Else
Set DeleteRange = Application.Union(DeleteRange, WS.Rows(RowNum))
End If
Else
''''''''''''''''''''''''''
' R is in the collection.
' Do nothing.
''''''''''''''''''''''''''
End If
On Error GoTo 0
Err.Clear
Else
'''''''''''''''''''''''''''''''''''''
' CountA > 0. Find the cells
' containing formula, and for
' each cell with a formula, find
' its precedents. Add the row number
' of each precedent to the RefColl
' collection.
'''''''''''''''''''''''''''''''''''''
If IsRowClear(RowNum:=RowNum) = True Then
'''''''''''''''''''''''''''''''''
' Row contains nothing but blank
' cells or cells with only an
' apostrophe. Cells that contain
' only an apostrophe are counted
' by CountA, so we use IsRowClear
' to test for only apostrophes.
' Test if this row is in the
' RefColl collection. If it is
' not in the collection, add it
' to the DeleteRange.
'''''''''''''''''''''''''''''''''
On Error Resume Next
Test = RefColl(CStr(RowNum))
If Err.Number = 0 Then
''''''''''''''''''''''''''''''''''''''
' Row exists in RefColl. That means
' a formula is referencing this row.
' Do not delete the row.
''''''''''''''''''''''''''''''''''''''
Else
If DeleteRange Is Nothing Then
Set DeleteRange = WS.Rows(RowNum)
Else
Set DeleteRange = Application.Union(DeleteRange, WS.Rows(RowNum))
End If
End If
Else
On Error Resume Next
Set FormulaCells = Nothing
Set FormulaCells = WS.Rows(RowNum).SpecialCells(xlCellTypeFormulas)
On Error GoTo 0
If FormulaCells Is Nothing Then
'''''''''''''''''''''''''
' No formulas found. Do
' nothing.
'''''''''''''''''''''''''
Else
'''''''''''''''''''''''''''''''''''''''''''''''''''
' Formulas found. Loop through the formula
' cells, and for each cell, find its precedents
' and add the row number of each precedent cell
' to the RefColl collection.
'''''''''''''''''''''''''''''''''''''''''''''''''''
On Error Resume Next
For Each Rng In FormulaCells.Cells
For Each Prec In Rng.Precedents.Cells
RefColl.Add Item:=Prec.Row, key:=CStr(Prec.Row)
Next Prec
Next Rng
On Error GoTo 0
End If
End If
End If
'''''''''''''''''''''''''
' Go to the next row,
' moving upwards.
'''''''''''''''''''''''''
Next RowNum
''''''''''''''''''''''''''''''''''''''''''
' If we have rows to delete, delete them.
''''''''''''''''''''''''''''''''''''''''''
If Not DeleteRange Is Nothing Then
DeleteRange.EntireRow.Delete shift:=xlShiftUp
End If
End Sub
Function IsRowClear(RowNum As Long) As Boolean
''''''''''''''''''''''''''''''''''''''''''''''''''
' IsRowClear
' This procedure returns True if all the cells
' in the row specified by RowNum as empty or
' contains only a "'" character. It returns False
' if the row contains only data or formulas.
''''''''''''''''''''''''''''''''''''''''''''''''''
Dim ColNdx As Long
Dim Rng As Range
ColNdx = 1
Set Rng = Cells(RowNum, ColNdx)
Do Until ColNdx = Columns.Count
If (Rng.HasFormula = True) Or (Rng.Value <> vbNullString) Then
IsRowClear = False
Exit Function
End If
Set Rng = Cells(RowNum, ColNdx).End(xlToRight)
ColNdx = Rng.Column
Loop
IsRowClear = True
End Function
I found current answer unnecessarily long.
My code below is checking all used range rows one by one and if they are blank - it deletes them.
Public Sub DeleteEmptyRows()
Dim SourceRange As Range
Dim EntireRow As Range
On Error Resume Next
Set SourceRange = Sheet1.UsedRange
If Not (SourceRange Is Nothing) Then
Application.ScreenUpdating = False
For i = SourceRange.Rows.Count To 1 Step -1
Set EntireRow = SourceRange.Cells(i, 1).EntireRow
If Application.WorksheetFunction.CountA(EntireRow) = 0 Then
EntireRow.Delete
End If
Next
Application.ScreenUpdating = True
End If
End Sub

Resources