Google Sheet "If" between two numbers is not working [duplicate] - google-sheets

I'm trying to set up a formula with multiple IF statements between number ranges but I'm seeing the error:
Formula parse error
Here is the forumula:
=IF((AND(A2>0,A2<500),"Less than 500",
If(AND(A2>=500,A2<1000),"Between 500 and 1000"),
If(AND(A2>=1000,A2<1500),"Between 1000 and 1500"),
If(AND(A2>=1500,A2<2000),"Between 1500 and 2000")))

It's a little tricky because of the nested IFs but here is my answer (confirmed in Google Spreadsheets):
=IF(AND(A2>=0, A2<500), "Less than 500",
IF(AND(A2>=500, A2<1000), "Between 500 and 1000",
IF(AND(A2>=1000, A2<1500), "Between 1000 and 1500",
IF(AND(A2>=1500, A2<2000), "Between 1500 and 2000", "Undefined"))))

I suggest using vlookup function to get the nearest match.
Step 1
Prepare data range and name it: 'numberRange':
Select the range. Go to menu: Data → Named ranges... → define the new named range.
Step 2
Use this simple formula:
=VLOOKUP(A2,numberRange,2)
This way you can ommit errors, and easily correct the result.

standalone one cell solution based on VLOOKUP
US syntax:
=IFERROR(ARRAYFORMULA(IF(LEN(A2:A),
IF(A2:A>2000, "More than 2000",VLOOKUP(A2:A,
{{(TRANSPOSE({{{0; "Less than 500"},
{500; "Between 500 and 1000"}},
{{1000; "Between 1000 and 1500"},
{1500; "Between 1500 and 2000"}}}))}}, 2)),)), )
EU syntax:
=IFERROR(ARRAYFORMULA(IF(LEN(A2:A);
IF(A2:A>2000; "More than 2000";VLOOKUP(A2:A;
{{(TRANSPOSE({{{0; "Less than 500"}\
{500; "Between 500 and 1000"}}\
{{1000; "Between 1000 and 1500"}\
{1500; "Between 1500 and 2000"}}}))}}; 2));)); )
alternatives: https://webapps.stackexchange.com/questions/123729/

For multiple conditions that are sequential, Google sheets provides the more efficient and legible IFS formula:
=IFS(
A2<500, "Less than 500",
A2<1000, "Between 500 and 1000",
A2<1500, "Between 1000 and 1500",
A2<2000, "Between 1500 and 2000" )
You could also add a condition for cases less than 0 or greater than 2000, but this is basically what you asked.

Shorter than accepted A, easily extensible and addresses 0 and below:
=if(or(A2<=0,A2>2000),"?",if(A2<500,"Less than 500","Between "&500*int(A2/500)&" and "&500*(int(A2/500)+1)))

Related

How to check for overlapping dates

I am looking for a solution on either Google sheets or app script to check for overlapping dates for the same account. There will be multiple accounts and the dates won't be in any particular order. Here is an example below. I am trying to achieve the right column "check" with some formula or automation. Any suggestions would be greatly appreciated.
Start Date
End Date
Account No.
Check
2023-01-01
2023-01-02
123
ERROR
2023-01-02
2023-01-05
123
ERROR
2023-02-25
2023-02-27
456
OK
2023-01-11
2023-01-12
456
OK
2023-01-01
2023-01-15
789
ERROR
2023-01-04
2023-01-07
789
ERROR
2023-01-01
2023-01-10
012
OK
2023-01-15
2023-01-20
012
OK
I also found some similar past questions, but they don't have the "for the same account" component and/or requires some sort of chronological order, which my sheet will not have.
How to calculate the overlap between some Google Sheet time frames?
How to check if any of the time ranges overlap with each other in Google Sheets
Another approach (to be entered in D2):
=arrayformula(lambda(last_row,
lambda(acc_no,start_date,end_date,
if(isnumber(match(acc_no,unique(query(query(split(flatten(acc_no&"|"&split(map(start_date,end_date,lambda(start_date,end_date,join("|",sequence(1,end_date-(start_date-1),start_date)))),"|")),"|"),"select Col1,count(Col2) where Col2 is not null group by Col1,Col2",0),"select Col1 where Col2>1",1)),0)),"ERROR","OK"))(
C2:index(C2:C,last_row),A2:index(A2:A,last_row),B2:index(B2:B,last_row)))(
counta(A2:A)))
Briefly, we are creating a sequence of dateserial numbers between the start & end dates for each row, doing some string manipulation to turn it into a table of account number against each date, then QUERYing it to get each account number which has dateserials with count>1 (i.e. overlaps), using UNIQUE to get the distinct list of those account numbers, then finally matching this list against the original list of account numbers to give the ERROR/OK output.
(1) Here is one way, considering each case which could result in an overlap separately:
=ArrayFormula(if(A2:A="",,
if((countifs(A2:A,"<="&A2:A,B2:B,">="&A2:A,C2:C,C2:C,row(A2:A),"<>"&row(A2:A))
+countifs(A2:A,"<="&B2:B,B2:B,">="&B2:B,C2:C,C2:C,row(A2:A),"<>"&row(A2:A))
+countifs(A2:A,">="&A2:A,B2:B,"<="&B2:B,C2:C,C2:C,row(A2:A),"<>"&row(A2:A))
)>0,"ERROR","OK")
)
)
(2) Here is the method using the Overlap formula
min(end1,end2)-max(start1,start2)+1
which results in
=ArrayFormula(if(byrow(A2:index(C:C,counta(A:A)),lambda(r,sum(text(if(index(r,2)<B2:B,index(r,2),B2:B)-if(index(r,1)>A2:A,index(r,1),A2:A)+1,"0;\0;\0")*(C2:C=index(r,3))*(row(A2:A)<>row(r)))))>0,"ERROR","OK"))
(3) Most efficient is to use the original method of comparing previous and next dates, but then you need to sort and sort back like this:
=lambda(data,sort(map(sequence(rows(data)),lambda(c,if(if(c=1,0,(index(data,c-1,2)>=index(data,c,1))*(index(data,c-1,3)=index(data,c,3)))+if(c=rows(data),0,(index(data,c+1,1)<=index(data,c,2))*(index(data,c+1,3)=index(data,c,3)))>0,"ERROR","OK"))),index(data,0,4),1))(SORT(filter({A2:C,row(A2:A)},A2:A<>""),3,1,1,1))
HOWEVER, this only checks for local overlaps. not globally. You can see what I mean if you change the dataset slightly:
Clearly the first and third pair of dates have an overlap but G4 contains "OK". This is because each pair of dates is only checked against the adjacent pairs of dates. This also applies to the original reference cited by OP - here's an example where it would give a similar result:
The formula posted by #The God of Biscuits gives the correct (global) result :-)

