VBA Macro to Delete Rows Based on Cell Values

Bottom Line: Learn how to use VBA macros to delete rows based on cell values or conditions. Includes video tutorial and sample code.

Skill Level: Intermediate

Video Tutorial

Watch on YouTube & Subscribe to our Channel

Download the Excel File

Here is the file I use in the video above that contains the VBA macro code examples.

Using a Macro to Delete Rows Based on Cell Values

Does your data preparation process include deleting the same rows based on a condition? If so, you can use a macro to instantly delete any rows that have a particular value, date, or even blank cells.

The overall process is two simple steps:

  1. The first step is to filter the rows based on filter criteria for the values to be deleted.
  2. Then the macro deletes the visible cells in the range.

The Process Explained

Below is an image of a data set that has some blank cells in column E (Product). You can see one of those blank cells is E6.

Delete blank cells using a macro

To remove the rows that have blank cells like this one, the macro first applies a filter to the product column.

Next, the macro simply deletes all of the visible rows that have been left by the filter. It uses the SpecialCells method to create a reference to the visible cells.

This is the same as using the Go To Special menu (keyboard shortcut Alt+;) to select blanks. Checkout my article and video on how to copy & paste visible cells to learn more.

Rows with blank cells deleted

Finally, the macro can also clear the filters so that you are left viewing the entire data range, minus the rows you've deleted.

New data set with blank rows deleted

It's a simple 2 or 3 step macro that will save time from doing this process manually.

Important Note: I added a step to clear all filters in the range or Table at the beginning of the macro. This ensures that there are no filters applied to other columns that could cause additional rows to be filtered out.

A big thanks to Hoang for pointing this out on the YouTube video!

The VBA Macro Code

The VBA code below can be copy/pasted to the VB Editor. The code is also included in the Excel file in the Download section above.

Sub Delete_Rows_Based_On_Value()
'Apply a filter to a Range and delete visible rows
'Source: https://www.excelcampus.com/vba/delete-rows-cell-values/


Dim ws As Worksheet

  'Set reference to the sheet in the workbook.
  Set ws = ThisWorkbook.Worksheets("Regular Range")
  ws.Activate 'not required but allows user to view sheet if warning message appears
  
  'Clear any existing filters
  On Error Resume Next
    ws.ShowAllData
  On Error GoTo 0

  '1. Apply Filter
  ws.Range("B3:G1000").AutoFilter Field:=4, Criteria1:=""
  
  '2. Delete Rows
  Application.DisplayAlerts = False
    ws.Range("B4:G1000").SpecialCells(xlCellTypeVisible).Delete
  Application.DisplayAlerts = True
  
  '3. Clear Filter
  On Error Resume Next
    ws.ShowAllData
  On Error GoTo 0

End Sub

You will just need to update the Worksheet and Range references for your specific file.

Avoiding the Pop-up Warning

When you run the macro you will receive a pop-up warning message that says “Delete entire sheet row?”

If you want to run the macro without having that pop-up box interrupting, you can simply remove the apostrophes before the two lines of code that begin with Application.DisplayAlerts.

So that portion of the macro now looks like this:

  '2. Delete Rows
  Application.DisplayAlerts = False
    ws.Range("B4:G1000").SpecialCells(xlCellTypeVisible).Delete
  Application.DisplayAlerts = True

The Application.DisplayAlerts property is a toggle to turn warning alerts on/off. Setting it to False will turn off the alerts. These are alerts you might see from Excel when deleting ranges, deleting sheets, closing without saving, etc.

Applying the Macro to Tables

If your data is in an Excel Table instead of just a range of cells, you can still delete rows based on cell contents using a macro. The code is almost the same, but tweaked slightly so that it applies to Tables. Here is the code you would use for a Table.

Sub Delete_Rows_Based_On_Value_Table()
'Apply a filter to a Table and delete visible rows
'Source: https://www.excelcampus.com/vba/delete-rows-cell-values/

Dim lo As ListObject

  'Set reference to the sheet and Table.
  Set lo = Sheet3.ListObjects(1)
  ws.Activate
  
  'Clear any existing filters
  lo.AutoFilter.ShowAllData
  
  '1. Apply Filter
  lo.Range.AutoFilter Field:=4, Criteria1:="Product 2"
  
  '2. Delete Rows
  Application.DisplayAlerts = False
    lo.DataBodyRange.SpecialCells(xlCellTypeVisible).Delete
  Application.DisplayAlerts = True

  '3. Clear Filter
  lo.AutoFilter.ShowAllData

