如何在VBA上获得单元格内容的平均值
在Excel中,我有第1列和第2列数字,如下所示:
AB 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 missing is”
也许在C1这样的事情。
=IF(A1<>A2,AVERAGEIF(A:A,A1,B:B),"")
在你的代码中:
- 总和忽略了第一个AAA
- 错过了结束如果
- 递增行两次,一行一行=第一行,然后是第二行
- 和其他一些未使用的variables
尝试这个:
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
为了从Jeeped中得到答案,用一个没有sorting的列表来做,你也可以这样做:
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 + Enter确认
要通过VBA来实现(应该比我的公式更快),你可以使用类似的东西:(把它放在VBA窗口中的“模块”中,就像写入的loggingmacros一样)
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
然后select一个范围如C2:D12并input:
=getAllAvg(A:B)
并用Ctrl + Shift + Enter确认 。 它会直接输出整个列表(并在需要时重新计算)
编辑 :
如果您的列表总是按照sorting顺序,那么您也可以使用以下代码:
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