Running SUM with ARRAYFORMULA - google-sheets

I have a list of values per day and I want, for each day, to sum the last 7 days using an array formula.
Basically, I want to use this formula
=SUM(A1:A7) inside an ARRAYFORMULA but I can't get it to work.
Theoretically it should look something like
ARRAYFORMULA(SUM(B1:B:B7:B)) which of course doesn't work.
Note: the formula must be at the top row, since new data is added daily so row 2 of today will become row 3 tomorrow. The solution therefor must fit the top cell of the column.
I created a sheet with an example. Col A is dates, Col B is values Col C is the manual sum of the 7 days just as a reference
https://docs.google.com/spreadsheets/d/1jsC5mN2Bdq5a1u2GjoufTTPmSjyurOPd1YXQEv_AGfk/edit#gid=0

I have entered the following in cell D2:
=flatten(
index(
query(
if(
(sequence(counta(B2:B))<sequence(1,counta(B2:B))+7)*
(sequence(counta(B2:B))>=sequence(1,counta(B2:B))),
B2:B,
),
"select sum(Col"&join("), sum(Col",sequence(counta(B2:B)))&")"),
2))

You can also use this old-school method:
=ArrayFormula(if(isnumber(B:B),sumif(row(B:B),"<"&row(B:B)+7,B:B)-sumif(row(B:B),"<"&row(B:B),B:B),))
Or better this to include a header:
=ArrayFormula(if(B:B="",,if(isnumber(B:B),sumif(row(B:B),"<"&row(B:B)+7,B:B)-sumif(row(B:B),"<"&row(B:B),B:B),"Running Total")))

Related

ARRAYFORMULA is only populating the first row

