使用LBound和UBound将一个列表与另一个列表(VBA)进行比较。或任何可行的方式

时间:2018-11-19 22:11:34

标签: excel vba excel-vba

我试图对照打开的PO列表检查PO列表,并从中清除单元格  PO列表(如果不在打开的PO列表中)。我尝试了多种代码变体(如下),而这给了我一个Mismatch错误。通常,我会执行类似i = 0到5的操作,但是那时候我才知道列表的确切长度。在不知道长度的情况下做到这一点一直是一个挑战。任何帮助将不胜感激。

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

3 个答案:

答案 0 :(得分:2)

使用数组和Application.Match可以非常快速地查看当前值是否在包含要匹配的值的数组中。一次不会读取和写入循环的单元格和数据。

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

答案 1 :(得分:0)

Option Explicit添加到代码模块的顶部并声明具有正确数据类型的变量被认为是最佳实践。

Dim LastRow As Long, LastRowPO As Long

串联字符串时,请使用&而不是And

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

LastRowPO在设置其值之前被使用。

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

使用Range.Find搜索一组单元格而不是单个单元格。

  

如果不是cell.Find(OpenPOList(i))没什么

与嵌套循环相比,使用Scripting.Dictionary来匹配唯一值要快得多。观看:Excel VBA Introduction Part 39 - Dictionaries

您应该下载RubberDuck并经常使用其代码格式化程序。

答案 2 :(得分:0)

您可以执行vlookup来查看它是否存在,然后如果相邻单元格中的vlookup不是#N / A,则清除该值。

还是向下循环第一个列表,然后在VBA中做一个计数,以查看它是否位于另一个列表中,如果存在,请清除它?

所以也可以在VBA中做到这一点...