如何在VBA上按单元格内容获得平均值

时间:2016-02-20 12:40:40

标签: excel vba excel-vba

在excel中,我的第1列包含代码,第2列包含数字,如下所示:

      A  B    
1    AAA 10
2    AAA 12
3    AAA 14
4    BBB  9
5    BBB 10
6    BBB 11

我需要一段代码来计算平均BY TICKER,这意味着在这种情况下我会得到AAA平均值:12和BBB平均值= 10等等。到目前为止我得到的是这个代码试图计算总和,我稍后会做分,但是出了点问题:

For row = 2 to 6
Ticker = Cells(row - 1, 1)
If Cells(row, 1) = Cells(row - 1, 1) Then
sum = sum + Cells(row, 2)
Else
Cells(row, 6) = sum
sum = 0
row = row + 1
Next

我收到错误消息“For is missing”

3 个答案:

答案 0 :(得分:4)

在C1中可能是这样的。

=IF(A1<>A2,AVERAGEIF(A:A,A1,B:B),"")

averageif_once

答案 1 :(得分:0)

在您的代码中:

  • 总和忽略了第一个AAA
  • 错过了结束如果
  • 两次递增行,一次按行=行+ 1然后按下一行
  • 和其他一些未使用的变量

试试这个:

Prev = "***"
For row = 1 to 6
  If Cells(row, 1) = prev Then
    sum = sum + Cells(row, 2)
  Else
    Cells(row, 6) = sum
    sum = 0
  End If
  prev = Cells(row,1)
Next

答案 2 :(得分:0)

要从Jeeped扩展答案并使用未订购的列表进行,您也可以这样做:

C1:       =A1
C2:       =IF(LEN(C1),IFERROR(INDEX(A:A,MATCH(1,(COUNTIF(C$1:C1,A$1:A$1000)=0)*(A$1:A$1000<>""),0)),""),"")}
C3....Cn: copy down from C2

D1:      =IF(LEN(C1),AVERAGEIF(A:A,C1,B:B),"")
D2...Dn: copy down from D1

C2是一个数组公式,需要通过 Ctrl + Shift + 输入确认

通过VBA(比我的大表的公式要快)你可以使用类似的东西:(把它放在VBA窗口的“模块”中,就像你编写的记录宏一样)

Option Explicit

Public Function getAllAvg(rng As Range) As Variant
  Set rng = Intersect(rng.Parent.UsedRange, rng)

  Dim varInput As Variant
  varInput = rng.Value

  Dim varOutput() As Variant
  ReDim varOutput(1 To UBound(varInput), 1 To 2)
  varOutput(1, 1) = ""

  Dim i As Long, j As Long
  For i = 1 To UBound(varInput)
    If Len(varInput(i, 1)) Then
      j = 1

      While Len(varOutput(j, 1)) And (varOutput(j, 1) <> varInput(i, 1)) And (j < UBound(varOutput))
        j = j + 1
      Wend

      If Len(varOutput(j, 1)) = 0 Then
        varOutput(j, 1) = varInput(i, 1)
        varOutput(j, 2) = Application.AverageIf(rng.Columns(1), varOutput(j, 1), rng.Columns(2))
        varOutput(j + 1, 1) = ""
      End If

    End If
  Next

  While Len(varOutput(j, 1)) And (j < UBound(varOutput))
  j = j + 1
  Wend

  If Len(varOutput(j, 1)) = 0 Then
    For i = j To UBound(varOutput)
      varOutput(i, 1) = ""
      varOutput(i, 2) = ""
    Next
  End If
  getAllAvg = varOutput
End Function

然后选择像C2:D12这样的范围并输入:

=getAllAvg(A:B)

并使用 Ctrl + Shift + 输入确认。它将直接输出整个列表(并在需要时重新计算)

修改

如果您的列表始终按排序顺序排列,您也可以使用以下代码:

Option Explicit

Public Function getAllAvgSorted(rng As Range) As Variant
  Set rng = Intersect(rng.Parent.UsedRange, rng)

  Dim varInput As Variant
  varInput = rng.Value

  Dim varOutput() As Variant
  ReDim varOutput(1 To UBound(varInput), 1 To 2)
  varOutput(1, 1) = ""

  Dim i As Long, j As Long
  j = 1

  For i = 1 To UBound(varInput)
    If Len(varInput(i, 1)) Then
      If varOutput(j, 1) <> varInput(i, 1) Then
        If Len(varOutput(j, 1)) Then j = j + 1
        varOutput(j, 1) = varInput(i, 1)
        varOutput(j, 2) = Application.AverageIf(rng.Columns(1), varOutput(j, 1), rng.Columns(2))
      End If
    End If
  Next

  While j < UBound(varOutput)
    j = j + 1
    varOutput(j, 1) = ""
    varOutput(j, 2) = ""
  Wend

  getAllAvgSorted = varOutput
End Function