Excel: Index-Match using keywords and then SUM results (no VBA) - excel

I've got a sheet with a transaction list. It includes a description of the transaction and the transaction total cost.
I'm looking for a way, without using Visual Basic, to use comma-separated keywords entered in a cell to search for all matching transactions, and then give their total value.
For example:
B4:B6 are keywords for look up.
C4 should look up in range B10:B26 for all cells containing any of the keywords in B1 (tesco OR co-op OR waitrose), and return the total value of the corresponding values in Range C10:C26. In this case it should SUM C11, C16, C21, C23, C25.
It's important to note that it shouldn't be case sensitive.
Can it be done?

You can do this with Array Functions. These functions operate similarly to "Sumifs" / "Countifs" / "Sumproduct": they perform functions normally designed to look at a specific cell, over an entire range of cells.
First let's deal with summing the total for "giffgaff" / "paypal":
In cell C5, use the following formula [As it is an Array formula, you must confirm by pressing CTRL + SHIFT + ENTER every time you edit the cell, instead of just ENTER] , and drag down to C6.
=sum(if(iserror(search(B5,$B$10:$B$26)),"",$C$10:$C26))
This looks at each row from B10:B26 (note that the entire column cannot be selected as an array formula calculates for all cells, even blank ones - so this drastically slows performance. You must specifically identify the rows you care about like this), and if there is an error when trying to search for the term in B4, that means the term does not appear on that particular row. If there is no error, it pulls the amount from column C. All of these rows are then summed together to get a single total.
Now to do the same for cell C4, you need to add in the complexity of first pulling apart each term which appears between a comma. I agree that #Tom Sharpe that you should probably do this in different cells to make it more clear what you're doing. This could be done by individually pulling terms between commas, and then having individual totals (which use the array formula above).
To do this most efficiently, I'd have use a helper column in column C, which will identify how many commas are in the text in column B, like so, in C4:
=len(B4)-len(substitute(B4,",",""))
This takes the length of B4, less the length of B4 where all commas have been replaced by blanks - giving the # of commas.
That formula can then be used to split out the words between commas, using the MID and SUBSTITUTE functions. Let me know if you need elaboration on how to do that. Once you have broken out the individual words, you can search with the Array function as above.

Related

How to display start and end times in one cell in excel?

