Среднее значение VBA, если строки равны

#excel #vba #loops

#превосходить #vba #петли

Вопрос:

Я пытаюсь что-то сделать в VBA, но я не уверен, как это сделать.

Предположим, у меня есть что-то вроде следующего в Excel:

 Group Rate 1 20% 2 35% 3 31% 3 24% 3 25% 1 15% 3 22% 4 50% 2 50% 2 32%  

И я хотел бы рассчитать среднее значение по группе, сбрасывая его каждый раз, когда обнаруживается новый номер группы, т. Е.:

 Group Rate Final_Rate 1 20% 20% 2 35% 35% 3 31% 26.67% 3 24% 26.67% 3 25% 26.67% 1 15% 15% 3 22% 22% 4 50% 50% 2 50% 41% 2 32% 41%  

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

Как я могу сделать что-то подобное в VBA?

Мы можем предположить, что значения для Группы и Скорости заполнены в столбцах A и B соответственно.

Я очень новичок, я пытался написать какой-то фиктивный код, но я не знаю, на правильном ли я пути.

 Sub Calculate_Funny_Average()   Dim sh As Worksheet  Dim rw As Range  Dim RowCount As Integer      Set sh = Worksheets("Sheet1")    For Each rw In sh.Rows    If sh.Cells(rw.Row, 1).Value lt;gt; "" Then    If sh.Cells(rw.Row, 1).Value = "" Then  Exit For  End If    Cur_Group = sh.Cells(rw.Row, 1).Value  Cur_Rate = sh.Cells(rw.Row, 4)    Next_Group = sh.Cells(rw.Row   1, 1).Value    Do While Cur_Group = Next_Group    'Something ??    Loop      End If    Next rw  End Sub  

Комментарии:

1. @braX — Я добавил некоторые основные работы из того, что я пробовал. Извините, я не слишком разбираюсь в VBA. Я не совсем уверен, на правильном ли я пути.

2. Вы можете использовать AVERAGEIF, чтобы сделать это без VBA

3. @DarrellH — Я думал об этом, но проблема в том, что я не знаю, как его сбросить. Например, если один и тот же номер группы вернется позже, но не повторится в этом конкретном случае, тогда как что-то вроде AVERAGEIF просто даст мне общее среднее значение для группы, а не «текущий повторный выбор» группы.

4. @DarrellH , или я, возможно, что-то упускаю? Не могли бы вы, пожалуйста, показать мне СРЕДНЕЕ значение, если бы оно обеспечивало необходимое? Я с радостью приму это в качестве ответа. Более чем рад не использовать VBA, если в этом нет необходимости.

5. С помощью Office 365: =AVERAGE(XLOOKUP(TRUE,$A$1:A2lt;gt;A2,$B$2:B3,,0,-1):XLOOKUP(TRUE,A2:A$1040000lt;gt;A2,B1:B$1039999))

Ответ №1:

 Option Explicit Sub test() Dim arr Dim i As Integer, m As Integer, x As Integer arr = Cells(1, 1).CurrentRegion 'catch all data to an array. Make sure there are headers Group, Rate and Final Rate  For i = LBound(arr)   1 To UBound(arr) 'loop all rows, without the header arr(i, 3) = CDbl(arr(i, 2)) 'the first one must be recorded. cdbl() converts to Double type x = 1 'x will be the times the group is repeated If i   x lt;= UBound(arr) Then 'ifthe row   times the group appears is bigger than number of data rows,quit looping, else  Do While arr(i, 1) = arr(i   x, 1) 'while the group below is the same as the "i"  arr(i, 3) = arr(i, 3)   CDbl(arr(i   x, 2)) 'record the value   the value below  x = x   1 'add  1 to x to see the next row  If i   x gt; UBound(arr) Then 'again, if is i   x is bigger than the array, quit  Exit Do  End If  Loop End If  For m = x - 1 To 0 Step -1 'now, let's divide. Step-1 is to keep the original number and for the last one being changed  arr(i   m, 3) = arr(i, 3) / x  'if you want, record the value with %  arr(i   m, 3) = Format(arr(i   m, 3), "0.00 %")  Next m    i = i   x - 1 Next i Range(Cells(1, 1), Cells(UBound(arr), UBound(arr, 2))) = arr 'print the array over the original range End Sub  

Комментарии:

1. Один комментарий, неквалифицированные диапазоны(диапазоны без продиктованного родительского листа) обычно не одобряются в ответах. Это одна из проблем, которая часто возникает здесь. Но мне нравится использовать массивы для итерации. Даже если вы просто поставите ActiveSheet. перед своими диапазонами, это более приемлемо, чем ничего.

Ответ №2:

Один из способов использования формулы включает добавление вспомогательного столбца. Вспомогательный столбец изменит значение при изменении «Группы».

Я поместил вспомогательный столбец в другое место на листе, но вы можете поместить его куда угодно и/или скрыть его

Вспомогательная колонка

 E2: 1  E3: =IF($A3=A2,E2,E2 1)   

и заполните

окончательная_рейт

 C2: =AVERAGEIFS(Sheet1!$B$2:$B$11,Sheet1!$E$2:$E$11,Sheet1!$E2)  

и заполните

введите описание изображения здесь

Если у вас есть Office 365 с XLOOKUP , вы можете использовать более сложную формулу, упомянутую @ScottCraner в комментариях, и избегать вспомогательной колонки.