Home » excel » excel – Check one list against another list (VBA) using LBound and UBound . Or any way that works

excel – Check one list against another list (VBA) using LBound and UBound . Or any way that works

Posted by: admin May 14, 2020 Leave a comment

Questions:

I am trying to check a PO list against an open PO list and clear the cell from
the PO List if not in the open PO List. I tried multiple variations of code (below) and this one is giving me a Mismatch error. Usually, I do something like i = 0 to 5 but that’s when I know the exact length of the list. Doing this without knowing the length has been a challenge. Any help would be very much appreciated.

Sub POCheck()
Dim OpenPO As Worksheet
Set OpenPO = Worksheets("OpenPO")
Dim All As Worksheet
Set All = Worksheets("All")
Dim OpenPOList As Variant
OpenPOList = OpenPO.Range("A2:A" And LastRowPO).Value
Set AllPO = All.Range("B2:B" & LastRow)
Dim i As Long
LastRow = All.Range("AH" & Rows.Count).End(xlUp).Row
LastRowPO = OpenPO.Range("A" & Rows.Count).End(xlUp).Row

For Each cell In AllPO.Cells
For i = LBound(OpenPOList) To UBound(OpenPOList)
Found = False
If Not cell.Find(OpenPOList(i)) Is Nothing Then
Found = True
Exit For
End If
Next i
If Not Found Then cell.Value = ""
Next cell
How to&Answers:

It is very quick to use arrays and Application.Match to see if current value is in the array containing the values to match against. No looping cells and data is read in and written out in one go.

Option Explicit
Public Sub POCheck()
    Dim openPO As Worksheet, all As Worksheet, lastRow As Long, lastRowPO As Long
    Set openPO = ThisWorkbook.Worksheets("OpenPO")
    Set all = ThisWorkbook.Worksheets("All")

    With all
        lastRow = .Range("AH" & .Rows.Count).End(xlUp).Row
    End With
    With openPO
        lastRowPO = .Range("A" & Rows.Count).End(xlUp).Row
    End With

    Dim openPOList(), allPOList(), i As Long
    openPOList = Application.Transpose(openPO.Range("A2:A" & lastRowPO))
    allPOList = Application.Transpose(all.Range("B2:B" & lastRow))

    For i = LBound(allPOList) To UBound(allPOList)
        If IsError(Application.Match(allPOList(i), openPOList, 0)) Then
            allPOList(i) = vbNullString
        End If
    Next
    openPO.Range("A2").Resize(UBound(allPOList), 1) = Application.Transpose(allPOList)
End Sub

Answer:

It is considered a best practice to add Option Explicit to the top of the code modules and declare a variables with the correct datatypes.

Dim LastRow As Long, LastRowPO As Long

Use & not And when concatenating strings.

OpenPOList = OpenPO.Range("A2:A" And LastRowPO).Value

LastRowPO is being used before its value is set.

LastRowPO = OpenPO.Range("A" & Rows.Count).End(xlUp).row
OpenPOList = OpenPO.Range("A2:A" & LastRowPO).Value

Use Range.Find to search a group of cells not a single cell.

If Not cell.Find(OpenPOList(i)) Is Nothing Then

Using a Scripting.Dictionary to match unique values is vastly faster then using nested loops. Watch: Excel VBA Introduction Part 39 – Dictionaries.

You should download RubberDuck and use its code formatter often.

Answer:

You can do a vlookup to see if it exists and then clear the value if vlookup in adjacent cell isn’t #N/A?

Or loop down the first list and do a countif in VBA to see if it resides within the other list, if it does, clear it?

So may ways to do it in VBA also…