My ArrayFormula with SUM and non-contiguous fields is not calculating correct totals per row

I have a spreadsheet (Google Sheets) with several non-contiguous Cost columns. When I try to user ArrayFormula to sum each row "Grand Total", it's returning some interesting (incorrect) numbers.
Here's a sample, stripped down the number of cost columns for brevity.
Venue Cost
Moving
Moving Details
AV Support
Grand Total
1500
500
500
2500
2500
500
750
3750
1500
500
500
2500
My Array Formula for the Grand Total Column is
=ARRAYFORMULA(filter(G2:G, G2:G<>"") + SUM(H2:H,J2:J))
where G is the Venue Cost and H and J are additional costs.
This is the resulting Grand Total:
Venue Cost
Moving
Moving Details
AV Support
Grand Total
1500
500
500
4750
2500
500
750
5750
1500
500
500
4750
I tried moving away from SUM, to just manually adding the additional costs together.
=ARRAYFORMULA(filter(G2:G, G2:G<>"") + (J2:J + H2:H ))
but received the #N/A error, which expanded to "Error: Array arguments to ADD are of different size." We have a document generating tool that sees those N/A's as additional jobs to process, so any extra spillover is not good:
Venue Cost
Moving
Moving Details
AV Support
Grand Total
1500
500
500
2500
2500
500
750
3750
1500
500
500
2500
#N/A
#N/A
I'm pretty sure that the SUM and the ADD versions are including more than one row, do I need to filter the 'Additional Costs' Columns as well as the Venue Costs? Or, are the non-contiguous columns an issue?
Thank you!
try:
=INDEX(IF(G2:G="",,G2:G+H2:H+J2:J))
or:
=BYROW({G2:H, J2:J}, LAMBDA(x, SUM(x)))
or:
=BYROW({G2:H, J2:J}, LAMBDA(x, IFERROR(1/(1/SUM(x)))))
or:
=BYROW({G2:INDEX(H:H, COUNTA(G:G)), J2:INDEX(J:J, COUNTA(G:G))}, LAMBDA(x, SUM(x)))
I don't know if I fully understand what you're trying to accomplish, but try this:
=ARRAYFORMULA(IF(G2:G="","",G2:G+H2:H+J2:J))

List all numbers between 0 and 10^n containing repdigits in google sheets

