VBA code - database Autofilter with cells in orther Sheet - excel

i need your help on the VBA code :
i would like to make a filter on a database according cells in another sheets
my code is working but make a filter only in one cell. How to filter if the code found all cells from the Range
Please see my code :
Sub test()
Sheets("Dashboard").Select
Dim arr As Variant
'arr = Sheets("Dashboard").Range("B4:B11")
With Sheets("Database")
With .Range("A1:Z" & .Cells(.Rows.Count, "A").End(xlUp).Row)
.AutoFilter 'Turn off any previous filtering
.AutoFilter Field:=1, Criteria1:=Sheets("Dashboard").Range("B4:B11")
End With
End With
End Sub
Thanks for your help

Please, test the next way:
Sub filterByRange()
Dim arr, rng As Range
Set rng = Sheets("Dashboard").Range("B4:B11")
rng.TextToColumns Destination:=rng.cells(1), FieldInfo:=Array(1, 2)
arr = rng.Value
arr = Application.Transpose(Application.Index(arr, 0, 1)) '1D array
With Sheets("Database")
With .Range("A1:Z" & .cells(.Rows.count, "A").End(xlUp).row)
.AutoFilter
.AutoFilter field:=1, Criteria1:=arr, Operator:=xlFilterValues
End With
End With
End Sub

Less is more. I adapted the code provided by #FaneDuru utilising some shortcuts. Please note that when it comes to AutoFilter, there’s (usually) no need to specify the complete range you want to filter – it filters all rows meeting the criteria so last column is irrelevant. As long as the data is contiguous, there’s no need to specify the last row either.
Provided for interest only.
Sub testFilter()
Dim Arr
Arr = Sheets("Dashboard").Range("B4:B11").Value
Arr = Application.Transpose(Application.Index(Arr, 0, 1))
With Sheets("Database").Range("A1").CurrentRegion
.AutoFilter 1, Array(Arr), 7
End With
End Sub

Try this:
Sub SubRangeBasedAutofilter()
'Declarations.
Dim RngCell As Range
Dim RngCriteria As Range
Dim StrCriteria() As String
Dim DblCriteriaCount As Double
'Selecting Dashboard sheet.
Sheets("Dashboard").Select '<-IS THIS NECESSARY?
'Setting RngCriteria.
Set RngCriteria = Sheets("Dashboard").Range("B4:B11")
'Redeclaring StrCriteria() with proper size.
ReDim StrCriteria(Excel.WorksheetFunction.Max(Excel.WorksheetFunction.CountA(RngCriteria) - 1, 1))
'Covering each in RngCriteria.
For Each RngCell In RngCriteria
'Checking if RngCell is not empty.
If RngCell.Value <> "" Then
'Storing the criteria.
StrCriteria(DblCriteriaCount) = "=" & RngCell.Value
DblCriteriaCount = DblCriteriaCount + 1
End If
Next
'Focusing Database sheet.
With Sheets("Database")
'Turning off any eventual autofilter.
.AutoFilterMode = False
'Setting a new autofilter.
With .Range("A1:Z" & .Cells(.Rows.Count, "A").End(xlUp).Row)
.AutoFilter Field:=1, Criteria1:=StrCriteria, Operator:=xlFilterValues
End With
End With
End Sub

Related

autofilter erroring out

