I have a long row of data that I am averaging week-by-week. I would like to grab the first 7 cells with data and be able to drag my formula over so that it grabs the next 7 days of data. Every time that I try this it always grabs the adjacent cell and averages numbers that I have already averaged in the previous formula:
So what happens is that when I drag to the right it grabs D60:K60 and I want it to grab L60:R60 instead.
How would I accomplish this?
This formula uses OFFSET to both stagger and shape the range which is calculated by AVERAGE.
=AVERAGE(OFFSET($C60, 0, (COLUMN(A:A)-1)*7, 1, 7))
Fill right as necessary. It will process AVERAGE(C60:I60) then AVERAGE(J60:P60), etc.
EDIT:
As OFFSET is a volatile function that re-calculates whenever any calculation cycle occurs within the workbook, here is a non-volatile equivalent.
=AVERAGE(INDEX(6:6, 1, (COLUMN(A:A)-1)*7+3):INDEX(6:6, 1, (COLUMN(A:A)-1)*7+9))
Related
This is the formula :
=IF(A674=1,CONCATENATE(Sheet1!A7,"(",Sheet1!B7,")"),0)
where, when I am pasting this formula on every n+7 row, the value is incrementing by 7(obviously). I need to paste this formula but increment by only one on every n+7 row.
PS: This task if from company where i am involved in making the test case for my development, but there are around 1200 objects :(.
To get incrementation of one for every 7 rows, divide row number by 7 and round up. For example:
=ROUNDUP(ROW(A1)/7, 0)
The above formula will return 1 for range A1:A7, 2 for range A8:A14, etc. - use it within your formula to get the desired incrementation.
I have a list of values that looks like this. Every 30min the top row in my data is shifted down and a new latest value is inserted. I'd like to be able to take the average of all the values in the model column from 18:30 to the top most cell each day (so just the latest cell that has an 18:30 value to the top most cell)
Any help would be greatly appreciated
I've been able to find the row that contains the date I need using this:
=MATCH(DATE(YEAR(TODAY()),MONTH(TODAY()),DAY(TODAY()-1))+TIME(18,30,0),AF47:AF4595,0)
So now I just need to able to average from row 1 to the output of that formula. I've tried Index(NamedRange,1:3,0) but that didn't work
=INDEX(AF:AF,1):INDEX(AF:AF,MATCH(DATE(YEAR(TODAY()),MONTH(TODAY()),DAY(TODAY()-1))+TIME(18,30,0),AF47:AF4595,0))
Although I would change your formula just to shorten it...your formula is more readable. I would change your formula to:
MATCH(INT(TODAY())-1+TIME(18,30,0),AF:AF,0)
I was assuming your data was all in AF based on your formula. Adjust AF to match the column of your needs.
Since INDEX returns a cell address, you just need to wrap the range defined by the two indexes in an AVERAGE function:
=AVERAGE(INDEX(AF:AF,1):INDEX(AF:AF,MATCH(DATE(YEAR(TODAY()),MONTH(TODAY()),DAY(TODAY()-1))+TIME(18,30,0),AF47:AF4595,0)))
This is pretty ugly and a roundabout way of doing it, but you can first identify the last row you care about using sumproduct() and some sneakiness. And then pump that into your =Average() formula using Indirect:
=AVERAGE(INDIRECT("B1:B" & SUMPRODUCT((HOUR(A:A)=18)*(MINUTE(A:A)=30)*ROW(A:A))))
It's going to be SLOW though hitting up all of A:A so maybe narrow that range down like A1:A1000 or whatever row is likely to be the max possible row to hold that 18:30 time.
Here is another way using AVERAGEIF:
=IF(NOW()-TODAY()<5.5/24,AVERAGEIF(A:A,">" & (TODAY()-5.5/24),B:B),AVERAGEIF(A:A,">" & (TODAY()+18.5/24),B:B))
It first checks if the current time is before 18:30 then calculates the average as described (from the last 18:30 to now)
An AVERAGEIF/AVERAGEIFS can solve your problem but I see at least three problematic areas.
The 18:30:00 time you want to stop at may or may not be in the same day as the day in the top of the Prediction Area column. This means that you cannot construct a limiting date time from the day at the top of column AF and add TIME(18, 30, 0). You might need to subtract a day if the top of column AF is after midnight and before 18:30:00. A TRUE is considered 1 in a worksheet formula and FALSE is considered zero so taking the date at the top of column AF and subtracting
'Is the time of the datetime in AF47 less than 18:30:00?
(MOD(AF47, 1)<TIME(18, 30, 0))
will make the deciding date today or yesterday depending on the time in AF47.
Your program is inserting Prediction Area datetimes and Model numbers at the top of the list. Depending on the method, this can disrupt conventional formula range addressing, even when using absolute row references. While INDIRECT can be used to 'lock' a cell address by converting from a text string, INDEX is a more efficient method.
'cell address with 'absolute' row (will change with inserted rows)
AF$47
'INDIRECT method (will not change with inserted rows)
INDIRECT("AF47")
'better INDEX method (will not change with inserted rows)
INDEX(AF:AF, 47)
'range of datetimes in column AF
INDEX(AF:AF, 47):INDEX(AF:AF, 95)
Time values typically resolve to pseudo-irrational numbers (aka *repeating decimals') that cannot be relied upon in Excel's 15 significant digit floating point mathematics. For this reason you should use the 00:30:00 interval to ensure true comparity by avoiding >= and <= in favor of > and < against a time value offset by a second. IOW, 18:30:00 is not equal to either 18:29:59.999 or 18:30:00.001.
So if your datetimes (e.g. 04/25/2019 15:00) start in AF47 and are incremented every thirty minutes then the furthest cell you need to examine is AF95 (47 + 24*2).
With Prediction Area in AF46 and and Model in AG46 this is my effort.
' |<----------AG47:AG95---------->| |<----------AF47:AF95---------->| |<----AF47---->| |<----AF47---->|
=AVERAGEIFS(INDEX(AG:AG, 47):INDEX(AG:AG, 95), INDEX(AF:AF, 47):INDEX(AF:AF, 95), ">"&INT(INDEX(AF:AF, 47))+TIME(18, 29, 59)-(MOD(INDEX(AF:AF, 47), 1)<TIME(18, 30, 1)))
Truth be told, the AVERAGEIFS function does suffer significantly by using full column references so if there are no rogue values that could produce false positives above or below the ranges referenced, full column references could be used for the average_range and criteria1_range cell range references. Full column references would not be affected by row/data insertion.
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.
I have a worksheet called Start at the beginning and a worksheet called End at the end of the sheets.
On my sheet in the middle, I want a cell to add up all of the I7 values from Start to End and if it is greater than 0 to display 0. If not, I want it to display the sum of all of the I7 values.
When I use this formula:
=IF(Start!I7:End!I7>0, 0, Start!I7:End!I7)
I get the error #value!
This formula works if I do =IF(Start!I7-End!I7>0, 0, Start!I7-End!I7) with the subtraction.
=IF(Start!I7+End!I7>0, 0, Start!I7+End!I7)
or are you asking to sum all pages between and including Start and End? You're subtraction equation only references those two pages...
You can use the sum function, but the syntax for summing the same cell across multiple sheets is a little different than what you have.
=IF(SUM(Start:End!I7) > 0, 0, SUM(Start:End!I7))
Refer to the sheet range, then the cell.
After your other question, I think the way to subtract all the subsequent I7 cells from the first one would be to just sum everything after it the same way we're doing here and subtract that from the initial value.
=IF(Start!I7 - SUM(Sheet2:End!I7) > 0, 0, Start!I7 - SUM(Sheet2:End!I7))
(I used Sheet2 as a placeholder. You would use the name of whatever sheet comes after Start.)
I think that it could be written more simply, though, using MIN.
=MIN(Start!I7 - SUM(Sheet2:End!I7), 0)
I have old Excel table that I need to manually fill and I made new Excel table where I used CTRL+T to fill in data automatically when typing formula in first row under the header/title cell.
My data is vertical in old:
Numbers Average (for last 10 Numbers from Left Row)
5,780.00
5,730.00
6,600.00
7,300.00
6,120.00
5,250.00
5,210.00
5,100.00
5,770.00
6,370.00 5923.00
6,000.00 5945.00
5,480.00 5920.00
5,120.00 5772.00
4,990.00 5541.00
This is how it should look, this is how I made it manually.
Formula is:
=IF(L11<>"",AVERAGE(L2:L11),"")
Where forumula is in M row (Average) and checking and calculating for L row (Numbers).
But for Table to auto-fill till last row, formula has to be made in first row, then Excel auto-fills.
Average:
5923.00
is from this numbers:
Numbers
5,780.00
5,730.00
6,600.00
7,300.00
6,120.00
5,250.00
5,210.00
5,100.00
5,770.00
6,370.00
How can Average formula for 10 vertical numbers from L row be inserted into any cell above 5923.00 in Average - M Row.
I do know how to fill row, I could copy formula, press CTRL + SHIFT + DOWN to find end of my table and paste formula, but when new data comes (imported CSV that updates), new data would not be filled, I need Excel to auto-fill it.
Here is answer for all if needed, if you have by dates, old data up and new down, then average of first 10 items, can't be calculated in first 10 rows without issues where you have Average.
Here is solution for one way direction:
=IF(AND((ROW())>=11,L2<>""),AVERAGE(OFFSET(M2,-9,-1,10)),"")
What Offset does, is goes up +9 places from current cell M2, then it goes 1 cell left, and from there takes 10 down to mark the range.
IF if statement is wrong it doesn't go left and up, thus no error, after and including ROW 10 it's true statement.
And this is more complicated to use with Table in Excel, when you have sorting by date, when newest date is on top, bottom is data that you can use for average:
=IF($A$2>$A$3,AVERAGE(OFFSET(M2,0,-1,10)),IF(AND((ROW())>=11,L2<>""),AVERAGE(OFFSET(M2,-9,-1,10)),""))
I have first IF (A2>A3) that checks how is table sorted:
- if sorted newest - oldest (1st case) then it takes average from first row on the left, and down 10 places
- if sorted opposite, it goes as said: left one place, and up 9, then takes 10 range.
Works like a charm, bit long, but it works!
You could add a test for which row the formula is in and only return a result if it's 11 or higher. Then you could enter it in the entire column table and it would fill automatically:
=IF(AND(ROW()>=11,L11<>""),AVERAGE(L2:L11),"")
ROW() returns the number of the row the fomula is in.
EDIT: Ok, here's a better one. Put this in M2 and copy down:
=IF(AND(ROW()>=11,L2<>""),AVERAGE(OFFSET($L$1,ROW()-10,0):OFFSET($L$1,ROW()-1,0)),"")