Reputation: 531
I have a table below:
I'm trying to filter the data and then display the filtered data to a Listbox on a userform. Code so far:
Dim iList As Variant
Sheet1.ListObjects("PostOneTable").Range.AutoFilter Field:=1, Criteria1:=TextBox1.Value & "*"
Sheet1.ListObjects("PostOneTable").Range.AutoFilter Field:=2, Criteria1:=TextBox2.Value & "*"
Sheet1.ListObjects("PostOneTable").Range.AutoFilter Field:=3, Criteria1:=TextBox3.Value & "*"
Sheet1.ListObjects("PostOneTable").Range.AutoFilter Field:=5, Criteria1:=TextBox4.Value & "*"
Dim jList As Range
Set jList =
Sheet1.ListObjects("PostOneTable").DataBodyRange.SpecialCells(xlCellTypeVisible)
ListBox1.List = jList
However, upon running the code, I run into a few problems. Firstly, the filters don't seem to apply correctly. For example, if I use a string, such as:
Sheet1.ListObjects("PostOneTable").Range.AutoFilter Field:=1, Criteria1:="ryd"
I would expect to only see the fourth item, both in the Table and in the ListBox. However, both are blank.
Second issue is that the code doesn't drive the filtered list to the textbox.
Please note that I am aware of other ways to search, using loops. However, this method is good because the end users will be able to see results of their actions on the form directly in the table.
Thanks!
EDIT: Upon playing with it, I noticed something interesting. If I comment out the section that drives the data to the listbox AND rewrite the filtering lines, the filtering now works.
Upvotes: 2
Views: 2120
Reputation: 7759
Range.Value
only returns the values from the first area in a range. Range.SpecialCells(xlCellTypeVisible)
will return a Range that has an Area for each contiguous block of cells.
ListBox1.List = jList
ListBox1.List
will only have the data for the first group of visible rows (the first Are in jList
).
You can still use the ListObject
to filter the data. You just need to write a function to return the visible data. Which is a trivia task to do.
ListBox1.List = ListObjectVisibleData(Sheet1.ListObjects("PostOneTable"))
Public Function ListObjectVisibleData(ByVal ListObject As ListObject)
Dim Map As New Collection
Dim Row As Range
For Each Row In ListObject.DataBodyRange.Rows
If Not Row.EntireRow.Hidden Then
Map.Add Row
End If
Next
Dim Results As Variant
Dim r As Long, c As Long
If Map.Count = 0 Then
ReDim Results(1 To 1, 1 To ListObject.ListColumns.Count)
Else
ReDim Results(1 To Map.Count, 1 To ListObject.ListColumns.Count)
For Each Row In Map
r = r + 1
For c = 1 To UBound(Results, 2)
Results(r, c) = Row.Cells(1, c).Value
Next
Next
End If
ListObjectVisibleData = Results
End Function
Upvotes: 2