End Sub

Additional Macros

I've also included a few additional macros to help customize the process further.

Custom Warning Message

You can create a custom message box before deleting rows, instead of the default Excel warning to delete rows. The macro below also tells you the number of rows it is going to delete, and asks if you want to proceed.

Sub Delete_Rows_Based_On_Value_Table_Message()
'Display Yes/No message prompt before deleting rows
'Source: https://www.excelcampus.com/vba/delete-rows-cell-values/

Dim lo As ListObject
Dim lRows As Long
Dim vbAnswer As VbMsgBoxResult

  'Set reference to the sheet and Table.
  Set lo = Sheet6.ListObjects(1)
  lo.Parent.Activate 'Activate sheet that Table is on.
  
  'Clear any existing filters
  lo.AutoFilter.ShowAllData
  
  '1. Apply Filter
  lo.Range.AutoFilter Field:=4, Criteria1:="Product 2"
  
  'Count Rows & display message
  On Error Resume Next
    lRows = WorksheetFunction.Subtotal(103, lo.ListColumns(1).DataBodyRange.SpecialCells(xlCellTypeVisible))
  On Error GoTo 0
  
  vbAnswer = MsgBox(lRows & " Rows will be deleted.  Do you want to continue?", vbYesNo, "Delete Rows Macro")
  
  If vbAnswer = vbYes Then
    
    'Delete Rows
    Application.DisplayAlerts = False
      lo.DataBodyRange.SpecialCells(xlCellTypeVisible).Delete
    Application.DisplayAlerts = True
  
    'Clear Filter
    lo.AutoFilter.ShowAllData
    
  End If

End Sub

This is what the custom pop-up box looks like:

Delete Rows Macro Custom Message

This pop-up just serves as a check before deleting rows. It's a great way to double check everything looks good before deleting. It also prevents you or your users from accidentally running the macro.

Checkout my video on how to add a Yes/No message box before the macro runs for details on this code. It's part of my 4 part video series on the Personal Macro Workbook.

Deleting Rows Based on Multiple Criteria

You can also delete rows with a macro using more than one criteria. In the video above, I filter for rows that have both a blank Product field and a date before 1/1/2015.

Sub Delete_Rows_Based_On_Multiple_Values()
'Apply a filter to a Table and delete visible rows
'Source: https://www.excelcampus.com/vba/delete-rows-cell-values/

Dim lo As ListObject

  'Set reference to the sheet and Table.
  Set lo = Sheet5.ListObjects(1)
  lo.Parent.Activate 'Activate sheet that Table is on.
  
  'Clear any existing filters
  lo.AutoFilter.ShowAllData
  
  '1. Apply Filter - Blanks in Product for before 2015 only
  lo.Range.AutoFilter Field:=4, Criteria1:=""
  lo.Range.AutoFilter Field:=1, Criteria1:="<1/1/2015"
  
  '2. Delete Rows
  Application.DisplayAlerts = False
    lo.DataBodyRange.SpecialCells(xlCellTypeVisible).Delete
  Application.DisplayAlerts = True

  '3. Clear Filter
  lo.AutoFilter.ShowAllData

End Sub

This allows you to delete rows based on values in multiple columns. The filtering essentially uses AND logic between the columns and all conditions must be met.

If you want to use OR logic where any of the conditions are met, you can run multiple macros, or create a formula in a helper column with the logic.

Depending on the logic, it might be easiest to just create two separate macros. You can put the code all in one macro, or create another macro to call each macro. Here's an example of what that macro might look like.

Sub Delete_Rows()

  Call Delete_Blank_Rows
  Call Delete_Before_2015

End Sub

This method also allows you to run each macro individually.

Delete Rows Based on Criteria Specified by User

Daniel and Bob asked a great question in the comments below. They want the user of the file to be able to specify the filter criteria, instead of having it hard-coded in the macro.

We can use the Application.InputBox method to ask the user to input the criteria.

Input Box to Prompt User for Filter Criteria for Delete Rows Macro

