首页 > 解决方案 > 变量未在 vlookup 中分配

问题描述

我有一个表,我试图用它在表的 column2 中进行 vlookup 并从表中的 column8 中获取数据。但是,不会分配变量。当代码到达指定的变量时,继续不分配变量,然后完全跳过 if 语句。我没有收到错误,代码只是继续进行,就好像它不存在一样。有人能告诉我为什么没有从 vlookup 中为这个变量分配数据吗

Option Explicit
Dim RevSID As String
Dim RevSupLev As String
Dim RevActive As String
Dim DueDate As Date



Private Sub Contact_Update()
Set CaseRng = CaseRevPvt.DataBodyRange *Another pivot table in the workbook
Set Contact = Worksheets("Tables").ListObjects("Contact") 

 For Each cell In CaseRng

    RevSID = cell.Offset(0, 1)
    RevSupLev = cell.Offset(0, 2)
    RevActive = cell.Offset(0, 3)

    If RevSID = 0 Then 'An integer variable function doesn't need to run if no data
        On Error Resume Next
        End If  

    elseif RevActive = "No" then
         'Do stuff..works fine
    elseif RevSupLev = "String indicated" then
        if PADate>duedate then 'checks PADue for condition
             'does stuff, this works
        else: Call StandRev 'the intent is to do a Vlookup using RevSID,
                'find the matching data in Column2 of the Contact table and assign the
                information in Column8 to lastrev

Private Sub StandRev()
Dim VlookUp As Range
Dim lastrev As Date


With Worksheets("Tables") 'sets a look up range within the table "Contact"
Set VlookUp = Contact.Parent.Range(Contact.ListColumns("SID").DataBodyRange, Contact.ListColumns("Last Review").DataBodyRange)

lastrev = Application.WorksheetFunction.VlookUp(RevSID, VlookUp, 8,False)  '*** problem here -- RevSID variable is assigned in previous sub
' no data is saved in variable, program ends sub

If lastrev > AttempDate2 Then
    'code that will replace lastrev with data in AttempDate2, AttempDate2 varaiable assigned in another sub
End If

End With

End Sub

标签: excelvba

解决方案


如果RevSID没有显式声明,那么RevSID在procedure1 中的变量将与procedure2 中的变量不同RevSID:未声明的变量始终是局部作用域的,因此在procedure2 中分配它不会影响procedure1 中同名变量的值。

但这不是这里发生的事情。由于RevSID 某处声明,您的查找必须失败(即它没有RevSID在查找表中找到值)。

我将建议一种截然不同的方法,使用一个函数,以及一种称为“尝试模式”的模式,其中您有一个函数返回 aBoolean并在通过引用传递的参数中输出结果,该参数只有一个有意义的函数返回时的值True- 并且因为乍一看似乎该[SID]列不是表中最左边的列(为什么要一直到Contact.Parent其他地方?),我建议使用 INDEX 的组合和 MATCH 执行查找 - 请注意列的顺序如何与此查找方法无关。

这是一个带有早期绑定WorksheetFunction调用的版本,它会在失败时引发运行时错误:

Private Function TryGetRevisionDate(ByVal SID As String, ByRef outResult As Date) As Boolean
    On Error GoTo CleanFail

    With Application.WorksheetFunction
        Dim matchRow As Long
        matchRow = .Match(SID, Contact.ListColumns("SID").DataBodyRange, 0)

        Dim indexValue As Variant
        indexValue = .Index(Contact.ListColumns("Last Review").DataBodyRange, matchRow)
    End With

    If IsDate(indexValue) Then outResult = indexValue
    TryGetRevisionDate = True

CleanExit:
    Exit Function

CleanFail:
    'lookup failed
    Resume CleanExit
End Function

还有一个带有后期绑定WorksheetFunction调用的版本,它在失败时返回一个错误值(请注意,您没有获得参数信息,也没有使用后期绑定代码进行编译时验证,因此请注意拼写错误 -Option Explicit无法在此处保存您) :

Private Function TryGetRevisionDate(ByVal SID As String, ByRef outResult As Date) As Boolean
    With Application

        Dim matchRow As Variant
        matchRow = .Match(SID, Contact.ListColumns("SID").DataBodyRange, 0)
        If IsError(matchRow) Then Exit Function

        Dim indexValue As Variant
        indexValue = .Index(Contact.ListColumns("Last Review").DataBodyRange, matchRow)
        If IsError(indexValue) Then Exit Function

    End With

    If IsDate(indexValue) Then
        outResult = indexValue
        TryGetRevisionDate = True
    End If

End Function

使用任一版本,您的调用代码现在可以执行此操作:

Dim revDate As Date
If TryGetRevisionDate(RevSID, revDate) Then
    MsgBox revDate
Else
    MsgBox "SID '" & RevSID & "' was not found."
End If

推荐阅读