Excel formula to sum non-overlapping ranges of cells? - excel

Say I have numbers in A1 to A20 and I wanted to sum non-overlapping ranges of 5 cells in column A and store the results in cells in column E, it would look something like this (if the formulas were typed into each E column cell manually):
E1 = SUM(A1:A5)
E2 = SUM(A6:A10)
E3 = SUM(A11:A15)
E4 = SUM(A16:A20)
However, I don't want to type the formulas into E cells manually. I want to be able to select the formula in E1 and drag it down to E4, whilst maintain the non-overlapping ranges of 5 cells in A! Excel does not give me this behavior by default, it does this instead:
E1 = SUM(A1:A5)
E2 = SUM(A2:A6)
E2 = SUM(A3:A7)
E4 = SUM(A4:A8)
See how the ranges of 5 cells in each SUM() function overlap? e.g. A1:A5 and A2:A6. That's not what I want.
So, what is a formula that would enable me to do this? Basically, the following pseudocode would work, but I can't seem to implement anything like it in Excel:
SUM(CELL(COLUMN, (CURRENT_ROW - 1) * 5 + 1):CELL(COLUMN, (CURRENT_ROW - 1) * 5 + 5))
For example, for E2, CURRENT_ROW = 2, meaning it would look like this:
SUM(CELL(A, (2 - 1) * 5 + 1):CELL(A, (2 - 1) * 5 + 5))
= SUM(CELL(A, 6):CELL(A, 10))
This pseudocode assumes CELL has the method signature CELL(row, column).

The key to this is the OFFSET function. Offset takes a starting cell, and a number of rows, columns, and optional height and width to generate a reference to a cell/range on the fly. The trick would be to use other functions to generate the row offset and other parameters.
I've just knocked together something that seems to do what you want, I'll see if I can explain it...
Column A: integers (A1) 0, (A2) 1, (A3) 2,3,4,5 etc... this is an index for how many you're offsetting by, you could probably remove this using something like the ROW function)
Column D (or any other arbitrary location): the numbers you're wanting to sum, starting at D1 - I actually just used (D1) 1, (D2) 2,3,4,5...
Column B is the one that's interesting to you, formula is:
=SUM(OFFSET(D$1,A1*5,0,5,1))
What it's doing: summing the range defined by: A block of cells starting (A1 * 5) cells down and 0 across from $D$1, which is 5 high by 1 wide. See edit, I left this in because you could put arbitrary numbers in the A cells and use this principle.
Hope that makes some kind of sense? Excel doesn't lend itself to text explanations!
Edit: Removed the cells A1..., remembered that ROW() allows self-references, which means you can do
=SUM(OFFSET(D$1,(ROW(B1)-1)*5,0,5,1))
Where this formula is in Cell B1 (pasted down), and your data is in Column D starting at 1.

This formula will get correct results when entered into cell E1 and populated down into E2, E3 etc...
=SUM(OFFSET(A1,ROW(A1)*4-4,0,5,1))

Related

Apply result of IF statement on multiple cells

I want to apply the result of an IF statement on multiple cells, so for example A2, A2 and A3 are equal to 1, 2 or 3.
When A2 is equal to 1 I want to get B2,B3,B4 = 1,0,0
When A3 is equal to 2 to get B5,B6,B7 = 0,1,0
And when A4 is equal to 3 to get B8,B9,B10 = 0,0,1
Is this possible?
First thing about Excel: you can't write a formula that changes the contents of another cell. A formula only gives a result in the current cell. That result may well be based on the contents of several other cells, and the result in the current cell may be used by several other cells.
So here are two possible answers:
(1) In B2, write
=If(A2=1,1,"")
In B3, write
=If(A2=1,0,"")
and keep going for the other 7 cells B4:B10.
(2) If you wanted a single formula that would do roughly what you describe, it would be quite complicated but do-able.
In B2, write
=IF(INDEX(A$2:A$4,(ROW()+1)/3)=INT((ROW()+1)/3),IF(MOD(ROW()+1,3)+1=INDEX(A$2:A$4,(ROW()+1)/3),1,0),"")
and pull or copy this down through cells B3:B10.
Then use Formulas | Evaluate Formula to see what it does.
EDIT
If A2, A3 etc can be 1, 2 or 3 then the formula would be simpler
=IF(MOD(ROW()+1,3)+1=INDEX(A$2:A$4,(ROW()+1)/3),1,0)
you're just seeing if the remainder on dividing the row in column B by 3 (+1) is equal to the corresponding value (1, 2 or 3) in A2, A3 etc.