The InputBox method creates a pop-up message box that allows the user to type in the text box. The value in the text box is passed back to the macro and stored in a variable.

Here is the VBA code. I also added it to the sample file in the downloads section above.

Sub Delete_Rows_User_Input()
'Display Yes/No message prompt before deleting rows
'Source: https://www.excelcampus.com/vba/delete-rows-cell-values/

Dim lo As ListObject
Dim lRows As Long
Dim vbAnswer As VbMsgBoxResult
Dim sCriteria As Variant

  'Set reference to the sheet and Table.
  Set lo = Sheet9.ListObjects(1)
  lo.Parent.Activate 'Activate sheet that Table is on.
  
  'Clear any existing filters
  lo.AutoFilter.ShowAllData
  
  'Ask user for input
  sCriteria = Application.InputBox(Prompt:="Please enter the filter criteria for the Product column." _
                                    & vbNewLine & "Leave the box empty to filter for blanks.", _
                                    Title:="Filter Criteria", _
                                    Type:=2)
  
  'Exit if user presses Cancel button
  If sCriteria = False Then Exit Sub
  
  '1. Apply Filter
  lo.Range.AutoFilter Field:=4, Criteria1:=sCriteria
  
  'Count Rows & display message
  On Error Resume Next
    lRows = WorksheetFunction.Subtotal(103, lo.ListColumns(1).DataBodyRange.SpecialCells(xlCellTypeVisible))
  On Error GoTo 0
  
  vbAnswer = MsgBox(lRows & " Rows will be deleted.  Do you want to continue?", vbYesNo, "Delete Rows Macro")
  
  If vbAnswer = vbYes Then
    
    'Delete Rows
    Application.DisplayAlerts = False
      lo.DataBodyRange.SpecialCells(xlCellTypeVisible).Delete
    Application.DisplayAlerts = True
  
    'Clear Filter
    lo.AutoFilter.ShowAllData
    
  End If

End Sub

Pre-fill the User's Name in the Input Box

Daniel also had a question about setting the filter criteria to the current user's name. The Application.UserName property actually returns this value as long as the user has set it properly in Office/Excel.

Input Box to Prompt Default to User Name

We can use this as the Default parameter value in the input box.

  sCriteria = Application.InputBox(Prompt:="Please enter the filter criteria for the Product column." _
                                    & vbNewLine & "Leave the box empty to filter for blanks.", _
                                    Title:="Filter Criteria", _
                                    Default:=Application.UserName, _
                                    Type:=2)

The user might still need to change the name if it does not match the value in the worksheet column you are filtering, but you can also get that synced up with the user to save them a lot of time.

Related Topics

Check out my posts on these similar topics as well.

Conclusion

Macros like this can be especially helpful if you are looking to clean up data and get rid of entries that you know you don't need–maybe because they are too old or they are only partially complete.

There are a lot of ways to accomplish this task. Another common approach is to loop through cells and check their values individually.

However, I typically use this approach because it can be a lot faster to use the built in filters in Excel. It also allows us to preview the range before we delete it.

What will you use these macros for? Please leave a comment below with any suggestions and questions. Thank you! 🙂

60 comments

