Использование элементов управления (ComboBox) в рабочем листе для управления автоматическим фильтром - PullRequest
0 голосов
/ 16 мая 2019

Копирование отфильтрованных данных на другой лист, где пользователь вводит критерии фильтрации через ComboBox (пользовательская форма или ActiveX)

В конечном итоге я хочу скопировать выбранные данные из набора основных данных на одном листе в другой лист. Чтобы выделить соответствующие данные для копирования через я планирую использовать фильтры. Я хочу включить в рабочую таблицу объект раскрывающегося списка, который позволит пользователю выбрать критерии фильтрации

По сути, это просто репликация функции фильтра данных Excel, но без ограничения по позициям для фильтруемого столбца.

Я предполагаю, что пользовательская форма или ActiveX ComboBox - это способ добиться этого? Это где я терплю неудачу. Я не могу понять, как вызвать значение, выбранное пользователем в ComboBox, чтобы сообщить процедуре автофильтра.

Sub M_00()

    Dim wB As Workbook
    Dim wS1, wS2 As Worksheet
    'Dim x As ???
    Dim rng3 As Range
    Dim lrowS3 As Long

    Set wB = This.Workbook
    Set wS1 = wB.Sheets(1)
    Set wS3 = wB.Sheets(3)

    'define range for Combo Box drop down list from data on Sheet 3
    lrowS3 = wS3.Cells(Rows.Count, 1).End(xlUp).Row

    Set rng3 = wS3.Range(Cells(2, 2), Cells(lrowS3, 2))

    'Don't know how to
    ' a) assign my rng3 values to the ComboBox drop down list
    ' b) call the selection from the ComboBox to inform my AutoFilter

    wS1.ComboBox1.List = rng3.Value

    x = wS1.ComboBox1.Selection

    ' turn off any autofilters that may already be active in Sheet 1
    wS1.AutoFilterMode = False

    ' filter column 4 based on combo box selection
    wS1.UsedRange.AutoFilter Field:=4, Criteria1:=x

    'Once filtered I plan you assign the visible data to an array and copy 
    'it to the required sheet.
End Sub

Ответы [ 3 ]

0 голосов
/ 16 мая 2019

Так что я не уверен, что получаю 100% того, что вы пытаетесь сделать, но вот один из способов сделать это:

Следующий подход предназначен для работы со списком ActiveX.

Для простоты предположим, что у вас есть следующие настройки:

enter image description here

Значения фильтра находятся в A1:A8, и вы хотите отфильтровать столбец C по названию дня.

Во-первых, вам нужен сабвуфер, который инициализирует поле со списком. Это может быть расположено в вашем модуле. Как называется sub, решать вам. Если список необходимо регулярно обновлять, у вас может быть специальная кнопка для этого.

Sub initializeComboBox() 'The name of the Sub is self explanatory

Dim sht As Worksheet
Set sht = ThisWorkbook.Worksheets("Name of your Worksheet") 'The worksheet where the combobox is located
With sht.OLEObjects("ComboBox1").Object 'Referring to the combobox from outside the worksheet where it's located can be a bit tricky
    .Clear 'Clear the combobox's list
    .List = sht.Range("A1:A8").Value 'assign the values contained in range A1:A8 to the combobox's list
End With

End Sub

Затем вам нужно событие, которое будет фиксировать изменение значения поля со списком всякий раз, когда пользователь выбирает его. Это должно быть расположено на рабочем листе, к которому относится комбинированный список.

Private Sub ComboBox1_Change() 'This event fires up whenever the user selects an item from the dropdown menu
Dim x As String
x = ComboBox1.Value 'referring to the combobox from inside the worksheet where it belongs is easier
Module1.testFilter (x)
End Sub

Тогда у вас может быть либо sub, который находится в вашем модуле и вызывается этим событием, либо вы можете просто делать все, что захотите, используя само событие. Я применил первый подход здесь, но это действительно ваш выбор.

Sub testFilter(filterValue As String) 'A sub that is located in the module and applies the filter. This is called whenever the Value of the combobox is changed

Dim sht As Worksheet
Dim rngToBeFiltered As Range
Set sht = ThisWorkbook.Worksheets("Name of your Worksheet") 'The worksheet where the range that needs to be filtered is located
Set rngToBeFiltered = sht.Columns("C")
If filterValue = "No Filter" Then
    rngToBeFiltered.AutoFilter field:=1 'If No Filter is selected then all data is displayed
Else
    rngToBeFiltered.AutoFilter field:=1, Criteria1:=filterValue 'else the filter is applied
End If

End Sub

Результат бы так:

enter image description here

0 голосов
/ 22 мая 2019

В итоге я разделил операцию на два модуля, M_00_Filter () и M_00_Generate ().

Сначала выполняется фильтрация данных на основе выбора из выпадающего списка формы пользователя, статически назначаемого диапазону из другого листа в той же книге.

Sub M_00_Filter()

Dim wB As Workbook
Dim myindex As Long
Dim filterValue As String
Dim wS As Worksheet
Dim rng2BF As Range

Set wB = ThisWorkbook
Set wS = wB.Sheets("Master Schedule")

'~~> Currently selected item index at runtime
myindex = wS.Shapes("Drop Down 1").ControlFormat.Value

'~~> Currently selected item value at runtime
filterValue = wS.Shapes("Drop Down 1").ControlFormat.List(myindex)

lRow = wS.Cells(wS.Rows.Count, 4).End(xlUp).Row
lCol = wS.Cells(5, wS.Columns.Count).End(xlToLeft).Column

'Set rngToBeFiltered
Set rng2BF = wS.Range(Cells(5, 1), Cells(lRow, lCol))

If filterValue = "Select a Phase" Then

    rng2BF.AutoFilter field:=4 'If No Filter is selected then all data is displayed

Else

    rng2BF.AutoFilter field:=4, Criteria1:=filterValue 'else the filter is applied

End If

End Sub

Второй модуль копирует видимые данные и копирует их в другую рабочую книгу. Еще раз спасибо за вашу помощь.

Ценю всех вас, что нашли время. Приветствия.

0 голосов
/ 16 мая 2019

По сути, автофильтр скрывает целые строки, которые не соответствуют выбору. В этом примере я собираю информацию, которую вы ищете, если в столбце B

'getting the value I am looking for
  cbVal = comboBox1.Text

 'getting the last row filled
 lr = activesheet.cells(rows.count,2).end(xlup).row


'asuming that B1 is the title of the table, so I'm starting since B2 to last row

for i = 2 to lr
if not activesheet.range("B"&i) == cbVal then
  activesheet.range("B"&i).entireRow.Hidden = true
end if
next i

Наконец, вы установите еще один sub для показа строк

for i = 2 to lr
activesheet.range("B"&i).hidden = false
next i

Надеюсь, это решило вашу проблему, я не проверял вас, но идея в том, что вы получаете логику

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...