搜索谷歌和搜索引擎优化后,我发现有一种方法可以在字典中搜索现有密钥:
dict.exists("search string")
我的问题是如何使用通配符搜索字典:
dict.exists("search*")
我想首先在字典中搜索一个术语,因为我的宏让用户选择一组文件(文件名作为字典键,完整路径作为值),我想确定某个命名文件是否存在在迭代字典元素以应用文件处理之前,组中存在约定。
如果找到某个命名约定,则对字典中的每个文件运行X处理,而不是Y处理。诀窍在于,如果元素的 ANY 遵循特定的命名约定,那么它们都需要相应地进行处理。也就是说,如果元素1-19不符合约定但是20次通过,则所有元素1-20都需要特定处理。这就是我不能随时检查每个名称并一次有选择地处理一个文件的原因。
我目前的解决方案是在搜索命名约定后迭代整个字典,然后在我知道在处理文件时使用哪种方法后重复字典。我循环遍历所有元素两次,这看起来效率不高......
你们有没有合理的解决方案来搜索字典键的通配符?
答案 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
<强>输出:强>
答案 3 :(得分:0)
如果要使用通配符搜索字典键,则可以使用方法 [yourdictionary] .Keys 和函数 Application.Match
例如: Dim position As Variant'它将返回首次出现的位置
position = Application.Match("*Gonzalez", phoneBook.Keys, 0)
如果电话簿具有密钥:(胡安·卡洛斯,路易斯·冈萨雷斯,佩德罗·冈萨雷斯)
它将返回LuisGonzalez的职位