[英]Excel Macro, vlookup function works slow, ways to speed up macro
Hello stackexchange community. 您好stackexchange社区。
I've built a simple tables converter, the main function of which is to convert the table from 我建立了一个简单的表转换器,其主要功能是将表转换为
1a Value
1b Value
1c Value
1d Value
to 至
a b c d
1 Value Value Value Value
Unfortunately, the macro runs pretty slow (~ 3 lines per second for one column). 不幸的是,宏运行得非常慢(一列每秒大约3行)。
I'd really appreciate if someone could take a look at my piece of code and suggest the way to speed it up. 如果有人可以看一下我的代码并提出加速方法的建议,我将非常感激。
Here's the piece of code: 这是一段代码:
Dim LastFinalList As Integer: LastFinalList = Sheet1.Range("O1000").End(xlUp).Row
For Col = 16 To 19
For c = 2 To LastFinalList
searchrange = Sheet1.Range("J:L")
lookfor = Sheet1.Cells(c, 15) & Sheet1.Cells(1, Col)
CountFor = Application.VLookup(lookfor, searchrange, 3, False)
If IsError(CountFor) Then
Sheet1.Cells(c, Col).Value = "0"
Else
Sheet1.Cells(c, Col).Value = CountFor
End If
Next c
Next Col
Thanks in advance and best regards! 在此先感谢您,并致以最诚挚的问候!
UPD: UPD:
The Data in unconverted table looks like this (eg): 未转换表中的数据如下所示(例如):
Updated by Macro
Value Number Type Key Count Average Value
10 1 a 1a 2 20
30 1 a 1a 2 20
40 1 b 1b 1 40
50 1 c 1c 1 50
So it is also required to calculate averages of repeating types, create a unique list of Numbers (which is LastFinalList in my case) and finally convert it to this: 因此,还需要计算重复类型的平均值,创建一个唯一的Numbers列表(在我的情况下为LastFinalList),最后将其转换为:
Number a b c
1 20 40 50
application.vlookup
seraches by Number&Type Key, which is also assigned in the unconverted table by macro. application.vlookup
通过Number&Type键搜索,该键在未转换的表中也由宏分配。 The same time those Keys are counted, in order to calculate average for the repeating ones. 在计算那些键的同时,为了计算重复键的平均值。
Everything works in a blink of an eye till it comes to 'to update final table
part. 一切都在眨眼间完成,直到涉及
'to update final table
零件。
Full Code: 完整代码:
Sub ConvertToTable()
Dim LastMeter As Integer: LastMeter = Sheet1.Range("I1000").End(xlUp).Row
Sheet1.Range(Cells(2, 9), Cells(LastMeter, 9)).AdvancedFilter Action:=xlFilterCopy, CopyToRange:=Sheet1.Range("O2"), Unique:=True
Sheet1.Range("O1").Value = "The List"
Sheet1.Range("O2").Delete Shift:=xlUp
' to assign keys
For i = 2 To LastMeter
Set CountOpt = Sheet1.Cells(i, 10)
Sheet1.Cells(i, 10).FormulaR1C1 = "=r[0]c[-1]&r[0]c[-2]"
Sheet1.Cells(i, 11).FormulaR1C1 = "=COUNTIF(c10:c10, r[0]c10)"
Next i
'to calculate averages
For x = 2 To LastMeter
If Sheet1.Cells(x, 11).Value = 1 Then
Sheet1.Cells(x, 12).FormulaR1C1 = "=rc7"
ElseIf Sheet1.Cells(x, 11).Value > 1 Then
If Sheet1.Cells(x, 10).Value <> Sheet1.Cells(x - 1, 10).Value Then
Sheet1.Cells(x, 12).FormulaR1C1 = "=ROUND((SUM(rc7:r[" & Sheet1.Cells(x, 11).Value - 1 & "]c7)/" & Sheet1.Cells(x, 11).Value & "),4)"
Else
Sheet1.Cells(x, 12).FormulaR1C1 = "=r[-1]c12"
End If
End If
Next x
'to update final table
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Dim LastFinalList As Integer: LastFinalList = Sheet1.Cells(Rows.Count, 15).End(xlUp).Row
For Col = 16 To 19
For c = 2 To LastFinalList
searchrange = Sheet1.Range("J:L")
lookfor = Sheet1.Cells(c, 15) & Sheet1.Cells(1, Col)
CountFor = Application.VLookup(lookfor, searchrange, 3, False)
If IsError(CountFor) Then
Sheet1.Cells(c, Col).Value = "0"
Else
Sheet1.Cells(c, Col).Value = CountFor
End If
Next c
Next Col
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
Sheet1.Range("O1").Select
End Sub
Also, initially i had a SUMIF formula instead of application.vlookup
to be input in each cell in the converted table. 另外,最初我要在转换表的每个单元格中输入一个SUMIF公式而不是
application.vlookup
。 But the code was working as slow as now an was bit bulky, that's why i've decide to switch to VLOOKUP. 但是代码的运行速度现在慢到有点笨拙,这就是为什么我决定切换到VLOOKUP的原因。
The thing is, if it actually the way application.vlookup works (with 0.3sec delay for each row), then i guess there's nothing that can be done, and i'm ok to accept that. 问题是,如果它实际上是application.vlookup的工作方式(每行延迟0.3秒),那么我想那是无能为力的,我可以接受。 Although, if that's not the case, i'd really appreciate if someone could help me out and speed up the process.
尽管不是这样,但如果有人可以帮助我并加快流程,我将非常感激。
Thanks! 谢谢!
You can redefine your LastFinalList variable something like 您可以重新定义LastFinalList变量,例如
LastFinalList = Sheets("Sheet1").UsedRange.Rows.Count
OR 要么
LastFinalList = Sheets("Sheet1").Cells(Rows.Count, 2).End(xlUp).Row
instead of explicitly defining used range. 而不是明确定义使用范围。
Also use following line of code before your code 还要在代码之前使用以下代码行
Application.ScreenUpdating = False
(Turn screen updating off to speed up macro code. User won't be able to see what the macro is doing, but it will run faster.) (关闭屏幕更新以加快宏代码的速度。用户将无法看到宏在做什么,但是它将运行得更快。)
After the whole code runs you can(optional) turn screen updating on with 整个代码运行后,您可以(可选)使用打开屏幕更新
Application.ScreenUpdating = True
It appears that application.vlookup
in my particular case was indeed working very slow (no idea why, though). 看来在我的特殊情况下,
application.vlookup
的确确实运行很慢(尽管不知道为什么)。 I've managed to improve macro by replacing vlookup with SUMIF formula in each cell, so now the converted table is updated instantly. 我设法通过在每个单元格中用SUMIF公式替换vlookup来改善宏,所以现在转换后的表可以立即更新。 Thanks everyone who participated and provided their suggestions!
感谢所有参与并提供建议的人!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.