Calculating a running sum with reset in Excel - excel

I have a need to calculate a running sum of column D's count data in column E. However, I only want to calculate the running sum for the appropriate categories in columns B and C. In other words, there are four combinations of categories and I need a running sum for each. The easiest way is to do what I currently have in column F (cell F3=SUM($D$2:D3)) and drag it down through F11 and manually restart it at F12. I can't do this in my full dataset though because there are about 20k rows of data. So, I'm trying to make column E dynamically calculate what's in column F. I started with =SUMIFS() and can return the final sum for each combination of the two categories, but it's not a running sum, created dynamically, that resets with the new day count in column A.
Any suggestions would be appreciated. TIA

Initial Response
If I understand the problem correctly, the solution is actually very simple.
This formula goes to E2 (and then copy down):
=IF(B1&C1<>B2&C2,D2,SUM(E1,D2))
In each case (including the first) of a change of either Cat A or Cat B, it takes the count value at that row (i.e. the new starting balance). Thereafter, it does a running balance addition (balance from row above + count at this row), until the next change of Cat A or Cat B is encountered.
Catering for a wider range of Categories:
The above assumes: Cat A and Cat B are only ever 0 or 1 (per the example in OP).
If this isn't true (and the Cats could be any range of values), change the formula per chris neilsen's suggestion (per comments):
=IF(OR(B1<>B2,&C1<>&C2),D2,SUM(E1,D2))
Catering for Previous Same-State Categories:
Both the original formula and the alternate above assume:
Should Cat A & Cat B states change, but subsequently return a 'previous same-state', the running total should still start afresh (i.e. don't 'carry forward' from 'previous same-states').
If one wanted the running balance to include the balance of previous same-states for Cat A & Cat B, use solution suggested by Apostolos55 (below)
=SUMIFS($D$1:D2,$B$1:B2,B2,$C$1:C2,C2)

all you need is a minor adjustment to the cumulative count:
=Sumifs($D$2:D2,$B$2:B2,B2,$C$2:C2,C2)
Put in Current Count and it is done. Drag/drop OR Autocomplete down as needed
Now it takes into account only above/previous than the current...

It's a bit hacky, but you can add a few columns:
consecutive numbers from 2 to end of your data (say this is in Column G).
references to every 10th cell (e.g. G2, G12) for every cell in that cluster. (say this is in Column H)
you can fill in the first few rows for these two columns and then drag it down.
a reference to the count column ('D') in a single cell (say I1).
You can then use CONCATENATE and INDIRECT inside SUM:
Cumulative Count:
SUM(INDIRECT(CONCATENATE($I$2,H2)):D2)
and drag this down.

Related

Copy and paste from horizontal to vertial

I am wondering if there is a way to do what I want more automatically, i've been doing it with good old regular copy paste but it's taking a lot of time, I need to take the horizontal data I have currently and put it vertically while keeping the first column for each rows, the first column is my "main" part number and I need to link all the other numbers starting from column B to this main part number, example below,
I sometimes have hundreds of rows and columns to do this for, here is what i'm working with
[1]: https://i.stack.imgur.com/dIyZv.png
And here's what the end result needs to look like;
[2]: https://i.stack.imgur.com/PvxGh.png
Thank you in advance!
It can be achieved either with VBA Code or with formulas. I did it with formulas and will try to show you how below.
I have one sheet with all the data, lets call it Sheet1. It looks like this:
Then, I have another sheet which returns what you want (Sheet2). It looks as follows:
Note that the first two columns are necesary for the formulas to work. The actual result is on Columns C and D.
Now, below are the formulas (or values) you would need to put in Sheet2 to make it work:
Cell A1: 0
Cell B1: 1
Cell A2: IF(B2=1,A1+1,A1)
Cell B2: IF(B1+1=$G$1,1,B1+1)
Cell C1: OFFSET(Sheet1!$A$1,A1,0)
Cell D1: OFFSET(Sheet1!$A$1,A1,B1)
Cell G1: The number of columns in the data on Sheet1
Then, just drag the formulas (not the values in A1, B1), until you have the expected result.
I would suggest you try to implement this simple example first, and then move it to your actual spreadsheet.
Let me know how it goes.
EDIT: Regarding your comment, we could do a trick to make it work for a variable number of columns.
First, lets add some variability to the number of columns in Sheet1. This is how my new Sheet1 looks like:
On Sheet2 I added a formula to count the number of columns per row. See Column F below:
Then, the trick is to change the formulas in Column B in Sheet2:
Before: Cell B2: IF(B1+1=$G$1,1,B1+1)
After: Cell B2: IF(B1+1=OFFSET($F$4,A1,0),1,B1+1)
Note: My formula to count the number of columns per row is:
Cell F4: COUNTA(Sheet1!A1:D1)
Note: Change D1 to the max column in Sheet1. Eg. M1.
Note2: You can get rid of cell G1 now.
Start with column B and everything else becomes a doddle. I only use 1 formula for column B and no more than 1 or 2 for column A (there are 3-4+ methods, no need to duplicate yourself but choose any of them to construct A).
I'm only using 1 formula to make each column. Entire job task done in a minute-5.
Column B. Do this first for all your "column B's":'
=IF(ROW(A1)=1,INDEX(A$1:T$1,INT(((ROW()-20)/20+1-ROW($A$1))/COLUMNS(A$1:T$1))+1,MOD(ROW()-20-ROW($A$1),COLUMNS(A$1:T$1))+1),INDEX(A$1:T$1,INT(((ROW()-20)/20+1-ROW($A$1))/COLUMNS(A$1:T$1))+1,MOD(ROW()-20-ROW($A$1),COLUMNS(A$1:T$1))+1))
So all you have to do is drag down. Change only the row references to refer to your 100's if different rows you need to do this for. 1 minute. Job done
for 30 columns/cells change T to AD, for 200 cells , change T to GR, etc. You can also force it to stop at number of your choice.
If you put it anywhere else, it will still work, but your going to have to jiggy with the math a bit to get it to start from the the first entry in the row ( or the specific Wherever you want). Its up to you.
It acts like a modular clock. Been using it for a few years. Ticker tape. Rolling slabs of concrete laying out for you.
here, this is what I get when I plug it into the first row of any column , referring to a 20 field length header on my sheet.
Etc... It continues forever (or for however long you want it). (and you can change the mod anytime).
The first argument you could change to whatever your requirements are , for instance , if(LEN(F8)<1, or whatever, to Start/"Set the clock."
And For any corresponding ranges (your first column for each) (** Your "Column A's" **):
=IF(LEN(H20)<1,K21,H20)
or you can use this logic. It Becomes elementary.
=IF(J21=K21,J21,J20)
Better if you use this starting from row 2 on each column A: if(and(j1=it's next door neighbour, row(it's next door neighbour cell=1)), it's self j1,.. blah blah blah blah
OR AM I MISSING THE POINT ?
Method for getting column A;
Since you already have B, A becomes a simple trivial matter. Like cell =$fixed$cell , i.e. A1=$B$1 and drag down.
simple. headache over. game over. Its all effortless.
But if you want me to elaborate more ,
method 2 for getting 1st column, column A's;
=IF(LEN(AV1)>1,IF(ROW(AV1)=1,AV1,INDIRECT("Av"&1)),"")
=IF(ROW(B1)=1,B1,INDIRECT("B"&1)) <---- drag down from row 1
Method 1 for getting 1st column;
=IF(LEN(AV1)>1,$AV$1,"") <----- drag down from row 1
Method 3, below was my favourite:
=$B$1 <---- from row1 drag down (where row1 was just = column B, cell b1, a1=b1) easy peasy .
You could always demand a further simplification of M3:
A1=if(len(b1)>1,$b$1,"") <--drag down from b2 (where b1 was already set) *probably best because only returns a value as long as column B is .otherwise returns blank.
It's like handling duplicates by formula. Similar .
there was a method 4 too. bUt its late. (Written # 02:00)
Or did I miss the point? It's easy. Imo
Im only using 2 formulas. 1 for each column you need done . do column B first, and colimn A becomes a matter of fact . A doddle.
method 1 is my new favourite.
Its late, my naighbours have pissed me off again. Pardon my fonts and writing but seriously. didnt expect this. some people need to go to jail.(my naighbours)
So in the end: 1 formula for B. 1 for A (any one of any the 4+ methods. There are more also) , plug in and scroll for all the rows you need this done for . takes you 30 seconds? 5 minutes tops for all your rows.

Climate: Calculate Consecutive Days of Rain

I have a data column rainfall, and a column is on that date;
I intend to extract Consecutive Days of Rain from it in a separate column.
With the formula below, I extracted Consecutive :
columnF=IF(B2>0,SUM(F1)+1,0)
But the result is in a column and I can not separate them like in attached picture (see desired result).
If we want to extract the continuity of rainfall in a separate column
How to do?
My result:
Desired result:
Following from Ted D's comment... a possible formula for the second helper column would be (in cell G2):
=IF(F2=0,0,MATCH(0,F3:F999,0)-1+F2)
This looks for the first 0 in the counter column (F) beneath our row (looking around 1000 rows down - that 999 can be changed as appropriate). We use that plus our current counter to give us the size of the block.
From there, we can make the columns with the dx1day etc. titles and populate them with the formula:
=IF($G2=VALUE(SUBSTITUTE(MID(H$1,3,999),"day","")),$F2,"")
This is parsing the number from dx1day at the top of the column (in this case H) (if you did it with just numbers and a custom format you could save that bit*). We then check if the current "block size" value (in column G) is the same as that in the header. If it is we copy the counter value (from column F), otherwise blank.
You can get away from this second helper column by replacing the $G2 with (IF($F2=0,0,MATCH(0,$F3:$F999,0)-1+$F2)) - but if makes it a bit more of a headache to understand (and debug :-)
*the way for this is to do custom format with the "Type" being "dx"0"day"... then the formula becomes =IF($G2=H$1,$F2,"") or =IF((IF($F2=0,0,MATCH(0,$F3:$F999,0)-1+$F2))=H$1,$F2,"") for the no-second-helper-column version

Google Spreadsheet, SUM or MINUS of above cell in the column using ARRAYFORMULA in the first row

I'm learning to use array formulas and have been successful doing simple things like adding 2 columns together in a third column. For example, I can put =arrayformula(B:B+C:C) in D1 and it adds B and C for each row.
But now I have a situation where I want to subtract two numbers in the same column. I want to take the value of that column in the current row and subtract the previous row's value from it. Without array formulas this is simple: in O7 I put =N7-N6 and cop that down so O8 gets =N8-N7, etc. But that requires copying down every time - can I do the same thing with an array formula?
Basically, can I do something like =arrayformula(B:B+(B-1):(B-1)) ?
Context: column N is a monthly account balance. I would like to calculate how much that balanced changed each month. So for row 7, =N7-N6 gives me that difference. But I'm changing the entire spreadsheet to array formulas so I can stop pasting all of the formulas and I'm stuck on this one since it's comparing the same column.
I'm trying to get everything into Row 1 so my values and calculations can start in Row 2. For example, here's one of my formulas in Row 1:
arrayformula(if(row(A:A)=1,"Total gross income",if(LEN(B:B),B:B+C:C,"")))
Unfortunately, in Column O (the one I asked about originally) if I do this:
=arrayformula(if(row(A:A)=1,"Amount saved this month",if(row(A:A)>1,if(LEN(N:N),N2:N-N:N,""))))
Or this:
=arrayformula(if(row(A:A)=1,"Amount saved this month",if(row(A:A)>1,if(LEN(N:N),offset(N:N,1,0)-N:N,""))))
Every row is off by 1 - the result that should go in Row 3 goes in Row 2, etc. And if I do this:
=arrayformula(if(row(A:A)=1,"Amount saved this month",if(row(A:A)>1,if(LEN(N:N),N:N-offset(N:N,-1,0),""))))
Then it gives me an error because the offset function is trying to evaluate something out of range (possibly it starts with N1 and tries to grab a value 1 row above N1?)
Any advice on how to handle that out-of-range error?
I think the error is because of offset range N:N which starts from N1 and you are trying to shift it -1 or one cell up, which brings the formula out of sheet.
Try this formula instead:
=arrayformula(
{"Amount saved this month";
if(LEN(N2:N),N2:N-offset(N2:N,-1,0),"")})
It uses {} to make an array. See more info:
https://support.google.com/docs/answer/6208276?hl=en
Bonus. There is no reason to check row number now.

Excel formula to lookup the last value in a column and return the value of the adjacent cell

I have the following formula to return the value of the last value in a column:
=LOOKUP(2,1/(D:D<>""),D:D)
What I need now is to return the value of the cell adjacent to it as well. (It will not necessarily be the last value in that column and the info in Column D could have duplicates.
If your data looks like this:
A 1
A 2
A 3
B 4
B 5
B 6
C 7
To get last value this will do the trick:
=INDIRECT("B"&COUNTA(A:A))
And to get last where value is A:
=INDIRECT("B"&MATCH("A",A1:A7,0)+COUNTIF(A1:A7,"A")-1)
Just use next column:
=LOOKUP(2,1/(D:D<>""),E:E)
Ok, So I have found an answer by playing around with array formulas.
The problem was that this is a stock control sheet where there are changes made at multiple times, each recorded in the next available row. There is always a date (Column E) but not necessarily a Supplier, as it might be stock moving out. When a Supplier delivers, the Supplier name is recorded in Column D. In D1 the last supplier is then shown with the following formula.
=LOOKUP(2,1/(D:D<>""),D:D)
I want to then see what date it was last received. The formula I found that works is as follows (Array Formula):
=INDEX(E:E,MAX(IF(D:D=D1,ROW(D:D)-ROW(INDEX(D:D,1,1))+1)))
This is generally how I do it:
=XMATCH(FALSE,ISBLANK(A:A),0,-1)
This is what each part does:
Parameter
Explanation
FALSE
Instructs Excel to find the first instance of FALSE that it finds
ISBLANK(A:A)
Takes in the column A:A and notionally assigns a value to every item in the column
0
Means we want an exact match. Probably not necessary to put in, but I think it's good practice anyway
-1
Instructs Excel to start the search at the bottom/right of the range and work up/left. If you change this to 1 (the default), Excel will begin the search at the top/left and work down/right
So, taken together, this will search from the bottom of the column A:A, until Excel finds the first cell that is not blank, and return that cell.
Also, yes, this equation can be changed to a row format (e.g. 1:1), and can take a smaller range (e.g. A1:A20), but it cannot take a 2-dimensional range (e.g. A1:B20).
As a practical matter, this approach is much faster than other approaches (and much faster than you'd think, given it's evaluating against every row/column in the range), and won't get fooled by columns that have empty spaces in them (like with a COUNTA style approach).

Count If match multiple fields: First field by initials, second field if date has been filled

I'm trying to create a simple tracker. In columns B and C, tasks are tagged with an author, and then the author fills in a completion date.
Above is a dashboard that counts items for easy viewing. I countif for the total, but have not been able write a formula for the complete column. I've tried countifs, but haven't been able to get the formula to work.
Thoughts?
Try below formula as per attached
OUTPUT
Using DSUM will probably send you in the right direction.
http://office.microsoft.com/en-gb/excel-help/dsum-HP005209069.aspx
From what I see in your image, you should do a Pivot table for your dashboard.
If you absoluteley have to (???) get along without a Pivot table, do the following:
start the dashboard in column B, so that column A just contains column header "Tasks" and data (no blank rows allowed!)
count the number of tasks as =COUNTA(A:A)-1 (-1 for the header)
count all other columns as =COUNTA(OFFSET(B5;0;0;$E$2;1)) (in this example you count column B, header is in B4, first data therefore in in B5, number in tasks from above formula in $E$2)
The Offset function basically gives back a range starting relative to a reference and being of chooseable size. So we start it at the first data cell and make it 1 column wide, and #oftasks rows deep
With COUNTIFS, assuming VH is in A8, Tasks/Author/Completed are in Row12 and you have or might have data up to Row1000:
=COUNTIFS(B$12:B$1000,A8,C$12:C$1000,">1")
copied down as required.
You can use SUMPRODUCT to find the amount completed per author.
=SUMPRODUCT(--($B$8:$B$16=A3),--($C$8:$C$16>1))
In this case, the "--" tells SUMPRODUCT to treat each cell in the array (I used the example by User2063626) individually so it starts at the beginning and checks if B8=VH and records the answer as a boolean (1 for TRUE or 0 for FALSE), in this case it does equal VH so it uses a 1. Then it checks to see if C8>1 (it will be if there is a date) and stores a 1. It then multiplies the two values together 1*1=1 to give you a value for the first row. It then moves on and does the check for B9 (gets a 1 because it is equal to VH) and C9 (gets a 0 because there is no date), multiplies the row result 1*0=0 and adds it to the previous result. It repeats for each row in the array and returns the count of rows where the author was VH AND there is a completed date (2).

Resources