Arrays 在vba中创建黑名单的最佳方法?
我正在尝试创建一个排除一些项目的arraylist 示例:列表a包含{a,b,c,d,e,f,g} 黑名单包含{a,c,e} 我希望我的新列表只有{b,d,f,g} 这是我到目前为止试过的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
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
谢谢,它可以工作!