Your email address will not be published. Required fields are marked *

  • Very interesting, wouldn’t have thought to do it that way.
    My usual way would be to use a For Next loop to check each row individually.
    You’re way is much more elegant and considerably faster I would presume

  • Hey Jon,

    How would you modify these macros so they take input for the criteria?

    Is there a way to say Blank as an input and how would it be sent to the Criteria part of the AutoFilter?

    This would allow anyone to use it for whatever data they have.

    I guess getting multiple inputs would be a little bit harder to implement but how would we go about it? I currently have a similar macro just for filtering my data based on multiple criteria so I can see my workload for the week but if I want to pass it to someone else I have to create a copy of the code and change my name to theirs.

    • Hi Daniel,

      Great question! I added a section to the article above that answers this. I added a new macro that uses the InputBox method to prompt the user to input the filter criteria.

      I also added a section that will return the user’s name to the InputBox as a default value, using the Application.UserName property. This will work well if the user has set their name in Office/Excel, and it matches the value in your spreadsheet. If it doesn’t match then they can retype it in the InputBox. Or you can change Office or the value in the file so they match, and this will save the user time with typing their name.

      The sample file also contains the new macro.

      I hope that helps. Thanks again!

      • Is there a way to make the user input to filter using the search filter function? For example, I have a file that has a column I want to delete rows from that contain the word “Buckslip.” However, the rows containing that keyword have text like, “Buckslip, TRC” as an example. There are may rows with the keyword but the cells do not all contain “TRC” as in this example. I typically use the search function in the filter drop-down to manually filter for Buckslip and then I delete those rows.

        • I figured out that if I enter *buckslip* it will filter correctly. Thanks for the great tutorial!

  • Hi John, as always very informative. Brand new to VBA so doubly appreciate your granular and detailed approach. It “appears” that the range is hard coded for the filter (B3:G1000).

    Is it difficult to determine this range on the fly? .. most situations I encounter, the range is dynamic from one day to the next.

    I would like to begin capturing snippets for reuse and identifying and documenting the multitude of ways to determine the range to manipulate is far and away at the top of my list. Thanks for any direction..

  • Hi Jon – Thanks for another relevant topic and your perfectly executed explanation (and accompanying visuals!) I was wondering if you would consider adding vba code asking the user their filtering/deleting criteria, and then applying their response to the data. This method eliminates the need to write more than one set of macro instructions.
    Thanks again for sharing your Excel expertise!!

    Bob

    • Hi Bob,
      Great question! I just added a new section in the article above for this feature. It uses the Application.InputBox method to prompt the user to specify the filter criteria.

      The sample file has also been updated with the new macro.

      I hope that helps. Thanks! 🙂

  • Jon, your macros are extremely helpful!

    When I use the custom warning message macro, it breaks counting the rows, with the error message: “424: object required”.

    I’m using your exact code:

    lRows = WorksheetFunction.Subtotal(103, lo.ListColumns(1).DataBodyRange.SpecialCells(xlCellTypeVisible))

    Does it make a difference that I’m sorting a csv file as opposed to excel file?

    Thanks

    • Hi Gary,
      The file should definitely be saved as an xlsm file. This code is also for an Excel Table, so the data will need to be in an Excel Table. Or you can modify the code for regular ranges, which is in the first macro.

      I hope that helps.

  • Thanks again Jon,

    Another for me very useful set of macros.

    Together with the “delete blank rows” macro, this comes in very handy.

  • Jon, I love your videos and your instructions! Do you plan on authoring any books?

    In order to avoid errors if the range or table has been saved with filters applied,
    I add this line of code before I filter with my criteria:

    If worksheets(“name”).filtermode = true then worksheets(“name”).showalldata

  • Hi Jon,

    Thanks for this! Is there any way to make your filter look up the values to use to filter? I have a list of things that I need to filter by which I usually do manually using an advanced filter – any way to include this in the macro?

    Thanks
    Bec

  • I am great fan of your easy to understand codes with very simple illustrations to demonstrate what and how the code works. I really appreciate the way you explain and write the code so that non professional or rather beginner can easily understand and modify the code according to his requirements. Thanks for your superb tutorials keep it up.

  • Hi Jon,

    this is super helpful.
    When I modify the criteria it all works, but when there are no rows that match the criteria (I used the code for multiple criteria) it somehow gets stuck, shows no rows and does not show the remaining data again.
    Is there anything I am doing wrong (I used exactly your code and it is working fine if there are rows that match the critera) or should something else be applied to the code?

    Thanks a lot
    Christina

    • I had a similar challenge, and eventually figured out it came down to number formatting. I wanted to delete rows that had zero balances, but they were in dollar format. It wouldn’t work for me until I changed the filter criteria to “$0.00”. Hope this helps!

  • Hi Jon

    I am trying to delete a number of rows from a worksheet as per your first example. I would like to pick up the “Criteria” from a cell on another worksheet in the same workbook.

    I have tried the following:

    Dim Wk as String
    Set Wk = ThisWorkbook.Worksheets(“Design”).Range(“K2”)
    .
    .
    .
    .
    ws.Range(“A2:D1000”).AutoFilter Field:=3, Criteria1:=Wk

    but I get a compile error at the Set WK line of code!

    Where am I going wrong?
    Your help would be much appreciated.

  • Dear Jon, Wonderful, as usual.
    Please correct the code in the Excel Table first example above:
    ws.Activate

    the variable ws has not been declared & hence the code is not performing.

    All that I have learnt in VBA is because of you largely.

  • please am a novice in VBA i will like to modify your VBA code for multiple criteria to filter my data but am having my first column A as date and time in this format 1/1/2015 0:00 so i want to delete each row except between 9:00 and 18:00 daily for every day in a month as each sheet has data for a complete month. please i need your assistance. thanks.

  • Thanks for all the tutorials!
    I am working with your code for deleting rows for multiple criteria in a table.
    How would I apply it with criteria on the same column?

    For example I want to filter for values that are not “A, B, C, D” and delete those rows.

  • How would I go about getting “Delete Rows Based on Criteria Specified by User” to work across multiple sheets but only ask to put in the name one time?

    • Started to try and do it myself and got stuck

      Sub WorksheetLoop()

      Dim WS_Count As Integer
      Dim I As Integer
      Dim lo As ListObject
      Dim lRows As Long
      Dim vbAnswer As VbMsgBoxResult
      Dim sCriteria As Variant

      ‘ Set WS_Count equal to the number of worksheets in the active
      ‘ workbook.
      WS_Count = ActiveWorkbook.Worksheets.Count

      ‘ Begin the loop.
      For I = 1 To WS_Count

      ‘Display Yes/No message prompt before deleting rows

      ‘Set reference to the sheet and Table.
      Set lo = ActiveSheet.ListObjects(1)
      lo.Parent.Activate ‘Activate sheet that Table is on.

      ‘Clear any existing filters
      lo.AutoFilter.ShowAllData

      ‘Ask user for input

      sCriteria = ActiveSheet.Range(“e1”).Value

      ‘Exit if user presses Cancel button
      If sCriteria = False Then Exit Sub

      ‘1. Apply Filter
      lo.AutoFilter.ShowAllData

      ‘trying to set it up to referance one cell, the other worksheets have it set to get the value from the same cell in sheet 1
      lo.Range.AutoFilter Field:=1, Criteria1:=ActiveSheet.Range(“e1″).Value

      ‘Count Rows & display message
      On Error Resume Next
      ‘error message here with this code
      lRows = WorksheetFunction.Subtotal(103, lo.ListColumns(1).DataBodyRange.SpecialCells(xlCellTypeVisible))
      On Error GoTo 0

      vbAnswer = MsgBox(lRows & ” Rows will be deleted. Do you want to continue?”, vbYesNo, “Delete Rows Macro”)

      If vbAnswer = vbYes Then
      ‘Application.DisplayAlerts = False
      lo.DataBodyRange.SpecialCells(xlCellTypeVisible).EntireRow.Delete
      Application.DisplayAlerts = True

      lo.AutoFilter.ShowAllData

      End If

      MsgBox ActiveWorkbook.Worksheets(I).Name

      Next I

      End Sub

  • Looks good but I am getting the following error message when trying to run this:

    o.DataBodyRange.SpecialCells(xlCellTypeVisible).Delete – this brings up and error as does ws.Activate

    ——————-

    Sub Delete_Rows_Based_On_Value_Table()
    ‘Apply a filter to a Table and delete visible rows
    ‘Source: https://www.excelcampus.com/vba/delete-rows-cell-values/

    Dim lo As ListObject

    ‘Set reference to the sheet and Table.
    Set lo = Sheet3.ListObjects(1)
    ws.Activate

    ‘Clear any existing filters
    lo.AutoFilter.ShowAllData

    ‘1. Apply Filter
    lo.Range.AutoFilter Field:=4, Criteria1:=”Product 2″

    ‘2. Delete Rows
    Application.DisplayAlerts = False
    lo.DataBodyRange.SpecialCells(xlCellTypeVisible).Delete
    Application.DisplayAlerts = True

    ‘3. Clear Filter
    lo.AutoFilter.ShowAllData

    End Sub

  • Hi

    This tutorial is good.

    How do yo delete cells in column A to column M depending on the value in column M (blank). I don’t want to delete the entire row!

  • I’m trying to set up a macro to pick up when a row /cell says yes and then copy and paste that data to a new page and refresh the original page….. I can only seem to get out to do row 1, rather than when a row says “yes “…. Can anyone help? Or know someone who can? Ta very muchly!

  • Hi Jon, i am trying to built a macro file to retain certain columns based on the headers and delete rest of all, Valid column headers should be referred with another sheet of excel ( This can be dynamic), i am trying to built it up and unable to do that- can you help me on the same.

  • Hi Jon,
    I am new to Excel macros. In your example, I wasn’t sure where the “Field:=4 comes from. If I wanted to delete all rows where a column date is prior to some value, would I use this?

    s.Range(“AV2:G1000”).AutoFilter Field:=4, Criteria1:=”<= 1/1/2000"

    Thanks so much.

  • Thank you for the information! How would I delete multiple rows with different cells
    For example

    I would like to delete rows with the cell value of 156,158, 189, 200.

    How would that change the criteria1 portion of your macro code:
    lo.Range.AutoFilter Field:=4, Criteria1:=”Product 2″

  • What if No “Product 2” in the selected range/column to delete! will macro stop? Or it will proceed with next step.
    I have set of instructions to create a report everyday i have to select particular data and want to delete that entire row. If i will use above macro to delete data like u did for Product 2. It will do the job but what if my entire worksheet dont have data product 2, will macro stop? How to record macro for this check?

  • Jon,
    I am having trouble with this macro leaving the first row containing the criteria, but deleting all others when I apply it to my data.
    Any suggestions?
    TIA

  • Great tutorial. Thanks. I have one question. Is it possible to make the range dynamic? Like using a variable for lastrow as the 2nd parameter. Thanks.

  • Thank you Jon !!

    I have used your code as the base to create a macro to meet my requirement. What I am trying to achieve is to be able to delete the rows from the original spreadsheet and save it as a NEW file in the same path where the original spreadsheet is located. However, close the original spreadsheet without making any changes (i.e. no row deletion).

    I have 2 issues:
    1. I am not able to disable the Msgbox, as per your suggestion.
    2. Despite selecting “Cancel”, the code continues and save a new file.

    ‘1. Apply Filter
    ws.Range(“A2:W1474″).AutoFilter Field:=21, Criteria1:=”Location”

    ‘2. Delete Rows
    Application.DisplayAlerts = False
    ws.Range(“A2:W1474”).SpecialCells(xlCellTypeVisible).Delete
    Application.DisplayAlerts = True

    ‘On Error GoTo 0

    ‘3. Clear Filter
    On Error Resume Next
    ws.ShowAllData
    On Error GoTo 0

    On Error Resume Next
    wb.SaveAs FileName:=(strFolder & “NEW_” & strFile)
    On Error GoTo 0

    xlApp.Visible = False
    wb.Close

    End Sub

  • Delete Rows Based on Criteria Specified by User

    This is so close to what I need……
    I need it to delete everything BUT what the user has input.

    Delete not equal to the Users input.
    A 1
    A 2
    A 3
    B 4
    B 5
    B 6
    C 7
    C 8
    C 9

    If the user puts in B – I want it to delete all the A & C rows, preserving B

    Any help would be appreciated.

  • Hello,

    Is there a way to run the macros above but on a specific set of worksheets within a workbook? For example all sheets that are a specific tab color? I’m using the delete values within a table if that helps.

    Super handy macro! Thanks so much.

  • Hi Jon,

    What would be a macro to delete rows for the voided sales in the following three columns Excel sheet (i.e., all rows for Tran# 1053899)?

    Tran# Code
    1053898 1 2402C MODELO ESPECIAL 2/12 CN
    1053898 900 1 ITEMS SUBTOTAL
    1053898 941 6.875% NJ Tax on 15.99
    1053898 950 ID # 101 TOTAL
    1053898 980 CASH
    1053898 999 CASH CHANGE
    1053899 1 1515C BUD ICE 25 OZ CAN
    1053899 2 750ML TRAVELERS CLUB VODKA
    1053899 3 375ML SEAGRAMS EXTRA GIN
    1053899 1001 ******* VOID SALE *******
    1053900 1 2402C GROLSCH 2/12 NR
    1053900 900 1 ITEMS SUBTOTAL
    1053900 941 6.875% NJ Tax on 16.99
    1053900 950 ID # 101 TOTAL
    1053900 980 CASH
    1053900 999 CASH CHANGE

  • This helped a lot but I have one issue. The table I want to use this Macro on is in a worksheet that has other data as well. My problem is that when deleting the data in that databodyrange it also deletes the data that is outside of the table on the same rows. Is there a way to fix this?

  • Hi Jon,
    Your tutorial was very helpful and explanatory. Interestingly I’ve tried several different code options and the “.Delete” part of

    Range(“A3:Y1000”).SpecialCells(xlCellTypeVisible).Delete

    simply doesn’t delete the cells. Very frustrating! Can you possibly offer any explanation as to why?

    For reference, I recorded my macro in Excel 365 then debugged/inserted your code where it belonged… I’m trying to clean up a table after a mass copy n paste, deleting unneeded rows based on Column A being blank. As mentioned, everything works perfectly except nothing deletes.

    Thank you so much! I’m sure there is coffee in order if you can help 🙂

  • I love the information you have provided THANK YOU! This is very useful and I am sure it will extend my capabilities. I am trying to crack a nut that I find difficult and I would imagine many other users have ran into a similar issue. I can do the task manually but it takes a long time. It is ideal for a script. The idea is to remove duplicate records meeting certain criteria, i.e. 2 identical records, where one has a “Pass” statement in a cell and the other does not. I need to delete the non-pass (empty) line/record but when duplicate records occur, delete one of the 2 duplicates if no “Pass” component exists. I think this will turn into 2 separate VB Scripts. I will continue searching the web and especially your site as I think you may have already answered enough of this in another article where the information is there it only needs slightly modified or combine 2 and work with it. Again, thanks for a great website!

  • Hi,
    Thank you for the code it works great but how can I do it work on multiple sheets and delete the same criteria.

    Thanks

  • This was brilliant in every way. The solutions are elegant, the documentation and examples thorough, and the video explanation completely accessible, even for an OG like me who knows very little. Thank you!

  • Thanks for this excellent tutorial. I’m very new to excel macros, and I was able to apply this to my worksheet.

    I’d like to be able to delete everything except the user entered value.

    Would I need to add something in the Apply Filter section to filter for everything except sCriteria?

    Or would I need to change something in the Delete Rows section to delete all invisible data? Is there something like SpecialCells(xlCellTypeInvisible)?

    Thanks for your help!

  • Thank you so much, Jon, for the excellent videos. Finding what I’m looking for on the web isn’t always easy, but once I zero in on it and see your name, your explanation hits the spot!

  • Is there a way to prevent the macro from going into debug mode when no target values are present? Say I am targeting blanks and there isn’t any blanks. If the button is hit it goes into debug mode.

  • Hi Jon Acampora,

    I appreciate the code and it works great except when there is no data matching the criteria. How can I clear filters if no data is found so the code does not error out?

  • Thanks for the tips. However, the problem with a statement like:

    ws.Range(“B4:G1000”).SpecialCells(xlCellTypeVisible).Delete

    Is you have no idea how many rows are in the range, so you’re just setting it to a large number (not that 1000 is that large). However, you could make it something like:

    ‘Do we have any visible rows after a filter
    lVisRows = Application.WorksheetFunction.Subtotal(103, ws.Columns(2))

    ‘This also works, I’ve read people complaining the specialcells…cell.count only works if the cells are contiguous, however, always seems to work for me.
    lVisRows = ws.AutoFilter.Range.Columns(2).SpecialCells(xlCellTypeVisible).Cells.Count

    lHeadRow = activesheet.AutoFilter.Range.row

    ‘Greater than the first row of the filter as we don’t want to delete the headings

    If lVisRows > lHeadRow then
    ‘Last actual row (visible or hidden, so the bottom of your filter) in a filtered list:
    lLastRow = ws.AutoFilter.Range.rows.count

    ‘Now delete those visible rows
    ws.Range(“B” & lHeadRow + 1 & “:G” & lLastRow).SpecialCells(xlCellTypeVisible).Delete

Generic filters
Exact matches only

Excel Shortcuts List

keyboard shortcuts list banner

Learn over 270 Excel keyboard & mouse shortcuts for Windows & Mac.

Excel Shortcuts List

Join Our Weekly Newsletter

The Excel Pro Tips Newsletter is packed with tips & techniques to help you master Excel.

Join Our Free Newsletter