-2

I have this situation
enter image description here

The code deletes rows A3 and A10, though there are values at B3 and D10.

I want to delete rows across all the sheets in the workbook.

Sub Delete()
Dim xlastrow As Integer
Dim xrow As Integer
xrow = 1

Range("a65000").End(xlUp).Select
xlastrow = ActiveCell.Row

Do Until xrow = xlastrow

    If Cells(xrow, 1).Value = "" Then
        Cells(xrow, 1).Select
        Selection.EntireRow.Delete
        
        xrow = xrow - 1
        xlastrow = xlastrow - 1
    End If
        
    xrow = xrow + 1

Loop

End Sub
Community
  • 1
  • 1
Jake
  • 65
  • 2
  • 14

6 Answers6

0
 Dim r As Range
 Dim i As Integer
 i = 3
 Set r = Rows(i)
 MsgBox "Number of cells with value " + Str(WorksheetFunction.CountA(r))

This will return the text "Number of cells with value" with the number of cells with a value in row 3.

For an empty row this should return 0.

NOTE: If you delete row 3, then you need to check row 3 again, because it will contain the previous values of row 4 ...

Luuk
  • 12,245
  • 5
  • 22
  • 33
0

To check for all cells of a row, you can use the function CountA. As you are talking about dealing with lots of sheets, you should create a Sub that gets a worksheet as parameter and work on that sheet rather than relying on the active sheet. And you should avoid to use Select

Deleting data should always be done in reverse order, this makes it much easier to implement. Your routine could look like

Sub DeleteEmptyRows(ws As Worksheet)
    Dim row As Long
    For row = ws.UsedRange.Rows.Count To 1 Step -1
        Dim r As Range
        Set r = ws.Cells(row, 1).EntireRow
        If WorksheetFunction.CountA(r) = 0 Then
            r.Delete
        End If
    Next
End Sub
FunThomas
  • 23,043
  • 3
  • 18
  • 34
  • I tried running this by creating new sub it did not run. I am totally new to this VB stuff. could you please elaborate me on how to run..thank you. when I run it shows macro dialog box to create a macro if i feed the same name DeleteEmptyRows it does not accept as it's duplciate. – Jake Oct 23 '20 at 16:22
  • For testing, open the immediate window and type `DeleteEmptyRows ActiveSheet` - it will work on the current active sheet. But then you need to think of how you want to call it for all your sheets (probably in lots of workbooks). – FunThomas Oct 23 '20 at 16:26
  • what is the immediate window, I created sub and entered name add procedure window as DeleteEmptyRows ActiveSheet click ok button it says invalid procedure name – Jake Oct 23 '20 at 16:38
  • https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/use-the-immediate-window – FunThomas Oct 23 '20 at 16:40
  • https://learn.microsoft.com/en-us/office/vba/language/concepts/getting-started/calling-sub-and-function-procedures – FunThomas Oct 23 '20 at 16:43
  • @FunThomas, `UsedRange` doesn't have to start at row 1. To be safe, use `For row = ws.UsedRange.Row + ws.UsedRange.Rows.Count - 1 To ws.UsedRange.Row Step -1` – Profex Oct 23 '20 at 17:51
0

This will check the entire length of the rows (for numbers and / or text values). And remove blank rows. It will also only run delete rows statement once, improving performance.

Option Explicit

Sub removeBlankRows()

    Dim ws As Worksheet
    Set ws = ThisWorkbook.Worksheets("Sheet1")
    
    Dim xlastrow As Long
    xlastrow = ws.Range("a65000").End(xlUp).Row

    Dim xrow As Long
    
    For xrow = xlastrow To 1 Step -1
    
        Dim c As Long
        c = WorksheetFunction.CountA(ws.Rows(xrow))
        
        Dim d As Long
        d = WorksheetFunction.Count(ws.Rows(xrow))
        
        If c = 0 And d = 0 Then
        
            Dim deleteRng As Range
            If deleteRng Is Nothing Then
                Set deleteRng = ws.Cells(xrow, 1)
            Else
                Set deleteRng = Union(ws.Cells(xrow, 1), deleteRng)
            End If
            
        End If
        
    Next

    If Not deleteRng Is Nothing Then deleteRng.EntireRow.Delete
    
