Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/15.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
Arrays 在vba中创建黑名单的最佳方法?_Arrays_Vba_Arraylist_Range - Fatal编程技术网

Arrays 在vba中创建黑名单的最佳方法?

Arrays 在vba中创建黑名单的最佳方法?,arrays,vba,arraylist,range,Arrays,Vba,Arraylist,Range,我正在尝试创建一个排除一些项目的arraylist 示例:列表a包含{a,b,c,d,e,f,g} 黑名单包含{a,c,e} 我希望我的新列表只有{b,d,f,g} 这是我到目前为止试过的 Dim a As Object Set a = CreateObject("System.Collections.ArrayList") Dim blacklist As Object Set blacklist = CreateObject("System.Collectio

我正在尝试创建一个排除一些项目的arraylist

示例:列表a包含{a,b,c,d,e,f,g} 黑名单包含{a,c,e} 我希望我的新列表只有{b,d,f,g}

这是我到目前为止试过的

Dim a As Object
Set a = CreateObject("System.Collections.ArrayList")

Dim blacklist As Object
Set blacklist = CreateObject("System.Collections.ArrayList")

Dim newList As Object
Set newList = CreateObject("System.Collections.ArrayList")

a.Add "a"
a.Add "b"
a.Add "c"
a.Add "d"
a.Add "e"
a.Add "f"
a.Add "g"


blacklist.Add "a"
blacklist.Add "c"
blacklist.Add "e"


For Each c In a
    For Each b In blacklist
      If c.value <> b Then newList.Add c.value
    Next b
Next c
将对象变暗为对象
设置a=CreateObject(“System.Collections.ArrayList”)
作为对象的黑名单
Set blacklist=CreateObject(“System.Collections.ArrayList”)
Dim newList作为对象
Set newList=CreateObject(“System.Collections.ArrayList”)
a、 加上“a”
a、 加上“b”
a、 加上“c”
a、 加上“d”
a、 加上“e”
a、 加上“f”
a、 加上“g”
黑名单。添加“a”
黑名单。添加“c”
黑名单。添加“e”
对于a中的每个c
对于黑名单中的每个b
如果c.value为b,则新建列表。添加c.value
下一个b
下一个c

它不起作用,从arraylist打印项目两次

首先,需要将
c.value
替换为
c
。现在代码运行了,但它是错误的,因为它将简单地将每个字母添加多次,最终您将得到重复的字母

您需要替换此:

For Each c In a
    For Each b In blacklist
      If c.value <> b Then newList.Add c.value
    Next b
Next c
代码将按预期运行

当然,@ScottCraner在评论部分提供的解决方案更加优雅,您应该使用它。在下文中,我将介绍代码的其他方面以及实现相同结果的其他方法

您应该打开
选项Explicit
,以便编译器始终强制您声明变量。在代码中,
b
c
变量均未声明。它们应该是
Variant
类型,因为您在
中为每个
循环使用它们,但实际上它们将具有
字符串
值。比如:

Option Explicit

Sub Test()
    Dim a As Object
    
    Set a = CreateObject("System.Collections.ArrayList")
    
    Dim blacklist As Object
    Set blacklist = CreateObject("System.Collections.ArrayList")
    
    Dim newList As Object
    Set newList = CreateObject("System.Collections.ArrayList")
    
    a.Add "a"
    a.Add "b"
    a.Add "c"
    a.Add "d"
    a.Add "e"
    a.Add "f"
    a.Add "g"
    
    blacklist.Add "a"
    blacklist.Add "c"
    blacklist.Add "e"
    
    Dim c As Variant
    Dim b As Variant
    Dim found As Boolean
    
    For Each c In a
        found = False
        For Each b In blacklist
            If c = b Then
                found = True
                Exit For
            End If
        Next b
        If Not found Then newList.Add c
    Next c
End Sub
Option Explicit

Sub Test()
    Dim originalList As Object
    Dim blackList As Object
    Dim newList As Object
    
    Set originalList = CreateObject("System.Collections.ArrayList")
    Set blackList = CreateObject("System.Collections.ArrayList")
    Set newList = CreateObject("System.Collections.ArrayList")
    
    originalList.Add "a"
    originalList.Add "b"
    originalList.Add "c"
    originalList.Add "d"
    originalList.Add "e"
    originalList.Add "f"
    originalList.Add "g"
    
    blackList.Add "a"
    blackList.Add "c"
    blackList.Add "e"
    
    Dim originalItem As Variant
    Dim blackListedItem As Variant
    Dim foundItem As Boolean
    
    For Each originalItem In originalList
        foundItem = False
        For Each blackListedItem In blackList
            If originalItem = blackListedItem Then
                foundItem = True
                Exit For
            End If
        Next blackListedItem
        If Not foundItem Then newList.Add originalItem
    Next originalItem
End Sub
Option Explicit

Sub Test()
    Dim originalList() As Variant
    Dim blackList As Collection
    Dim newList As Collection

    originalList = Array("a", "b", "c", "d", "e", "f", "g")
    Set blackList = New Collection
    With blackList
        .Add Empty, "a" 'Note we only need the key
        .Add Empty, "c"
        .Add Empty, "e"
    End With
    Set newList = New Collection

    Dim originalItem As Variant
    
    On Error Resume Next 'In case key already exists
    For Each originalItem In originalList
        blackList.Item CStr(originalItem) 'Check if key exists
        If Err.Number <> 0 Then
            newList.Add originalItem
            Err.Clear
        End If
    Next originalItem
    On Error GoTo 0
End Sub
您应该为变量命名,以便它们传递更多信息<代码>a
b
c
对代码的读者/维护者没有任何意义。您已经正确地使用了
黑名单
,因此只需应用相同的约定即可。此外,我还将使用camelCase使代码更易于阅读(就像您在
newList
中所做的那样)。比如:

Option Explicit

Sub Test()
    Dim a As Object
    
    Set a = CreateObject("System.Collections.ArrayList")
    
    Dim blacklist As Object
    Set blacklist = CreateObject("System.Collections.ArrayList")
    
    Dim newList As Object
    Set newList = CreateObject("System.Collections.ArrayList")
    
    a.Add "a"
    a.Add "b"
    a.Add "c"
    a.Add "d"
    a.Add "e"
    a.Add "f"
    a.Add "g"
    
    blacklist.Add "a"
    blacklist.Add "c"
    blacklist.Add "e"
    
    Dim c As Variant
    Dim b As Variant
    Dim found As Boolean
    
    For Each c In a
        found = False
        For Each b In blacklist
            If c = b Then
                found = True
                Exit For
            End If
        Next b
        If Not found Then newList.Add c
    Next c
End Sub
Option Explicit

Sub Test()
    Dim originalList As Object
    Dim blackList As Object
    Dim newList As Object
    
    Set originalList = CreateObject("System.Collections.ArrayList")
    Set blackList = CreateObject("System.Collections.ArrayList")
    Set newList = CreateObject("System.Collections.ArrayList")
    
    originalList.Add "a"
    originalList.Add "b"
    originalList.Add "c"
    originalList.Add "d"
    originalList.Add "e"
    originalList.Add "f"
    originalList.Add "g"
    
    blackList.Add "a"
    blackList.Add "c"
    blackList.Add "e"
    
    Dim originalItem As Variant
    Dim blackListedItem As Variant
    Dim foundItem As Boolean
    
    For Each originalItem In originalList
        foundItem = False
        For Each blackListedItem In blackList
            If originalItem = blackListedItem Then
                foundItem = True
                Exit For
            End If
        Next blackListedItem
        If Not foundItem Then newList.Add originalItem
    Next originalItem
End Sub
Option Explicit

Sub Test()
    Dim originalList() As Variant
    Dim blackList As Collection
    Dim newList As Collection

    originalList = Array("a", "b", "c", "d", "e", "f", "g")
    Set blackList = New Collection
    With blackList
        .Add Empty, "a" 'Note we only need the key
        .Add Empty, "c"
        .Add Empty, "e"
    End With
    Set newList = New Collection

    Dim originalItem As Variant
    
    On Error Resume Next 'In case key already exists
    For Each originalItem In originalList
        blackList.Item CStr(originalItem) 'Check if key exists
        If Err.Number <> 0 Then
            newList.Add originalItem
            Err.Clear
        End If
    Next originalItem
    On Error GoTo 0
End Sub
我不知道您是否真的需要使用
ArrayList
对象。使用数组和
Collection
对象可以获得相同的结果。使用集合的键散列也比循环项(我指的是第二个For循环)更有效。比如:

Option Explicit

Sub Test()
    Dim a As Object
    
    Set a = CreateObject("System.Collections.ArrayList")
    
    Dim blacklist As Object
    Set blacklist = CreateObject("System.Collections.ArrayList")
    
    Dim newList As Object
    Set newList = CreateObject("System.Collections.ArrayList")
    
    a.Add "a"
    a.Add "b"
    a.Add "c"
    a.Add "d"
    a.Add "e"
    a.Add "f"
    a.Add "g"
    
    blacklist.Add "a"
    blacklist.Add "c"
    blacklist.Add "e"
    
    Dim c As Variant
    Dim b As Variant
    Dim found As Boolean
    
    For Each c In a
        found = False
        For Each b In blacklist
            If c = b Then
                found = True
                Exit For
            End If
        Next b
        If Not found Then newList.Add c
    Next c
End Sub
Option Explicit

Sub Test()
    Dim originalList As Object
    Dim blackList As Object
    Dim newList As Object
    
    Set originalList = CreateObject("System.Collections.ArrayList")
    Set blackList = CreateObject("System.Collections.ArrayList")
    Set newList = CreateObject("System.Collections.ArrayList")
    
    originalList.Add "a"
    originalList.Add "b"
    originalList.Add "c"
    originalList.Add "d"
    originalList.Add "e"
    originalList.Add "f"
    originalList.Add "g"
    
    blackList.Add "a"
    blackList.Add "c"
    blackList.Add "e"
    
    Dim originalItem As Variant
    Dim blackListedItem As Variant
    Dim foundItem As Boolean
    
    For Each originalItem In originalList
        foundItem = False
        For Each blackListedItem In blackList
            If originalItem = blackListedItem Then
                foundItem = True
                Exit For
            End If
        Next blackListedItem
        If Not foundItem Then newList.Add originalItem
    Next originalItem
End Sub
Option Explicit

Sub Test()
    Dim originalList() As Variant
    Dim blackList As Collection
    Dim newList As Collection

    originalList = Array("a", "b", "c", "d", "e", "f", "g")
    Set blackList = New Collection
    With blackList
        .Add Empty, "a" 'Note we only need the key
        .Add Empty, "c"
        .Add Empty, "e"
    End With
    Set newList = New Collection

    Dim originalItem As Variant
    
    On Error Resume Next 'In case key already exists
    For Each originalItem In originalList
        blackList.Item CStr(originalItem) 'Check if key exists
        If Err.Number <> 0 Then
            newList.Add originalItem
            Err.Clear
        End If
    Next originalItem
    On Error GoTo 0
End Sub

只有外部循环和
如果不是黑名单。包含(c)然后是新名单。添加c.value
谢谢,它可以工作!