bla*_*ord 0 vba class user-defined-types
我有一个工作簿,其中包含两个我需要执行操作的数据.我开始直接从工作表中处理数据,但很快就发现它非常慢,所以改变了将工作表读入两个数组(在两个单独的方法中调用Workbook_Open).
我为每张工作表上的数据创建了一个用户定义的类型,然后我发现我无法将这些添加到集合或脚本字典中,因此我将它们转移到了类中.
所以现在我有一个名为CDealerData4个私有字段和公共属性的类.问题是,将数据读入数组的执行时间是我使用类型时的两倍.这是它是怎么回事,或者我做错了什么.
类:
Option Explicit
Private pBAC As String
Private pAccountNumber As String
Private pYear As Integer
Private pUnits As Variant
Public Property Get BAC() As String
BAC = pBAC
End Property
Public Property Let BAC(Value As String)
pBAC = Value
End Property
Public Property Get AccountNumber() As String
AccountNumber = pAccountNumber
End Property
Public Property Let AccountNumber(Value As String)
pAccountNumber = Value
End Property
Public Property Get Year() As String
Year = pYear
End Property
Public Property Let Year(Value As String)
pYear = Value
End Property
Public Property Get Units() As String
Units = pUnits
End Property
Public Property Let Units(Value As String)
pUnits = Value
End Property
Option Explicit
Private pBAC As String
Private pAccountNumber As String
Private pYear As Integer
Private pUnits As Variant
Public Property Get BAC() As String
BAC = pBAC
End Property
Public Property Let BAC(Value As String)
pBAC = Value
End Property
Public Property Get AccountNumber() As String
AccountNumber = pAccountNumber
End Property
Public Property Let AccountNumber(Value As String)
pAccountNumber = Value
End Property
Public Property Get Year() As String
Year = pYear
End Property
Public Property Let Year(Value As String)
pYear = Value
End Property
Public Property Get Units() As String
Units = pUnits
End Property
Public Property Let Units(Value As String)
pUnits = Value
End Property
Run Code Online (Sandbox Code Playgroud)
模块:
Option Explicit
Public NumberOfYears As Integer
Public DealersData() As CDealerData
Public Sub ReadDealerData()
'** Reads the contents of RawData into an Array
'** of custom type DealerData, defined above
Dim MyDealerData As CDealerData
Dim LastRow As Long
Dim i As Long
Dim j As Long
LastRow = SheetRawData.UsedRange.Rows.Count
ReDim DealersData(LastRow * NumberOfYears)
For i = 0 To LastRow
For j = 0 To NumberOfYears - 1 'Year columns
Set MyDealerData = New CDealerData
MyDealerData.BAC = SheetRawData.Cells(i + 2, 1).Value
MyDealerData.AccountNumber = SheetRawData.Cells(i + 2, 3).Value
MyDealerData.Year = j + 1
MyDealerData.Units = CDec(SheetRawData.Cells(i + 2, 4 + j).Value) 'Assign column based on j
Set DealersData(i) = MyDealerData
Next j
Next i
End Sub
Run Code Online (Sandbox Code Playgroud)
出于多种原因,UDT将比以这种方式使用类快得多.
为了提高性能,您可以考虑使用公共变量而不是私有属性,但是这可能会使您无法使用类的目的.
此外,加快速度的一般方法是尽可能少地访问电子表格.
例如,如下的代码
For i = 1 to 10
Variable = Worksheets("Sheet1").Range("A1").Cell(i,1).Value
Next i
Run Code Online (Sandbox Code Playgroud)
可以替换为
Dim VariantArray as Variant
VariantArray = Workeheets("Sheet1").Range("A1:A10")
' Now VariantArray(0,0) has the first element, (1,0) has the second, etc.
Run Code Online (Sandbox Code Playgroud)
关于分析的说明:请注意@ BlackHawk在下面的评论中的建议,使用MicroTimer工具.它非常有用,可以隔离部分代码并将性能影响发现到非常精确的级别.
此外,虽然对于任何平台都是如此,但VBA性能有时可能会不一致,具体取决于Excel目前的资源压力有多大,因此,即使MicroTimer精确,也可能没有准确的代表性.我想考虑在不同时间运行循环,以正确衡量代码不同部分的影响.