arrays - 有没有办法将此循环更改为数组/范围引用?
问题描述
我正在尝试使用字典将与唯一 ID 组合关联的总余额移动到另一张表。循环可能必须在数万行上运行,即使在 900 行上,该过程也需要大约 30 秒。
我的代码可以使用(多个)字典和循环,但速度很慢。我想知道是否有办法优化循环(可能通过使用数组?虽然我对它们非常缺乏经验)。
我试图为 I=lbound 设置一个数组循环到 ubound 但我离让它工作还差得很远(代码一团糟)。下面是一段代码和我正在尝试优化的循环之一。稍后还有 4 个其他循环,但现在我只想优化一个。
'declare start/end rows
Dim StartRowPeriod As Long
StartRowPeriod = 7
Dim LastRowPeriod As Long
LastRowPeriod = ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Row
'more dims for total bal
Dim HardCopyID As String
Dim Old_Balance As Double
Dim New_Balance As Double
Dim Updated_Balance As Double
Application.ScreenUpdating = False
'RUNNING THE DICTIONARY (ADDING THE TOTAL VALUES TO THE UNIQUE IDS)
For I = StartRowPeriod To LastRowPeriod
HardCopyID = Cells(I, 11).Value
If HardCopyID = "" Then
Exit For
ElseIf HardCopy_Dictionary.Exists(HardCopyID) Then
Old_Balance = HardCopy_Dictionary(HardCopyID)
New_Balance = Cells(I, 10).Value
Updated_Balance = Old_Balance + New_Balance
HardCopy_Dictionary(HardCopyID) = Updated_Balance
Else
HardCopy_Dictionary(HardCopyID) = Cells(I, 10).Value
End If
Next I
解决方案
你是对的,切换到 Variant Array 方法将大大加快速度。
您编写代码,重构为使用 Array,以及其他一些清理工作:
Sub Demo()
' declare all variables
Dim i As Long
Dim HardCopy_Dictionary As Dictionary ' early bound: set a reference to Microsoft Scripting Runtime
'Dim HardCopy_Dictionary As Object ' late bound
Dim ws As Worksheet
Dim Dat As Variant
'declare start/end rows
Dim StartRowPeriod As Long
Dim LastRowPeriod As Long
'more dims for total bal
Dim HardCopyID As String
Dim Old_Balance As Double
Dim New_Balance As Double
Dim Updated_Balance As Double
' Application.ScreenUpdating = False 'not needed as there is no sheet interaction
Set HardCopy_Dictionary = New Dictionary ' Early bound
'Set HardCopy_Dictionary = CreateObject("Scripting.Dictionary") ' Late bound
Set ws = ActiveSheet
StartRowPeriod = 7
With ws
LastRowPeriod = .Cells(.Rows.Count, 1).End(xlUp).Row
' Copy data to array
Dat = .Range(.Cells(1, 1), .Cells(LastRowPeriod, 11)).Value
'RUNNING THE DICTIONARY (ADDING THE TOTAL VALUES TO THE UNIQUE IDS)
For i = StartRowPeriod To LastRowPeriod
HardCopyID = Dat(i, 11) '.Cells(i, 11).Value
If HardCopyID = vbNullString Then
Exit For 'are you sure about this? Surley it should run to the end of the data?
ElseIf HardCopy_Dictionary.Exists(HardCopyID) Then
Old_Balance = HardCopy_Dictionary(HardCopyID)
New_Balance = Dat(i, 10) '.Cells(i, 10).Value
Updated_Balance = Old_Balance + New_Balance
HardCopy_Dictionary(HardCopyID) = Updated_Balance
Else
HardCopy_Dictionary.Add HardCopyID, Dat(i, 10) '.Cells(i, 10).Value
End If
Next i
End With
End Sub
这几乎可以立即在 100,000 行的一些模型数据上运行。
推荐阅读
- python - Python:将第一个元素更改为列表本身
- php - Visual Studio Code、PHP 项目、全局包含/自动加载/自动包含一个 functions.php 文件,仅用于智能感知
- maps - Android中的室内定位地图设计
- android - AlarmManager 没有在特定时间执行任务
- c# - 当我单击向 gridview 添加按钮时,以下代码将添加双记录
- python - 迭代列表中的元素时如何在python中创建对象?
- php - SabreDAV 客户端创建日历对象
- android - Android ndk not bundle v8 .a file symbols
- javascript - Mastermind (HTML+jQuery+PHP) - 重复数字的问题
- python - 在 Python 中使用 Stack 切换迷宫求解算法中的 X 和 Y 坐标