【问题标题】:VLookup multiple columnsVLookup 多列
【发布时间】:2013-09-20 20:27:21
【问题描述】:

我正在使用 VLookup 函数来查找列中存在的多个值。这工作得很好,但只需要很多时间,因为我在 Excel 表中有 100,000 行。

有什么方法可以加快这段代码的速度吗?

代码基本上是在列中查找特定值并获取偏移量。简单 VLookup 和 this 的区别在于,如果有多行具有相同的查找值,那么它会获取所有元素。

   Function VLookupAll(ByVal lookup_value As String, _
                ByVal lookup_column As Range, _
                ByVal return_value_column As Long, _
                Optional seperator As String = ", ") As String

 Dim i As Long
 Dim result As String

For i = 1 To lookup_column.Rows.Count
If Len(lookup_column(i, 1).Text) <> 0 Then
    If lookup_column(i, 1).Text = lookup_value Then
        result = result & (lookup_column(i).Offset(0, return_value_column).Text & seperator)
    End If
End If
Next

If Len(result) <> 0 Then
result = Left(result, Len(result) - Len(seperator))
End If

VLookupAll = result

End Function

【问题讨论】:

  • 如果您对查找列进行排序,那么只要找到至少一个值并且下一行不匹配,您就可以退出循环。您是从工作表公式还是从 VBA 调用它?

标签: vba excel vlookup


【解决方案1】:

这比一个简单的循环快大约 20-30 倍(在 20k 个值的列上进行测试,其中 3 个与正在搜索的值匹配)。

'rng: a single-column range to search for matches
'val: the value to match on
'col: offset from match in rng to concatenate values from (similar
'       to the matching VLOOKUP argument)
Function MultiLookup(rng As Range, val As String, col As Long)

    Dim i As Long, v, s
    Dim r As Long

    r = rng.Cells.Count
    v = Application.Match(val, rng, 0)
    s = ""
    Do While Not IsError(v)
        s = s & IIf(s <> "", ",", "") & rng.Cells(v).Offset(0, col - 1).Value
        r = r - v
        Set rng = rng.Offset(v, 0).Resize(r, 1)
        v = Application.Match(val, rng, 0)
    Loop
    MultiLookup = s

End Function

【讨论】:

  • 嗨,蒂姆,非常感谢!它已将时间从 1 分钟缩短到 1 秒!!!
  • 这里没有 cmets!有人能解释一下“val”和“col”是什么吗?
【解决方案2】:

http://www.excelhero.com/blog/2011/03/the-imposing-index.html 说“Excel INDEX MATCH 比 VLOOKUP 快得多

【讨论】:

  • 嗨,我唯一的问题是我需要它返回匹配的所有行。
【解决方案3】:

在继续之前,您可以尝试执行 Range.Find 以查看查找列中是否存在该值。您正在遍历查找列中的每个项目,只是发现它不存在。如果是我,我会做一个 Range.find 来查看查找值是否在 lookup_column 中。如果是这样,那么您可以进行计数以查看有多少次出现...如果只有一次出现,请使用普通的旧 VLookup ...并且仅在出现多次时才回退到您的流程中... ..可以工作..当然,如果 Find 失败,请退出该功能。

另一种选择是将 lookup_column 加载到任何数组中...并处理数组而不是 range.mn,这有时会有所帮助。

【讨论】:

    【解决方案4】:

    总结: 连接这些值并对该新值执行vlookup

    对我来说,我需要一个公式而不是一个函数来查找 2 个值。 VLOOKUP 只能通过我所看到的单个值起作用,所以我的解决方案是连接单个主键的 2 个值。

    在我的原始数据选项卡中,我添加了一个名为 Lookup 的列,它只是将 ID 列与我拥有的 Timestamp 列连接起来。

    然后在我的比较标签中我有

    =VLOOKUP(CONCATENATE(A4, $F$1),'Historical Data'!$A:$G,3,FALSE)
    

    其中 ID 列与我在$F$1 的查找日期和vlookup 连接到我的数据选项卡(历史数据)中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-14
      • 2019-10-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多