我尝试了两种不同的配置电子表格工具的方法,用于将客户端提供的数据转换为我们自己的数据代码。
数据集可能会特别大(这一行是76,335行),因此宏观性能非常重要。
我尝试的第一种方法是将一系列索引/匹配公式记录到VBA中,并将代码插入到列M到Y中并向下拖动到原始数据集中最后一行的任何位置(存在于Col A到J)。这些公式中只有一个是数组公式,我尝试了没有数组公式的代码,总体效益很小。这种方法(让我们称之为方法A)花了14分8秒(带有i7-2600 CPU和8 GB RAM的Windows PC)。
如果我让VBA进行excel公式所做的计算,我认为它会提高性能,我运行了以下循环(方法B)。
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False
Application.EnableEvents = False
lastRow = ActiveSheet.Cells(Rows.Count, "F").End(xlUp).Row
For i = 6 To lastRow
With ThisWorkbook.Worksheets("CONVERSION")
If Range("M" & i) = "BIN" Then
Range("N" & i) = "Duplicate"
Else
Range("N" & i) = Range("B" & i) & "-" & Range("D" & i) & "-" & Range("M" & i)
End If
If Range("B" & i) = "Duplicate" Then
Range("O" & i) = "D"
Else
Range("O" & i) = "N"
End If
If Range("E2") = "Groundwater" Then
Range("P" & i) = "WG"
ElseIf Range("E2") = "Leachate" Then
Range("P" & i) = "LE"
ElseIf Range("E2") = "Surface water" Then
Range("P" & i) = "WS"
Else
Range("P" & i) = "Other"
End If
'Plus another six If statements similar to the above to populate Cols P to Y... Not included here to keep this code on StackOverflow easier to read
End With
Next i
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
Application.EnableEvents = True
这令人惊讶地花了27分27秒。尽管有Application.Calculation = xlCalculationManual
,Application.ScreenUpdating = False
和Application.EnableEvents = False
。
为什么VBA计算方法较慢?这与我的循环效率低下有关吗?可能是因为VBA必须反复回访电子表格的值,来回吗?
一般的引导和建议将不胜感激。我知道我有一个大型数据集,但我希望能够以超过14分钟的速度运行此转换代码。
答案 0 :(得分:2)
您需要使用数组 - 我已经切换了您的代码并将所有内容弹出到数组中以完成大部分工作:
Sub SpeedUp()
Dim iLastRow As Long, iLastCol As Long, i As Long
Dim Arry() As Variant
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False
Application.EnableEvents = False
iLastRow = ActiveSheet.Cells(Rows.Count, "F").End(xlUp).Row
iLastCol = ActiveSheet.Cells(5, Columns.Count).End(xlToLeft).Column 'I'm assuming Row 1 is the header row. Also, if you're creating colums (to column Y) then just change this to "iLastCol = 25"
ReDim Arry(1 To iLastRow, 1 To iLastCol) ' This array is a 2 dimensionnel array and you can referance rows/columns within it like you would using Cells([Row number],[Column number])
Arry = Range(Cells(1, 1), Cells(iLastRow, iLastCol))
For i = 6 To iLastRow
If Arry(i, 13) = "BIN" Then '13 corresponds to column M
Arry(i, 14) = "Duplicate"
Else
Arry(i, 14) = Arry(i, 2) & "-" & Arry(i, 4) & "-" & Arry(i, 13)
End If
If Arry(i, 2) = "Duplicate" Then
Arry(i, 15) = "D"
Else
Arry(i, 15) = "N"
End If
If Arry(i, 5) = "Groundwater" Then
Arry(i, 16) = "WG"
ElseIf Arry(i, 5) = "Leachate" Then
Arry(i, 16) = "LE"
ElseIf Range("E2") = "Surface water" Then
Arry(i, 16) = "WS"
Else
Arry(i, 16) = "Other"
End If
'Plus another six If statements similar to the above to populate Cols P to Y... Not included here to keep this code on StackOverflow easier to read
Next i
ThisWorkbook.Worksheets("CONVERSION").Range(Cells(1, 1), Cells(iLastRow, iLastCol)) = Arry ' Sets all the values
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
Application.EnableEvents = True
End Sub