Массивы быстрее
Окончательная версия (надеюсь)
Эта версия дополнительно имеет аргумент NumberOfLastValues
( Обязательно ), поэтому вы можете выбрать, сколько значений будетсуммируется и сокращается с помощью оператора GoSub...Return
, поскольку оператор If
одинаков для строк и столбцов.
Дополнительные сведения см. в первой версии ниже.
Использование
В VBA :
Sub LastAverage()
Debug.Print AvgLast(Range("B4:G14"), 5)
End Sub
В Excel :
=AvgLast(B4:G14,5)
Function AvgLast(SearchRange As Range, ByVal NumberOfLastValues As Long, _
Optional ByVal Row_0_Column_1 As Integer = 0) As Double
Dim vntRange As Variant ' Range Array
Dim i As Long ' Range Array Rows Counter
Dim j As Integer ' Range Array Columns Counter
Dim k As Long ' Values Counter
Dim dblSum As Double ' Values Accumulator
If SearchRange Is Nothing Then Exit Function
vntRange = SearchRange.Value
If Row_0_Column_1 = 0 Then
' By Row
For i = UBound(vntRange) To 1 Step -1
For j = UBound(vntRange, 2) To 1 Step -1
GoSub Calc
Next
Next
Else
' By Column
For j = UBound(vntRange, 2) To 1 Step -1
For i = UBound(vntRange) To 1 Step -1
GoSub Calc
Next
Next
End If
TiDa:
If k > 0 Then
AvgLast = dblSum / k
End If
Exit Function
Calc:
If vntRange(i, j) <> "" And IsNumeric(vntRange(i, j)) Then
k = k + 1
dblSum = dblSum + vntRange(i, j)
If k = NumberOfLastValues Then GoTo TiDa
End If
Return
End Function
Первая версия
Возвращает среднее значение, если существует хотя бы 1 значение и не более 5 значений, в противном случае возвращается 0.
Параметр arguments Row_0_Column_1 по умолчанию равен 0 и означает, что поиск выполненпо ряду (первый цикл).Если оно равно 1, то поиск выполняется по столбцу (второй цикл).
Основой является то, что диапазон вставляется (depsited) в массив, а затем в массиве выполняется поиск существующих «числовых» значений ине «» значения, которые суммируются, и при достижении пятого значения оно «выпрыгивает» из цикла и делит сумму на 5.
Function AvgLast5(SearchRange As Range, Optional Row_0_Column_1 As Integer = 0) _
As Double
Dim vntRange As Variant ' Range Array
Dim i As Long ' Range Array Rows Counter
Dim j As Integer ' Range Array Columns Counter
Dim k As Long ' Values Counter
Dim dblSum As Double ' Values Accumulator
If SearchRange Is Nothing Then Exit Function
vntRange = SearchRange.Value
If Row_0_Column_1 = 0 Then
' By Row
For i = UBound(vntRange) To 1 Step -1
For j = UBound(vntRange, 2) To 1 Step -1
If vntRange(i, j) <> "" And IsNumeric(vntRange(i, j)) Then
k = k + 1
dblSum = dblSum + vntRange(i, j)
If k = 5 Then GoTo TiDa
End If
Next
Next
Else
' By Column
For j = UBound(vntRange, 2) To 1 Step -1
For i = UBound(vntRange) To 1 Step -1
If vntRange(i, j) <> "" And IsNumeric(vntRange(i, j)) Then
k = k + 1
dblSum = dblSum + vntRange(i, j)
If k = 5 Then GoTo TiDa
End If
Next
Next
End If
TiDa:
If k > 0 Then
AvgLast5 = dblSum / k
End If
End Function