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
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…
Tags: excelexcel, list, vba