这对我来说是一个棘手的解释,所以我将从我到目前为止的代码开始,然后开始我想要实现的目标。
当前代码
Option Explicit
Public eSigTickerArr As Variant
' Public type to save array
Type Watchlist
eSigTicker As String
Op As Double
Hi As Double
Lo As Double
Cl As Double
Vol As Double
BarTime As Variant
End Type
Public WatchlistArr() As Watchlist ' save an array of special type "Watchlist"
'====================================================================
Sub Mainr()
ReDim WatchlistArr(0) ' init array size
eSigTickerArr = Array("Part1", "Part2", "Part3")
For Each eSigTickerElem In eSigTickerArr
' check if first member of array is occupied
If WatchlistArr(0).eSigTicker <> "" Then ' not first time running this code >> increase array size by 1
ReDim Preserve WatchlistArr(UBound(WatchlistArr) + 1) ' increase array size by 1
End If
' ... Some Code, working fine ....
' populate array Type with data (also works)
With WatchlistArr(UBound(WatchlistArr))
.eSigTicker = eSigTickerElem
.Op = LastCSVLine(2)
.Hi = LastCSVLine(3)
.Lo = LastCSVLine(4)
.Cl = LastCSVLine(5)
.Vol = LastCSVLine(6)
.BarTime = LastCSVLine(1)
End With
Next eSigTickerElem
' ******* calculate the average of only "Hi" ******
Dim myAvg
myAvg = WorksheetFunction.Average(WatchlistArr.Hi) '<--- Getting an Error !
End Sub
我在上面的一行收到错误。
我的挑战:我想获得我的类型数组WatchlistArr
的某个变量的平均值,并且我不想使用循环,因为它可以是10,000条记录(或更多)。
有没有办法通过Average
函数获取值?
我应该切换到2-D阵列吗?或者可能是3-D阵列?
答案 0 :(得分:1)
myAvg = WorksheetFunction.Average(WatchlistArr.Hi) '<--- Getting an Error !
是的。此代码的含义与此类似:
myAvg = watchListArr.Select(item => item.Hi).Average();
其中item => item.Hi
是一个为watchListArr
中的每个项调用的选择器函数。唯一的问题是这是LINQ / C#,而不是VBA。 VBA不支持代表和其他时髦的东西,即使C#无法在v1.0中做到这一点。
但是VBA 具有控制流结构,可以让您对数组中的每个项执行操作:使用For
循环!
Dim i As Long, total As Double, count As Long
For i = LBound(watchListArr) To UBound(watchListArr)
total = total + watchListArr(i).Hi
If watchListArr(i).Hi <> 0 Then count = count + 1 'assuming zeroes are excluded
Next i
If count <> 0 Then myAvg = total / count
如果您想使用Application.WorksheetFunction.Average
,则需要将数组中每个项目的Hi
成员复制到自己的数组中,然后将 >数组 - 这将需要......一个循环...如果该循环不是也 计算平均值,则浪费周期。
只要您不使用For Each
循环来迭代数组,您就可以了。使用For
循环迭代30K项目数组非常快,不用担心。
答案 1 :(得分:1)
您可以将WatchlistArr
定义为二维数组,然后尝试以下逻辑:
Dim myArray As Variant
myArray = Application.WorksheetFunction.Index(WatchlistArr, 0, 2)
这将返回第2列和数组,可以将其传递给Average方法:
myAvg = WorksheetFunction.Average(myArray)