【问题标题】:Find string within an array optimization for excel vba在excel vba的数组优化中查找字符串
【发布时间】:2018-05-13 11:42:59
【问题描述】:

我有一段代码可以满足我的需要。但是,它运行得太慢了。通过研究,我发现“缓慢”来自不断访问工作簿,如果我可以从数组中执行操作,它应该会显着提高性能速度。我还没有找到任何专门帮助我解决这个问题的东西。所以这就是我得到的。

我的代码在一个单元格中搜索一个字符串 (xlpart),该单元格将包含多个用逗号分隔的数据条目。它会找到该实例和所有其他实例(以及它们在逗号分隔字符串中的位置),然后将它们重新组合成一个以逗号分隔的新字符串。

就像我说的那样,这行得通,但是当我将它应用到 4000 行时,它会破坏 CPU。我什至尝试添加一些我发现的“加速”想法,例如 .Calculation 和 .Screenupdating。我看到的问题在“Set test =”行中。有没有办法搜索数组、查找字符串的实例并提取特定信息?还是我做错了?

Function FindRef(lookupValue As Range, lookupRange As Range, resultsRange As Range) As String
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False

Dim OutputName1 As String
Dim OutputName2 As String
Dim r As Long
Dim test As Range
Dim working1() As String
Dim working2() As String

i = 0
For r = 1 To lookupRange.Rows.Count
  Set test = lookupRange.Cells(r, 1).Find(lookupValue.Value, LookIn:=xlValues, lookat:=xlPart)
  If Not test Is Nothing Then
    working1() = Split(lookupRange.Cells(r, 1), ", ")
    For j = LBound(working1) To UBound(working1)
      If working1(j) = CheckValue Then
        working2() = Split(resultsRange.Cells(r, 1), ", ")
        If UBound(working2) > 0 Then
          OutputName1 = working2(j)
        Else
          OutputName1 = resultsRange.Cells(r, 1)
        End If
      End If
    i = i + 1
    If i = 1 Then
      OutputName2 = OutputName1
    Else
      OutputName2 = OutputName2 & ", " & OutputName1
    End If
    OutputName1 = ""
    Next j
  End If
Next
FindRef = OutputName2

Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Function

更新代码:

Function FindRef(lookupValue As Range, lookupRange As Range, resultsRange As Range) As String

Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False

Dim OutputName1 As String
Dim OutputName2 As String
Dim r As Long
Dim test As Variant
Dim working1() As String
Dim working2() As String
Dim CheckValue As String
Dim data() As Variant
Dim data2() As Variant

CheckValue = lookupValue.Value2
data = lookupRange.Value2
data2 = resultsRange.Value2

i = 0
r = 0
For Each test In data
  r = r + 1
  If test = CheckValue Then
    working1() = Split(data(r, 1), ", ")
    For j = LBound(working1) To UBound(working1)
      If working1(j) = CheckValue Then
        working2() = Split(data2(r, 1), ", ")
        If UBound(working2) > 0 Then
          OutputName1 = working2(j)
        Else
          OutputName1 = data2(r, 1)
        End If
      End If
    i = i + 1
    If i = 1 Then
      OutputName2 = OutputName1
    Else
      OutputName2 = OutputName2 & ", " & OutputName1
    End If
    OutputName1 = ""
    Next j
  End If
Next
FindRef = OutputName2
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Function

【问题讨论】:

  • 是的,将范围分配给一个数组,然后循环遍历其中的每个项目。
  • 所以我像这样调整它:i = 0 r = 0 For Each test In data r = r + 1 If test = CheckValue Then working1() = Split(lookupRange.Cells(r, 1), ", ") 这帮了很多忙。你还有什么可以做得更快的吗?
  • 我的意思是将lookupRange 转移到一个数组中。与工作表的每次交互都会减慢速度。如果您遇到困难,如果有机会,我稍后会发布代码,但是在线应该有很多示例。您只需在最后将结果写回工作表即可。
  • 所以我更新了代码(见原帖),我没有看到速度上有太大的差异。还有其他建议吗?需要明确的是,感谢您最初的建议,这是巨大的。现在只是在寻找更快的速度。 :) 我还使用了 .Value2 而不是 .Value,因为另一篇文章说它更快。

标签: arrays vba excel optimization


【解决方案1】:

使用 Range.Find 很慢。

使用变体数组要快得多。见我的Match vs Find vs Variant Array

【讨论】:

  • 这确实是一篇好文章,但它没有提供问题的答案。我会把它放在 cmets 部分。
  • 不确定为什么它不回答这个问题:OP 希望加快搜索速度 - 答案是使用变体数组,文章给出了一个工作代码示例。你指望我为他重写他的代码吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-12-10
  • 2016-06-02
  • 1970-01-01
  • 2019-06-04
  • 1970-01-01
  • 2020-08-20
  • 1970-01-01
相关资源
最近更新 更多