首页 > 解决方案 > Excel VBA - 比较两个数组并返回一个数组中但不在另一个数组中的字符串

问题描述

我有两个大小不同(行数不同)的二维字符串数组,名为 NewAssigneesArray 和 AssigneesDatabase。仅使用两个数组的第一列,我想比较两个数组并提取出现在 AssigneesDatabase 但不在 NewAssigneesArray 中的字符串。我已经坚持了一段时间了,似乎并没有破解它。因为在我的嵌套循环中,我比较了每个似乎不起作用的元素。

PS 两个数组中都有重叠的字符串。这意味着如果字符串在它们两者中,它应该被忽略。

这是我到目前为止所得到的:

For a = LBound(NewAssigneesArray, 1) To UBound(NewAssigneesArray, 1)
    For b = LBound(AssigneesDatabase, 1) To UBound(AssigneesDatabase, 1)
        If NewAssigneesArray(a, 1) <> AssigneesDatabase(b, 1) Then
            lastrow = DBSheet.Cells(Rows.count, 1).End(xlUp).Row
            DBSheet.Cells(lastrow + 1, 1) = AssigneesDatabase(b, 1)
            DBSheet.Cells(lastrow + 1, 2) = AssigneesDatabase(b, 2)
            DBSheet.Cells(lastrow + 1, 3) = "New Entry"
            Exit For
        End If
    Next b
Next a

标签: arraysexcelvba

解决方案


如果将 NewAssignees 数组的第一列转换为脚本字典,则可以将 For b 循环替换为单个 Exists 语句

Const ArrayRows As Long = 1
Const Column1 As Long = 0

Dim myAssignees As Scripting.Dictionary
Set myAssigness = New Scripting.Dictionary

Dim myRow As Long

For myRow = LBound(NewAssigneesArray, ArrayRows) To UBound(NewAssigneesArray, ArrayRows)

    myAssignees.Add LCase$(Trim(NewAssigneesArray(myRow, Column1))), myRow

Next

然后我将 for b 循环的逻辑移动到一个单独的 sub 例如

Sub UpdateDatabase(ByVal myRow As Long)

    If NewAssigneesArray.Exists(Trim(LCase$(AssigneeDatabase(Column1, myRow)))) Then Exit Sub

    lastrow = DBSheet.Cells(ArrayRows.Count, 1).End(xlUp).Row
    DBSheet.Cells(lastrow + 1, 1) = assigneesDatabase(myRow, 1)
    DBSheet.Cells(lastrow + 1, 2) = assigneesDatabase(myRow, 2)
    DBSheet.Cells(lastrow + 1, 3) = "New Entry"

End Sub

这允许将 For a 循环减少到

For myRow = LBound(assigneesDatabase, ArrayRows) To UBound(assigneesDatabase, ArrayRows)

    UpdateDatabase myRow

Next

您还在比较字符串,因此安全的做法是将字符串转换为一致的大小写,修剪以删除任何无意的空格,并在必要时替换字符串中的任何 vbcrlf 或 vbtab


推荐阅读