Is it possible to have multiple OR conditions in a countifs statement?
I am trying to write a statement that counts the number of records where the relationship is either 'Contractor' OR 'Supplier' AND if the Severity is either 'Serious' OR Major. The first OR condition will work, but only the first condition in the second OR statement is being picked up. Here is what i have written:
=(COUNTIFS(Data!F:F,{"Contractor","Supplier"},Data!E:E,{"Serious","Major"}))
=SUMPRODUCT((Data!F:F="Contractor")+(Data!F:F="Supplier"),(Data!E:E="Serious")+(Data!E:E="Major"))
The (Data!F:F="Contractor") will produce an array of TRUE/FALSE the size of column F, with TRUE only where Column F is "Contractor".
The (Data!F:F="Supplier") will produce an array of TRUE/FALSE the size of column F, with TRUE only where Column F is "Supplier".
the above two arrays are "ADDED" - this converts them to 1/0s instead and adds the two arrays together, producing an array the size of column F, with 1 / 0 s, with 1s where cells in column F are EITHER "Contractor" or "Supplier".
the same for "Serious"/"Major"
inside the SUMPRODUCT the two arrays with 1&0s are MULTIPLIED together, so will return a 1 ONLY when there is a 1 in BOTH arrays so: F is {"Contractor OR "Supplier"} AND E is {"Serious" OR "Major"}
the whole array is then summed (by the SUMPRODUCT() ) to return the COUNT of rows that match the criteria (as a single number)
Related
I posted a similar question: Filter an excel range based on multiple dynamic filter conditions. Now I am considering a more general case, i.e. for one of the filter column (Releases, column E) it may have several values delimited by comma. The expected result should filter by rows that have as release values: A or B, but the releases column can come with more than one value and for team filter by specific one or all of them (ALL wildcard).
Here is the sample (when we have a maximum of two values for releases column):
I was able to obtain the desired result based on filter conditions, but it requires helper columns (columns: J,K,L), via the formula in N3:
=FILTER(D3:H15, (IF(B3="ALL", D3:D15<>"*",D3:D15=B3)) * (L3:L15))
and column L does the magic to identify the rows with the wanted release values:
=LET(result, ISNUMBER(MATCH(J3:K15,TEXTSPLIT(B4,", "),0)), IF((FILTER(result, {1,0})
+ FILTER(result, {0,1}))>0, TRUE, FALSE))
I am looking for a solution that wouldn't require helper columns and also for the general case where Release column can have more than two values, for example: A, C, G, F... if that is possible.
Here a link to my sample file:
https://1drv.ms/x/s!AlZxw2GG3C7Ihyyx8_AM5ylbZWaI?e=F3WUep
Note:
I cannot use TEXTSPLITin a single invocation to obtain columns J,K, because when the text input argument is an array (range) there is no way to delimit by empty string, so TEXTSPLIT(E3:E15,",") doesn't return two columns (it works for a single cell, but not for a range), so I have to use TEXTAFTER(E3:E15,",") to obtain the information after the comma in column K
Lets try-
=FILTER(D3:H15,BYROW(E3:E15,
LAMBDA(x,MAX(--ISNUMBER(XMATCH(TOCOL(TEXTSPLIT(x,",")),
TOCOL(TEXTSPLIT(B4,", ")),0)))))
* IF(B3="ALL",D3:D15<>"",D3:D15=B3))
Explanation of the solution to identify if release value is present:
It uses BYROW function which processes each row by a LAMBDA function you define.
The formula: TOCOL(TEXTSPLIT(B4,", ")
Generates a column array with the values of B4, i.e.: {A;B}(semicolon represents a column array) in our case a 2x1 array. TEXTSPLIT spits a string by delimiter (", ").
The formula: TOCOL(TEXTSPLIT(x,", "))
Generates an array column for a value represented by x split by the delimiter (", ") . For example if x is: A it will generate: {A} and for A,C the output will be: {A;C}, i.e 2x1 array.
The XMATCH function with signature: XMATCH(lookup_value, lookup_array, 0)
will return the index position of lookup_array when an exact match is found for look_value, otherwise N/A. If lookup_value is a column array, the XMATCH function is evaluated for each element of the array and return the result in a column array.
For lookup_array: {A;B} it will produce the following output, based on the following input values:
Lookup_value
Result
{A}
{1}
{A;C}
{1;N/A}
{C;D}
{N/A;N/A}
{A;B}
{1;2}
{B;A}
{2;1}
{B;A;C}
{2;1;N/A}
{C}
{N/A}
In our case:
XMATCH(TOCOL(TEXTSPLIT(x,", ")),TOCOL(TEXTSPLIT(B4,", ")),0)
will return for each releases value (x) ({A}, {A;B}, {A;C}, etc.) a column array of size of the number or elements of x, indicating the row position of {A, B} (if matches) or N/A (not found) for each element of x.
ISNUMBER converts the result to TRUE (if matches) or FALSE (for N/A). --ISNUMBER(cell) converts the result to 1 (match) or 0 (for N/A). Finally MAX function returns 1 if there is at least one match, otherwise 0.
Because BYROW processes the LAMBDA function for each row, it returns 1 (at least one match) or 0 (no match) for each row of E3:E15.
=BYROW(E3:E15,LAMBDA(x,
MAX(--ISNUMBER(XMATCH(TOCOL(TEXTSPLIT(x,", ")),
TOCOL(TEXTSPLIT(B4,", ")),0)))))
which is what we need as a filter condition
Note: You can use MATCH function instead of XMATCH, but keep in mind that for the third input argument the default behavior is different. The default value for MATCH is 1 (largest value that is less than or equal to lookup_value) and for XMATCH is 0 (exact match).
I am trying to do a summation of rows with certain dynamic conditions. I have rows like:
A can be only one value, K can have multiple OR-values. In the end M is to be summed.
I have tried to use SUMPRODUCT() which works for column A but not for K. What I am looking for is something like:
=SUMPRODUCT(--(!$A$2:$A$20000="AA")*--(!$K$2:$K$20000="AA" OR "BB")*$M$2:$M$20000)
I know I can do ="AA" and then ="BB" but I need "AA" and "BB" to be dynamic based on other cells. And the number of arguments is different. I tried {"AA";"BB"} but I know this will not work as the match then needs to be in the same row.
Can it at all be achieved?
Thanks a lot!
=SUMPRODUCT(($A$2:$A$20000="AA")*(($K$2:$K$20000="AA")+($K$2:$K$20000="BB"))*$M$2:$M$20000)
Note that:
Since you are multiplying/adding arrays, there's no need to include the double unary's
I don't know why you have a ! in your example formula.
To return an OR array of TRUE;FALSE, we add.
Your comments still do not provide a clear explanation of what you are making dynamic.
But to create a dynamic OR for column K, including testing for column A and summing column M, you can do the following:
For column K, let us assume that your possible OR's are entered separately in the range F2:F10
=SUMPRODUCT(MMULT(--($K$2:$K$20000=TRANSPOSE($F$2:$F$10)),--(ROW($F$2:$F$10)>0))*($A$2:$A$20000="AAA")*$M$2:$M$20000)
The matrix multiplication will produce a single column of 19,999 entries which will be a 1 for matches of any of the OR's and 0 if it does not match.
See How to do a row-wise sum in an array formula in Excel?
for information about the MMULT function in this application.
In the above formula, "blanks" in the OR range (F2:F10) will also match blank entries in column K. So it is conceivable that if there is a blank in K and F and a AAA in col A and a value in column M that a wrong result might be returned.
To avoid that possibility, we can use a dynamic formula to size column F where we are entering our OR values:
=INDEX($F$2:$F$10,1):INDEX($F$2:$F$10,COUNTA($F$2:$F$10))
will return only the values in col F that are not blank (assuming no blanks within the column)
So:
=SUMPRODUCT(MMULT(--($K$2:$K$20000=TRANSPOSE(INDEX($F$2:$F$10,1):INDEX($F$2:$F$10,COUNTA($F$2:$F$10)))),--(ROW(INDEX($F$2:$F$10,1):INDEX($F$2:$F$10,COUNTA($F$2:$F$10)))>0))*($A$2:$A$20000="AAA")*$M$2:$M$20000)
Given this data:
the last formula will return a value of 5 (sum of M2,M3,M7)
Use SUMIFS with SUMPRODUCT wrapper:
=SUMPRODUCT(SUMIFS($M$2:$M$20000,$A$2:$A$20000,"AA",$K$2:$K$20000,{"AA","BB"}))
I want to count a certain type with a certain step.
For instance, I want to count Type A and Step 1 with =COUNTIFS(A:A,"A",B:B,"Step 1").
However, Steps from Column B come from VLOOKUP function that fetches from different Excel file: for instance, =IFERROR(VLOOKUP($AC9,'Sheet X'!$B$1:$Y$893,21,FALSE),""). Is there a way to count a certain text that comes from VLOOKUP?
I prefer the double unary operator for counting instances like this, it allows you to easily combine as many conditions like this as you like:
=sumproduct(--($A$1:$A$893 = "A", $B$1:$B$893 = "Step 1"))
You can add more conditions by addint commas within the --() section of the sumproduct. What this does is force each column to a one/zero array of the condition (1 if = "A") and multiplies them together, so only if all conditions are true / 1, they'll be counted. In this instance the function will return the value 2, as both are true only for two rows.
If the values in the steps column come from a vlookup, it would not affect this function, as it is just using the values in the cell shown.
I have a column contains some texts as follow:
one
two
three
four
I want to sum the values this column cells according to their content, so I should check the content then return a value, as if(cell = one) then 1
so the sum result should be 1+2+3+4 = 10
I tried to do a formula like =SUM(IF(A1=apartment,1),...) but its absolutely wrong.
how can I write this formula?
You can also do:-
=SUMPRODUCT((A1:A10={"One","two","three","four"})*{1,2,3,4})
This builds up a 2d array where the rows correspond to your data and the columns correspond to the strings "one","two","three" and "four". The elements are set 'true' only where the data matches one of the four strings. Then this array is multiplied by the row of numbers 1,2,3 and 4. 'TRUE' counts as 1 in the multiplication and 'FALSE' counts as 0.
Count the words and multiple by the associated values:
=COUNTIF(A:A,"one")+2*COUNTIF(A:A,"two")+3*COUNTIF(A:A,"three")+4*COUNTIF(A:A,"four")+5*COUNTIF(A:A,"five")
You can extend this formula by adding more terms if necessary, or use a VLOOKUP() table.
Suppose several dices (3 for example) thrown each time. It also could be more than six possible outcomes per "dice", but I took six for better illustration.
1). Columns E or G:
Lookback is simply the size of an array. Arrey should include only unique values and ignore zero values. The tricky thing is that the series of observations are sorted from oldest to newest, and values of an array must be updated based on the newest series of 3 numbers (largest row number in the selected range).
So the parameters of a function should include (array range, max value, array size).
What I need to do is simply to take all values from 1 to 'max value' (1,2,3,...) and subtract all values from an array. In other words, take only those values, which are not included in array for a given range. Finally, type them in ascending order using comma delimiter.
2). Columns D or F:
Here we take any particular range of values, and compare it with our comma delimited list. If there is a match, then type matched numbers similarly using comma delimiter.
I suggest splitting out a lookup table in col h to m with 1,2,3,4,5,6... Across the top in h1 to m1 then in each row you can do a hlookup( h1, a3:c3, 1,false) in cell h3 to m3. This will return either a number or error, you could further wrap this function in an if function if(iserror(hlookup...),h1, ""). This would give you a row of numbers that it does not find in your dice roll which you could concatenate to get what your looking for.