如何计算自定义类型数组的1个变量的平均值

时间:2017-08-14 14:57:41

标签: arrays vba excel-vba multidimensional-array excel

这对我来说是一个棘手的解释,所以我将从我到目前为止的代码开始,然后开始我想要实现的目标。

当前代码

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阵列?

2 个答案:

答案 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)