I have a schedule for work that lists employees shifts as durations, i.e. 11-7, 1030-6, etc. within a single cell. If these were single times like 6, 1130, etc, I could convert to time format easily, but how can I make these cells display the shift start and end time in time format?
The goal is to have excel use these times to sort and filter the corresponding employees on another sheet according to their scheduled shift. Is there a way to display "hh:mm-hh:mm" to represent a shift in one cell?
This is possible using formulas, but you have to be specific about formats and testing the entries.
The primary piece of the formula to understand is how to separate the time "values" on either side of the "-". This solution assumes that a dash ("-") will ALWAYS be present in the cell. For the shift entry "2-11" (assume this is in cell A2), you can use a combination of FIND, LEFT, and RIGHT to separate all the characters on either side of the "-" using these formulas
Cell A2 contains "2-11"
LEFT(A2,FIND("-",A2)-1 returns "2"
RIGHT(A2,LEN(A2)-FIND("-",A2)) returns "11"
IMPORTANT: these formulas now become "the time value" and will be repeated inside a larger formula.
From here on out, it's a matter of reformatting the string into a time-formatted string by adding a colon ":" at the appropriate place in the string in order to create an Excel time value.
Helper columns are used to get all the values cleanly, as shown in this example:
Formula in B2: =IF(LEN(LEFT(A2,FIND("-",A2)-1))<=2,TIMEVALUE(LEFT(A2,FIND("-",A2)-1)&":00"),TIMEVALUE(LEFT(A2,FIND("-",A2)-3)&":"&RIGHT(LEFT(A2,FIND("-",A2)-1),2)))
Formula in C2:
=TIMEVALUE(IF(LEN(RIGHT(A2,LEN(A2)-FIND("-",A2)))<=2,RIGHT(A2,LEN(A2)-FIND("-",A2))&":00",LEFT(RIGHT(A2,LEN(A2)-FIND("-",A2)),LEN(RIGHT(A2,LEN(A2)-FIND("-",A2)))-2)&":"&RIGHT(RIGHT(A2,LEN(A2)-FIND("-",A2)),2)))
Formula in D2: =IF(C2>B2,C2,C2+TIME(12,0,0))
Formula in E2: =(D2-B2)*24
Formula in F2: =TEXT(B2,"hh:mm")&" - "&TEXT(D2,"hh:mm")

Count occurrences of values in a specific range (Excel) (no VBA)

I need to count all of the occurrences of a given value from a specific range of cells (containing strings or numbers), depending on a parameter stored in another cell.
I prepared a simple Excel table as an example (see attached image): let's say I want to count all of the occurrences of the VALUE "4" for the BASE "100". The result should be: 2 (C4 + C5).
Attached image
I tried to use COUNTIFS and FIND functions but with no results. The former only considers exact values (so the 4 in cell C5 will be ignored) while I seem to be unable to add another condition - the BASE column - to the latter.
Fact is I need to solve this with formulas only, no programming.
Thanks in advance for your help!
Use the SUMPRODUCT:
=SUMPRODUCT(($B$2:$B$10=100)*(ISNUMBER(SEARCH(4,$C$2:$C$10))))
There's a couple of other approaches, the simpler one is just to add another column which identifies matches for you, then have your count just sum the results of that column.
Solution image
So we put the values we want to find in some reference cells, the BASE match goes in G2, and the VALUE we're looking for goes in G3.
In column D we put a formula in D2:
"=IF(B2=$G$2,IF(ISERR(SEARCH($G$3,C2)),0,1),0)"
Returns 0 if the BASE matches and we can find at least one occurent of VALUE
B2=$G$2 - Does the BASE column match the BASE we're looking for
ISERR(SEARCH($G$3,C2)) - Does searching for the VALUE return an error (if it does, we know that VALUE isn't there)
Copy this formula to all the cells in column D, and then you can just use a simple SUM(D:D) to count the occurences where your conditions are met.
The neater but slightly more complex alternative is to use an array formula to do the match finding and counting all in one formula. This would look like this:
"{=SUM(IF(B:B=$G$2,IF(ISERR(SEARCH($G$3,C:C)),0,1)))}"
Pretty much the same as the formulas in column D, but now we use B:B and C:C in place of B2 / C2 etc. and stick the SUM around the whole thing. If you finish editing with Ctrl+Shift+Enter instead of just Enter, that'll make it an array formula.
Microsoft Array Formula Guidelines
NB: this WILL NOT count multiple occurences of 4 in a single VALUE cell.
p.s. Assuming you would want it to actually return 3 in this case (you missed the 4 in C7)

Excel: Countifs "Not equal to"

I'm having trouble writing a Countifs to accomplish what I want. I run a claims report every month with tons of data organized in columns and export it to excel every month. On a separate tab I have formulas that reference the tab that this data is copied to.
The formulas are used to count and organize the claims according to certain criteria. One of the columns (G:G) is "State of Jurisdiction".
The state of jurisdiction for each claim is important because certain groups of "special states" get charged a unique rate, and the "non special states" get charged a flat rate.
I've figured out how to count the "special states" without issue. my problem is counting the "non special states". I need to be able to write a countifs that references a range, for example, 010:U10, and count everything in column G EXCEPT what's stored in range O10:U10. I need 010:U10 to be able to have blank cells for expansion. Let me know if any additional information is necessary.
This could be done with Array Formulas in a single cell, but as you seem less comfortable with Excel, then I would recommend that you use some helper columns.
So instead of just reading directly from row 10 in O->U and trying to search all of them within your COUNTIFS formula, add a new row column to your data. This new column will indicate solely whether the jurisdiction in column G is a special state. So for example, assuming that $O$10:$U$10 has a list of all special states [I'm not clear on what sheet everything is on here, so you may need to adjust]. In H2 and copied down for all of your data entries, put the following [This assumes your data starts on G2]:
=IF(ISERROR(MATCH(G2,$O$10:$U$10,0)),"Non-Special State","Special State")
This says: try to MATCH the jurisdiction name from G2, out of the list of all special states in row 10. If there's no match, that means that it's not a special state, and MATCH will return an error. ISERROR will then return TRUE, which will make the IF statement give the result "Non-Special State". If MATCH finds a result, however, it will return "Special State".
Then, in your countifs formula, add this criteria:
=COUNTIFS(SUM COLUMN, OTHER CRITERIA COLUMN, OTHER CRITERIA, H:H, "Non-Special State")
The way to do exactly what you're asking for, though I'd advice against it, would be something like
=COUNT(A2:A21)-COUNTIF(A2:A21,C1)-COUNTIF(A2:A21,C2)
So on for each cell you want to include, long and tiresome.
But as you say you can count the special, just do "total" minus "special total"
Any formula that single-handedly performs this will be using cyclic calculation (with or without Ctrl+Shift+Enter or CSE) so you are going to want to cut the range of cells in column G down to what is absolutely necessary. Full column references will result in many blank cells being calculated that do not have to be.
As a standard non-CSE formula with full column reference with G:G,
=SUM(INDEX(SIGN(LEN(G:G))*ISERROR(MATCH(G:G, O10:U10, 0)), , ))
With dynamic range references,
=SUM(INDEX(SIGN(LEN(G2:INDEX(G:G, MATCH("zzz", G:G ))))*ISERROR(MATCH(G2:INDEX(G:G, MATCH("zzz", G:G)), O10:U10, 0)), , ))
      
The formula assumes that column G contains text, not numbers.

One to many relationship to fetch values in an alternate rows

I am trying to fetch dates from sheet1 with common ID (there are multiple occurrences in sheet1) using an array formula in a cell (then dragging it to the right side to have all the dates belong to specific ID):
=IF(COLUMNS($E2:E2)<=$D2,INDEX(Sheet1!$B$2:$B$13,SMALL(IF(Sheet1!$A$2:$A$13=Sheet2!$A2,
ROW(Sheet1!$A$2:$A$13)-ROW(Sheet1!$A$2)+1),COLUMNS($E2:E2))),"")
But, whenever I try to insert one column (for counting purposes) in b/w the columns, this formula doesn't work. I can't figure out the issue, would really appreciate the help?
Thank you.
Assuming that your first formula is in E2, and that the cells in row 2 of any newly-inserted columns will always be blank, replace the two instances of:
COLUMNS($E2:E2)
in your formula in E2 with:
COUNT(1/LEN($D2:D2))
As a way of explanation, take the formula in F2, for which this part will be:
COUNT(1/LEN($D2:E2))
(The only part having changed naturally being the end range reference.)
And let's assume that 3 new columns are inserted to the left of column E, which means that E2, F2 and G2 will now be blank, H2 will contain the entry which was previously in E2, and, for the formula in I2, the above part will now be:
COUNT(1/LEN($D2:H2))
Clearly we wish this part to continue to give 2, since this cell should still represent the second of our returns.
Using LEN is a rigorous way to determine whether a cell is empty or not. Other functions are also available for this purpose, though may give incorrect results depending upon whether the blanks in that range are "genuine" blanks or the null string "" as a result of formulas in those cells.
If a cell is empty, it has a length of 0. Hence, in this example, the above resolves to:
COUNT(1/{1,0,0,0,2})
(Where I've made some random assumptions about the lengths of the strings in cells D2 and H2.)
There are many ways to determine how many non-zeroes there are in an array. SUMPRODUCT would be one; I chose another, the logic being that the above becomes, after reciprocation with unity:
COUNT({1,#DIV/0!,#DIV/0!,#DIV/0!,0.5})
and, since COUNT ignores any errors in the range passed to it, the above resolves to 2, as desired.
Regards

search multiple columns for a value and concatenate the address of the cells

I have been breaking my head over this formula for sometime now. I have found a solution which is too big and not so convenient to use every time. So can any Excel Expert give me a solution/suggestion?
Column A contains 150 values. Column D to R contains a table in which I need to look up the values in A one by one. I want to return address of all the cells that contains the value.
For example, Value in A2 is present in cells D5, E15, H10, R3 then my result should be D5,E15,H10,R13.
Please Note that some columns may not contain the value of A2, I do not want them displayed.
Here is the formula I have written:
=CONCATENATE(
IF(A2=IF(COUNTIF(D:D,A2),VLOOKUP(A2,D:D,1,FALSE),""),ADDRESS(MATCH(A2,D:D,0),4,4),0),",",
IF(A2=IF(COUNTIF(E:E,A2),VLOOKUP(A2,E:E,1,FALSE),""),ADDRESS(MATCH(A2,E:E,0),5,4),0),",",
IF(A2=IF(COUNTIF(F:F,A2),VLOOKUP(A2,F:F,1,FALSE),""),ADDRESS(MATCH(A2,F:F,0),6,4),0),",",
IF(A2=IF(COUNTIF(G:G,A2),VLOOKUP(A2,G:G,1,FALSE),""),ADDRESS(MATCH(A2,G:G,0),7,4),0),",",
IF(A2=IF(COUNTIF(H:H,A2),VLOOKUP(A2,H:H,1,FALSE),""),ADDRESS(MATCH(A2,H:H,0),8,4),0),",",
IF(A2=IF(COUNTIF(I:I,A2),VLOOKUP(A2,I:I,1,FALSE),""),ADDRESS(MATCH(A2,I:I,0),9,4),0),",",
IF(A2=IF(COUNTIF(J:J,A2),VLOOKUP(A2,J:J,1,FALSE),""),ADDRESS(MATCH(A2,J:J,0),10,4),0),",",
IF(A2=IF(COUNTIF(K:K,A2),VLOOKUP(A2,K:K,1,FALSE),""),ADDRESS(MATCH(A2,K:K,0),11,4),0),",",
IF(A2=IF(COUNTIF(L:L,A2),VLOOKUP(A2,L:L,1,FALSE),""),ADDRESS(MATCH(A2,L:L,0),12,4),0),",",
IF(A2=IF(COUNTIF(M:M,A2),VLOOKUP(A2,M:M,1,FALSE),""),ADDRESS(MATCH(A2,M:M,0),13,4),0),",",
IF(A2=IF(COUNTIF(N:N,A2),VLOOKUP(A2,N:N,1,FALSE),""),ADDRESS(MATCH(A2,N:N,0),14,4),0),",",
IF(A2=IF(COUNTIF(O:O,A2),VLOOKUP(A2,O:O,1,FALSE),""),ADDRESS(MATCH(A2,O:O,0),15,4),0),",",
IF(A2=IF(COUNTIF(P:P,A2),VLOOKUP(A2,P:P,1,FALSE),""),ADDRESS(MATCH(A2,P:P,0),16,4),0),",",
IF(A2=IF(COUNTIF(Q:Q,A2),VLOOKUP(A2,Q:Q,1,FALSE),""),ADDRESS(MATCH(A2,Q:Q,0),17,4),0),",",
IF(A2=IF(COUNTIF(R:R,A2),VLOOKUP(A2,R:R,1,FALSE),""),ADDRESS(MATCH(A2,R:R,0),18,4),0))
As I said, this works but I am looking for a simpler and smaller formula.
Hint: Maybe using array can help?
Thanks in advance :)
What you are trying to accomplish is not a great fit for Excel formulas, but it can be done with a smaller, simpler formula dragged across 15 columns instead of 1 giant complicated formula that tries to do everything at once.
Assuming column A has 150 values (from A1 to A150), and there is a table going from D1 to R50...
Enter =S1&IFERROR(","&ADDRESS(MATCH($A1,D$1:D$50,0),COLUMN(D1)),"") into T1.
Drag the formula across to AH1.
Enter =RIGHT(AH1,LEN(AH1)-1) into AI1.
Select T1 to AI150 and press Ctrl-D.
Column AI1 will contain the results you are looking for.
How does this work?
The formula in T1 begins by taking the result of one cell to the left (which is blank). Then it concatenates this with the address of the first match in column D (prefixed by a comma). If there is no match, it just concatenates blank (""). As you drag this formula to the right, it keeps concatenating addresses as matches come up (or blank if there are none). When you get to the end, you will have looked for matches in all 15 column of your table.
The formula in AI1 just strips off the initial comma if there is one.

Resources