Filtering By blanks in VBA - excel

Could anyone give me some insight on how to Filter/Delete Blanks using VBA code? For some reason when I record a Macro to do this it is not allowing some of my custom functions built using VBA to hold their values. Thanks.

The below code will delete out rows that have a blank in a selected column. The code below assumes the second column in your data is being tested for blanks. Let us know if you need additional assistance.
Sub DeleteBlanks()
Dim rDataToProcess As Range
Set rDataToProcess = Sheet1.Range("A1").CurrentRegion
'Field in the below method refers to the column that is being filtered, so the second colum
rDataToProcess.AutoFilter field:=2, Criteria1:=""
rDataToProcess.Offset(1).Resize(rDataToProcess.Rows.Count).EntireRow.Delete
Sheet1.AutoFilterMode = False
End Sub

An alternative to delete cells that are blank is to set a range, and use Range([your range]).SpecialCells(xlCellTypeBlanks).Delete
edit: If you want to delete the entire row, Range([your range]).SpecialCells(xlCellTypeBlanks).EntireRow.Delete

Just as #user3561813 said and please take a look at this link for more complicated filters such as multiple criteria, etc:
ActiveSheet.Range("AD1").AutoFilter Field:=30, Criteria1:="", Operator:=xlOr, Criteria2:="XXXX"
For example, the above code filters for both Blanks and "XXXX" fields

Sub Blank_Cells_Filter()
'Apply filters to include or exclude blank cells
Dim lo As ListObject
Dim iCol As Long
'Set reference to the first Table on the sheet
Set lo = Sheet1.ListObjects(1)
'Set filter field
iCol = lo.ListColumns("Product").Index
'Blank cells – set equal to nothing
lo.Range.AutoFilter Field:=iCol, Criteria1:="="
'Non-blank cells – use NOT operator <>
lo.Range.AutoFilter Field:=iCol, Criteria1:="<>"
End Sub

Related

Hide arrows from filter in VBA

I am trying to hide the arrows of the fields in the range that I applied filter manually.
For example I have filtered the range A5:S500 by the column R and then I need a code that hides the arrows from the filer (the first row which is row 5)
I have tried this
Sub HideArrows()
Dim c As Range
With ThisWorkbook.Worksheets(1)
For Each c In .Range("A5:S5")
.Range("A5:S5").AutoFilter Field:=c.Column, VisibleDropDown:=False
Next c
End With
End Sub
But this takes too long time moreover it removes the filtered range
Is there a way to hide the arrows of the filter without removing the filtered range?
Here are two possible ways to workaround this issue; you will need to modify the worksheet, row, and range to meet your specific needs.
The first one inserts an empty row where you want to insert the autofilter, after inserting the autofilter, it will hide the row.
With ThisWorkbook.Sheets("Sheet1")
.Rows(5).EntireRow.Insert
With Range("A5:S5")
.AutoFilter Field:=3, Criteria1:="2"
.EntireRow.Hidden = True
End With
End With
The other way; is to set your range in one column, which will insert only one drop down (in the first cell of the range) and still filter the used range. When you add VisibleDropDown:=False, the single drop down will be hidden.
With ThisWorkbook.Sheets("Sheet1").Range("C4:C20")
.AutoFilter
.AutoFilter Field:=1, VisibleDropDown:=False
End With

combobox, how do i exclude blanks from list retrieved via listobject

Trying to apply data to a combobox, which works out great, except it also include filtered values.
i filter on field 1, filter by a number, there are several empty cells in this row,
those with empty cells in field1 i dont want to see this time.
I pupulate the databodyrange value from column 13 into the combobox list, however even when filtered correctly
it also adds the rows i filtered away.
code..
Private Sub UserFrom_Initialize()
Dim db As ListObject
Set db = Worksheets("baseOfData").ListObjects("database")
db.Range.AutoFilter Field:=1, Criteria1:="<>"
Me.cmbTasks.List = db.ListColumns(13).DataBodyRange.Value
End Sub
I can solve it by running a for loop, and checking every cell before adding it
but that would kinda defeat the purpose of doing it all with 2 lines of code.
any suggestions
however even when filtered correctly it also adds the rows i filtered away.
Me.cmbTasks.List = db.ListColumns(13).DataBodyRange.Value
That is because you are incorrectly doing it. You are referring to complete column and not the filtered range. Try this
Dim db As ListObject
Set db = Worksheets("baseOfData").ListObjects("database")
db.Range.AutoFilter Field:=1, Criteria1:="<>"
Me.cmbTasks.List = db.DataBodyRange.Columns(13).SpecialCells(xlCellTypeVisible).Value
The next problem that you may face will be that it will show values from the first Area only if there are multiple areas.
To handle this, try
Dim db As ListObject
Dim aCell As Range, rngArea As Range
Set db = Worksheets("baseOfData").ListObjects("database")
db.Range.AutoFilter Field:=1, Criteria1:="<>"
'~~> Loop through each area
For Each rngArea In db.DataBodyRange.Columns(13).SpecialCells(xlCellTypeVisible).Areas
'~~> Loop though each cell in the area
For Each aCell In rngArea
cmbTasks.AddItem aCell.Value
Next aCell
Next rngArea
Why not a little simpler (if iteration is an option):
Dim db As ListObject, cel As Range
Set db = Worksheets("baseOfData").ListObjects("database")
For Each cel In db.DataBodyRange.Columns(13).Cells
If cel.EntireRow.Hidden <> True Then
cmbTasks.AddItem cel.value
End If
Next
Would you like to do some modifications on the table, according to selected combo value? If yes, the real row number associated to each combo value must be memorized. In a hidden column of the combo, for instance (using cel.Row).

