Excel SUMIFS Multiple Criteria Cell Value - excel

Similar questions to this have been asked but not exactly like this. There is one that is very close, but that solution is not working for me.
I have a function which returns comma separated values into a cell. I would like to pass the elements in that cell as criteria to a SUMIFS function using an approach like this one.
My attempt is pictured below:
I believe that this is somehow tied to the way that the function is understanding what is in cell G8. It looks like it is adding some extra quotes. If I highlight G8 in the formula bar and press F9, I get:
There are extra quotes on each side of each criteria.
I am open to a custom VBA function solution, but I would prefer something which can be built as a worksheet function. The criteria are returned from a custom VBA function that pulls elements out of a list box and does some regex work to remove extra commas. The number of elements that can be selected is variable so I would like to avoid having to split the criteria into more than one cell. Thanks.

Seems that the raw comma-separated criteria is in G6, All you need is to split this criteria into an array and feed it to SUMIFS. Splitting is available in VBA, but not exposed to Excel. All we need is to write a little UDF that does the splitting of the CSV and use it in our formula:
Function splitCSV(str As String)
splitCSV = Split(str, ",")
End Function
Now the formula in F10 would be:
=SUM(SUMIFS(C3:C10, B3:B10, "blue", A3:A10, splitCSV(G6)))
EDIT
The above is an array formula (Ctrl+Shift+Enter). To have it a normal formula we can use SUMPRODUCT instead of SUM. This leads to more flexibility (normal formula vs array formula) as well as some "expected" performance improvement.
=SUMPRODUCT(SUMIFS(C3:C10, B3:B10, "blue", A3:A10, splitCSV(G6)))

Related

COUNTIFS with unique values Excel

I am trying to produce a count of the number of times different strings come up in an Excel table. An example table, currently in SHEET1, would be this:
I have another table in another spreadsheet where I want to indicate, for each letter on the left in Table 1, how many entries for "za", "zc" or "zd" come up on the right. However, I would only like to only consider one entry of each.
The end result, on row B of SHEET2, would have to be something like this:
At the moment I am using a combination of SUM and COUNTIFS to do the job.
More specifically, applied to the example, I am using the following formula:
=SUM(COUNTIFS(Sheet1!A1:A18,Sheet2!$A1,Sheet1!B1:B18,{"za","zc","zd"}))
The formula is doing some of what is intended. However, it is not counting each entry just one time. Instead, its is counting, for each letter on the left, every entry of "za","zc" or "zd". The table that the formula is returning is as follows:
How can I change the formula so that it does what I intend?
Thank you.
My initial thought would be:
=SUM(MIN (1,COUNTIFS(Sheet1!A1:A18,Sheet2!$A1,Sheet1!B1:B18,{"za","zc","zd"}))
but I’m not where I can test if the MIN will apply properly to the COUNTIFS array of results. ;-)
EDITED: The MIN function is taking minimum of 1 or all of the items in the COUNTIFS array, rather than minimum of 1 and each item in the COUNTIFS array, which is what I was afraid of. Using
=MIN(COUNTIFS(Sheet1!A$1:A$18,Sheet2!$A1,Sheet1!B$1:B$18,"za"),1)+MIN(COUNTIFS(Sheet1!A$1:A$18,Sheet2!$A1,Sheet1!B$1:B$18,"zc"),1)+MIN(COUNTIFS(Sheet1!A$1:A$18,Sheet2!$A1,Sheet1!B$1:B$18,"zd"),1)
will gain the desired results. It is a little clunky, but simpler than an array formula. If you want an array formula, you can use:
=SUM(FREQUENCY(IFERROR(MATCH({"za","zc","zd"},(IF(Sheet1!$A$1:$A$18=$A5,Sheet1!$B$1:$B$18)),0),""),IFERROR(MATCH({"za","zc","zd"},(IF(Sheet1!$A$1:$A$18=$A5,Sheet1!$B$1:$B$18)),0),"")))
This uses the FREQUENCY function to take a set of values and see how many items in another set of values fall within each of the data ranges. Since you need text instead of numbers, we use the MATCH function to find out the first time the value occurs in your list, returning "" with the IFERROR function if it doesn't. (We only need the first occurrence since you don't want to know how many occurrences there are). Since it is text, we use the same input for both arguments for FREQUENCY.
Therefore, if you need to change the values you are looking for or the ranges in which you are searching, make sure to change both! Alternately, you could list the values out somewhere, say in F1:F3, and make a named range for this, another one for A1:A18, and another for B1:B18. Your formula would then look something like this:
=SUM(FREQUENCY(IFERROR(MATCH(SearchValues,(IF(colA=$A2,colB)),0),""),IFERROR(MATCH(SearchValues,(IF(colA=$A2,colB)),0),"")))
Then you need only change your named range definitions and your formulas would update. :-)
NOTE: Since this is an array formula, you must close out of the cell by pressing CTRL+SHIFT+ENTER rather than only ENTER. When you look at the formula bar, you should see
{=SUM(FREQUENCY(IFERROR(MATCH(SearchValues,(IF(colA=$A2,colB)),0),""),IFERROR(MATCH(SearchValues,(IF(colA=$A2,colB)),0),"")))}
It does NOT work to enter the curly braces yourself. ;-)
You can use this formula at B1 and fill down:
B1:
=SUMPRODUCT(((Sheet1!$A$1:$A$18=A1)*(Sheet1!$B$1:$B$18= {"za","zc","zd"}))/
COUNTIFS(Sheet1!$A$1:$A$18,Sheet1!$A$1:$A$18,Sheet1!$B$1:$B$18,Sheet1!$B$1:$B$18))