Excel formula to Sum 12 rows every 3 rows

I need to make a sum of 12 rows every 3 rows in excel. That is, I need to sum first from C4 to C15, then from C7 to C18, and so on.
You can use OFFSET function for this, also volatile, but shorter!
Assuming first formula in E2 copied down
=SUM(OFFSET(C$4,(ROWS(E$2:E2)-1)*3,0,12))
I prefer this because it explicitly contains all the required information
C4 = first cell to sum,
E2 = first cell with formula,
3 = row increment,
12 = number of cells to sum
The above gives you the sums on successive rows from E2 (or any other chosen cell) down. If you actually want the sum to be shown every 3 cells e.g. on the first row for each sum then that's simpler - try this formula in D4 copied down
=IF(MOD(ROWS(E$2:E2),3)=1,SUM(C4:C15),"")
.......or even easier.....just put this formula in D4
=SUM(C4:C15)
....leave D5 and D6 blank, then select the range D4:D6 and drag down
You can also use the non-volatile INDEX function
=SUM(INDEX(C:C,ROWS($1:1)*3+1):INDEX(C:C,ROWS($1:1)*3+12))
This works because INDEX returns a reference so you can use the normal Ref1:Ref2 notation for a range.
=SUM(INDIRECT("C"&ROW(1:1)*3+1&":C"&ROW(1:1)*3+12))
Be warned that INDIRECT() is a volatile formula... This means that any change made anywhere in the workbook this formula will recalculate and can cause performance issues.

Summing result of formula applied to rows

I have a column of numbers and would like to summarize the result of a formula applied to each row.
For example, if my formula is to square the cell value, in the following table I would like B1 to represent A1^2 + A2^2 + A3^2.
A B
- -
1 14
2
3
Is this possible without creating a column to store the result of the formula for each row before summing (i.e. here, a column containing 1, 4, 9)?
For your example:
=SUM((A1:A3)^2)
But here is the key: enter it as an array formula with Ctrl+Shift+Enter. It will add braces to it and should work.
It should look like this after pressing Ctrl+Shift+Enter:
{=SUM((A1:A3)^2)}
For summing squares of range values, please use this formula =SUMSQ(A2:A80).
So if you have data in Column A, put above formula in cell B2.

Reference every second cell in Excel formula

I currently have a formula like this:
=ROUND((('Sheet1'!D77-'Sheet1'!D75)/'Sheet1'!D75)*100,1)
with the next cell below that:
=ROUND((('Sheet1'!D79-'Sheet1'!D77)/'Sheet1'!D77)*100,1)
What I want is to drag the formula down and to reference every 2nd cell. So for e.g. it should go from referencing D79-D77 to D81-D79 (and not D80-D78) etc. How can I go about doing this?
Thanks
You can also do it with INDEX, multiplying the row that the formula is in relative to the first row by 2 and adding it to either 75 or 77:
=ROUND(((INDEX(Sheet1!D:D,77+(ROWS(A$1:A1)-1)*2)-INDEX(Sheet1!D:D,75+(ROWS(A$1:A1)-1)*2))/INDEX(Sheet1!D:D,75+(ROWS(A$1:A1)-1)*2))*100,1)
Oh, this is interesting.
Assuming you have your first cell at
B1
and the value you are looking into is in column C, starting at cell
C1
To do this, you need to have number at column A. Start with number 1, counting up. (you may include this in dragging)
So side by side, you have number column at A, while the absolute percentage at column B, and values at C (in alternating row).
I did the arithmetic progression, combined with the address and indirect functions to do the task.
where:
an = a1 + (n-1) * d
in B1, the code should look like this:
=(INDIRECT("C"&(3+(A1-1)*2))-INDIRECT("C"&(1+(A1-1)*2)))/INDIRECT("C"&(1+(A1-1)*2))
I guess this should do it.
Cheers..

Dynamically build array of values by indirect column reference