Delete Table Row Based on Criteria VBA

I am attempting to delete a specific table row based on values in two columns. I attempted to apply filters to the table columns to narrow my criteria, but once I click delete, the ENTIRE ROW is deleted causing values outside of the table to be deleted. Also, the macro recorder isn't as dynamic as I'd like it to be, since it ONLY selects the cell I clicked while recording.
Sub Macro2()
'
' Macro2 Macro
'
'
ActiveSheet.ListObjects("Table1").Range.AutoFilter Field:=1, Criteria1:= _
"Apple" \\Narrowing criteria in Column 1 of the table
Range("A4").Select \\This only applies to a specific cell, and the value can shift
Selection.EntireRow.Delete \\This will delete the entire sheet row, I'd like for only the table row to be deleted
Range("A5").Select
Selection.EntireRow.Delete
Selection.EntireRow.Delete
End Sub
Is there a way to find the desired string in a column and delete only the rows in the table once the criteria is met? I attempted to only delete the ListObject.ListRows, but it only references the row I've selected, and not the one based off criteria.
You could use .DataBodyRange and .SpecialCells(xlCellTypeVisible) to set a range variable equal to the filtered ranges, then unfilter and delete:
Dim dRng As Range
With ActiveSheet.ListObjects("Table1")
.Range.AutoFilter Field:=1, Criteria1:="Apple"
If WorksheetFunction.Subtotal(2, .DataBodyRange) > 0 Then
Set dRng = .DataBodyRange.SpecialCells(xlCellTypeVisible)
.Range.AutoFilter
dRng.Delete xlUp
End If
End With
You will have to indicate which cells/range you want to delete. You can find the relevant row by using the find function. Since your table is static I would propose the following macro.
A for loop checking each row is also possible, but not so efficient for a very large table. It can be useful to prepare your dataset by adding a flag to column c (e.g. a 1 if to be deleted).
EDIT suggestion by Tate also looks pretty clean
Sub tabledelete()
Dim ws As Worksheet
Dim rangecheck As Range
Dim rcheck As Integer
Set ws = Sheets("Sheet1") 'fill in name of relevant sheet
Set rangecheck = Range("A1") ' dummy to get the do function started
Do While Not rangecheck Is Nothing
With ws
With .Range("C2:C30") ' fill in relevant range of table
Set rangecheck = .Find(what:=1, LookAt:=xlWhole)
End With
If Not rangecheck Is Nothing Then 'only do something if a 1 is found
rcheck = rangecheck.Row
.Range(.Cells(rcheck, 1), .Cells(rcheck, 3)).Delete Shift:=xlUp 'delete 3 columns in row found
End If
End With
Loop
End Sub

How to use <> array criteria

let me ask my problem, i'm just a beginner in vba.
I have to filter a column with criteria
<>array ("0402", "0603", "0805", "1206").
i have tried this one but not work for me :
Rows (1).AutoFilter Field:=9, Criteria1:=Array("=<>0402", =<>0603", "=<>0805", "=<>1206"), Operator:=xlFilterValues
For information, value in column field 9 is paste value of right text function. So what i have to define the character? is it text or numeric? and how about the array?
you can use only two not equal to criteria's. Refer the below post for more clarity
Autofilter for multiple not equal values
Public Sub REName_()
Dim d1() As Variant: d1 = Array("0402", "0603", "0805", "1206")
Dim r As Range: Set r = Cells(1, 1).CurrentRegion
r.AutoFilter Field:=1, Criteria1:=d1, Operator:=xlFilterValues
End Sub

AutoFilter - Dynamically change in Filter Criteria

I'm having the same kind of question as in this link -
Get AutoFilter sort criteria and apply on second sheet
I've gone thru the link but not able to get the required output.
I've the filtered criteria in Sheet1 (which we can change as required) on one of the column values (eg: col 10) and now based on what ever the data in column 10 which are shown based on the filter criteria, I want to filter on sheet2 with the data in sheet 1.
I have seen that many of them using with static values in ARRAY as shown but how can I autofilter dynamically changing values in the sheet1 and filtering in Sheet2. Please advise
.AutoFilter Field:=10, Criteria1:=Array("value1", "value2"), Operator:=xlFilterValues
What if you just define the array in VBA?
Dim CritArray(2) as String
CritArray(0) = Cells(1,1).Value
CritArray(1) = Cells(2,1).Value
Then just editing your line of code:
.AutoFilter Field:=10, Criteria1:=Array(CritArray(0),CritArray(1)), Operator:=xlFilterValues
I dont know how many criteria you have (or their location), but you can add/edit as such. I based this off the fact you only have 2 criteria, but it can be enlarged of course.
I think you want something like this:
Sub tgr()
Dim wsData As Worksheet
Dim wsCriteria As Worksheet
Dim arrCriteria As Variant
Set wsData = Sheets("Sheet2")
Set wsCriteria = Sheets("Sheet1")
arrCriteria = Application.Transpose(wsCriteria.Range("J4", wsCriteria.Range("J4").End(xlDown)).Value)
With wsData.UsedRange
.AutoFilter 10, arrCriteria, xlFilterValues
End With
Set wsData = Nothing
Set wsCriteria = Nothing
If IsArray(arrCriteria) Then Erase arrCriteria
End Sub

Resources