通配符搜索字典

时间:2015-01-30 23:03:54

标签: vba excel-vba excel-2010 excel

搜索谷歌和搜索引擎优化后,我发现有一种方法可以在字典中搜索现有密钥:

dict.exists("search string")

我的问题是如何使用通配符搜索字典:

dict.exists("search*")

我想首先在字典中搜索一个术语,因为我的宏让用户选择一组文件(文件名作为字典键,完整路径作为值),我想确定某个命名文件是否存在在迭代字典元素以应用文件处理之前,组中存在约定。

如果找到某个命名约定,则对字典中的每个文件运行X处理,而不是Y处理。诀窍在于,如果元素的 ANY 遵循特定的命名约定,那么它们都需要相应地进行处理。也就是说,如果元素1-19不符合约定但是20次通过,则所有元素1-20都需要特定处理。这就是我不能随时检查每个名称并一次有选择地处理一个文件的原因。

我目前的解决方案是在搜索命名约定后迭代整个字典,然后在我知道在处理文件时使用哪种方法后重复字典。我循环遍历所有元素两次,这看起来效率不高......

你们有没有合理的解决方案来搜索字典键的通配符?

4 个答案:

答案 0 :(得分:4)

Dictionary Items方法返回所有项目的数组。您可以将它们加入一个大字符串,然后使用Instr()来确定您的搜索字符串是否在大字符串中。

从你的例子中,你最后有星号,所以我假设你关心项目是如何开始的,而不是任何地方都存在子串。所以我查找分隔符+子字符串并将分隔符添加到Join的前面(为了第一个项目)。如果你有不同的要求,你必须调整,但理论是一样的。

我使用了两个管道作为分隔符,因为它不太可能存在于数据中并返回误报。这可能不适合您的数据。

Public Function WildExists(ByRef dc As Scripting.Dictionary, ByVal sSearch As String) As Boolean        
    Const sDELIM As String = "||"        
    WildExists = InStr(1, sDELIM & Join(dc.Keys, sDELIM), sDELIM & sSearch) > 0        
End Function

测试代码

Sub Test()

    Dim dc As Scripting.Dictionary            
    Set dc = New Scripting.Dictionary

    dc.Add "Apple", "Apple"
    dc.Add "Banana", "Banana"
    dc.Add "Pear", "Pear"

    Debug.Print WildExists(dc, "App") 'true
    Debug.Print WildExists(dc, "Ora") 'false

End Sub

答案 1 :(得分:1)

此方法可以帮助您在Dictionary中进行通配符搜索

Sub test()
Dim Dic As Object: Set Dic = CreateObject("Scripting.Dictionary")
Dim KeY, i&: i = 1
For Each oCell In Range("A1:A10")
    Dic.Add i, Cells(i, 1).Value: i = i + 1
Next
For Each KeY In Dic
    If LCase(Dic(KeY)) Like LCase("Search*") Then
        MsgBox "Wildcard exist!"
        Exit For
    End If
Next
End Sub

答案 2 :(得分:1)

您可以使用Filter与字典键数组相结合来返回匹配键的数组。

Function getMatchingKeys(DataDictionary As Dictionary, MatchString As String, Optional Include As Boolean = True, Optional Compare As VbCompareMethod = vbTextCompare) As String()

    getMatchingKeys = Filter(DataDictionary.Keys, MatchString, Include, Compare)

End Function

以下是将过滤器应用于字典键时可以执行的操作的一些示例。

选项明确

Sub Examples()
    Dim dict As Dictionary
    Dim arrKeys() As String
    Dim key

    Set dict = New Dictionary

    dict.Add "Red Delicious apples", 10
    dict.Add "Golden Delicious Apples", 5
    dict.Add "Granny Smith apples", 66
    dict.Add "Gala Apples", 20
    dict.Add "McIntosh Apples", 30
    dict.Add "Apple Pie", 40
    dict.Add "Apple Sauce", 50

    dict.Add "Anjuo Pears", 60
    dict.Add "Asian Pears", 22
    dict.Add "Bartlett Pears", 33
    dict.Add "Bosc Pears", 44
    dict.Add "Comice Pears", 3

    arrKeys = getMatchingKeys(dict, "Apple")
    Debug.Print "Keys that contain Apple"
    Debug.Print Join(arrKeys, ",")
    Debug.Print

    arrKeys = getMatchingKeys(dict, "Apple", False)
    Debug.Print "Keys that do not contain Apple"
    Debug.Print Join(arrKeys, ",")
    Debug.Print

    arrKeys = getMatchingKeys(DataDictionary:=dict, MatchString:="Apple", Include:=True, Compare:=vbBinaryCompare)
    Debug.Print "Keys that contain matching case Apple"
    Debug.Print Join(arrKeys, ",")
    Debug.Print

    arrKeys = getMatchingKeys(DataDictionary:=dict, MatchString:="Pears", Include:=True, Compare:=vbTextCompare)
    Debug.Print "We can also use the array of keys to find the values in the dictionary"
    Debug.Print "We have " & (UBound(arrKeys) + 1) & " types of Pears"
    For Each key In arrKeys
        Debug.Print "There are " & dict(key) & " " & key
    Next

End Sub

<强>输出:

enter image description here

答案 3 :(得分:0)

如果要使用通配符搜索字典键,则可以使用方法 [yourdictionary] .Keys 和函数 Application.Match

例如: Dim position As Variant'它将返回首次出现的位置

position = Application.Match("*Gonzalez", phoneBook.Keys, 0)

如果电话簿具有密钥:(胡安·卡洛斯,路易斯·冈萨雷斯,佩德罗·冈萨雷斯)

它将返回LuisGonzalez的职位