Advanced filter is used to filter by a range of criteria, but to get a result based on one criteria gotten by a combobox value, a simple autofilter will do the trick as so:
Private Sub ComboBox1_Change()
Dim lastr As Integer
lastr = Range("A" & Rows.Count).End(xlUp).Row
Sheets("Sheet1").Range("A1:C" & lastr).AutoFilter Field:=3, Criteria1:=ComboBox1.Value, Operator:=xlFilterValues
End Sub
Explanation: the lastrow is dimmed to take an integer (numerical whole value). Then it is determined with the most reliable lastrow method to date.
Then the range A1 to C and your lastrow (So effectively A1:C7
for example) and an autofilter is applied. The field is the column within your range it filters on, 3 in this case means column C (if your range was B:D instead, 3 would mean the 3rd column in the range so column D). The criteria is the value taken directly from your combobox with ComboBox1.value
. The operator xlFilterValues means it will filter by the values found in the column, which will work even if the column has formulas.
Please note: You can get the value directly from the combobox, there is no need to put it in a cell first, but you can do so if you want. Also finding the last row of your data isn’t strictly necessary in this case either, just put range as Range("A:C")
would do as well.
EDIT:
I have also explored the .advancedfilter
method, and even though I don’t know much about it, here are my findings:
Private Sub ComboBox1_Change()
Dim sh As Worksheet: Set sh = ThisWorkbook.Sheets("Sheet1")
Dim lastr As Integer
If sh.FilterMode Then sh.ShowAllData
lastr = sh.Range("A" & Rows.Count).End(xlUp).Row
sh.Range("A1:C" & lastr).AdvancedFilter Action:=xlFilterInPlace, CriteriaRange:=("Table1[#All]"), Unique:=False
End Sub
Notes: There is a combobox with linkedcell F2, the range F1:F2 is in a table called table1. I didn’t get the advancedfilter to work without putting it in a table due to the advancedfilter properties. The header of table 1 needs to be exactly the header of the column you want to filter by. If you set the header to the same as column 1, it will search for the value in the table in column 1.
Explanation: The worksheet dim sets the worksheet to the current file sheet1. This isn’t strictly necessary, but comes in handy later on.
lastr
is the same as last time, determine the last row and apply your filter to this range. Not strictly necessary again, but in this case speeds it up quite a bit.
The If sh.FilterMode Then sh.ShowAllData
is important for when you select a new value. It basically resets the filter so a new filter can be applied. It detects if there is a filter applied to your sheet, and then sets it to show all data. If no filter is applied this is not needed, but if you leave out the test and just put in the showalldata
it will fail since there is nothing else to show and throw an error, therefore the test. If the filter is not reset when applying a new one it will throw an error as well, since the data isn’t found (because it’s filtered out by the previous one).
Then the advancedfilter is applied to the range with your data as previously. The criteria is to note here: it takes the full range of Table1, in this case just the combobox value below the header identical to column 2. The advancedfilter then hides all rows that don’t match these data.
Notes: The advancedfilter can take much more criteria than just the one combobox value.
For every row in Table1, it will handle it as an OR statement: So if in Table 1 I have a header similar to header 2 with below it value A, and a header similar to header 3 with two rows below it value B, it will search the range for column 2 to be A OR column 3 to be B, and hides everything that doesn’t match.
Header2 | Header3 'this will return rows with A under Header2 and rows with B under Header3
A | 0
0 | B
All criteria on the same row is used as an AND statement. If I have the two headers as above, but the A and B are on the same row, then the filter will search for rows with both A and B on the same line.
Header2 | Header3 'this will return rows with both A under Header2 and B under Header3
A | B
This can be expanded with as many columns and values as your data has. Just note that your table cannot have empty values, as this will match with ALL your data. This is the reason advancedfilter, if used right, is much more powerful than .autofilter
as autofilter will only search one column by default and is finicky to work with multiple criteria.
msugak Пользователь Сообщений: 13 |
Добрый день! Просьба помочь с написание кода для решения такой задачи: есть книга excel с двумя листами (файл во вложении), на первом листе расположена таблица с 6 столбцами, под ней две кнопки, которые запускают формы через которые выполняется наполнение таблицы, на втором листе расположен справочник городов. Наполнение таблицы реализовано через две формы, т.к. работать с каждой из них должны разные люди, к примеру один человек заполняет перечень город и адресов с помощью первой формы (код для нее удалось написать самостоятельно), потом человек из города Винница, с помощью второй формы, а именно Combobox’а Город, выбирает Винница и получает в Combobox’е Адрес только те адреса, которые соответствуют этому городу и заполняет дополнительную информацию через textbox’ы, тем самым наполняя таблицу. Вопрос, как заставить вторую форму работать? Надеюсь на помощь, подсказку или готовое решение! |
sva Пользователь Сообщений: 1027 |
|
msugak Пользователь Сообщений: 13 |
Роман, спасибо за ответ! Пытаюсь разобраться с принципом действия… |
sva Пользователь Сообщений: 1027 |
|
msugak Пользователь Сообщений: 13 |
Роман, огромное спасибо! Особенно за комментарии! |
msugak Пользователь Сообщений: 13 |
#6 24.07.2013 11:17:41 С предыдущими примерами разобрался! Спасибо за помощь! Прикрепленные файлы
|
I have already faced a similar situation, but instead of a ComboBox, I needed to filter the ListBox based on the selection of other ListBox and the selection of an Option. The way I found to meet my need was to use a Pivot Table in a hidden sheet. It worked fine for me, bit not all data can be rearranged in a Pivot Table, so I will understand if my suggestion does not work for you.
- First Step: set up a Pivot Table with your data source to be used in your ListBox. Pull the fields you want to filter in the Filters area. Create a dinamic named range with your data, like in the image:
=OFFSET('Certificates Pivot'!$A$5;0;0;COUNTA('Certificates Pivot'!$A$5:$A$50);2)
- Second Step: create your UserForm. I set up 2 ComboBoxes as filters to the ListBox, but you can remove or add as many as you can, you’ll just need to adjust your code. I also named the ranges that will be available in the list options of the ComboBoxes. So we’ll have:
The UserForm’s code will be something like this:
Private Sub UserForm_Initialize()
ComboBox1.RowSource = "CustomerID"
ComboBox2.RowSource = "SalesOrg"
With ListBox1
.RowSource = "Consult_List"
.ColumnCount = 2
.ColumnWidths = "60;90"
End With
End Sub
Private Sub ComboBox1_Change()
Dim SelectedCID As String
Dim SelectedSO As String
SelectedCID = ComboBox1.Text
SelectedSO = ComboBox2.Text
With Sheets("Certificates Pivot").PivotTables("Certificates_PivotTable")
.ClearAllFilters
If Not SelectedCID = "" Then .PivotFields("Customer ID").CurrentPage = SelectedCID
If Not SelectedSO = "" Then .PivotFields("Sales Org.").CurrentPage = SelectedSO
End With
ListBox1.RowSource = "Consult_List"
End Sub
Private Sub ComboBox2_Change()
Call ComboBox1_Change
End Sub
You can hide the sheet where your Pivot Table is, so when you filter it through your UserForm, it will update in the background. You should also set up your Pivot Table to update its cache to capture new inputs in your data source.
I hope it works for you! Let me know what were the results.
Suppose you are asked to add a combo box (drop down) in your sheet and pull values from a range based on selection in the combo box (drop down).
How to add a combo box (drop down)
- Check if Developer tab is enabled.
If it is not enabled, you need to add Developer Tab. To add Developer tab into Excel 2010 and 2013, follow the instructions below:
- Click the File tab
- Click the Options tab
- Click the Customize Ribbon at the left
- At the right, select the Main Tabs from Customize The Ribbon drop down box
- Check the Developer item
- Click the OK button.
2. On the Developer tab, in the Controls group, click Insert, and then under Form Controls, click Combo box Button.
3. Click on the cell(s) where you want the drop down to appear.
4. To display the text box, drag the left-center sizing handle to the right.
Create dummy data
Enter data into column A to C.
Task : Filter data based on column A values listed in drop down.
- Right click on the drop down and select Format Control and then go to Control tab
- In the Input range: enter A2:A6 (values to display in the drop-down list).
- In the Cell link:, enter D1 (cell reference that tells you which value is selected in the drop-down list).
- Press ALT + F11 to open VBA editor window.
- Click on Insert Tab and then click Module option
- In the module, paste the following code
Sub FilterData()
‘Get the Name of ComboBox (Drop Down)
Cbo = Application.Caller‘Get the line number of the entry and the entry data
With Sheets(«Sheet1»).Shapes(Cbo).ControlFormat
CboLine = .ListIndex
cboData = .List(CboLine)
End With‘ turn off any autofilters that are already set
Sheets(«Sheet1»).AutoFilterMode = False‘ filter column A based on combo box selection
ActiveSheet.UsedRange.AutoFilter 1, cboData‘ copy the visible cells to cell E8
ActiveSheet.UsedRange.SpecialCells(xlCellTypeVisible).Copy Range(«E8»)‘ Turn off any autofilters that are already set
Sheets(«Sheet1»).AutoFilterMode = FalseEnd Sub
Next Step : Right Click on the drop down and click Assign Macro and select FilterData and then click OK.
Customize the above code
1. Copy visible cells from one column of a filtered range
ActiveSheet.UsedRange.AutoFilter 1, «Sandy»
rng.SpecialCells(xlCellTypeVisible).Copy
2. Customize filter range — Filter only two columns
lastRow = Sheets(«Sheet1»).Range(«A» & Sheets(«Sheet1»).Rows.Count).End(xlUp).Row
Set filterRange = Sheets(«Sheet1»).Range(«A1:B» & lastRow)
‘ In this case we are filtering Deepanshu from column A
filterRange.AutoFilter 1, «Deepanshu»
3. Copy data only when at least one record is available after applying filter
Sheets(«Sheet1»).UsedRange.AutoFilter 1, cboData
Nrows=Sheets(«Sheet1»).Range(«A1»).CurrentRegion.Columns(1).SpecialCells(xlCellTypeVisible).CountIf Nrows < 2 Then
MsgBox («No record available»)
Else
‘ Your code
4. Copy data from second row (Excluding header)
Sheets(«sheet1»).UsedRange.Offset(1).SpecialCells(xlCellTypeVisible).Copy
Related Link — Filtering and Pasting Data to New Sheet
About Author:
Deepanshu founded ListenData with a simple objective — Make analytics easy to understand and follow. He has over 10 years of experience in data science. During his tenure, he has worked with global clients in various domains like Banking, Insurance, Private Equity, Telecom and Human Resource.
Next →
← Prev
This might seem a very basic question, but it has me completely stumped and from my days in VB6, I was sure this was an automatic feature built into dropdown combo boxes, but in VBA excel (on a form, not sheet!) I am unable to do this.
The form has a single combobox, nothing else.
I have a single column of data in Excel with 90,000 commodities on it. I have manually created a range of all 90,000 items and set the range name of these to ‘rCommodity’.
I run the form, the list populates with all 90,000 perfectly.
As I type into the combobox, I want the list to autofilter itself and contain only those results that contain (not just starting with) the entered text. Two ways I can do this I guess, filter the actual list in the worksheet and then copy the results back into the combobox as the new rowsource or find some way to filter the list in the items of the combobox itself.
My question is this — virtually every combobox today seems to have an autofilter built in that shortlists only those matches with the input text. Is there one of the properties of the excel vba combobox that filters this automatically? Am I missing something obvious or am I going to have to code this into the events of the combobox and filter the list and reload. In which case can someone suggest which event I should be using to perform this? Afterupdate, change, enter?? I have not been able to find a clear explanation of these events of a combobox