简体   繁体   中英

Excel VBA - Compare two arrays and return strings that are in one array but not in the other

i have two 2-d string arrays which are of different sizes(diff number of rows), named NewAssigneesArray and AssigneesDatabase. Using only the first column of both arrays, i want to compare the two arrays and extract the strings that appear in AssigneesDatabase BUT NOT in NewAssigneesArray. I've been stuck on thisquite awhile now and dont seem to crack it. Because in my nested loop im comparing each element which doesnt seem to work.

PS There are overlapping strings in the both arrrays. That means if the string is in both of them, it should be ignored.

This is what i've got so far:

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

If you convert the first column of your NewAssignees array to a scripting dictionary then you can replace the For b loop with a single Exists statement

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

I'd then move the logic of the for b loop to a separate sub eg

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

This allows the For a loop to be reduced to

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

    UpdateDatabase myRow

Next

You are also comparing strings so a safe course of action is to convert the strings to a consistent case, trim to remove any inadvertent whitespace and, if necessary, replace any vbcrlf or vbtabs in the string

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM