Как мне нарезать вектор в Excel VBA? - PullRequest
1 голос
/ 11 июня 2019

Я хочу взять среднее значение только нескольких элементов в массиве в Microsoft Excel-VBA. Например, возьмем среднее значение для каждой пары чисел в векторе: 45 21 63 12 19. Главная проблема здесь заключается в том, что я хочу иметь возможность сделать количество чисел динамическим, чтобы оно также всегда могло принимать среднее из каждых 3 цифр.

Я пытался использовать функцию Index или функцию Offset, но оба не работали.

Dim arrMarks(1 To 5) As Long

arrMarks(1) = 45
arrMarks(2) = 21
arrMarks(3) = 63
arrMarks(4) = 12
arrMarks(5) = 19

length = UBound(arrMarks, 1) - LBound(arrMarks, 1) + 1

' take the average of m numbers

m = 3
m_length = length - (m-1)

Dim arravg(1 To m_length)

For i = 1 To m_length
    If (i + m) <= length Then
        arravg(i) = Application.WorksheetFunction.Average(arrMarks.Offset(m, 0))
    End If
Next i

Этот пример просто возвращает ошибку.

Желаемый результат:

Значения arravg:

Average(45, 21, 63) 
Average(21, 63, 12) 
Average(63, 12, 19)

Я надеюсь сделать код таким образом, чтобы m мог быть заполнен любым числом (до m

1 Ответ

1 голос
/ 11 июня 2019

Получить средние значения в последовательных группах элементов массива

Позволяет гибкие группы размеров

Пример вызова

Единственное изменение, внесенное в ваше сообщение, заключается в том, что я использую 2-мерный исходный массив arrMarks с возможным преимуществом, позволяющим легко назначать данные из заданного диапазона (строки).

Sub ExampleCall()
ReDim arrMarks(1 To 1, 1 To 5)
arrMarks(1, 1) = 45
arrMarks(1, 2) = 21
arrMarks(1, 3) = 63
arrMarks(1, 4) = 12
arrMarks(1, 5) = 19

Dim arrAvg
arrAvg = getAverages(arrMarks, 3)           ' calculate averages in groups of 3 elements
Debug.Print "~> " & UBound(arrAvg) - LBound(arrAvg) + 1 & " averages: " & Join(arrAvg, "|")

End Sub

Результаты в ...

1) current group: 45, 21, 63               43 
2) current group: 21, 63, 12               32 
3) current group: 63, 12, 19               31,3333333333333 
~> 3 averages: 43|32|31,3333333333333

Основная функция getAverages ()

Function getAverages(arrData, Optional groupSize As Long = 2) As Variant()
' count array elements
  Dim lg As Long
  lg = UBound(arrData, 2) - LBound(arrData, 2) + 1

' take the average of m numbers
  Dim m_lg As Long
  m_lg = lg - (groupSize - 1)

  ReDim arrAvg(1 To m_lg)
  Dim temp, i As Long
  For i = 1 To m_lg
      If (i + groupSize) <= lg + 1 Then
          temp = Application.Index(arrData, Array(1), getElements(i, groupSize))
          arrAvg(i) = Application.WorksheetFunction.Average(temp)
          Debug.Print i & ") current group: " & Join(temp, ", "), arrAvg(i)
      End If
  Next i
' return averages
  getAverages = arrAvg
End Function

Вспомогательная функция, содержащая текущие номера элементов

Function getElements(ByVal start As Long, Optional ByVal groupSize As Long = 2)
ReDim temp(0 To groupSize - 1)
Dim i&
For i = 0 To groupSize - 1
    temp(i) = start + i
Next i
getElements = temp
End Function

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...