I have a formula that will calculate the working hours between two dates.
It works perfectly well when referring a few lines and ranges. As the data in this sheet is going to be automatically added to over time I wanted to use arrayformula to automatically calculate the duration for these new rows.
However when used within arrayforumla the values are unpredictably different.
I can't make any sense of why it's different.
Below is an example;
https://docs.google.com/spreadsheets/d/1cWZwpnkp2MPyM-EppjOYHRcMEcblscU70R62uf691Xw/edit#gid=0
Any suggestions as to why the formula is behaving differently would be greatly appreciated!
Edit
For posterity;
Formula that worked when inline (COL C);
=TEXT((NETWORKDAYS.INTL(A2,B2,1,F$7:F$9)-1)*($G$2-$F$2)+IF(NETWORKDAYS.INTL(B2,B2,1,F$7:F$9),MEDIAN(MOD(B2,1),$F$2,$G$2),$G$2)-MEDIAN(NETWORKDAYS.INTL(A2,A2,1,F$7:F$9)*MOD(A2,1),$F$2,$G$2),"[hh]:mm:ss")
Forumla that didn't work in arrayformula (COL D);
=ARRAYFORMULA(
IF(ROW(B:B)=1, "Array Formula Duration",
IF(ISBLANK(B:B),"",
(NETWORKDAYS.INTL(A2:A,B2:B,1,F$7:F$9)-1)*($G$2-$F$2)+IF(NETWORKDAYS.INTL(B2:B,B2:B,1,F$7:F$9),MEDIAN(MOD(B2:B,1),$F$2,$G$2),$G$2)-MEDIAN(NETWORKDAYS.INTL(A2:A,A2:A,1,F$7:F$9)*MOD(A2:A,1),$F$2,$G$2)
)
)
)
Forumla that sorted it (COL E);
={"Array Formula Duration";map(A2:A,B2:B,lambda(a,b,if(b="",,TEXT((NETWORKDAYS.INTL(a,b,1,F7:F9)-1)*(G2-F2)+IF(NETWORKDAYS.INTL(b,b,1,F7:F9),MEDIAN(MOD(b,1),F2,G2),G2)-MEDIAN(NETWORKDAYS.INTL(a,a,1,F7:F9)*MOD(a,1),F2,G2),"[hh]:mm:ss"))))}
You may try:
={"Array Formula Duration";map(A2:A,B2:B,lambda(a,b,if(b="",,TEXT((NETWORKDAYS.INTL(a,b,1,F7:F9)-1)*(G2-F2)+IF(NETWORKDAYS.INTL(b,b,1,F7:F9),MEDIAN(MOD(b,1),F2,G2),G2)-MEDIAN(NETWORKDAYS.INTL(a,a,1,F7:F9)*MOD(a,1),F2,G2),"[hh]:mm:ss"))))}
Related
I have a formula that works when it is dragged down but it stops working as soon as it's changed to be an array formula - why could this be?
This is the formula that works when dragged down
=IF(AND($W246:W= "Hired",$Y246:Y<>"Y"),"Workforce Needed","Not")
This is an array formula that suddenly doesn't work. (It no longer pulls back "Workforce Needed" when conditions change - despite me running the same test with the original formula and it working then)
=ARRAYFORMULA(
IF(ISBLANK(F91:F),,IF(AND($W91:W= "Hired",$Y91:Y<>"Y"),"Workforce Needed","Not")))
Column W is a data validation drop down (text)
Column Y is an array formula doing a vlookup
Any ideas much appreciated.
The and() function is an aggregating function and will not get row-by-row results in an array formula. To make it work, use Boolean arithmetic, like this:
(W91:W = "Hired") * (Y91:Y <> "Y")
use:
=ARRAYFORMULA(IF(ISBLANK(F91:F),,IF(($W91:W="Hired")*($Y91:Y<>"Y"),
"Workforce Needed","Not")))
I recently noticed a mistake in my calculation, and I've identified the root cause of the problem: it seems that I mistakenly used the SUMIF function in Google Sheets' ARRAYFORMULA.
I have the sample spreadsheet here.
I wrote the ARRAYFORMULA function that results in column C, which I thought would be the same with the formula in column B.
The formula in column C:
=ARRAYFORMULA(SUMIF(H$3:H$6&I$3:I$6,"<="&A3:A31&">="&A3:A31,G$3:G$6))
The formula in column B:
=SUMIFS(G$3:G$6,H$3:H$6,"<="&A3,I$3:I$6,">="&A3)
In essence, I want to get the value for each date based on predefined values with their own periods.
Please, use this formula in the cell C3:
=ARRAYFORMULA(MMULT(IF((A3:A31>=TRANSPOSE(H3:H5))*
(A3:A31<=TRANSPOSE(I3:I5))=1,TRANSPOSE(G3:G5),0),ROW(G3:G5)^0))
I made a new tab called MK.Help and erased all the other formulas. then i put this formula in C3:
=ARRAYFORMULA(ARRAY_CONSTRAIN(MMULT(N(A3:A>=TRANSPOSE(A3:A)),MMULT((A3:A>=TRANSPOSE(H3:H))*(A3:A<=TRANSPOSE(I3:I)),N(G3:G))),COUNTA(A3:A),1))
Does that work for you?
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))
Based on this sample data, I have this formula which gives me the accurate results with one major problem... It does not auto-populate to new rows
=arrayformula(if(countif(filter(G$2:G,A$2:A=A2,B$2:B=B2),">"&G2)>0,countif(filter(G$2:G,A$2:A=A2,B$2:B=B2),">"&G2),COUNTIF(filter(E$2:E,A$2:A=A2,B$2:B=B2),"Finished")))
I have tried this formula to see if it will auto-populate to the new rows...
=arrayformula(IF(ISNA(A2:A),,if(countif(filter(G$2:G,A$2:A=A2,B$2:B=B2),">"&G2)>0,countif(filter(G$2:G,A$2:A=A2,B$2:B=B2),">"&G2),COUNTIF(filter(E$2:E,A$2:A=A2,B$2:B=B2),"Finished"))))
...the above formula does auto-populate; however, every value is 1 instead of the correct value.
I tried a simple formula which does not do everything the above does but might help troubleshoot. I was under the suspicion that the above formula was only displaying results of the first row over and over. To test I tried this formula...
=arrayformula(IF(ISNA(A2:A),,indirect("g"&ROW(indirect("g2:g"&counta(G2:G))))))
...it turns out that the above formula does display the results from G2 into each row. If I could figure out the reason why, I am sure I could take the concept from the solution to this simple formula and add it to the above more complex one.
Please, try this formula:
=ArrayFormula(if(
mmult(
--(A2:A=TRANSPOSE(A2:A))*
--(B2:B=TRANSPOSE(B2:B))*
--(G2:G<TRANSPOSE(G2:G)),
row(A2:A)^0)>0,
mmult(
--(A2:A=TRANSPOSE(A2:A))*
--(B2:B=TRANSPOSE(B2:B))*
--(G2:G<TRANSPOSE(G2:G)),
row(A2:A)^0),
mmult(
--(A2:A=TRANSPOSE(A2:A))*
--(B2:B=TRANSPOSE(B2:B)),
--(E2:E="Finished"))
)
)
Caution! It works slow, so it's better to delete blank rows in the worksheet. Even better to use this formula in 2 steps. Step 1 formula:
=ArrayFormula(mmult(--(A2:A=TRANSPOSE(A2:A))*
--(B2:B=TRANSPOSE(B2:B))*
--(G2:G<TRANSPOSE(G2:G)),
row(A2:A)^0))
And step 2 formula:
=ArrayFormula(mmult(--(A2:A=TRANSPOSE(A2:A))
*--(B2:B=TRANSPOSE(B2:B)),
--(E2:E="Finished")))
Open ranges overload this formula. It also could work faster if you use:
offset(E2,,,counta(E2:E)) instead of E2:E
I've been at this problem for a while now. I am trying to sum numbers under a specific column when the rows equal a certain text and then display that sum on a different sheet. So far I came up with this formula: =IF(EXACT(A2,Table!A2:A)=TRUE,SUM(Table!C2:C)); however the only problem is that is sums everything in column C (which makes sense).
I wish there was a way to do something like the following: SUM(Table!C2:C where EXACT(A2,TABLE!A2:A)=TRUE). I've also tried the SUMIF(), DSUM(), and QUERY() functions to no avail. I must be getting logically tripped up somewhere.
Figured it out: =SUM(FILTER(Table!E4:E, EXACT(Table!A4:A,A4)=TRUE)).
=sum ( FILTER (b1:b10, a1:a10 = "Text" ) )
// the above formula will help you to take the sum of the values in column B when another column A contain a specific text.
The formula is applicable only in Google Spreadsheets