In Google sheets How to get a list of all repdigits numbers between 0 and 10^n.
Example: We have the input n in B1 set to 3 therefore our numbers are between 0 and 10^3 alternatively between 0 and 1000
We should get this list of repdigits.
11,22,33,44,55,66,77,88,99,111,222,333,444,555,666,777,888,999
Requirments
Less references
Shortest formula
Efficient processing
If possible without lambda and its helpers
Note
If cell or row/column limit is reached is acceptable not to join the result.
More examples
n
Output
3
11,22,33,44,55,66,77,88,99,111,222,333,444,555,666,777,888,999
4
11,22,33,44,55,66,77,88,99,111,222,333,444,555,666,777,888,999,1111,2222,3333,4444,5555,6666,7777,8888,9999
5
11,22,33,44,55,66,77,88,99,111,222,333,444,555,666,777,888,999,1111,2222,3333,4444,5555,6666,7777,8888,9999,11111,22222,33333,44444,55555,66666,77777,88888,99999
6
11,22,33,44,55,66,77,88,99,111,222,333,444,555,666,777,888,999,1111,2222,3333,4444,5555,6666,7777,8888,9999,11111,22222,33333,44444,55555,66666,77777,88888,99999,111111,222222,333333,444444,555555,666666,777777,888888,999999
7
11,22,33,44,55,66,77,88,99,111,222,333,444,555,666,777,888,999,1111,2222,3333,4444,5555,6666,7777,8888,9999,11111,22222,33333,44444,55555,66666,77777,88888,99999,111111,222222,333333,444444,555555,666666,777777,888888,999999,1111111,2222222,3333333,4444444,5555555,6666666,7777777,8888888,9999999
8
11,22,33,44,55,66,77,88,99,111,222,333,444,555,666,777,888,999,1111,2222,3333,4444,5555,6666,7777,8888,9999,11111,22222,33333,44444,55555,66666,77777,88888,99999,111111,222222,333333,444444,555555,666666,777777,888888,999999,1111111,2222222,3333333,4444444,5555555,6666666,7777777,8888888,9999999,11111111,22222222,33333333,44444444,55555555,66666666,77777777,88888888,99999999
9
11,22,33,44,55,66,77,88,99,111,222,333,444,555,666,777,888,999,1111,2222,3333,4444,5555,6666,7777,8888,9999,11111,22222,33333,44444,55555,66666,77777,88888,99999,111111,222222,333333,444444,555555,666666,777777,888888,999999,1111111,2222222,3333333,4444444,5555555,6666666,7777777,8888888,9999999,11111111,22222222,33333333,44444444,55555555,66666666,77777777,88888888,99999999,111111111,222222222,333333333,444444444,555555555,666666666,777777777,888888888,999999999
10
11,22,33,44,55,66,77,88,99,111,222,333,444,555,666,777,888,999,1111,2222,3333,4444,5555,6666,7777,8888,9999,11111,22222,33333,44444,55555,66666,77777,88888,99999,111111,222222,333333,444444,555555,666666,777777,888888,999999,1111111,2222222,3333333,4444444,5555555,6666666,7777777,8888888,9999999,11111111,22222222,33333333,44444444,55555555,66666666,77777777,88888888,99999999,111111111,222222222,333333333,444444444,555555555,666666666,777777777,888888888,999999999,1111111111,2222222222,3333333333,4444444444,5555555555,6666666666,7777777777,8888888888,9999999999
11
11,22,33,44,55,66,77,88,99,111,222,333,444,555,666,777,888,999,1111,2222,3333,4444,5555,6666,7777,8888,9999,11111,22222,33333,44444,55555,66666,77777,88888,99999,111111,222222,333333,444444,555555,666666,777777,888888,999999,1111111,2222222,3333333,4444444,5555555,6666666,7777777,8888888,9999999,11111111,22222222,33333333,44444444,55555555,66666666,77777777,88888888,99999999,111111111,222222222,333333333,444444444,555555555,666666666,777777777,888888888,999999999,1111111111,2222222222,3333333333,4444444444,5555555555,6666666666,7777777777,8888888888,9999999999,11111111111,22222222222,33333333333,44444444444,55555555555,66666666666,77777777777,88888888888,99999999999
12
11,22,33,44,55,66,77,88,99,111,222,333,444,555,666,777,888,999,1111,2222,3333,4444,5555,6666,7777,8888,9999,11111,22222,33333,44444,55555,66666,77777,88888,99999,111111,222222,333333,444444,555555,666666,777777,888888,999999,1111111,2222222,3333333,4444444,5555555,6666666,7777777,8888888,9999999,11111111,22222222,33333333,44444444,55555555,66666666,77777777,88888888,99999999,111111111,222222222,333333333,444444444,555555555,666666666,777777777,888888888,999999999,1111111111,2222222222,3333333333,4444444444,5555555555,6666666666,7777777777,8888888888,9999999999,11111111111,22222222222,33333333333,44444444444,55555555555,66666666666,77777777777,88888888888,99999999999,111111111111,222222222222,333333333333,444444444444,555555555555,666666666666,777777777777,888888888888,999999999999
Repdigits are multiples of Repunits like 11, 111. We can easily create Repunits of 1 by REPeaTing 1 and supplying a SEQUENCE to number of times argument of REPT. Once created, just multiply them by sequence of 1..9 and JOIN them using ,.
Snippet(for 3):
=ARRAYFORMULA(TEXTJOIN(",",,REPT("1",SEQUENCE(3-1,1,2))*SEQUENCE(1,9)))
This question could phrased like:
How to get all repdigit, monodigit or numbers that consist of the same digit between 0 and 10^n
Use this formula
=ArrayFormula(
LAMBDA(n, REGEXEXTRACT(TEXTJOIN(",",1,BYROW(SEQUENCE(n), LAMBDA(r, TEXTJOIN(",",1,REPT(SEQUENCE(9),r))))),"11.+"))
(B1))
Explanation
We are repeating each number in the sequence {1;2;...n} 1,2,...n times and joining with comma , and join all with comma ,.
In other words:
For each number in {1;2;...n} REPT once and twice and ... n times then join all with a comma.
Used formulas help
ARRAYFORMULA - LAMBDA - REGEXEXTRACT - TEXTJOIN - BYROW - SEQUENCE - REPT
not sure how serious you are with n but try:
={""; INDEX(QUERY(FLATTEN(QUERY(TRANSPOSE(REPT(
SEQUENCE(1, 9), SEQUENCE(C1, 1, 2))&","),,9^9)),,9^9))}
where C1 = 1000 -----> (10^1000)
and if you are brave enough, change 1000 to 10000 or 50000 :)

