我有一个产品多年价格变化的清单,以及价格变化的相关日期,直到一天。但是,这些价格很少变化,这意味着我一年可能只有4个数据点。 最重要的是,在这些价格变化点之间,即使未在数据中列出价格,价格也从上一个报告的点开始保持不变。
我如何找到未显示数据的天的加权月平均值?
例如,Item3
在2015年1月的平均价格应加权平均为31天的平均价格,其中21天的价格为110,7天的价格为94,三天的价格为88。一月的天。因此,这是104.26
我尝试在previously asked question中使用建议的公式,但是这样做只是以2015年1月列出的平均值为例。答案是97.33,而不是104.26
最终输出表应为时间序列表,每年从一月到十二月开始。 例如:
答案 0 :(得分:2)
看看这是否适合您。将以下代码粘贴到VBA中的新模块中……
Public Function CalculateAveragePrice(ByVal strItemNo As String, ByVal dtMonth As Date, ByVal rngData As Range) As Variant
Dim lngRow As Long, lngCol As Long, lngItemCol As Long, i As Long, bFoundTop As Boolean, lngYear As Long
Dim dtThisDate As Date, dtComparisonDate As Date, arrDays() As Double, dtNextDate As Date, lngMonth As Long
Dim lngBottomRow As Long, lngTopRow As Long, lngDaysInMonth As Long, dblCurrentPrice As Double
' Initialise the array with something.
ReDim arrDays(0)
lngMonth = Month(dtMonth)
lngYear = Year(dtMonth)
With rngData
' Find the header column for the item
For lngItemCol = 1 To .Columns.Count
If .Cells(1, lngItemCol) = strItemNo Then Exit For
Next
For i = 1 To 2
If i = 1 Then
dtComparisonDate = DateSerial(Year(dtMonth), Month(dtMonth), 1)
Else
dtComparisonDate = DateAdd("d", -1, DateAdd("m", 1, dtMonth))
lngDaysInMonth = Day(dtComparisonDate)
ReDim Preserve arrDays(lngDaysInMonth)
End If
For lngRow = 2 To .Rows.Count
dtThisDate = .Cells(lngRow, 1)
If i = 1 Then
If dtThisDate < dtComparisonDate Then lngBottomRow = lngRow
Else
If dtThisDate > dtComparisonDate And Not bFoundTop Then
lngTopRow = lngRow
bFoundTop = True
End If
End If
Next
Next
If lngTopRow = 0 Then lngTopRow = .Rows.Count
If lngBottomRow = 0 Then lngBottomRow = 2
For i = 1 To UBound(arrDays)
For lngRow = lngTopRow To lngBottomRow Step -1
dtThisDate = .Cells(lngRow, 1)
dblCurrentPrice = .Cells(lngRow, lngItemCol)
If dtThisDate <= DateSerial(lngYear, lngMonth, i) Then
arrDays(i) = dblCurrentPrice + arrDays(i - 1)
Exit For
End If
Next
Next
If UBound(arrDays) > 0 Then CalculateAveragePrice = arrDays(UBound(arrDays)) / UBound(arrDays)
End With
End Function
...,然后将您的公式设置为如下所示...
该代码也可用于远远超出给定价格范围的日期。那对您来说可能并不重要,而只是需要注意的地方。
也许有一种更优雅的方法,但它对我有用,我相信它也对您有用。
看看进展如何。
答案 1 :(得分:1)
数组公式解决方案如下:
=AVERAGE(
IF((ROW(INDEX($A:$A,MIN($B$3:$B$20)):INDEX($A:$A,DATE(MAX(YEAR($B$3:$B$20)),12,31)))>=$G3)
*(ROW(INDEX($A:$A,MIN($B$3:$B$20)):INDEX($A:$A,DATE(MAX(YEAR($B$3:$B$20)),12,31)))<=EOMONTH($G3,0)),
INDEX(C$3:C$20,N(IF({1},MATCH(ROW(INDEX($A:$A,MIN($B$3:$B$20)):INDEX($A:$A,DATE(MAX(YEAR($B$3:$B$20)),12,31))),$B$3:$B$20))))
)
)
除了使用ROW(INDEX ...))语句在公式内部生成日期外,它与使用帮助程序列为整个范围内的每一天生成日期基本相同。
必须使用 Ctrl Shift Enter
输入