End Sub
Scott Holtzman
  • 27,099
  • 5
  • 37
  • 72
  • 1
    if the cells are filled with formula that return and empty string `""` COUNTA will still count it. – Scott Craner Oct 23 '20 at 16:56
  • 1
    Maybe you have to adapt the sheet name? – FunThomas Oct 23 '20 at 17:00
  • @Jake - step through the code line-by-line and see what it is doing that you would not expect it to do. I can't test against your data so you will have to. For example, are `c` and `d` both equal to 0 when there is a blank row? If not, what are the values? What type of information is in the cells - as Scott Craner alluded to? – Scott Holtzman Oct 23 '20 at 17:41
  • I think the trouble is that xlastrow = ws.Range("a65000").End(xlUp).Row is only looking at column A to find the last row. That column is not necessary populated. – tlemaster Oct 23 '20 at 18:16
  • @tlemaster that's also true , all rows aren't populated here.. in column A, I have also checked in emty cells there aren't any strings as such "" but when created mock or dummy data ran above it deleted the rows but still buggy. however my excel sheet rows are notgetting deleted. – Jake Oct 23 '20 at 20:48
  • @ScottHoltzman I found that my excel sheet contains cells that are blank but actually not empty(they have zero-length strings as data is exported from the database(SSRS reports)). When I checked for it I found a formula =OR(Len(CellNo)=0,Isblank(CellNo)) to clear that cell ... which evaluates to "TRUE" indicating that the cell is empty and I can delete. how to to make use of this above formula to delete all these cells which contains zero-length strings across the workbook. then execute this or if you have any other solution it would be great. – Jake Oct 24 '20 at 20:03
0

Two things you need:

  1. How to know that a row is empty?

The answer can be found in this other post (you need to use the check Application.CountA(SomeCell.EntireRow)=0).

  1. How to delete entries from a sorted collection?

"What? A sorted collection? What are you talking about?"
Well, you want to go from first row to last row and delete some of them (the simple fact that I can talk about first and last row means that the whole idea is sorted). There is only one correct way of doing this (plenty of explanations about this on the internet, it all comes down to the fact that you keep an index of your location, when you delete a row and you increase your index, you might jump over a row that you need to delete):

Start at the last row and go back to the first.

Good luck

Dominique
  • 16,450
  • 15
  • 56
  • 112
0

What if last row doesn't have a value in Column A, but in a different column?
Anyway, I think this a a full solution, other then protecting against the sheet being protected.
It uses a lot of small functions to make it easier to understand. it doesn't rely on the COUNTA or COUNT functions.
LastRowInRange will also work with subset ranges, instead of the entire sheet.

Sub ExampleCall()
Dim Sheet As Worksheet
    ' Clean up all sheets in ActiveWorkbook
    For Each Sheet In ActiveWorkbook.Worksheets
        DeleteEmptyRows Sheet
    Next
End Sub

DeleteEmptyRows

Sub DeleteEmptyRows(Optional Sheet As Worksheet)
Dim LastRow As Long, Row As Long
Dim DeleteRange As Range
    If Sheet Is Nothing Then Set Sheet = Application.ActiveSheet
    LastRow = LastRowInRange(Sheet.UsedRange)
    For Row = Sheet.UsedRange.Row To LastRow
        If IsRowEmpty(Row, Sheet) Then Set DeleteRange = MakeUnion(DeleteRange, Sheet.Cells(Row, 1))
    Next
    If Not DeleteRange Is Nothing Then DeleteRange.EntireRow.Delete
End Sub

LastRowInRange

Public Function LastRowInRange(Target As Range) As Long
Dim Column As Range
Dim Row As Long, MaxRow As Long
    If Target Is Nothing Then Exit Function
    For Each Column In Target.Columns
        ' This check added, in case you want to look into a subset range and not an entire table/sheet.
        If Column.Cells(Column.Row + Column.Rows.Count - 1) <> vbNullString Then
            MaxRow = Column.Row + Column.Rows.Count - 1
            Exit For
        Else
            Row = Column.Cells(Column.Row + Column.Rows.Count).End(xlUp).Row
            If Row > MaxRow Then MaxRow = Row
        End If
    Next
    LastRowInRange = MaxRow
End Function

IsRowEmpty

Public Function IsRowEmpty(Optional Row As Long = 1, Optional Sheet As Excel.Worksheet) As Boolean
Dim Col As Long
    If Sheet Is Nothing Then Set Sheet = Application.ActiveSheet
    Col = GetLastCol(Row, Sheet)
    IsRowEmpty = (Col = 1) And (Trim(Sheet.Cells(Row, 1)) = vbNullString)
    'For debuging, uncomment the following:
    'If Sheet.Cells(Row, Col) <> vbNullString Then
    '    Debug.Print "Found something in Row " & Row & ", Col " & Col & ": """ & Sheet.Cells(Row, Col) & """"
    'End If
End Function

GetLastCol

Public Function GetLastCol(Optional Row As Long = 1, Optional Sheet As Excel.Worksheet) As Long
    If Sheet Is Nothing Then Set Sheet = Application.ActiveSheet
    GetLastCol = Sheet.Cells(Row, Sheet.Columns.Count).End(xlToLeft).Column
End Function

MakeUnion

Public Function MakeUnion(Arg1 As Range, Arg2 As Range) As Range
    If Arg1 Is Nothing Then
        Set MakeUnion = Arg2
    ElseIf Arg2 Is Nothing Then
        Set MakeUnion = Arg1
    Else
        Set MakeUnion = Union(Arg1, Arg2)
    End If
End Function
Profex
  • 1,370
  • 8
  • 20
-1

Finally, I learnt to record a macro and recorded my own macro while using the data filter. modified it accordingly(to search generic columns) and deleted blank rows using the macro. and created also a short key for ease of executions.

Jake
  • 65
  • 2
  • 14