I want to create an autofilter macro for an excel sheet, that will filter out any rows that do not contain "ballroom*" in Column E, but will also leave any rows where Column E is empty
Have basic programming knowledge, have taught myself what I know thus far in VBA
This is what I have currently
Sub row_deleter()
Dim ws As Worksheet
Dim rng As Range
Dim lastrow As Long
''setting varibles
Set ws = ActiveSheet
lastrow = ws.Range("E" & ws.Rows.count).End(xlUp).Row
Set rng = ws.Range("E1:E" & lastrow)
''actual filter function
With rng
.AutoFilter field:=5, Criteria1:=IsEmpty(rng), Operator:=xlAnd, Criteria2:="=*ballroom*"
.SpecialCells(xlCellTypeVisible).EntireRow.delete
End With
''turn off filters
ws.AutoFilterMode = False
End Sub
When I try to run this code it gives me a 1004 error saying `AutoFilter` method of range class failed, and the debug points to the `AutoFilter` line. Have tried a few things thus far with syntax etc and nothing seems to be working.
First, let's make sure that your table has an AutoFilter. Additionally, your criteria shouldn't be relevant to any range, just what's being filtered. Also, I believe your criteria should be xlOr - a cell can't be blank AND have ballroom in it. Try this:
Sub row_deleter()
Dim ws As Worksheet
Dim rng As Range
Dim lastrow As Long
''setting varibles
Set ws = ActiveSheet
lastrow = ws.Range("E" & ws.Rows.Count).End(xlUp).Row
Set rng = ws.Range("E1:E" & lastrow)
''turn on autofilter if it's off
If ws.AutoFilterMode = False Then
ws.UsedRange.AutoFilter
End If
''actual filter function
With rng
.AutoFilter Field:=1, Criteria1:="=", Operator:=xlOr, Criteria2:="=*ballroom*"
.SpecialCells(xlCellTypeVisible).EntireRow.Delete
End With
''turn off filters
ws.AutoFilterMode = False
End Sub
field:= is an offset and you only have a single column as your range. You want that to be field:=1
You are also using xland you want xlor. Can't have both an empty cell and a cell with ballroom.
.AutoFilter Field:=1, Criteria1:=IsEmpty(rng), Operator:=xlOr, Criteria2:="=*ballroom*"
Thought you have your answer and because of your comment (you want to delete every row which doesn't match your criteria) I adjusted your code to make it easier to read and perform what you actually want it to:
Option Explicit
Sub row_deleter()
Dim lastrow As Long
''setting varibles
'you can use a With ActiveSheet and avoid the use of ws Thought I wouldn't recommend using ActiveSheet unless you attach
'this macro to a button on the sheet itself.
With ActiveSheet
lastrow = .Range("E" & .Rows.Count).End(xlUp).Row
''actual filter function
.UsedRange.AutoFilter Field:=5, Criteria1:="<>", Operator:=xlOr, Criteria2:="<>*ballroom*"
.Range("A2:A" & lastrow).SpecialCells(xlCellTypeVisible).EntireRow.Delete
''turn off filters
.AutoFilterMode = False
End With
End Sub

VBA code: "select rows to delete except headers" (not working)

I have the following code which should simply select a range of rows and delete them. Unfortunately it deletes the headers as well, no matter how I change the range.
I tried to change the "rng" parameter without success.
Thank you for the feedback you can provide.
Sub delete_rows_range()
'Application.ScreenUpdating = False
Dim rng, Rng_del As Range
Dim leg As Range
Set leg = Worksheets("Sheet1").Range("aB1")
Set rng = Worksheets("Sheet1").Range("b1")
If Worksheets("Sheet1").AutoFilterMode = True Then
Worksheets("Sheet1").AutoFilter.ShowAllData
End If
rng.Select
rng.AutoFilter Field:=2, Criteria1:=leg
'rng.Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow.delete
rng.Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow.Select
Worksheets("Sheet1").AutoFilterMode = False
End Sub
Your problem is that you are using a single cell as the range.
When you .Offset a single cell range, then use `xlCelTypeVisible.EntireRow.Delete
Excel selects every cell on the sheet and deletes them.
You really should clarify your range with a properly defined range object. e.g.
Dim ws As Worksheet, lRow As Long, rng As Range
Set ws = Worksheets("Sheet1")
lRow = ws.Cells(Rows.Count, 1).End(xlUp).Row
Set rng = ws.Range("A1:AB" & lRow)
But if you want to use B1 as your rng you can replace your line, rng.Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow.Select with this line...
rng.Range(Cells(2, 2), Cells(rng.Rows.Count, 2)).SpecialCells(xlCellTypeVisible).EntireRow.Delete
You are trying to select from a single cell range.
You should do instead:
Sub delete_rows_range()
'Application.ScreenUpdating = False
Dim rng, Rng_del As Range
Dim leg As Range
Set leg = Worksheets("Sheet1").Range("AB1")
Set rng = Worksheets("Sheet1").Range("B1")
If Worksheets("Sheet1").AutoFilterMode = True Then
Worksheets("Sheet1").AutoFilter.ShowAllData
End If
rng.Select
rng.AutoFilter Field:=2, Criteria1:=leg
'rng.Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow.delete
Worksheets("Sheet1").UsedRange.SpecialCells(xlCellTypeVisible).Rows(2).Select
Worksheets("Sheet1").AutoFilterMode = False
End Sub

How can I have my loop search for a value rather than a string of words?

I have some data that has both words and values in cells and I am trying to delete the rows that don’t have values in the cells. My code works now if all of the numbers are negative but if there are positive numbers then my code won’t work. How do I fix this?
Sub tval
Dim s As Long
Dim LastRow As Long
S=2
LastRow= cells.find(“*”,[A1],,, xlByRows,xlPreviousRow).row
Do until s>LastRow
DoEvents
If InStr(1,Cells(s,4), “-“) > 0 Then
S=s+1
Else
Cells(s,4).EntireRow.Delete
LastRow=LastRow -1
End if
Loop
End sub
When deleting rows, you should always start from the end.
Sub tval
Dim s As Long
Dim LastRow As Long
LastRow= Cells(Rows.Count, 1).End(xlUp).Row
For s= LastRow to 2 Step -1
If Not IsNumeric(Cells(s,4)) then
Cells(s,4).EntireRow.Delete
End if
Next s
End sub
This should work for you:
Sub tgr()
Dim ws As Worksheet
Dim rTextConstants As Range
Dim rTextFormulas As Range
Dim rCombined As Range
Set ws = ActiveWorkbook.ActiveSheet
'Exclude row 1 so that only text values found in rows 2+ are found
With ws.Range("A2", ws.Cells(ws.Rows.Count, ws.Columns.Count))
On Error Resume Next 'prevent error if no cells found
Set rTextConstants = .SpecialCells(xlCellTypeConstants, xlTextValues)
Set rTextFormulas = .SpecialCells(xlCellTypeFormulas, xlTextValues)
On Error GoTo 0 'remove on error resume next condition
End With
If Not rTextConstants Is Nothing Then Set rCombined = rTextConstants
If Not rTextFormulas Is Nothing Then
If rCombined Is Nothing Then Set rCombined = rTextFormulas Else Set rCombined = Union(rCombined, rTextFormulas)
End If
If Not rCombined Is Nothing Then
rCombined.EntireRow.Delete
Else
MsgBox "No cells containing text found in sheet '" & ws.Name & "'", , "Error"
End If
End Sub
May I suggest a bit of a different approach:
Before:
Code:
Dim RNG1 As Range, RNG2 As Range
Option Explicit
Sub TestCase()
With ActiveWorkbook.Sheets(1)
Set RNG1 = .Range("A1:A" & .Cells(Rows.Count, 1).End(xlUp).Row)
If RNG1.SpecialCells(xlCellTypeConstants, 1).Count <> RNG1.Cells.Count Then
Set RNG2 = Application.Intersect(RNG1, RNG1.SpecialCells(xlCellTypeConstants, 2))
RNG2.EntireRow.Delete
End If
End With
End Sub
After:
You'll need to change this around to suit your range obviously. It should be a good starting point nonetheless.
You can also use AutoFilter to filter the numbers, and delete the visible cells to accomplish this task. The code accounts for a header row.
With ThisWorkbook.Sheets("Sheet1")
With .Range("A1").CurrentRegion
.AutoFilter
.AutoFilter Field:=4, Criteria1:="<>*"
.Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow.Delete
.AutoFilter
End With
End With

Adding AutoFilter Criteria one by one

I would like to add AutoFilter Criteria to my excel table in separate Subs.
What I have at the moment looks a little something like this
.AutoFilter Field:=deviceTypeColumnId, Criteria1:=[dScenarioIndependent], Operator:=xlOr, _
Criteria2:=[dSmartphoneDeviceType]
What I would like to have is a method to first filter by Criteria1, and then, in another Sub, add Criteria2 to the existing AutoFilter. To my mind, it should look something like this:
Sub firstSub
.AutoFilter Field:=deviceTypeColumnId, Criteria1:=[dScenarioIndependent]
end sub
Sub secondSub
.AutoFilter mode:=xlAddCriteria, Field:=deviceTypeColumnId, Criteria1:=[dSmartphoneDeviceType]
'I know that mode doesn't exist, but is there anything like that?
end sub
Do you know any way to achieve this?
There isn't, that I know of, a way of "adding on" criteria to a filter which has previously been applied.
I have produced a work-around, which would work for what you are attempting to do. You will just have to add on scenarios to the select case statement, going up to the maximum number of filters which you will want to have.
EDIT: what it does; copy the filtered column to a new worksheet, and remove duplicates on that column. You're then left with the values which have been used to filter the column. Assign the values to an array, and then apply the number of elements of the array as a filter on the column, whilst including the new value you wish to filter on.
EDIT 2: added in a function to find the last row for when a table is already filtered (we want the last row, not the last visible row).
Option Explicit
Sub add_filter()
Dim wb As Workbook, ws As Worksheet, new_ws As Worksheet
Dim arrCriteria() As Variant, strCriteria As String
Dim num_elements As Integer
Dim lrow As Long, new_lrow As Long
Set wb = ThisWorkbook
Set ws = wb.Sheets("data")
Application.ScreenUpdating = False
lrow = ws.Cells(Rows.Count, 1).End(xlUp).Row
ws.Range("A1:A" & lrow).Copy 'Copy column which you intend to add a filter to
Sheets.Add().Name = "filter_data"
Set new_ws = wb.Sheets("filter_data")
With new_ws
.Range("A1").PasteSpecial xlPasteValues
.Range("$A$1:$A$" & Cells(Rows.Count, 1).End(xlUp).Row).RemoveDuplicates _
Columns:=1, Header:=xlYes 'Shows what has been added to filter
new_lrow = Cells(Rows.Count, 1).End(xlUp).Row
If new_lrow = 2 Then
strCriteria = .Range("A2").Value 'If only 1 element then assign to string
Else
arrCriteria = .Range("A2:A" & Cells(Rows.Count, 1).End(xlUp).Row) 'If more than 1 element make array
End If
Application.DisplayAlerts = False
.Delete
Application.DisplayAlerts = True
End With
If new_lrow = 2 Then
num_elements = 1
Else
num_elements = UBound(arrCriteria, 1) 'Establish number elements in array
End If
lrow = last_row
Select Case num_elements
Case 1
ws.Range("$A$1:$A$" & lrow).AutoFilter 1, _
Array(strCriteria, "New Filter Value"), Operator:=xlFilterValues
Case 2
ws.Range("$A$1:$A$" & lrow).AutoFilter 1, _
Array(arrCriteria(1, 1), arrCriteria(2, 1), _
"New Filter Value"), Operator:=xlFilterValues
Case 3
ws.Range("$A$1:$A$" & lrow).AutoFilter 1, _
Array(arrCriteria(1, 1), arrCriteria(2, 1), _
arrCriteria(3, 1), "New Filter Value"), Operator:=xlFilterValues
End Select
Application.ScreenUpdating = True
End Sub
Function:
Function last_row() As Long
Dim rCol As Range
Dim lRow As Long
Set rCol = Intersect(ActiveSheet.UsedRange, Columns("A"))
lRow = rCol.Row + rCol.Rows.Count - 1
Do While Len(Range("A" & lRow).Value) = 0
lRow = lRow - 1
Loop
last_row = lRow
End Function
Hope this helps.

AutoFilter to find blank cells

I am trying to apply an autofilter in VBA for three different criterias in the same field. Once I have applied the filter I would like to find all those cells that are blank, can anyone advise?
Sub ApplyAutoFiler()
Dim ws As Worksheet
Dim I, j, NumberOfErrors As Long
IsErrors = False
Set ws = Sheets("Assessments")
NumberOfErrors = 0
Dim Z As Range
Set Z = Cells(4, 3).EntireColumn.Find("*", SearchDirection:=xlPrevious)
If Not Z Is Nothing Then
NumberOfRows = Z.Row
End If
For I = 4 To NumberOfRows
With ws
.AutoFilterMode = False
.Range("W4:AA4").AutoFilter Field:=1, Criteria1:=Array("A", "B", "C"), Operator:=xlFilterValues
.Cells.SpecialCells(xlCellTypeBlanks).Interior.Color = 65535
.AutoFilterMode = False
End With
Next I
End Sub
I ended up doing this as a nested if statement
If Range("W" & i).Value = "A" Or Range("W" & i).Value = "B" Or Range("W" & i).Value = "C" Then
If Range("AD" & i).Value = "" Then
Range("AD" & CStr(i)).Interior.ColorIndex = 3
NumberOfErrors = NumberOfErrors + 1
End If
End If
This seemed to get me close (it also assumes you have a worksheet called "Assessments"):
Sub ApplyAutoFiler()
Dim ws As Worksheet
Set ws = Sheets("Assessments")
With ws
.AutoFilterMode = False
.Range("A:AZ").AutoFilter Field:=23, Criteria1:=Array("a", "b", "c"), Operator:=xlFilterValues
.Cells.SpecialCells(xlCellTypeBlanks).Interior.Color = 65535
.AutoFilterMode = False
End With
End Sub
I know this treads had been quite long. But just want to share. To filter out blank cells, you could use autofilter using the following criteria:
Worksheets("sheet name").Range("A1").autoFilter Field:=18, Criteria1:=(Blanks)
"Field" refers to the column numbers. As for "Criteria1", it can be either
Criteria1:=(Blanks)
or
Criteria1:="="
or
Criteria1:=""
Something I just discovered today about filtering for blanks using VBA code. Be sure to include this in ALL code where you need to have blank cells:
' Get Rows with blanks
WorkRange.AutoFilter Field:=1, Criteria1:="=", Operator:=xlOr, Criteria2:="=" & ""
' Hides Rows with blanks ... same idea with the "<>" for operator
WorkRange.AutoFilter Field:=1, Criteria1:="<>", Operator:=xlOr, Criteria2:="<>" & ""
The first criteria gets true blank cells and those cells with hidden/non-printable characters, the 2nd criteria gets those cells containing an empty string. Excel user-interface handles this nicely, but VBA code requires both criteria.
This undocumented caveat just cost me several hours of debugging, not to mention a few choice words from my manager about "I thought we were removing the blanks from these columns..."
Just thought I would share, in the hopes of saving you all some headaches.
You don't need VBA for this. You can use Conditional Formatting for this. See this example
In the CF rule, set this formula
=AND($AA5="",OR($W5="a",$W5="b",$W5="c"))
ScreenShot
If you still want VBA then see this
Sub Sample()
Dim blnkRange As Range, rng As Range, aCell As Range
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("Assessments")
With ws
'~~> Sample range for testing purpose
Set rng = .Range("W4:AA11")
.AutoFilterMode = False
With rng
'~~> Filter on "a","b","c"
.AutoFilter Field:=1, Criteria1:=Array("a", "b", "c"), Operator:=xlFilterValues
'~~> Then filter on blanks on Col AA
.AutoFilter Field:=5, Criteria1:="="
'~~> Using offset. Assuming that Row 4 has headers
Set blnkRange = .Offset(1, 0).SpecialCells(xlCellTypeVisible).Cells
End With
.AutoFilterMode = False
End With
'~~> This will give you the blank cells in Col AA
If Not blnkRange Is Nothing Then
For Each aCell In blnkRange
'~~> Color the blank cells red in Col AA
If aCell.Column = 27 Then aCell.Interior.ColorIndex = 3
Next
End If
End Sub

Resources