Google Sheets: Average percentage using multiple conditions

I would like to get an average percentage out of my sample, however, I need to use several conditions. I tried to use the AVERAGE and AVERAGEIF together with FILTER but everything returns an error and I think I'm incorrectly "merging" formulas.
You can find my test sheet here.
The rules I need to apply:
The score for individual rows is possible to find in the "Data" sheet in cell N and the total results should be visible in the sheet "Calculation" cell E.
As the sample is huge in real life, I need to filter out several pieces of information and add conditions:
to filter out all items where the code/ID starts with 0: Data!A:A&"", "^0.+"
to filter out all items that are matching the date in the Calculation sheet: Data!C:C=$B3
to filter all items with the specific name: Data!B:B=$A3
Any idea how to get the average % out of items with specific filters?
UPDATE
Expected results: I want to see the total average for a specific date, name, and ID, and let's say I would use these filters, then I would see only the final average percentage.
Test =100%
Test = 0%
Test = 100%
Total Average %: 66.7%
Also, I think the best way would be to use AVERAGEIFS, but I'm getting the error "Array arguments to AVERAGEIFS are of different size".
=AVERAGEIFS(Data!N:N,Data!B:B=$A3,Data!C:C=$B3,Data!A:A&"", "^0.+")
=IFERROR(AVERAGEIFS(Data!N3:N,Data!B3:B,A3,Data!C3:C,B3,ARRAYFORMULA(if(LEN(Data!A3:A),REGEXMATCH(Data!A3:A,"^0.+"),"")),TRUE),"")
or
=IFERROR(AVERAGE(FILTER(Data!N3:N,Data!B3:B=A3,Data!C3:C=B3,REGEXMATCH(Data!A3:A,"^0.+"))),"")
or
=IFERROR(INDEX(QUERY({Data!A3:C,Data!N3:N},"select avg(Col4) where Col1 starts with '0' and Col2 = '"&A3&"' and Col3 = '"&B3&"'"),2,0),"")

Automate Spreadsheet Calculation

I'm trying to build out a spreadsheet formula that will allow me to take one list of numbers and evenly distribute them into another list of numbers. Attaching an example below.
I'm sure there's a way to automate this process but I've done extensive research online and can't seem to figure out the right combination of existing formulas to make this work, would greatly appreciate any resources or tips to point me in the right direction. Currently using G Sheets.
Example spreadsheet: https://docs.google.com/spreadsheets/d/1JgFKXGJ2-eQEXAGtqu64p_Zw7gY2fVpEtuCFDvMb9YE/edit#gid=1179066278
List 1:
1000
500
List #2:
300
600
200
100
200
100
Desired result:
List 1 value -> List 2 values that add up to List 1 value
1000 -> 300, 600, 100
500 -> 200, 100, 200
try this partial solution:
=ARRAYFORMULA(TRANSPOSE(QUERY({ FILTER(A:A, A:A<=C3, A:A<>""), MMULT(
TRANSPOSE((ROW(INDIRECT("B1:B"&COUNTA(FILTER(A:A, A:A<=C3, A:A<>""))))<=
TRANSPOSE( ROW(INDIRECT("B1:B"&COUNTA(FILTER(A:A, A:A<=C3, A:A<>""))))))*
FILTER(A:A, A:A<=C3, A:A<>"")), SIGN(FILTER(A:A, A:A<=C3, A:A<>"")))},
"select Col1 where Col2 <="&C3)))
side note: it will give you only the exact number (as you request) or lower number (one number short)

Resources