Excel 执行循环的更快方法
我是VBA新手,需要帮助找出执行代码的更快方法。以下是我正在使用的代码: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)
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中数组的其他范围中没有空格