Excel array formula with wildcard

I have an array formula that refers to a drop down cell ($AG$7) to determine which cells to evaluate. This works well, however, I need to include an additional item in the drop down which is "All".
When this is selected, I want the array formula to use "*" to return all instances from the array, but i can't get it to work.
This is the formula I'm currently using;
={SUM(IF((tblSkillsMatrix[Role]=[#Role])*(INDIRECT("tblSkillsMatrix["&V$2&"]")=$AG$7),1,0))}
I've tried using
={SUM(IF((tblSkillsMatrix[Role]=[#Role])*(INDIRECT("tblSkillsMatrix["&V$2&"]")="*"&$AG$7),1,0))}
and
={SUM(IF((tblSkillsMatrix[Role]=[#Role])*(INDIRECT("tblSkillsMatrix["&V$2&"]")="*"&$AG$7&"*"),1,0))}
But these don't work.
Does anybody have any ideas?
Thanks
A explicit = comparison cannot use wildcards. COUTIFS and SUMIFS can. As far as I see, you want to count only (conditional sum 1 and 0).
Problem is, COUTIFS and SUMIFS will not deal with INDIRECT ranges. But INDIRECT can and should (because of its volatile bahavior) often replaced by INDEX- MATCH.
So:
=COUNTIFS(tblSkillsMatrix[role],[#role],INDEX(tblSkillsMatrix,,MATCH($V$2,tblSkillsMatrix[#Headers],0)),"*"&$AG$7)
If $AG$7 is empty then it counts independent of the column named in $V$2.
Btw.: Within a table (ListObject) this needs not be entered as a array formula.
This is not 100% replacement of your formula since it not works if $V$2 is empty and so no table column title is given. Your formula will then look at all columns but this is not possible using COUNTIFS where each additional range must have the same number of columns as the criteria_range1 argument. So if $V$2 shall also can be empty, then this will not work.
If so then you could use
{=SUM((tblSkillsMatrix[role]=[#role])*(LEFT(INDIRECT("tblSkillsMatrix["&$V$2&"]"),LEN($AG$7))=$AG$7))}
Advantage: both $V$2 and $AG$7can be empty.
Disadvantage: Volatile behavior of INDIRECT and this formula then must be a array formula even in a ListObject-table. It must be confirmed using Ctrl+Shift+Enter.

EXCEL: get criteria from a sumif formula

I've been trying to find a way to get the criteria from a sumif formula that looks like this
=SUMIFS(N:N,G:G,"1670",H:H,"2016")
Every sumif has been hardcoded.... so I'm wanting to just pull out criteria1 in a cell (1670) and criteria2 (2016) in a cell. Either an excel solution or vba is fine
With the appropriate version of excel you can use the FORMULATEXT function to get the string comprising the formula.
To get the criteria from this you have to make certain assumptions about the formatting of the formula - if you know commas occur only between argument it is quite easy to split the text on commas and extract; but in different locales you may find that a semicolon is used where you expect a comma; it is possible that ranges have commas in them; etc.
How robust do you need the solution to be?
Extending the answer from #Floris, the below set of formulas gives your the criteria range and criteria in the formula. The below formula is used to remove the "=SUMIF(" & ")"
=SUBSTITUTE(SUBSTITUTE(FORMULATEXT(SUMIF_FORMULA),"=SUMIFS(",""),")","")
The FIND functions find the position of the commas in the formula. The last LEN function is required to get the last criteria.
MID command is used to get the text between 2 commas. the "+1" and "-1" in the MID function are to remove the commas from the output. Couldn't generate a google sheet as the FORMULATEXT function was not recognised.

Return value of adjacent cell

I have a portion of code that is like the following:
I am trying to return the cell directly below the cell that is "A" but I do not want to have any whitespace in between the cells.
I tried using =IF(A1="A",OFFSET(A1,1,0)) but this adds "FALSE" in between the cells where this is not true like so:
How do I remove the whitespace using a formula only to get the output of:
This standard formula will collect the values directly under each cell containing A.
    
Use this in B1 =IFERROR(INDEX(A:A,SMALL(INDEX(ROW(A:A)+(A:A<>"A")*1E+99,,),ROW(1:1))+1),"") and fill down as necessary.
The IFERROR return empty strings when it runs out of values to return. These are not the same as truly blank cells.
Although entered as a standard formula, this does use array processing and if you find calculation lag a problem pare down the full column range references to something closer to what the extents of your data represent.
If you would prefer to avoid VBA, you can perform this calculation using the following formulas, or some variant thereof:
The output will look like the following for the example you provided:

IF function - is there a way to avoid repeating formula

Can't believe I don't know this, but is there a way to avoid repeating a formula in an if statement if the logical test is dependent on it?
i.e.
=IF((SUMIFS formula)=0,"",SUMIFs formula)
I want to replace that SUMIFS function in the false scenario with something short that will tell it to just programmatically repeat the formula it originally tested for. Repeating the formula twice has to have detrimental effects on processing speed. Negligible, maybe, but want to go for best-practices here. Thanks.
You can force an error like #DIV/0! and then use IFERROR, e.g.
=IFERROR(1/(1/SUMIFS_formula),"")
You can assign a Name to a formula and use the Name..............See:
Assigning a name to a formula
Relevant excerpt -
For example, let's suppose we frequently use a formula like:
=SUM(A1:A100)-SUM(B1:B100) and this resides in A101 and is copied across many columns on row 101. It would be better in this case to
create a custom formula that does this in each cell on row 101. Here
is how;
1) Select cell A101 (this is vital).
2) Go to Insert>Name>Define and
in the "Names in workbook" box type: SalesLessCosts
3) Now click in
the "Refers to" box and type: =SUM(A1:A100)-SUM(B1:B100) then click
Add.
Now you can replace the formula in cell A101 with: =SalesLessCosts.
You can also copy this across row 101 and it will change its relative
references just as the formula =SUM(A1:A100)-SUM(B1:B100) would. The
reason it does this is all down to the fact we selected A101 before
going to Insert>Name>Define and used relative references in
=SUM(A1:A100)-SUM(B1:B100) when we added it to the "Refers to" box.
If all you need to do is hide zeroes, there is an easy way:
Select all cells where you wish to hide zeroes
Go into Custom Number Formatting
Set format to "General;General;"
The custom formatting has a structure of [positive numbers];[negative numbers];[zeroes]
By making the last part blank you are effectively hiding zeroes, but showing everything else.
The advantage over conditional formatting is that you can use this on any background.
A neat trick which I sometimes use is to hide the cell value completely by using a custom format of ";;;". This way you can put images inside the cells, like the conditional formatting ones, and not see the value at all.
Try using the SUBSTITUTE function like this :
=SUBSTITUTE( VLOOKUP( H4; $D$5:$E$8; 2; 0 ); $H$1; $I$1 )
Here is an example:
Here the formula I don't want to repeat twice is the VLOOKUP function.
The result of VLOOKUP is a string found in another table (ex : "Green").
I want to check if that string matches a specific string value in $H$1 (here, "Yellow").
If it does, SUBSTITUTE replaces it with$I$1 (the error string you want. Here, "FORBIDDEN").
If it doesn't, it displays the VLOOKUP result string (the normal authorized output, like "Green").
This is useful for me because my actual formula is quite long, so I don't want to write it twice.
I also dont want to use two different cells, because I'm already applying this formula on 10 columns, meaning I should add an extra 10 columns to make it work.
In some scenarios, MAX() or MIN() can do a wonderful job.
E.g., something like this:
=IF(SUMIFSformula>0,SUMIFSformula, 0)
Can be shortened to this:
=MAX(0,SUMIFSformula)
The LET formula can be used for this exact scenario. You can define the formula as a variable and then within that same cell you can reference the variable in your formula.
The LET formula format looks like this:
=LET(name,name_value,calculation)
SUMIFS Example
Here's how it would work with your SUMIF example so that you don't have to repeat the formula:
In this screenshot we have an array A1:B7. We want to sum the values (Col B) if the name in ColA is "apple".
For this we have a standard SUMIFS formula of
=SUMIFS(B1:B7,A1:A7,"apple")
The formula is showing in E2. The result is shown in E3.
To put this into the IF statement without having to repeat the formula we can use LET as shown in the screenshot.
We create a variable with the SUMIFS formula as the value of that variable. We then write our IF statement using the variable name instead of rewriting the formula multiple times.
=LET(name,name_value,calculation)
Variable name: sumapples
Variable value: SUMIFS(B1:B7,A1:A7,"apple")
Calculation: IF(sumapples=0,"",sumapples)
Put together in the LET function it looks like this:
=LET(sumapples,SUMIFS(B1:B7,A1:B7,"apple"),IF(sumapples=0,"",sumapples))
This LET function can be used in any Excel formula, and is very useful for shortening long formulas that have repetition.
Optional: Extra complexity
If you want to you can get extra complicated by naming multiple variables.
=LET(name,name_value,name2,name_value2,calculation)
Since Excel 2007, the IFERROR statement does what the OP asked. From the help file:
Description:
Returns a value you specify if a formula evaluates to an error; otherwise, returns the result of the formula. [italics mine]
Syntax:
IFERROR(value, value_if_error)
I've since realised that this was already answered by #barry houdini above.
Here is a hack - depending on whether you are just interested in the displayed value, or whether you need to use the value in another formula:
Put your SUMIF formula in the cell (without the IF part)
Create a conditional formatting rule which sets the font color to the background color when the cell value is 0
And hey presto, you get the desired result.
As I said - it's a hack, but it does prevent the double evaluation.
There is no "clean" solution that I am aware of.

Resources