I have financial data that I am trying to summarize in a format that can be used by a line chart.
The example spreadsheet is here.
In my source data on the left, I have an entry per Date, Symbol, Account. I need to transform this data so there is a row per Date and a column for each Symbol. I will SUM Total Value regardless of account.
I found a way to pull a unique Date (see H2), and then transpose unique Symbols into columns (see I1).
I also found a way to use SUMIFS to get the aggregation I want (take a look at cell I2), but I can't figure out how to use ARRAYFORMULA to apply this value to all rows in column I.
I know I can drag my formula from I2 down to I3,I4,I.. etc, but this sheet is part of a larger project so I'd like it to auto-populate as dates are added to H.
From what I've read ARRAYFORMULA should apply the formula to multiple rows. What am I missing?
Thanks
use:
=QUERY(A1:F, "select A,sum(F) where A is not null group by A pivot B", 1)
Use formulas like this
=ARRAYFORMULA(IF(H2:H="",,SUMIFS($F$2:$F, $A$2:$A, $H2, $B$2:$B, I$1)))
Add IF(H2:H="",,
Explanation
if the range is empty "" do nothing ,, else Your formula
Your Example
Cells
Formulas
I2
=ARRAYFORMULA(IF(H2:H="",,SUMIFS($F$2:$F, $A$2:$A, $H2:H, $B$2:$B, I$1)))
J2
=ARRAYFORMULA(IF(H2:H="",,SUMIFS($F$2:$F, $A$2:$A, $H2:H, $B$2:$B, J$1)))
K2
=ARRAYFORMULA(IF(H2:H="",,SUMIFS($F$2:$F, $A$2:$A, $H2:H, $B$2:$B, K$1)))

How to pull data from every third column using QUERY function

I am using this formula but the same formula needs to be applied to every third column. ie: starting from D3:D, G3:G, J3:J, and so on... what is the best way to apply or pull the data from every third column. (data is on the second sheet called Sitemap)
Please advise and help, many many thanks much appreciated!
=query({
'Sitemaps'!D3:D1000},
"Select * where Col1 is not null ")
Adding the sheet link maybe that will be more helpful to understand the situation, "AllURLs" needs to pull all links from Sitemaps into one list
https://docs.google.com/spreadsheets/d/1AWGfA7cHmF3Q2kiX1xkQcoec6H5EPiHUXaiWENMzZkA/edit?usp=sharing
use:
=QUERY({INDIRECT("Sitemaps!"&
ADDRESS(3, (COLUMN($D1)-1)*COLUMN(A1)+1)&":"&
ADDRESS(1000, (COLUMN($D1)-1)*COLUMN(A1)+1))},
"where Col1 is not null")
and drag to the right
update:
use in B3:
=INDEX(IFERROR(REGEXEXTRACT(C3:C,"^(?:https?:\/\/)?(?:www\.)?([^\/]+)")))
use in C3:
=QUERY(FLATTEN(FILTER(IFERROR(Sitemaps!D3:1000), MOD(COLUMN(Sitemaps!D1:1)-1, 3)=0)),
"where Col1 is not null")
Try this:
=FILTER(FILTER(Sitemaps!D3:J,MOD(COLUMN(Sitemaps!D3:J)-4,3)=0),Sitemaps!D3:D<>"")
Just replace :J with whichever column is further to the right in your data set.
This one formula should produce all results, assuming that any rows that have data in Column D also have data in that row of every other included column, and that rows that are null in Column D are also null in that row of every other included column.
MOD is the modulus function. It returns whatever is left after dividing a number by another number. For instance, MOD(7,3) would return 1, because 7 divided by 3 is 6 with 1 left over. The leftover portion is the modulus.
We can apply this to your column numbers, since the ones you want to retrieve are evenly spaced three apart. We just need to start at a baseline of zero. Since Column D has a column number of 4, we can "zero out" that baseline by subtracting 4 from every column number. Only those columns that then are evenly divisible by 3 (i.e., those that, after subtracting 4, have a modulus of 0) are returned.

Why my ArrayFormula is giving error? How do I correct it? (I'm not looking for another Arrayformula as solutions!)

I wanted a ArrayFormula at C1 which gives the required result as shown.
Entry sheet:
(Column C is my required column)
Date Entered is the date when the Name is Assigned a group i.e. a, b, c, d, e, f
Criteria:
The value of count is purely on basis of Date Entered (if john is assigned a on lowest date(10-Jun) then count value is 1, if rose is assigned a on 2nd lowest date(17-Jun) then count value is 2).
The value of count does not change even when the data is sorted in any manner because Date Entered column values is always permanent & does not change.
New entry date could be any date not necessarily highest date (If a new entry with name Rydu is assigned a on 9-Jun then the it's count value will become 1, then john's (10-Jun) will become 2 and so on)
Example:
After I sort the data in any random order say like this:
Random ordered sheet:
(Count value remains permanent)
And when I do New entries in between (Row 4th & 14th) and after last row (Row 17th):
Random Ordered sheet:
(Doesn't matter where I do)
I already got a ArrayFormula which gives the required result:
={"AF Formula1"; ArrayFormula(IF(B2:B="", "", COUNTIFS(B$2:B, "="&B2:B, D$2:D, <"&D2:D)+1))}
I'm not looking for another Arrayformula as solutions. What I want is to know what is wrong in my ArrayFormula? and how do I correct it?
I tried to figure my own ArrayFormula but it's not working:
I got Formula for each cell:
=RANK($D2,FILTER($D$2:$D, $B$2:$B=$B2),1)
I figured out Filter doesn't work with ArrayFormula so I had to take a different approach.
I took help from my previous question answer (Arrayformula at H3) which was similar since in both cases each cell FILTER formula returns more than 1 value. (It was actually answered by player0)
Using the same technique I came up with this Formula which works absolutely fine :
=RANK($D2, ARRAYFORMULA(TRANSPOSE(SPLIT(VLOOKUP($B2, SUBSTITUTE(TRIM(SPLIT(FLATTEN(QUERY(QUERY({$B:$B&"×", $D:$D}, "SELECT MAX(Col2) WHERE Col2 IS NOT NULL GROUP BY Col2 PIVOT Col1", 1),, 9^9)), "×")), " ", ","), 2, 0), ","))), 1)
Now when I tried converting it to ArrayFormula:
($D2 to $D2:$D & $B2 to $B2:$B)
=ARRAYFORMULA(RANK($D2:$D,TRANSPOSE(SPLIT(VLOOKUP($B2:$B, SUBSTITUTE(TRIM(SPLIT(FLATTEN(QUERY(QUERY({$B:$B&"×", $D:$D}, "SELECT MAX(Col2) WHERE Col2 IS NOT NULL GROUP BY Col2 PIVOT Col1", 1),, 9^9)), "×")), " ", ","), 2, 0), ",")), 1))
It gives me an error "Did not find value '' in VLOOKUP evaluation", I figured out that the problem is only in VLOOKUP when I change $B2 to $B2:$B.
I'm sure VLOOKUP works with ArrayFormula, I fail to understand where my formula is going wrong! Please help me correct my ArrayFormula.
Here is the editable sheet link
if I understand correctly, you are trying to "rank" B column based on D column dates in such way that dates are in theoretical ascending order so if you randomize your dataset, the "rank" of each entry would stay same and not change based on the randomness you introduce.
therefore the correct formula would be:
={"fx"; INDEX(IFNA(VLOOKUP(B2:B&D2:D,
{INDEX(SORT({B2:B&D2:D, D2:D}, 2, 1),,1),
IFERROR(1/(1/COUNTIFS(
INDEX(SORT(B2:D, 3, 1),,1),
INDEX(SORT(B2:D, 3, 1),,1), ROW(B2:B), "<="&ROW(B2:B))))}, 2, 0)))}
{"fx"; ...} array of 2 tables (header & actual table) under each other eg. ;
outer shorter INDEX or longer ARRAYFORMULA (doesnt matter which one) is needed coz we are processing an array
IFNA for removing possible #N/A errors from VLOOKUP function when VLOOKUP fails to find a match
we VLOOKUP joint B and D column B2:B&D2:D in our virtual table {} and returning second 2 column if there is an exact match 0
our virtual table {INDEX(SORT({B2:B&D2:D, D2:D}, 2, 1),,1), ...} we VLOOKUP from is constructed with 2 columns next to each other eg. ,
we are getting the first column by creating an array of 2 columns {B2:B&D2:D, D2:D} next to each other where we SORT this array by date/2nd column 2, in ascending order 1 but all we need after sorting is the 1st column so we use INDEX where we bring all rows ,, and the first column 1
now lets take a look on how we getting the 2nd column of our virtual table by using COUNTIFS which will mimic the "rank"
IFERROR(1/(1/ is used to remove all zero values from the output (all empty rows would have 0 in it as the "rank")
under COUNTIFS we put 2 pairs of arguments: "if column is qual to column" and "if row is larger or equal to next row increment it by 1" ROW(B2:B), "<="&ROW(B2:B))
for "if column is qual to column" we do this twice and use range B2:D and sort it by date/3rd column 3 in ascending order 1 and of this we again need only the 1st column so we INDEX it and return all rows ,, and first column 1
with this formula you can add, remove or randomize your dataset and you will always get the right value for each of your rows
as for why your formula doesnt work... to not get #N/A error for vlookup you would need to define the end row of the range but still, the result wont be as you would expect coz formula is not the right one for this job.
as mentioned there are functions that are not supported under AF like SUM,AND,OR and then there are also functions which work but in a different way like IFS or with some limitations like SPLIT,GOOGLEFINANCE,etc.
I have answered you on the tab in your shared sheet called My Practice thusly:
You cannot split a two column array as you have attempted to do in cell CI2. That is why your formula does not work. You can only split a ONE column array.
I understand you are trying to learn, but attempting to use complicated formulas like that is going to make it harder I'm afraid.

Inserting formula to cell after every nth row and incrementing the number by +1 in the formula

I would like to use a formula =SUM(B2:B3) in cells A1, A5,A9 and so on but would like to increment the formula like this =SUM(B5:B6) etc.
Here is my spreadsheet links.
What I am trying to do is not as simple as I posted originally but the logic should be same.
I have two tabs in a sheet , namely 'Tickers' and 'Stock Details'. In Tickers Tab I have listed all tickers symbols in Column A sequentially.
In other Tab I have formula in Cell B1 '=tickers!A1' which get the ticker symbol from Tab Tickers.
In Cells A2 and B2 I have this formula respectively
=index(importhtml("https://www.gurufocus.com/stock/"&$B1&"/summary","table",6),,1)
=index(importhtml("https://www.gurufocus.com/stock/"&$B1&"/summary","table",6),,2)
Each ticker table fill approx 24-25 rows and then I want to repeat the process for the all tickers in first tab.
I had also sharing spreadsheet link here.
https://docs.google.com/spreadsheets/d/1uyc-KWvg45QLR4l1CvrKAFIMEZFh-dKIyI12t9Hvi5A/edit?usp=sharing
try:
=ARRAYFORMULA(IFERROR(IF(B1:B<>"",,QUERY(IF(B1:B="",,
MMULT(N(TRANSPOSE(IF((TRANSPOSE(ROW(
INDIRECT("B1:B"&MAX(IF(B1:B="",,ROW(B1:B))))))>=ROW(
INDIRECT("B1:B"&MAX(IF(B1:B="",,ROW(B1:B))))))*(
{""; TRANSPOSE(TRIM(SPLIT(QUERY(REPT("♦"&ROW(INDIRECT("B1:B"&COUNTBLANK(
INDIRECT("B1:B"&MAX(IF(B1:B="",,ROW(B1:B))))))), 2)&"♦",,999^99), "♦")))}=TRANSPOSE(
{""; TRANSPOSE(TRIM(SPLIT(QUERY(REPT("♦"&ROW(INDIRECT("B1:B"&COUNTBLANK(
INDIRECT("B1:B"&MAX(IF(B1:B="",,ROW(B1:B))))))), 2)&"♦",,999^99), "♦")))})),
INDIRECT("B1:B"&MAX(IF(B1:B="",,ROW(B1:B)))), 0))), ROW(
INDIRECT("B1:B"&MAX(IF(B1:B="",,ROW(B1:B)))))^0)), "offset 2", 0))))
if you want dragging formula use:
=IF(B1<>"",,SUM(INDIRECT("B"&ROW()+1&":B"&ROW()+2)))
I found that this also worked:
=ARRAYFORMULA(IF((MOD(ROW(A:A),3)=1)*({B2:B;""}<>""),VLOOKUP(FLOOR(ROW(A:A)-1,3),QUERY({FLOOR(ROW(A:A)-1,3),N(B:B)*(MOD(ROW(B:B)-1,3)>0)},"select Col1,SUM(Col2) group by Col1"),2,0),))
Here is a sample sheet.

ArrayFormula with GoogleFinance dynamic date

First of all, i'm not a powerful sheets user :)
I'm trying to use GOOGLEFINANCE to calculate amounts in multiple currencies.
I use this formula:
=IF($A2;
IF(
$C2:C;
$C2:C;
IF(
$D2:D;
$D2:D*INDEX(GoogleFinance("CURRENCY:USDUAH";"close";$A2);2;2);
$E2:E*INDEX(GoogleFinance("CURRENCY:EURUAH";"close";$A2);2;2)
));
0)
A-column contains dates,
C,D,E - amounts in 3 different currencies.
IFs are just to prioritize columns :)
The formula works well but i need to "extend" it each time i add row - to increment
$A2 -> $A3 to get rate for specified date.
I try to use ArrayFormula but it turns out it keeps reference to $A2 so i get same rate irrelevant from date specified in A-cells.
I have created sample sheet to illustrate:
https://docs.google.com/spreadsheets/d/1K2TbGIWl7JacYKiWgwwmJfelxJ-7fa9F9obp5XswW18/edit?usp=sharing
I have allowed editing by anyone, so if you decide to edit - please don't remove anything :) also you can drop your username in sticky row(above your proposed solution)
Is there a way to apply ArrayFormula to this to make it work?
Maybe you can provide more readable solution to nested IFs.
try:
=ARRAYFORMULA(IF(A2:A<>"";
IF(C2:C<>""; C2:C;
IF(D2:D<>""; VLOOKUP(TO_TEXT(A2:A);
TO_TEXT(QUERY(GOOGLEFINANCE("CURRENCY:USDUAH";
"close"; MIN(A:A); MAX(A:A)+1);
"offset 1 format Col1'dd.mm.yy'"; 0)); 2; 0)*1;
VLOOKUP(TO_TEXT(A2:A);
TO_TEXT(QUERY(GOOGLEFINANCE("CURRENCY:EURUAH";
"close"; MIN(A:A); MAX(A:A)+1);
"offset 1 format Col1'dd.mm.yy'"; 0)); 2; 0)*1)); ))
There is a new simpler and more flexible method now since the introduction of LAMBDA and its helper functions in Google Sheets in August 2022.
Assuming dates in A2:A, and amounts in UAH, USD, EUR in C2:C, D2:D, E2:E respectively, then the following formula will work, e.g. in cell F2:
=MAP(A2:A;C2:C;D2:D;E2:E;
LAMBDA(date;uah;usd;eur;
IFS(
uah;uah;
usd;usd*INDEX(GOOGLEFINANCE("currency:usduah";"price";date);2;2);
eur;eur*INDEX(GOOGLEFINANCE("currency:euruah";"price";date);2;2);
ISBLANK(date);)))
The trick here is that MAP(LAMBDA) calculates the specified formula for each row of the input array separately (effect similar to manually expanding the formula over the whole range), whereas ARRAYFORMULA passes the whole array as an argument to the formula (GOOGLEFINANCE is special and doesn't work intuitively with such input).
This general method with MAP(LAMBDA) can now be used to pass any arguments to GOOGLEFINANCE in a way one would otherwise expect to do with ARRAYFORMULA.
Try This One:
=arrayformula(
IF(query(arrayformula(if(A2:A="",False,True)),
"Select * where Col1=True"),
IF( $C2:C,
$C2:C,
IF( $D2:D,
$D2:D*INDEX(GoogleFinance("CURRENCY:USDUAH","close",$A2),2,2),
$E2:E*INDEX(GoogleFinance("CURRENCY:EURUAH","close",$A2),2,2))),0))

Resources