Multiple returns for IF statement [duplicate] - excel

This question already has answers here:
multiple excel if statements to produce value 1,2 or 3
(3 answers)
Closed 4 years ago.
Screenshot
I'm trying to use and if statement to return a possible 3 different values. I'm trying to determine if a customer re-ordered this year after ordering last year.
My results should be re-ordered, only 2018 or Q4 not Q1. My formula is : =IF(AND(I15>0,J15<1),"Q4 not Q1","Re-Ordered")
But as you can see I'm not sure if I should be adding an or statement or what the layout of the formula should be. Any help is greatly appreciated. Everything I've found on this keeps returning my statement as false.

An IF statement can only return 2 values, so if you want to return 3, you have to nest it inside another IF like this:
=IF(A=B,"A equals B",IF(A=C, "A equals C", "A does not equal B and A does not equal C"))
Based on your screenshot:
=IF(AND(I12>0,J12<1),"Q4 not Q1",IF(AND(I12>0,J12>0),"Re-Ordered","2018 Only"))

Related

How to fix the #SPILL! Error by displaying only the second value?

I have a column with some info displayed like that:
Product Info
I am the 3rd product from 2020
I was created in 1995 and I went public in 2021
I am a not sure if I'm from 2019 2020 2021
I have a formula to extract the year in the above column that is:
=IFERROR(FILTERXML("<k><m>"&SUBSTITUTE([#[Product Name]]," ","</m><m>")&"</m></k>","//m[.=number() and string-length()=4]"),"")
The problem with this formula is that it works fine with the first case, but it gives me a #SPILL! Error on the other two cases. My ideal output would be:
Product Info
Year
I am the 3rd product from 2020
2020
I was created in 1995 and I went public in 2021
2021
I am a not sure if I'm from 2019 2020 2021
Basically, for the first case, just return the 4 digits. EVERY time that I only have one sequence of 4 digits, I want to return that sequence.
For the second case, I want to return ONLY the second year. EVERY time I have 2 sequences of 4 digits, I want to return ONLY the second year.
For the third case, I want to return nothing. EVERY time I have more than 2 sequences of 4 digits, I want to return blank.
The last thing I tried to add was position()>5 and that would cut off the 1995 in the second example, but I would continue having the Error on the third example. Also, my list is quite huge, and I am not sure if the position()>5 thing would work for ALL products that fall in the same second example.
I am not very good with XPATH, so any help would be greatly appreciated.
Thank you!
Disclaimer: Below solution is written on the assumption that when 'count of years < 3', return the last given year. If 'count >= 3' then only return the last year if years come in pairs of two. Hence the use of 'modulus 2 == 0'.‡
You can expand the xpath for sure if you so desire. However, I'd rewrite it a little bit. Each predicate, the structure between the opening and closing square brackets, is a filter of a given nodelist. To write multiple of these structures is in fact anding such predicates. To get a better understanding of what most common xpath 1.0 functions can do within FILTERXML(), I'd like to redirect you to this post.
So to write a consecutive pattern of predicates I'd opt for:
[.*0=0] - First return a filtered nodelist of all numbers where a node multiplied by zero equals zero;
[string-length()=4] - Then return only those that are 4 characters long‡‡;
[position() = last() and (position() = 1 or position() mod 2 = 0)] - The 3rd and last predicate is the trickiest for your query. This is done with a first check that position() = last() meaning the node needs to be the last node in the filtered nodelist of step 2 and (position() = 1 or position() mod 2 = 0) means we want to check that this node is also at the 1st index or the modulus 2 of the indexed position equals 0‡‡‡.
Formula in B2:
=IFERROR(FILTERXML("<t><s>"&SUBSTITUTE(A2," ","</s><s>")&"</s></t>","//s[.*0=0][string-length()=4][position() = last() and (position() = 1 or position() mod 2 = 0)]"),"")
Whilst the above would work for Excel 2013 and higher‡‡‡‡, you do talk about spilled behaviour. If you happen to work with the current channel in ms365 you could also try:
=LET(x,TEXTSPLIT(A2," "),y,--FILTER(x,ISNUMBER(-(x&"**0"))*(LEN(x)=4),{1,2,3}),z,COUNT(y),IF(OR(z=1,MOD(z,2)=0),TAKE(y,,-1),""))
‡ If you need to simply return the last year if 'count < 3' then you can use xpath "//s[.*0=0][string-length()=4][position()<3 and position() = last()]" or ms365 formula =LET(x,TEXTSPLIT(A2," "),y,FILTER(x,ISNUMBER(-(x&"**0"))*(LEN(x)=4),""),IF(COUNTA(y)>2,"",TAKE(y,,-1))).
‡‡ Note that you can be more strict about this if you'd wish to validate that a year is between say 1900-2050 or so. One could replace the 1st and 2nd predicate with [.*1>1899][.*1<2051].
‡‡‡ Note that the order or writing your and/or statements in xpath do matter. We need to use explicit parentheses to control the precedence. See this
‡‡‡‡ This is not true for Excel Online or Excel for Mac
Just add a simple clause to determine the number of returns, for example using ROWS (since by default FILTERXML returns a vertical array):
=LET(
ζ, FILTERXML(
"<k><m>" &
SUBSTITUTE(
[#[Product Name]],
" ",
"</m><m>"
) & "</m></k>",
"//m[.=number() and string-length()=4]"
),
ξ, ROWS(ζ),
IF(ξ > 2, "", INDEX(ζ, ξ))
)
Edit: I might prefer to avoid FILTERXML here:
=LET(
ζ, TEXTSPLIT([#[Product Name]], " "),
ξ, -(ζ & "**0"),
IF(COUNT(ξ) > 2, "", IFERROR(-LOOKUP(1, FILTER(ξ, LEN(ζ) = 4)), ""))
)
You can try the following using TEXTAFTER function. Assuming you have years at the end delimited by space. If that is not the case, the formula can be adapted to have additional checks (it is a number and four-digit, but strictly speaking a year can have less or more than 4 digits). Let me know if the previous assumption doesn't apply so I can try to adapt it. The following is an array version, so you can use the entire table column in case you are using excel tables:
=LET(in,A2:A4,last,TEXTAFTER(in," ",-1),
IF(ISNUMBER(1*TEXTAFTER(SUBSTITUTE(in," "&last,"")," ",-1)),"",last))
For the case of more than one year, it removes the last year found, and if the second search is a number, then it returns empty, otherwise returns the previous year found.

Operand for matching any one of multiple cases [duplicate]

This question already has answers here:
How to test multiple variables for equality against a single value?
(31 answers)
Closed 3 years ago.
I would like to have an if statement where the match is one of several numbers without using a large number of | bars because I have many matching cases
if number == 1 | number == 5 | number == 7
do stuff
In R, there is the operand %in% that works sort of like the following:
if number %in% [1,5,7]
do stuff
Is there a similar operand/ability in python?
Thanks
You can use something like
if number in [1, 5, 7]:

Logic evaluation problem in SUMPRODUCT Formula

I am using a formula based on SUMPRODUCT, SUBTOTAL, and OFFSET. To enable count of visible rows only with criteria. I a trying it on a simple sample data which as follows. Data starts from B4 in the Range B4:B12 Header B3:
B Column
HD
2
2
4
6
2
1
8
9
2
Formula is :
=SUMPRODUCT((B4:B12=B4)*(SUBTOTAL(103,OFFSET(B4,ROW(B4:B12)-MIN(ROW(B4:B12)),0))))
It gives correct result of 4 counts for a value of 2.
I went for evaluation of the formula to fully understand its logic. I could comprehend major part of its logic but certain steps are not quite clear to me. I am reproducing evaluation steps below with my comments.
Step -1
=SUMPRODUCT(({2;2;4;6;2;1;8;9;2}=2)*(SUBTOTAL(103,OFFSET(B4,ROW(B4:B12)-MIN(ROW(B4:B12)),0))))
OK
Step -2
=SUMPRODUCT(({TRUE;TRUE;FALSE;FALSE;TRUE;FALSE;FALSE;FALSE;TRUE})*(SUBTOTAL(103,OFFSET(B4,ROW(B4:B12)-MIN(ROW(B4:B12)),0))))
OK
STEP-3
=SUMPRODUCT(({TRUE;TRUE;FALSE;FALSE;TRUE;FALSE;FALSE;FALSE;TRUE})*(SUBTOTAL(103,OFFSET(B4,ROW(B4:B12)-MIN(ROW(B4:B12)),0))))
OK
STEP-4
=SUMPRODUCT(({TRUE;TRUE;FALSE;FALSE;TRUE;FALSE;FALSE;FALSE;TRUE})*(SUBTOTAL(103,OFFSET($B$4,{4;5;6;7;8;9;10;11;12}-MIN({4;5;6;7;8;9;10;11;12}),0))))
OK
STEP-5
=SUMPRODUCT(({TRUE;TRUE;FALSE;FALSE;TRUE;FALSE;FALSE;FALSE;TRUE})*(SUBTOTAL(103,OFFSET($B$4,{4;5;6;7;8;9;10;11;12}-4),0))))
OK
STEP-6
=SUMPRODUCT({TRUE;TRUE;FALSE;FALSE;TRUE;FALSE;FALSE;FALSE;TRUE}*(SUBTOTAL(103,OFFSET($B$4,{0;1;2;3;4;5;6;7;8},0))))
Why {0;1;2;3;4;5;6;7;8} ??
STEP-7
=SUMPRODUCT({TRUE;TRUE;FALSE;FALSE;TRUE;FALSE;FALSE;FALSE;TRUE}*(SUBTOTAL(103,{#VALUE!;#VALUE!;#VALUE!;#VALUE!;#VALUE!;#VALUE!;#VALUE!;#VALUE!;#VALUE!;})))
Why {#VALUE!;#VALUE!;#VALUE!;#VALUE!;#VALUE!;#VALUE!;#VALUE!;#VALUE!;#VALUE!;} ??
STEP-8
=SUMPRODUCT({TRUE;TRUE;FALSE;FALSE;TRUE;FALSE;FALSE;FALSE;TRUE}*({1;1;1;1;1;1;1;1;1}))
How 1 instead of #VALUE!
STEP-9
=SUMPRODUCT({1;1;0;0;1;0;0;0;1})
OK
Step -10
4
OK
I am not having full clarity on the following points
STEP-6 : Why {0;1;2;3;4;5;6;7;8}
STEP-7: Why {#VALUE!;#VALUE!;#VALUE!;#VALUE!;#VALUE!;#VALUE!;#VALUE!;#VALUE!;#VALUE!;}
STEP-8: How 1 instead of #VALUE!
Hope Someone helps in clarifying the logic behind these mentioned spots. Please forgive me for asking clarity on such a trivial matter.
STEP-6 : Why {0;1;2;3;4;5;6;7;8}
Because the {4;5;6;7;8;9;10;11;12}-4 evaluates to {4-4;5-4;6-4;7-4;8-4;9-4;10-4;11-4;12-4} which is {0;1;2;3;4;5;6;7;8}
STEP-7: Why {#VALUE!;#VALUE!;#VALUE!;#VALUE!;#VALUE!;#VALUE!;#VALUE!;#VALUE!;#VALUE!}
The formula evaluator fails getting the values out of the 9 cell references got via OFFSET($B$4,{0;1;2;3;4;5;6;7;8},0) = {$B$4;$B$5;$B$6;$B$7;$B$8;$B$9;$B$10;$B$11;$B$12} in array context. But that does not matter because:
STEP-8: How 1 instead of #VALUE!
the SUBTOTAL(103,... is a COUNTA subtotal which, for each single cell reference of the 9 cell references got in step 7, counts 1 if it is not hidden, else 0. So it does not matter whether the cell values was evaluated or not.
Btw.: The same can be achieved using
=SUMPRODUCT((B4:B12=B4)*(SUBTOTAL(103,INDIRECT("B"&ROW(B4:B12)))))
Annotation:
Such formulas are result of trial and error. I doubt any Excel programmer was able predicting all usages of the functions they implemented. There are usages of Excel functions in the wild which are as much thought outside the box that they originally could not have thought so.
Bonus:
=SUMPRODUCT(OFFSET(B4,ROW(B4:B12)-MIN(ROW(B4:B12)),0))
results in 0 using your values in B4:B12.
Here the formula evaluator also fails getting the values out of the 9 cell references got via OFFSET($B$4,{0;1;2;3;4;5;6;7;8},0) = {$B$4;$B$5;$B$6;$B$7;$B$8;$B$9;$B$10;$B$11;$B$12} in array context. And the result is {#VALUE!;#VALUE!;#VALUE!;#VALUE!;#VALUE!;#VALUE!;#VALUE!;#VALUE!;#VALUE!}. But now it matters because we need the values.
In that case we can use N function to force getting the values
=SUMPRODUCT(N(OFFSET(B4,ROW(B4:B12)-MIN(ROW(B4:B12)),0)))
This results in 36, the sum of your values in B4:B12.

Excel - search function with wildcards

I have the following formula:
=(OR(ISERR(SEARCH("20??",F3871,1))=FALSE,F3871="",F3871 = "Customer Number:"))
which is setup as a helper column in order to pull another formula and manipulate some data.
My issue is that some of the products we have are being counted in the first OR section (ex. code 1320-T is being counted because there are 2 values to the right of 20 ), however the goal was to only select the years beyond 2005 only.
Is there a way to change the first parameter of SEARCH to reflect only years starting with 20.
Perhaps there is a better formula to use
Thank you.
sample data:
FALSE 1142-CR
FALSE 1142-TL
FALSE 1320
TRUE 1320-T
Note: There is a mix of years and products in this column which is why I am trying to clean it up and put the data into a table. Most products this will not be an issue but a few have the "20" in them

What does -- (minus minus) do in Excel? [duplicate]

This question already has an answer here:
Meaning of two minus signs together ("double unary")
(1 answer)
Closed 6 years ago.
In Excel I have two cells
A1 Gwen Stefani
B1 =SUMPRODUCT(--(A1:A10="Gwen Stefani"))
B1 records a value of 1 (it counts "Gwen Stefani" in cell A1)
My question is this: What is the -- operator called, for want of a better word, and what does it do?
Naturally looking up "--" in Excel help gets me 50,200 results of - which isn't helpful ;)
The (A1:A10="Gwen Stefani") evaluates to an array (TRUE, FALSE, FALSE, FALSE...). So you are multiplying it by 1 to get (1,0,0,...). The "- -" can be replaced by "1*" with the same result.

Resources