【问题标题】:Is it possible to use InStr() combined with Application.Vlookup()?是否可以将 InStr() 与 Application.Vlookup() 结合使用?
【发布时间】:2018-09-17 17:19:05
【问题描述】:

我目前有一个 With 语句,它将一个单元格的值与一系列单元格进行比较,InStr() 返回 true,然后将 cell.Value 标记为“Yes",如果不是,则标记为 "No"

这里是场景。假设我正在检查A2 的值,这是111。我将111 与一系列其他单元格进行比较,应该匹配的字段是111, 222, 333,因为它包含111。我下面的第一组代码适用于此,但速度很慢。我希望有一个更快的方法,我想我可以用一个公式来做到这一点,但是在 vlookup 中使用 True 而不是 False 并没有像我想象的那样工作。

代码如下:

With inv_twcg_ws
    For Each cell In .Range("A2:A" & .Cells(Rows.Count, "A").End(xlUp).Row)
        For Each cellx In report_rng
            If InStr(cellx.Value, cell.Value) Then
                cell.Offset(0, 6).Value = "Yes"
                Exit For
            End If
                cell.Offset(0, 6).Value = "No"
        Next cellx
    Next cell
End With

问题是它有点慢。我的应用程序运行大约需要 5 分钟。我希望以某种方式将InStr()Application.Vlookup() 结合起来,以尝试加速公式。这可能吗?

这是我当前的 Vlookup,但使用 True 并不能满足我的需求...

With inv_twcg_ws
    For Each cell In .Range("G2:G" & .Cells(Rows.Count, "A").End(xlUp).Row)
        cell.Value = Application.WorksheetFunction.IfError(Application.VLookup(CStr(cell.Value), report_rng, 1, True), "No")
    Next cell
End With

【问题讨论】:

  • 最好读入数组并使用数组,然后写回工作表。
  • @QHarr 我擅长 Python 中的列表/数组,但我根本没有使用 VBA 中的数组。此时我需要对数组进行一些研究。
  • @QHarr 如果值在单元格中,Vlookup 中的True 不应该返回匹配项吗?还是我对 True/False 参数的理解有误?
  • True 是相对的,因为它找到单元格按顺序排列的位置,并且查找列表必须按升序排序。
  • @ScottCraner 哦,我明白了。到时候我得再读一读。感谢您的信息。

标签: excel vba formula vlookup


【解决方案1】:

使用变体数组:

Dim report_ws As Worksheet
Set report_ws = report_wb.Worksheets(1)

Dim report_rng As Variant
report_rng = report_ws.Range("B2:B" & last_row)

Dim inv_twcg_ws As Worksheet
Set inv_twcg_ws = Worksheets("Sheet1") ' change to your sheet




With inv_twcg_ws
    Dim lkup_rng As Variant
    lkup_rng = .Range("A2:A" & .Cells(Rows.Count, "A").End(xlUp).Row).Value

    Dim otpt As Variant
    ReDim otpt(1 To UBound(lkup_rng, 1), 1 To 1) As Variant

    Dim i As Long
    For i = LBound(lkup_rng, 1) To UBound(lkup_rng, 1)
        otpt(i,1) = "No"
        Dim j As Long
        For j = LBound(report_rng, 1) To UBound(report_rng, 1)
            If InStr(report_rng(j, 1), lkup_rng(i, 1)) Then
                otpt(i,1) = "Yes"
                Exit For
            End If
        Next j
    Next i

    .Range("G2").Resize(UBound(otpt, 1)).Value = otpt
End With

【讨论】:

  • 感谢 Scott,我很快就会对此进行测试。
  • 非常好,速度很快。
  • @QHarr 我实际上是从 OP 的最后一个问题开始的,但是当我的 cmets 解决了这个特定问题时就停止了。
  • @Scott。这工作速度快了 100 倍!我需要真正阅读这种方法。这将对我的其他项目有很大帮助。
  • @Mike-SMT 工作表读取和写入几乎是您在 Excel+VBA 中可以做的最慢的事情 - 学会爱上内存数组,他们会爱你的!
猜你喜欢
  • 2011-02-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-07
  • 2015-01-02
  • 2019-02-15
  • 2020-09-17
  • 2019-11-06
  • 1970-01-01
相关资源
最近更新 更多