【问题标题】:VBA Vlookup across multiple sheets跨多个工作表的 VBA Vlookup
【发布时间】:2015-05-26 05:56:12
【问题描述】:

所以我有两个列表,每个列表都在不同的工作表中。我正在检查工作表 B 中的值是否也在工作表 A 中。我为此使用 VLookup,问题似乎出在范围语句上,因为这个范围似乎是“空的”。

我的 VBA 尝试类似于,

Dim lookupVal As String
Dim myString As String

For i = 1 to N
    lookupVal = Sheets("b").Cells(1 + i, 2)
    myString = Application.WorksheetFunction.VLookup(lookupVal, Sheets("a").range(Sheets("a").Cells(9,3), Sheets("a").Cells(N+8, 3)), 1, False)
    If IsEmpty(myString) Then
        Sheets("b").Cells(1+i, 3) = ""
    Else
        Sheets("b").Cells(1+i, 3) = myString
    End if

Next i

我收到“运行时 1004:应用程序定义或对象定义错误”。任何帮助表示赞赏。

【问题讨论】:

    标签: vba excel object defined


    【解决方案1】:

    你的代码有两个问题:

    1. 对于worksheetfunction.vlookup,搜索范围不能不稳定。 所以解决这个问题的方法是使用额外的变量来永久化

    2. 如果worksheetfunction.vlookup找不到搜索值,则会出现错误,这种情况下你需要使用额外的错误处理操作

    3. lookupVal 必须声明为as Range,因为单元格的格式(查找范围和查找值)可能不同,但在您的代码中,单元格值总是会转换为字符串类型,而您不会如果将数字转换为字符串,则能够找到数字

    4. myString 也需要声明为as Variant,原因与“3”中描述的相同。例如,单元格的类型可以是 double,但您的代码会将其转换为 string

    所以,您的更新代码如下,工作正常

    Sub test()
    Dim lookupVal As Range, myString As Variant, Rng$, n&
    n = Sheets("b").[B:B].Cells.Find("*", , , , xlByRows, xlPrevious).Row
    On Error Resume Next
    For i = 1 To n
        Set lookupVal = Sheets("b").Cells(1 + i, 2)
        Rng = Range(Cells(9, 3), Cells(n + 8, 3)).Address
        myString = WorksheetFunction.VLookup(lookupVal, Sheets("a").Range(Rng), 1, False)
        If Err.Number > 0 Then
            Sheets("b").Cells(1 + i, 3) = ""
            Err.Clear
        Else
            Sheets("b").Cells(1 + i, 3) = myString
        End If
    Next i
    End Sub
    

    下面的替代方式

    Sub test()
    Dim cl As Range, Dic As Object
    Set Dic = CreateObject("Scripting.Dictionary"): Dic.Comparemode = vbTextCompare
    With Sheets("a")
        For Each cl In .Range("C9:C" & .Cells(Rows.Count, "C").End(xlUp).Row)
            If Not Dic.exists(cl.Value) Then Dic.Add cl.Value, cl.Row
        Next cl
    End With
    With Sheets("b")
        For Each cl In .Range("B2:B" & .Cells(Rows.Count, "B").End(xlUp).Row)
            If Dic.exists(cl.Value) Then cl.Offset(, 1).Value = cl.Value
        Next cl
    End With
    Set Dic = Nothing
    End Sub
    

    【讨论】:

      【解决方案2】:

      将您的代码更改为以下内容。

      If IsEmpty(myString) 是错误的做法。在#N/A 的情况下,该陈述仍然是正确的。

      这是你正在尝试的吗?

      Sub Sample()
          Dim lookupVal As String
          Dim myString As Variant
          Dim rng As Range
      
          '~~> Change this whatever you want
          n = 5
      
          For i = 1 To n
              lookupVal = Sheets("b").Cells(1 + i, 2)
      
              Set rng = Sheets("a").Range(Sheets("a").Cells(9, 3), Sheets("a").Cells(n + 8, 3))
      
              myString = Application.Evaluate("=VLOOKUP(" & lookupVal & "," & "a!" & rng.Address & ",1,0)")
      
              Select Case CVErr(myString)
                  Case CVErr(xlErrName), CVErr(xlErrNA), CVErr(xlErrRef), CVErr(xlErrValue)
                  Case Else: Sheets("b").Cells(1 + i, 3) = myString
              End Select
          Next i
      End Sub
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-06-21
        • 1970-01-01
        • 1970-01-01
        • 2017-10-27
        相关资源
        最近更新 更多