Excel 执行循环的更快方法

Excel 执行循环的更快方法,excel,vba,Excel,Vba,我是VBA新手,需要帮助找出执行代码的更快方法。以下是我正在使用的代码: Sub loop() For i = 1 To 100000 check_cell = Sheets("Sheet1").Range("I" & i) For j = 1 To 14430 text_to_check = Sheets("Sheet2").Range("D" & j) text_to_fill = Sheets("Sheet2").Range("E" & j)

我是VBA新手,需要帮助找出执行代码的更快方法。以下是我正在使用的代码:

Sub loop()
For i = 1 To 100000
check_cell = Sheets("Sheet1").Range("I" & i)
  For j = 1 To 14430
    text_to_check = Sheets("Sheet2").Range("D" & j)
    text_to_fill = Sheets("Sheet2").Range("E" & j)
    If InStr(check_cell, text_to_check) Then
      Sheets("Sheet1").Range("J" & i).Value = text_to_fill
    End If
  Next j
Next i
End Sub
我知道我正在使用一种非常残酷的方式,通过1443000000次循环运行系统。如果您能帮我缩短时间,我们将不胜感激。谢谢

编辑:根据建议,我尝试了使用变体的新代码,但似乎什么都没有发生。你能告诉我我做错了什么吗?谢谢

Sub loop_2()
    Dim varray_1 As Variant
    Dim varray_2 As Variant
    Dim i As Long
    Dim j As Long
    varray_1 = Sheets("L1").Range("I2:I39997").Value
    varray_2 = Sheets("Sheet2").Range("G1:G14394").Value
    For i = UBound(varray_1, 1) To LBound(varray_1, 1) Step -1
        For j = UBound(varray_2, 1) To LBound(varray_2, 1) Step -1
            If varray_1(i, 1) = varray_2(j, 1) Then
                Sheets("L1").Range("L" & i).Value = Sheets("Sheet2").Range("H" & j).Value
            End If
        Next j
    Next i
End Sub

这里的最大成本是使用
InStr()
,但您还应该:

  • 声明变量时,
    Variant
    速度较慢
  • 把你的环用线包起来

    With Sheets("Sheet1")
       ...
    End With
    
  • 将单元寻址更改为
    .cell(10,i)
    而不是
    .Range(“D”&j)


我的测试显示它运行速度快了50%,请注意,我的所有单元格都是空的,因此在这种情况下,
InStr()
成本相对较低。

我还没有测试这段代码,但它至少应该给出如何将值放入数组、处理“内存中”的所有内容,然后写出结果的想法

Sub loop()
    Dim i As Long
    Dim j As Long
    Dim check_cell() As Variant
    Dim result() As Variant
    Dim text_to_check() As Variant
    Dim text_to_fill() As Variant

    check_cell = Sheets("Sheet1").Range("I1:I100000").Value
    result = Sheets("Sheet1").Range("J1:J100000").Value
    text_to_check = Sheets("Sheet2").Range("D1:D14430").Value
    text_to_fill = Sheets("Sheet2").Range("E1:E14430").Value
    For i = 1 To 100000
        For j = 1 To 14430
            If InStr(check_cell(i, 1), text_to_check(j, 1)) Then
                 result(i, 1) = text_to_fill(j, 1)
                 If i = 1 Then
                     Debug.Print "check_cell=" & check_cell(i, 1)
                     Debug.Print "j=" & j
                     Debug.Print "text_to_check=" & text_to_check(j, 1)
                     Debug.Print "text_to_fill=" & text_to_fill(j, 1)
                 End If
                 ' exit as soon as first match is made
                 Exit For
            End If
        Next j
    Next i
    Sheets("Sheet1").Range("J1:J100000").Value = result
End Sub

(a) 首先将数据传输到阵列,在阵列上进行处理,最后将阵列写回工作表。(b) 除非有可能将单元格更改为表2上的一个
text\u to\u fill
值,然后该值可以更改为以后的
text\u to\u fill
值,否则在更改单元格后,您可以将
退出。(而且,如果您的值中有一个
text\u to_fill
需要更改为另一个,请简化表2上的数据,以便您无法更改)。您好,对不起,我不明白您的解决方案。我不知道如何处理这些射线。您是否可以共享一个示例代码?您编辑的代码对我来说很有用,但显然它是在进行完全匹配,而不是部分匹配。在处理时将结果写入数组,然后在最后的一次操作中将数组写入工作表会更快。(我假设
L1!I:I
中没有任何单元格包含依赖于
L1!L:L
的公式)将消耗大量时间的是将信息写入工作表。我使用您的代码进行了测试。运行速度肯定快了很多,但在第J列中没有输出。开始时为空,运行代码后保持不变。您是否有任何
文本检查
(即Sheet2!D1:D14430)单元格为空?您的代码设计为只将最后一个匹配项存储到J列中,如果(例如)单元格D14430为空,则它将是最后一个匹配项。@AkshayNayar-P.S.是否要存储最后一个匹配项?还是第一场比赛?谢谢。我只想存储第一个匹配项。此外,D1:D14430范围内的所有单元格均为空。但是J列是空的。注意到一件有趣的事情。当我故意用一些数据填充J列时,它会在代码运行后被删除。我猜代码在给定范围内写空格,但我不知道为什么。在我传递到表2中数组的其他范围中没有空格