Arrays 如何快速有效地删除基于值的数组元素(VBA)

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到n,1到1)。为了系统地做到这一点,我们应该创建一个函数,如RemoveElementsFromArray\u ByValue(Arr为Variant,value为Variant)。我的问题是如何高效地编写此函数,以便即使在大型阵列和其他主Sub中也能快速执行。 请注意,可能有多个具有该值的元素应被删除。 假设我们希望在下面的子中使用这个函数来删除数组Xi、Yi的元素,它们分别具有数组席元素XyIn、yiIn f的任何元素的值,并将结果放在数组XII、YII中并打印成对(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