Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/apache-kafka/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vba 字典的通配符搜索_Vba_Excel_Excel 2010 - Fatal编程技术网

Vba 字典的通配符搜索

Vba 字典的通配符搜索,vba,excel,excel-2010,Vba,Excel,Excel 2010,在搜索google等之后,我发现有一种方法可以让我在字典中搜索现有密钥: dict.exists("search string") 我的问题是如何使用通配符搜索词典: dict.exists("search*") 我想先在字典中搜索一个术语,因为我的宏让用户选择一组文件(文件名作为字典键,完整路径作为值),我想在迭代字典元素以应用文件处理之前确定组中是否存在具有某种命名约定的文件 如果找到某个命名约定,则对字典中的每个文件运行X处理,而不是Y处理。诀窍在于,如果任何元素遵循特定的命名约定,那

在搜索google等之后,我发现有一种方法可以让我在字典中搜索现有密钥:

dict.exists("search string")
我的问题是如何使用通配符搜索词典:

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

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

我目前的解决方案是在搜索命名约定时迭代整个字典,然后在我知道在处理文件时使用哪种方法后重复字典。我在所有元素中循环了两次,这似乎没有效率


你们有一个通配符搜索字典键的合理解决方案吗?

这个方法可以帮助你们在字典中进行通配符搜索

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

Dictionary Items方法返回所有项的数组。您可以将这些字符串合并成一个大字符串,然后使用
Instr()
确定您的搜索字符串是否在大字符串中

从您的示例中,您的末尾有星号,因此我假设您关心项目如何开始,而不是子字符串是否存在。因此,我查找delimiter+子字符串,并将delimiter添加到
连接的前面(为了第一项)。如果你有不同的要求,你必须调整,但理论是一样的

我使用两个管道作为分隔符,因为它不太可能出现在数据中并返回假阳性。这可能不适合您的数据

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
测试代码


您可以将筛选器与字典键数组结合使用,以返回匹配键数组

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
输出:


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

例如: 变暗位置作为变量“它将返回第一次出现的位置

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

如果电话簿上有键:(胡安卡洛斯、路易斯冈萨雷斯、佩德罗冈萨雷斯)


它将返回LuisGonzalez的位置

通过字典键循环(甚至两次)可能只需要处理任何文件所需时间的一小部分,因此我不必担心。无论如何,这几乎是您唯一的选择,因为Exists不支持通配符匹配。好的。我认为这才是真正的“答案”,但我想尝试下面这些解决方案作为解决办法。Dick的方法当然是一个很好的方法,可以在可重用的函数中完成您想要做的事情。OP似乎想要跨键搜索(文件名与完整路径),所以应该是
Join(dc.Keys,sDELIM)
?exists功能在
dict.keys
上运行。在这个回答中,
LCase(Dic(键))
比较一个值。但是,您可以使用
LCase(KeY)
进行比较keys@Axel相信我,我确切地知道
exists
是如何工作的,但请在发表评论之前仔细阅读OP,
exists
不支持使用通配符进行搜索。我不是想质疑您对exists函数的了解。只是想帮助更多的观众。。。我认为你的答案是最合适的。但是,检查通配符的值,而不是键。
position = Application.Match("*Gonzalez", phoneBook.Keys, 0)