#excel #vba
#excel #vba
Вопрос:
У меня есть таблица ниже:
Я пытаюсь отфильтровать данные, а затем отобразить отфильтрованные данные в Listbox в пользовательской форме. Код пока:
Dim iList As Variant
Sheet1.ListObjects("PostOneTable").Range.AutoFilter Field:=1, Criteria1:=TextBox1.Value amp; "*"
Sheet1.ListObjects("PostOneTable").Range.AutoFilter Field:=2, Criteria1:=TextBox2.Value amp; "*"
Sheet1.ListObjects("PostOneTable").Range.AutoFilter Field:=3, Criteria1:=TextBox3.Value amp; "*"
Sheet1.ListObjects("PostOneTable").Range.AutoFilter Field:=5, Criteria1:=TextBox4.Value amp; "*"
Dim jList As Range
Set jList =
Sheet1.ListObjects("PostOneTable").DataBodyRange.SpecialCells(xlCellTypeVisible)
ListBox1.List = jList
Однако при запуске кода я сталкиваюсь с несколькими проблемами.
Во-первых, фильтры, похоже, применяются неправильно. Например, если я использую строку, такую как:
Sheet1.ListObjects("PostOneTable").Range.AutoFilter Field:=1, Criteria1:="ryd"
Я ожидал бы увидеть только четвертый элемент, как в таблице, так и в ListBox. Однако оба они пустые.
Вторая проблема заключается в том, что код не переносит отфильтрованный список в текстовое поле.
Пожалуйста, обратите внимание, что мне известны другие способы поиска, использующие циклы. Однако этот метод хорош тем, что конечные пользователи смогут видеть результаты своих действий над формой непосредственно в таблице.
Спасибо!
РЕДАКТИРОВАТЬ: Поиграв с этим, я заметил кое-что интересное. Если я закомментирую раздел, который переносит данные в listbox, И перепишу строки фильтрации, фильтрация теперь работает.
Комментарии:
1. ListBox должен быть отформатирован так, чтобы в нем было столько столбцов, сколько в списке, который вы ему назначаете. Вы также должны указать ширину для всех столбцов и назначить BoundColumn.
2. @Variatus все готово. Listbox содержит шесть столбцов, ширина которых указана правильно. Все это было сделано в поле свойств, а не в коде
3. В этом случае попробуйте присвоить listbox нефильтрованный диапазон базы данных. Если это сработает, перенесите
jList.Value
в массив, отформатированный вашим кодом. Если это не сработает, перенеситеjList.Value
в массив строк. Но в любом случае потребуется столько же кода и времени, сколько при использовании метода Add для заполнения listbox 🙂4. @Variatus код ошибки: «Не удалось установить свойство List. Недопустимый индекс массива свойств». ошибка в «ListBox1.List = JList». Можете ли вы показать мне метод добавления? После публикации я, возможно, стал большим поклонником цикла…
5.
AddItem
Метод немного сложен для нескольких столбцов данных и намного медленнее, чем назначение массива дляListBox.List
. Но, вероятно, для моего ответа начинающему или среднему разработчику будет проще написать мой ответ.
Ответ №1:
Range.Value
возвращает только значения из первой области диапазона. Range.SpecialCells(xlCellTypeVisible)
вернет диапазон, содержащий область для каждого непрерывного блока ячеек.
ListBox1.List = jList
ListBox1.List
будут иметь данные только для первой группы видимых строк (первые находятся в jList
).
Вы все еще можете использовать ListObject
для фильтрации данных. Вам просто нужно написать функцию для возврата видимых данных. Это простая задача, которую нужно выполнить.
ListBox1.List = ListObjectVisibleData(Лист1.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
Комментарии:
1. Вау. Как шарм. Мне кое-что интересно. Что такое «ReDim»? Я не видел многого, но я определенно никогда не видел этого. Конечно, это не учебная сессия…
2.
ReDim
является сокращением отRedimension
. Это позволяет вам устанавливать размеры массива. Вы должны ввести Redim в code module и нажать F1, чтобы перейти к справочной документации.