Посмотрите, работает ли это для вас. Вставьте приведенный ниже код в новый модуль в 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
... а затем настройте формулу так, как показано ниже ...
![Formula Setup](https://i.stack.imgur.com/6IxQ5.png)
Код также будет работать для дат, выходящих за пределы диапазона указанных цен. Это может быть не важно для вас, но просто кое-что отметить.
Возможно, есть более элегантный способ, но он работает для меня, и я верю, что он будет работать и для вас.
Посмотрите, как это происходит.