Excel宏,vlookup功能工作缓慢,加速宏的方法

时间:2015-02-13 10:45:14

标签: performance excel-vba vba excel

Hello stackexchange社区。

我已经构建了一个简单的表转换器,其主要功能是从表转换

1a Value
1b Value
1c Value
1d Value 

    a     b     c     d
1 Value Value Value Value

不幸的是,宏运行速度非常慢(一列约为每秒3行)。

如果有人可以查看我的代码并提出加快速度的方法,我真的很感激。

这是一段代码:

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

提前致谢和最诚挚的问候!

UPD:

未转换表中的数据如下所示(例如):

                      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 

因此,还需要计算重复类型的平均值,创建一个唯一的Numbers列表(在我的情况下是LastFinalList),最后将其转换为:

Number  a    b    c
   1    20   40   50
数字和类型键的

application.vlookup seraches,也是由宏在未转换的表中分配的。这些密钥计算的时间相同,以便计算重复密钥的平均值。

一切都在眨眼之间起作用,直到'to update final table部分。

完整代码:

    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

此外,最初我在转换表中的每个单元格中输入了SUMIF公式而不是application.vlookup。但是代码的工作速度和现在一样慢,这就是我决定切换到VLOOKUP的原因。

问题是,如果它实际上是application.vlookup的工作方式(每行延迟0.3秒),那么我想没有什么可以做的,我可以接受。虽然如果情况并非如此,如果有人可以帮助我并加快这一过程,我真的很感激。

谢谢!

2 个答案:

答案 0 :(得分:1)

您可以重新定义您的LastFinalList变量,例如

LastFinalList = Sheets("Sheet1").UsedRange.Rows.Count

OR

LastFinalList = Sheets("Sheet1").Cells(Rows.Count, 2).End(xlUp).Row

而不是明确定义使用的范围。

在代码

之前使用以下代码行
Application.ScreenUpdating = False 

(关闭屏幕更新以加速宏代码。用户将无法看到宏正在做什么,但它会运行得更快。)

在整个代码运行后,您可以(可选)使用

打开屏幕更新
Application.ScreenUpdating = True

答案 1 :(得分:0)

在我的特定情况下application.vlookup似乎确实工作得很慢(不知道为什么)。我已经设法通过在每个单元格中用SUMIF公式替换vlookup来改进宏,所以现在转换的表立即更新。感谢所有参与并提供建议的人!