In order to see what is happening (and given the assumption that your sample
table is in A1:H3 with labels in row 1 and column A), select a block of cells
that is 7 rows by 1 column. Then enter this (which I picked up from one of
Harlan Groves posts) in the formula bar and hit Ctrl+Shift+Enter
=MMULT(--(TRANSPOSE(COLUMN(B1:H1))>=COLUMN(B1:H1)),--(TRANSPOSE((B3:H3))))
This returns a running subtotal of your expense data.
30
40
100
120
190
280
330
By multiplying B3:H3 by (B1:H1="CD"), I get a running subtotal that only
includes expense items for "CD". This is due to the fact that excel stores
TRUE as 1 and FALSE as 0. So multiplying B3:H3 by an array of 1's (for CD)
and 0's (other values) causes the items that don't fit your criteria to drop
out:
=MMULT(--(TRANSPOSE(COLUMN(B1:H1))>=COLUMN(B1:H1)),--(TRANSPOSE((B3:H3)*(B1:H1="CD"))))
returns
30
30
90
90
160
160
160
The IF function eliminates duplicated values by testing B1:H1 for "CD" and
returning the corresponding value from the array returned by MMULT, otherwise
it returns FALSE
=IF(TRANSPOSE(B1:H1="CD"),MMULT(--(TRANSPOSE(COLUMN(B1:H1))>=COLUMN(B1:H1)),--(TRANSPOSE((B3:H3)*(B1:H1="CD")))))
returns
30
FALSE
90
FALSE
160
FALSE
FALSE
Then I used the Small function to return the second smallest number in the
above array (small ignores FALSE)
=SMALL(IF(TRANSPOSE(B1:H1="CD"),MMULT(--(TRANSPOSE(COLUMN(B1:H1))>=COLUMN(B1:H1)),--(TRANSPOSE((B3:H3)*(B1:H1="CD"))))),C10)
returns 90
Instead of hardcoding "2" in the Small function, I reference cell C10 which
contains
=MIN(2,COUNTIF(B1:H1,"CD"))
If there are fewer than 2 occurences of CD in B1:H1, Min returns the actual
count. Then divide the subtotal figure returned by Small by the number in
C10 to get the average
=SMALL(IF(TRANSPOSE(B1:H1="CD"),MMULT(--(TRANSPOSE(COLUMN(B1:H1))>=COLUMN(B1:H1)),--(TRANSPOSE((B3:H3)*(B1:H1="CD"))))),C10)/C10
which gives you 90/2 = 45.
You could move your criteria to other cells to make it more flexible. You
could use A10 and B10 as input cells so that you can easily modify your
criteria without having to edit the formula every time:
A10 = CD
B10 = 2
C10 = MIN(B10,COUNTIF(B1:H1,A10))
D10 =
IF(C10>0,SMALL(IF(TRANSPOSE(B1:H1=A10),MMULT(--(TRANSPOSE(COLUMN(B1:H1))>=COLUMN(B1:H1)),--(TRANSPOSE((B3:H3)*(B1:H1=A10))))),C10)/C10,0)
adding a check to ensure C10 is greater than 0, otherwise you'll get an error.