Hello stackexchange社区。 p>
我已经构建了一个简单的表转换器,其主要功能是从表转换
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秒),那么我想没有什么可以做的,我可以接受。虽然如果情况并非如此,如果有人可以帮助我并加快这一过程,我真的很感激。
谢谢!
答案 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来改进宏,所以现在转换的表立即更新。感谢所有参与并提供建议的人!