【问题标题】:VBA: Extract data using Vlookup and OffsetVBA:使用 Vlookup 和 Offset 提取数据
【发布时间】:2016-05-30 01:33:51
【问题描述】:

我正在尝试使用 VBA 从大型电子表格中提取数据。 A 列包含可以根据存储在其中的数据重复的 ID。

例如我有

ID           Value1             Value2
1111         item1               item2
1111         item3               item4
2222         item3               item4
3333         item3               item4
3333         item3               item4

我将 ID 输入到电子表格中,然后想使用 VBA 来查找 ID,然后将 B 列和 C 列中的值拉到另一个电子表格中。

这就是我所拥有的

    Sub populate()
Dim ID As String    
Dim Value1 As String
ID = Range("D5")
   Value1 = Application.WorksheetFunction.VLookup(ID, Worksheets("Required").Range("A4:J1913"), 2, False)
Response = Application.WorksheetFunction.VLookup(ID, Worksheets("Required").Range("A4:J1913"), 7, False)
Worksheets("Coversheet").Range("D8") = Value1
Worksheets("Coversheet").Range("D10") = Value2
Dim Value1address As Long
Value1address = VarPtr(Value1)
Worksheets("Coversheet").Range("D15").Value = Cells(Value1address).Offset(1, 0)
End Sub

除了最后 3 行之外,代码完全按照我的意愿工作。我试图从 Value1 获得 1 行的偏移量,但是它保存为空白,因此将空白值放入单元格 D15。

谁能帮我解决这个问题,或者我如何在 Vlookup 之后轻松地从以下行中获取数据?

【问题讨论】:

    标签: vba excel offset vlookup


    【解决方案1】:

    我建议使用 Power Query 来完成此任务(如果您已经使用 2016 年,则使用 Get&Transform): https://www.dropbox.com/s/my59casl9y8ac3y/SO_ExtractDataUsingVLookupAndOffset.xlsx?dl=0

    代码很短(例如 Var1):

    let
        Filter= Excel.CurrentWorkbook(){[Name="ID"]}[Content][Column1]{0},
        Source = Excel.CurrentWorkbook(){[Name="Tabelle1"]}[Content],
        #"Filtered Rows" = Table.SelectRows(Source, each [ID] = Filter)
    in
        #"Filtered Rows"
    

    您拥有输出的所有格式选项,并且解决方案是完全动态的:

    【讨论】:

      【解决方案2】:

      使用工作表的MATCH function 将行号返回到INDEX function,同时向其添加+1

      with Worksheets("Required")
          Worksheets("Coversheet").Range("D15").Value = _
            Application.Index(.Range("B4:B1913"), Application.Match(ID, .Range("A4:A1913"), 0) + 1))
      End With
      

      如果您正在查找该行,则将其存储并继续重复使用。

          Dim ID As String, val1 As String, val2 As String, val3 As String, rw As Long
          ID = Range("D5")
      
          With Worksheets("Required")
              If Not IsError(Application.Match(ID, .Range("A4:A1913"), 0)) Then
                  rw = Application.Match(ID, .Range("A4:J1913"), 0)
                  val1 = .Cells(rw + 3, 2).Value
                  val2 = .Cells(rw + 3, 7).Value
                  val3 = .Cells(rw + 4, 2).Value
              End If
          End With
      
          With Worksheets("Coversheet")
              .Range("D8") = val1
              .Range("D10") = val2
              .Range("D15") = val3
          End With
      

      Native Worksheet formulas

      这也可以通过标准(非数组)工作表公式来处理。在 D8、D10 和 D15 中,

      =INDEX(Required!$B$4:$B$914, MATCH($D$5, Required!$A$4:$A$914, 0))
      =INDEX(Required!$J$4:$J$914, MATCH($D$5, Required!$A$4:$A$914, 0))
      =IFERROR(INDEX(Required!$B$4:$B$914, AGGREGATE(15, 6, ROW($1:$911)/(Required!$A$4:$A$914=$D$5), 2)), "n/a")
      

          

      【讨论】:

      • with Worksheets("Required") Worksheets("Coversheet").Range("D15").Value = _ Application.Index(.Range("B4:B1913"), Application.Match( ID, .Range("A4:A1913"), 0) + 1)) End With 这将继续转储数据,即使 ID 已更改。例如,我只希望它转储 D5 中匹配的 ID。如果我将此方法用于 ID 2222,它将转储下一行值,即 id 3333
      • 是的,这是真的。这也与您尝试使用VarPtr 完成的完全一样。认识到这一点后,我提供了一种辅助方法。
      猜你喜欢
      • 1970-01-01
      • 2023-03-08
      • 2020-12-16
      • 2019-06-22
      • 1970-01-01
      • 2021-07-30
      • 1970-01-01
      • 2021-09-23
      • 2017-10-28
      相关资源
      最近更新 更多