【问题标题】:Is it possible to use auto-filter or find on a dictionary?是否可以使用自动过滤器或在字典中查找?
【发布时间】:2017-11-13 03:50:02
【问题描述】:

所以我有一个用户表单,其中组合框用作动态搜索框。

需要搜索的数据位于另一个工作簿(1200+ 行)中。为了避免不断打开和关闭该数据工作簿,我在表单初始化期间将其全部加载到字典中。

现在我的问题是:是否可以在用户输入时快速过滤掉字典数据(并更新组合框),还是我需要改变我的方法?

任何帮助将不胜感激。

这是我目前的代码:

Option Explicit
Private emplDict As Object
'all other constants and functions are declared in a separate module named "code"
Private Sub btnClose_Click()
    Unload Me
End Sub
Private Sub comboSearch_Change()
    Me.comboSearch.DropDown
End Sub
Private Sub UserForm_Initialize()
    Dim xlWS As Worksheet
    Dim xlWB As Workbook
    Dim rng As Range
    Dim lstRw As Long
    Dim item As Variant

    Application.Run "code.xlHelper", False ' turn off screen updating, alerts, events

    Set emplDict = CreateObject("scripting.dictionary")
    Set xlWB = Workbooks.Open(Filename:=SUB_PLANNING & EMPLOYEE_LIST)
    Set xlWS = xlWB.Sheets("namen_werknemers")

    With xlWS
        lstRw = .Cells(Rows.Count, 1).End(xlUp).Row
        Set rng = .Range(.Cells(2, 1), .Cells(lstRw, 1))
    End With

    For Each item In rng
        If Not emplDict.exists(item.Value) Then
            emplDict.Add item.Text, item.Offset(0, 1).Text
        End If
    Next

    xlWB.Close False

    Set xlWS = Nothing
    Set xlWB = Nothing

    Application.Run "code.xlHelper", True
End Sub
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
    Set emplDict = Nothing
End Sub

【问题讨论】:

  • 我不知道有任何内置的Dictionary 对象方法来过滤它,所以我会手动进行。但请澄清以下内容: 1) “当用户输入“:用户应该在哪里输入? 2) "(and update combobox)":用什么数据更新什么combobox?
  • user3598756 我的意思是类似于谷歌搜索引擎使用的功能。当用户输入字母时,会出现建议。这一切都发生在一个组合框中。用户输入查询,组合框的下拉菜单打开,显示找到的结果

标签: vba excel


【解决方案1】:

关键是使用字典的键。

使用 VBA Filter 方法返回一个过滤后的 Key 数组。

Private EEDict As Object

Private Sub cboEEList_Change()
    Dim Keys
    Keys = EEDict.Keys
    cboEEList.List = Filter(Keys, cboEEList.Text, True, vbTextCompare)
    cboEEList.DropDown

End Sub

Private Sub UserForm_Initialize()
    Dim arData
    Dim x As Long

    Set EEDict = CreateObject("scripting.dictionary")

    arData = Worksheets("Employees").Range("A1").CurrentRegion.Value2

    For x = 2 To UBound(arData)
        EEDict(arData(x, 1)) = arData(x, 2)
    Next

    cboEEList.List = EEDict.Keys
End Sub

样本数据来自:Fusion Tables - Employees.csv

【讨论】:

  • 好电话,我不认为你可以使用通配符,所以不认为这是可能的,但进一步阅读它有一个过滤器,用于默认以 w3schools.com/asp/func_filter.asp 开头的条目跨度>
  • 哇!惊人。这正是我一直在寻找的。谢谢你,托马斯
  • 很高兴能帮上忙。感谢您接受我的回答。
  • 嗨@ThomasInzina!一个问题,我应该将您的代码放在哪里才能获得与图像中相同的结果?它不在模块中吗?我试过了,也在用户表单中试过,但我只收到错误:/提前谢谢:)
【解决方案2】:

另一种方法,但有点混乱的是记录集,像这样,您需要向其中添加 excel 范围,我已经在其中拼凑了一些值。

Option Explicit

Private rs As ADODB.Recordset

Private Sub ComboBox1_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)

Set rfiltered = New ADODB.Recordset
rs.Filter = "Value like '" & Chr(KeyAscii) & "*'"

If Not rs.EOF Then
    Range("e1").CopyFromRecordset rs
    Me.ComboBox1.RowSource = "E1:E10"
End If

End Sub


Private Sub UserForm_Initialize()

Set rs = New ADODB.Recordset
Dim fieldsArray(1) As Variant
Dim values(1) As Variant

rs.Fields.Append "Key", adVarChar, 5
rs.Fields.Append "Value", adVarChar, 5

fieldsArray(0) = "Key"
fieldsArray(1) = "Value"

values(0) = 4
values(1) = "as"

rs.Open
rs.AddNew fieldsArray, values
rs.Update

End Sub

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-04-18
    • 2010-10-31
    • 1970-01-01
    • 1970-01-01
    • 2020-06-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多