Arrays 如何快速有效地删除基于值的数组元素(VBA)
我想基于一个值删除二维数组的元素(1到n,1到1)。为了系统地做到这一点,我们应该创建一个函数,如RemoveElementsFromArray\u ByValue(Arr为Variant,value为Variant)。我的问题是如何高效地编写此函数,以便即使在大型阵列和其他主Sub中也能快速执行。 请注意,可能有多个具有该值的元素应被删除。 假设我们希望在下面的子中使用这个函数来删除数组Xi、Yi的元素,它们分别具有数组席元素XyIn、yiIn f的任何元素的值,并将结果放在数组XII、YII中并打印成对(XII,YII): 我期望这一结果:Arrays 如何快速有效地删除基于值的数组元素(VBA),arrays,excel,vba,function,element,Arrays,Excel,Vba,Function,Element,我想基于一个值删除二维数组的元素(1到n,1到1)。为了系统地做到这一点,我们应该创建一个函数,如RemoveElementsFromArray\u ByValue(Arr为Variant,value为Variant)。我的问题是如何高效地编写此函数,以便即使在大型阵列和其他主Sub中也能快速执行。 请注意,可能有多个具有该值的元素应被删除。 假设我们希望在下面的子中使用这个函数来删除数组Xi、Yi的元素,它们分别具有数组席元素XyIn、yiIn f的任何元素的值,并将结果放在数组XII、YII
(1,2)
(2,5)
(10,7)
假设我们定义了一个函数RemoveElementFromArray_ByIndex(Arr1为变量,Index为Long),该函数根据索引从数组中移除元素,如下所示:
Function RemoveElementFromArray_ByIndex(Arr1 As Variant, Index As Long)
Dim UB1, LB1 As Long
Dim Arr2() As Variant
Dim i, k As Long
UB1 = UBound(Arr1, 1): LB1 = LBound(Arr1, 1)
ReDim Arr2(LB1 To UB1 - 1, 1 To 1)
If Index < LB1 Or Index > UB1 Then
MsgBox "The index is out of range!", vbExclamation
ElseIf Index = LB1 Then
k = LB1
For i = LB1 To UB1 - 1
Arr2(k, 1) = Arr1(i + 1, 1)
k = k + 1
Next i
ElseIf Index > LB1 And Index < UB1 Then
k = LB1
For i = LB1 To Index - 1
Arr2(k, 1) = Arr1(i, 1)
k = k + 1
Next i
k = Index
For i = Index To UB1 - 1
Arr2(k, 1) = Arr1(i + 1, 1)
k = k + 1
Next i
ElseIf Index = UB1 Then
k = LB1
For i = LB1 To UB1 - 1
Arr2(k, 1) = Arr1(i, 1)
k = k + 1
Next i
End If
RemoveElementFromArray_ByIndex = Arr2
End Function
函数通过索引从数组中移除元素(Arr1为变量,索引为长)
尺寸UB1,LB1与长度相同
Dim Arr2()作为变量
暗淡的i,k一样长
UB1=UBound(Arr1,1):LB1=LBound(Arr1,1)
重拨Arr2(LB1至UB1-1,1至1)
如果索引UB1,则
MsgBox“索引超出范围!”,请使用感叹号
ElseIf索引=LB1然后
k=LB1
对于i=LB1至UB1-1
Arr2(k,1)=Arr1(i+1,1)
k=k+1
接下来我
ElseIf指数>LB1,指数
我们应该在这里利用这个功能,还是基本上寻求另一个不同的想法?!。
请帮助我找到最佳函数RemoveElementsFromArray\u ByValue您可以使用字典来实现这一点。下面的示例将所有匹配值从colA和colB粘贴到colC,但您可以轻松地反转逻辑,添加空格,而不是跳过值并转换为函数
Sub DictMatch()
Dim Arr, Arr2, j As Long, i As Long, dict As Object
Set dict = CreateObject("Scripting.Dictionary") 'create dictionary lateB
With dict 'used because I'm to lazy to retype dict everywhere :)
.CompareMode = 1 'textcompare
Arr = Sheet1.Range("A1").CurrentRegion.Value2 'load source
For j = 1 To UBound(Arr) 'traverse source
If Not .exists(Arr(j, 1)) Then 'set key if I don't have it yet in dict
.Add Key:=Arr(j, 1), Item:=Arr(j, 1)
End If
Next j
ReDim Arr2(1 To UBound(Arr), 1 To 1) 'size the target array, just 2 cols
i = 1
For j = 1 To UBound(Arr)
If .exists(Arr(j, 2)) Then 'matching happens here, compare data from target with dictionary
Arr2(j, 1) = Arr(j, 2) 'write to target array if match
End If
Next j
End With
With Sheet1
.Range(.Cells(1, 3), .Cells(UBound(Arr2), 3)).Value2 = Arr2 'dump target array to sheet
End With
End Sub
由于数组的条件是有1列,因此可以遍历数组并将与值不匹配的结果存储到集合中。然后清除数组并使用集合中的计数进行重拨,然后重新加载。在第一个过程中,
redim-arr(1到n,1)
是两列(如果Option Base
不是1
)。您应该执行ReDim-arr(1到n,1到1)
。另外,Dim i As Long,j As Long
:每个变量“都需要”一个,因为@vbasic208您是对的。谢谢。谢谢。我来试试。
Sub DictMatch()
Dim Arr, Arr2, j As Long, i As Long, dict As Object
Set dict = CreateObject("Scripting.Dictionary") 'create dictionary lateB
With dict 'used because I'm to lazy to retype dict everywhere :)
.CompareMode = 1 'textcompare
Arr = Sheet1.Range("A1").CurrentRegion.Value2 'load source
For j = 1 To UBound(Arr) 'traverse source
If Not .exists(Arr(j, 1)) Then 'set key if I don't have it yet in dict
.Add Key:=Arr(j, 1), Item:=Arr(j, 1)
End If
Next j
ReDim Arr2(1 To UBound(Arr), 1 To 1) 'size the target array, just 2 cols
i = 1
For j = 1 To UBound(Arr)
If .exists(Arr(j, 2)) Then 'matching happens here, compare data from target with dictionary
Arr2(j, 1) = Arr(j, 2) 'write to target array if match
End If
Next j
End With
With Sheet1
.Range(.Cells(1, 3), .Cells(UBound(Arr2), 3)).Value2 = Arr2 'dump target array to sheet
End With
End Sub