I'm building a yearly scorecard (sample shown above). The requirements for the scorecard are listed below.
Year to Date values must cumulatively add each of the previous period values (circled in orange).
P1 = P1
P2 = P1 + P2
P3 = P1 + P2 + P3 (etc)
Year to Date formulas must all be the exact same, dynamically referencing the required columns and required rows so that they can be easily copied from period to period (on going).
With this formula I was trying looking at row 2 with each of the column indicators in it, and trying to test for ISTEXT() to add up the values in the ROW()-1. Using concatenate to build a string that references a row range might not be the best way to do it.
Example: If I have values in row 55
=SUM(INDIRECT(CONCATENATE(ROW()-1, ":", ROW()-1)))
=SUM(INDEX(INDIRECT(CONCATENATE(ROW()-1, ":", ROW()-1)),MATCH(ISTEXT(2:2),2:2,0)))
I was trying something like a horizontal sumifs() formula with little luck, attempting to use the modulus value of the column() function as a logical test.
formula doesn't work
=SUMIFS(INDIRECT(ROW()-1&":"&ROW()-1), MOD(COLUMN()-2, 6), 0)
Or Using some other method of testing which columns to add.
=SUMIFS(INDIRECT(CONCATENATE(ROW()-1, ":", ROW()-1)), IF(ISTEXT(2:2), 1, 0), TRUE)
If I change my lettering in Row 2 (N, H, T) to just "X" then test for X that works, but this formula doesn't factor in the requirement for only adding values from current and prior periods.
=SUMIFS(INDIRECT(CONCATENATE(ROW()-1, ":", ROW()-1)),2:2, "X")
I don't know of a way to accomplish adding up a dynamic number of indirect cell references based on the column you're in. So lets say its row 55 in period 3, I would need a formula that looks in row 2, sees each of the column values (H, N, T) and adds up H55, N55, T55). That same formula would need to construct a different list based on if its in period 2. (H, N), (H55, N55).
Maybe I need to rethink my approach entirely? Write VBA instead?
Edit
To better expand on what the data model is, to address some comments, I've thrown some dummy values and dirty formulas in.
Have a look at service level vs. service level year to date (YTD). Service level is just a flat data entry of weekly performance, then the Summary column is a simple average of the weekly performance in order to report period performance. The YTD number is an average of the period numbers, so these values progressively roll up.
The formulas I'm trying to write are for the summary columns, both period value and YTD values.
It's not entirely clear what your data layout is.
So, assuming:
Labels that identify columns to sum are in row 2
Values to sum are in row 55
Formula is to sum values in row 55, which have a non-blank entry in row 2, and sum values in columns up to and including the column the formula is in
Formula
=SUMPRODUCT($55:$55,--(COLUMN($55:$55)<=COLUMN()),--($2:$2<>""))
For column T use:
=SUM(IF(MOD(COLUMN($H:T),6)=2,$H$1:T$1,0))
This is an array formula and must be confirmed with Ctrl+Shift+Enter.
change the $H$1:T$1 to the rownumber you need to sum (it will only sum every sixth column starting with H)
Having UPEH at Row 9 and this code in row 10 then =SUM(IF(MOD(COLUMN($H:T),6)=2,$H$9:T$9,0))
If set correct one time you can copy paste it as you need it (as long as it stays with just sum every 6th column starting at H)
for making it more dynamically you may better use:
=SUM(IF($A$4:T$4="Summary",$A$9:T$9,0))
This is an array formula and must be confirmed with Ctrl+Shift+Enter.
it checks for Row 4 to contain "Summary" to get the values to sum :)
EDIT
However, if you want to have exactly the same formula in each part you would need to use something like that:
=SUM(IF(AND($4:$4="Summary",COLUMN($4:$4)<=COLUMN(),OFFSET($1:$1,ROW()-2,),0))
This is an array formula and must be confirmed with Ctrl+Shift+Enter.
it sums all the cells 1 row over itself from the beginning till (including) the own column for all columns containing "Summary" in row 4
however, this may get pretty slot pretty fast (calcs a LOT) ^^
BIG HINT: Just looking at what you have/need
lets asume the cells to add are in row 1 and the output in row 2...
we also skip the columns not to calculate (to make it easy)...
A2 would be just A1
B2 would be A1 + B1
C2 would be A1 + B1 + C1... but wait!
A1 + B1 = B2 so better -> C2 = B2 + C1
leads to:
R2Cx = R2C(x-1) + R1Cx
if you just use that behavior in column N (that it is the value over it and the calculated value to the left (column H)) and also write it that way, you could just copy it and paste it in column T and you will get =T(above) + N(calculated). check it :)

Resources