检查所有列值是否在另一个列表中

时间:2019-01-22 09:23:05

标签: excel vba

我创建的excel vba宏遍历了整个列,并针对另一个工作表上的另一列搜索该列中的每个值。我有一个T / F列,如果找到,则在其中标记“ T”,如果找不到,则标记“ F”。但是,我觉得我的操作方式可能不是很有效,因为该宏大约需要30分钟才能遍历31,000行值,然后从另一列中搜索大约27,000个值。

为简单起见,我提供了一些图像来解释宏的功能。

enter image description here

T / F列最初将为空。只有在执行宏之后,它才会被填充。我遍历A列中的每一行,并尝试在下一张图片中针对SearchCol查找值。

enter image description here

这是我当前正在使用的vba代码。

Sub CheckIfValuesExist()
    Dim ActiveWS As Worksheet, WS2 As Worksheet
    Dim ValueColLetter As String, SearchColLetter As String, TFColLetter As String
    Dim LastRow As Long, i As Long
    Dim target As Variant, rng As Range

    Set ActiveWS = ActiveWorkbook.Worksheets(1)
    Set WS2 = ActiveWorkbook.Worksheets(2)
    ValueColLetter = "A"
    SearchColLetter = "A"
    TFColLetter = "B"
    LastRow = ActiveWS.Cells.Find(What:="*", SearchOrder:=xlRows, _
               SearchDirection:=xlPrevious, _
               LookIn:=xlFormulas).Row

    For i = 2 To LastRow
        target = ActiveWS.Range(ValueColLetter & i).Value
        If target <> "" Then
            With WS2.Range(SearchColLetter & ":" & SearchColLetter) 'searches all of column A
                Set rng = .Find(What:=target, _
                                After:=.Cells(.Cells.Count), _
                                LookIn:=xlValues, _
                                LookAt:=xlWhole, _
                                SearchOrder:=xlByRows, _
                                SearchDirection:=xlNext, _
                                MatchCase:=False)
                If Not rng Is Nothing Then
                    ActiveWS.Range(TFColLetter & i).Value = "T" 'value found
                Else
                    ActiveWS.Range(TFColLetter & i).Value = "F" 'value not found
                End If
            End With
        End If
    Next i
End Sub

宏按预期工作,我只是发现它很慢。有什么更好的方法可以更快地完成相同的事情?

3 个答案:

答案 0 :(得分:2)

对照列检查列

数组匹配范围版本

Sub CheckIfValuesExist()

    Const cSheet1 As Variant = 1  ' Value Worksheet Name/Index
    Const cSheet2 As Variant = 2  ' Search Worksheet Name/Index
    Const cFirst As Long = 2      ' First Row
    Const cVal As Variant = "A"   ' Value Column
    Const cSrc As Variant = "A"   ' Search Column
    Const cTF As Variant = "B"    ' Target Column
    Const cT As String = "T"      ' Found String
    Const cF As String = "F"      ' Not Found String

    Dim RngS As Range     ' Search Range
    Dim vntV As Variant   ' Value Array
    Dim vntT As Variant   ' Target Array
    Dim LastV As Long     ' Value Last Column Number
    Dim LastS As Long     ' Search Last Column Number
    Dim i As Long         ' Value/Target Row Counter
    Dim dummy As Long     ' Match Dummy Variable

    With Application
        .Calculation = xlCalculationManual
        .ScreenUpdating = False
    End With
    On Error GoTo ProcedureExit

    With ThisWorkbook.Worksheets(cSheet1)
        LastV = .Columns(.Cells(1, cVal).Column).Find("*", , -4123, , 2, 2).Row
        vntV = .Range(.Cells(cFirst, cVal), .Cells(LastV, cVal))
    End With

    With ThisWorkbook.Worksheets(cSheet2)
        LastS = .Columns(.Cells(1, cSrc).Column).Find("*", , -4123, , 2, 2).Row
        Set RngS = .Range(.Cells(cFirst, cSrc), .Cells(LastS, cSrc))
        ReDim vntT(1 To UBound(vntV), 1 To 1)
        For i = 1 To UBound(vntV)
            On Error Resume Next
            If vntV(i, 1) <> "" Then
                dummy = Application.Match(vntV(i, 1), RngS, 0)
                If Err Then
                    vntT(i, 1) = cF
                  Else
                    vntT(i, 1) = cT
                End If
            End If
            On Error GoTo 0
        Next
    End With

    On Error GoTo ProcedureExit

    With ThisWorkbook.Worksheets(cSheet1)
        .Range(.Cells(cFirst, cTF), .Cells(.Rows.Count, cTF)).ClearContents
        .Cells(cFirst, cTF).Resize(UBound(vntT)) = vntT
    End With

ProcedureExit:
    With Application
        .Calculation = xlCalculationAutomatic
        .ScreenUpdating = True
    End With

End Sub

答案 1 :(得分:1)

让我们假设数据包含在工作表1中。

尝试:

df1 <- fread("Gate,  Set
  1,  PIP D04 LMI1 975
  6,  PIP D06 LMI1 363
 Time,  PIP d08 LMI1 wk7 539")

df2 <- fread("ID     Weeks
d01       6
d04       8
d06       9
d08       19")

结果:

enter image description here

答案 2 :(得分:0)

为什么不使用MATCH公式?

如果您的值在A列中,而搜索值在 单元格$ F $ 5:$ F $ 10的公式是:

= MATCH(A2,$ F $ 5:$ F $ 10,0)

或者如果您坚持要采用电汇结果:

= IF(ISERROR(MATCH(A2,$ F $ 5:$ F $ 10,0)),“ T”,“ F”)

当然,您也可以使用宏插入此公式。

enter image description here