Related
I have an Excel database query to get all the RBAC user roles that are assigned to each user, and the database returns a string delimited by & (ampersands) between each user role, e.g.:
&Admin&Supervisor&ViewReports&WriteReports&
My query filters records that only have a matching string, let's say it's Reports. However it still returns the full list of user roles for a matching user, and in this case some users have >10 roles assigned and it makes the table look really messy and not suitable for printing.
I could manually clean up each row, but there are quite a lot of them, and since this is going to be run regularly I'm wondering if there may be a good Excel formula or VBS method to split delimited sections of a string and only keep ones that match a string criteria.
I'm aware of "Text to Columns" and its ability to make use of delimiters, but it just spat out a ton of columns and made things worse. I've done several searches about cleaning up delimited strings in Excel but couldn't find any results that were similar to my situation: need to split a delimited string and do something RegEx-esque to only keep parts that match a pattern.
Ideally I'd like to keep the cleaned up results in a single cell, so the above example &Admin&Supervisor&ViewReports&WriteReports& would look like:
ViewReports WriteReports
or
ViewReports,WriteReports
or similar, in a single cell. Not too picky about formatting really, just need the non-relevant parts of the string gone.
you could use a combination of trim, mid and substitute to find your values so using your example above:
if oyu have a blank excel sheet and ad your example to cell A3 then place 1,2,3 and 4 in cells B2, C2, D2, E2 then use copy this formula into cell B3:
=TRIM(MID(SUBSTITUTE($A3,"&",REPT(" ",LEN($A3))),(B$2-1)*LEN($A3)+1,LEN($A3)))
this should give you the value "Admin".
After that just pull formulas to the right and you will get all 4 values in your example
Please let me know if you need more explanation.
For more info on this equation please see webpage:
https://exceljet.net/formula/split-text-with-delimiter
This formula will work in Excel/Office 365. It won't work in earlier versions due to the TEXTJOIN function which appeared in 2016.
Assumes the data is simple strings as above (i.e. not an XML document that might contain duplicates of the created nodes. If that were the case, there is another method of splitting the string we could use).
Split the string on the ampersand with FILTERXML
Use a variation of the INDEX function to return an array of the matching sections
Concatenate those sections with TEXTJOIN
=TEXTJOIN(" ",TRUE,INDEX(FILTERXML("<t><s>" & SUBSTITUTE(A1,"&","</s><s>")&"</s></t>","//s"),N(IF(1,{3,5}))))
The …N(IF(1,{3,5}))… portion is how to return an array of values from the INDEX functions. In this case, 3 and 5 refer to the value before the third and fifth ampersand. Note that 1 would return an error, since there is nothing before the first ampersand.
You can return whichever elements you want. You just need to know (or calculate using the MATCH function), the proper index number(s).
Note that, with TEXTJOIN you can specify whatever delimiter you want. I specified a space, but you could specify comma or anything.
I am trying to convert text of the month to the number
B2 cell:
BirthMonth_Jan
BirthMonth_Feb
BirthMonth_mar
BirthMonth_Apr
BirthMonth_May
BirthMonth_Jun, ect to december
for example, BirthMonth_Jan will output 1 based on the search of Jan, so i can compare this to another set of numbers
I have this, and tried this, but only works with two if statements, is there anyway i can do this with 12?
=(IF(ISNUMBER(SEARCH("sep",B2)),"9")),(IF(ISNUMBER(SEARCH("aug",B2)),"8")),(IF(ISNUMBER(SEARCH("jul",B2)),"7")),(IF(ISNUMBER(SEARCH("jun",B2)),"6")),(IF(ISNUMBER(SEARCH("may",B2)),"5")),(IF(ISNUMBER(SEARCH("apr",B2)),"4")),(IF(ISNUMBER(SEARCH("mar",B2)),"3")),(IF(ISNUMBER(SEARCH("feb",B2)),"2")),(IF(ISNUMBER(SEARCH("jan",B2)),"1"))
I get #Value!
If i try this, it also doesn't work
=IF(ISNUMBER(SEARCH("dec",B2)),"12",IF(ISNUMBER(SEARCH("nov",B2)),"11")),IF(ISNUMBER(SEARCH("DSH_KnowBe4_BirthMonth_Oc",B2)),"10"))
the second option only works with two but if i add more it throws an error
The questioner is trying to obtain a numeral equivalent to a partial month name extracted from a string. There are any number of examples in stackoverflow and the net generally on this theme. What is special in this case is the partial month name in the target cell, and use of the IF statement. The questioner is right to use search since it is not case-sensitive
Two formula are offered:
Formula 1
=(IF(ISNUMBER(SEARCH("sep",B2)),"9")),(IF(ISNUMBER(SEARCH("aug",B2)),"8")),(IF(ISNUMBER(SEARCH("jul",B2)),"7")),(IF(ISNUMBER(SEARCH("jun",B2)),"6")),(IF(ISNUMBER(SEARCH("may",B2)),"5")),(IF(ISNUMBER(SEARCH("apr",B2)),"4")),(IF(ISNUMBER(SEARCH("mar",B2)),"3")),(IF(ISNUMBER(SEARCH("feb",B2)),"2")),(IF(ISNUMBER(SEARCH("jan",B2)),"1"))
The questioner said "I get #Value!"
This is not a surprise because it is essentially a series of nine, self-contained, unrelated if statements, each separated by a comma. It is an invalid statement.
However, if the if statements were nested, then the formula would work. Something along these lines:
=IF(ISNUMBER(SEARCH("jan",B2)),"1",IF(ISNUMBER(SEARCH("feb",B2)),"2",IF(ISNUMBER(SEARCH("mar",B2)),"3")))
Formula 2
=IF(ISNUMBER(SEARCH("dec",B2)),"12",IF(ISNUMBER(SEARCH("nov",B2)),"11")),IF(ISNUMBER(SEARCH("DSH_KnowBe4_BirthMonth_Oc",B2)),"10"))
So close and yet so far... This statement uses the nested approach mentioned above. There is a major typo for the October search (instead of searching for "oct", the formula searches for "DSH_KnowBe4_BirthMonth_Oc") though this doesn't cause the formula to fail.
Failure is caused by two things:
1) The double bracket following "11")) in the "November" search. There should be zero brackets here.
2) The formula needs an additional closing bracket.
Two other things to note:
1) in the event of a match, the value returned is a string not an integer.
2) there's no provision to return a value in the event of a failure to match.
Working IF statement formula
The following formula, consisting of nested IF statements, works as intended by the questioner.
=IF(ISNUMBER(SEARCH("jan",B2)),"1",IF(ISNUMBER(SEARCH("feb",B2)),"2",IF(ISNUMBER(SEARCH("mar",B2)),"3",IF(ISNUMBER(SEARCH("apr",B2)),"4",IF(ISNUMBER(SEARCH("may",B2)),"5",IF(ISNUMBER(SEARCH("jun",B2)),"6",IF(ISNUMBER(SEARCH("jul",B2)),"7",IF(ISNUMBER(SEARCH("aug",B2)),"8",IF(ISNUMBER(SEARCH("sep",B2)),"9",IF(ISNUMBER(SEARCH("oct",B2)),"10",IF(ISNUMBER(SEARCH("nov",B2)),"11",IF(ISNUMBER(SEARCH("dec",B2)),"12",NA()))))))))))))
Note, the formula uses the NA() function to return #N/A if there is no match.
VLOOKUP alternative
Though the above-mentioned formula works, I find it complicated and inflexible. My preference in situations like this is VLOOKUP. My equivalent formula would be:
=VLOOKUP(RIGHT(B2,LEN(B2)-SEARCH("_",B2)),Sheet2!$A$2:$B$13,2,FALSE)
Using January as an example: BirthMonth_Jan, the formula lookup works like this:
RIGHT(B2,LEN(B2)-SEARCH("_",B2))
1) search for the underline character SEARCH("_",B2),
2) deduct the result from the total length LEN(B2)-SEARCH("_",B2) to give the number of characters to the right of the underline.
3) get all the characters to the right of the underline RIGHT(B2,LEN(B2)-SEARCH("_",B2)). This is the lookup value
4) Create a reference table on another sheet (refer screenshot); lookup this table and return column 2 (the number for that month).
5) If there is no valid result, VLOOKUP automatically returns #N/A.
The reference table on a separate sheet:
Not sure what you are trying to do with the formula but if your "BirthMonth_" text is consistent, you can use :
=MONTH(DATEVALUE("1 "&SUBSTITUTE(A12,"BirthMonth_","")&" 2018"))
Having a view of your data and expected result would help if this is not what you're after.
It is seems just possible what you might want is:
=MONTH(MID(B2,SEARCH("BirthMonth_",B2)+11,3)&0)
Returns a Number.
I'm trying to tweak this piece of code I found in a sample spreadsheet online but I can't quite get my head around it.
The original spreadsheet basically does an INDEX/MATCH based on a user-defined lookup and lists the matches neatly in a concatenated list. The sample spreadsheet's output looks like this:
http://i.stack.imgur.com/DyahB.png - Sample Excel Output (Note how there are no gaps between the first and second matches)
The underlying algorithm is:
=IF(ISERROR(INDEX($A$1:$B$8,SMALL(IF($A$1:$A$8=$E$1,ROW($A$1:$A$8)),ROW(1:1)),2)),"",INDEX($A$1:$B$8,SMALL(IF($A$1:$A$8=$E$1,ROW($A$1:$A$8)),ROW(1:1)),2))
Now, I want the lookup to instead retrieve PARTIAL matches, and in addition, generate the outputs horizontally like so:
http://i.stack.imgur.com/ShED0.png - Output is generated horizontally based on partial matches
I'm not sure how I would go about doing this. It seems like I would somehow try and change the IF condition to return true on partial matches but I can't get my head around it. Please help!
Assuming by "partial match" you mean text that starts with the value in L1 then use this formula in N1
=IFERROR(INDEX($I$2:$I$8,SMALL(IF(LEFT($H$2:$H$8,LEN($L$1))=$L$1,ROW($I$2:$I$8)-ROW($I$2)+1),COLUMNS($N1:N1))),"")
confirm with CTRL+SHIFT+ENTER
and copy across
For a match anywhere in the text you can use this version
=IFERROR(INDEX($I$2:$I$8,SMALL(IF(ISNUMBER(SEARCH($L$1,$H$2:$H$8)),ROW($I$2:$I$8)-ROW($I$2)+1),COLUMNS($N1:N1))),"")
Neither formula is case-sensitive, although you can easily make the latter so by changing SEARCH to FIND
Use of IFERROR function means you don't need repetition for error handling - needs Excel 2007 or later version
Building on Barry's code a little, I needed to make a few tweaks for my own use (current project I have at work).
Tweaks I made:
Returning the cell that matches my search criteria in my index
Making the cell draggable in two dimensions so I could index multiple columns for specific information
Making the "nth" counter vertical instead of horizontal (as my application is a database of sorts, and each column is a separate entry. At the top of each column is 5 rows populated based on the search term [in my case, the store number])
The final result is:
=IFERROR(INDEX(A$8:A$295,SMALL(IF(ISNUMBER(SEARCH('Store History'!$F$2,A$8:A$295)),ROW(A$8:A$295)-ROW(A$8)+1),ROWS(A$2:A2))),"")
It is worth repeating that this is an array formula and needs to be entered using CTRL+SHIFT+ENTER
This is placed in cell A2 and is dragged both vertically and horizontally (horizontally in my case is ever expanding as I add more entries into my database).
My purpose for adding this comment (even though it is a long inactive thread) is to try and make this a more relevant search result on Google for "excel index match partial strings with multiple results" or variations of that. It took me hours of searching to find this solution, and it is extremely functional and elegant. My thanks to the OP and especially to Barry for his code!!
I would like to create a succinct Excel formula that SUMS a column based on a set of AND conditions, plus a set of OR conditions.
My Excel table contains the following data and I used defined names for the columns.
Quote_Value (Worksheet!$A:$A) holds an accounting value.
Days_To_Close (Worksheet!$B:$B) contains a formula that results in a number.
Salesman (Worksheet!$C:$C) contains text and is a name.
Quote_Month (Worksheet!$D:$D) contains a formula (=TEXT(Worksheet!$E:$E,"mmm-yy"))to convert a date/time number from another column into a text based month reference.
I want to SUM Quote_Value if Salesman equals JBloggs and Days_To_Close is equal to or less than 90 and Quote_Month is equal to one of the following (Oct-13, Nov-13, or Dec-13).
At the moment, I've got this to work but it includes a lot of repetition, which I don't think I need.
=SUM(SUMIFS(Quote_Value,Salesman,"=JBloggs",Days_To_Close,"<=90",Quote_Month,"=Oct-13")+SUMIFS(Quote_Value,Salesman,"=JBloggs",Days_To_Close,"<=90",Quote_Month,"=Nov-13")+SUMIFS(Quote_Value,Salesman,"=JBloggs",Days_To_Close,"<=90",Quote_Month,"=Dec-13"))
What I'd like to do is something more like the following but I can't work out the correct syntax:
=SUMIFS(Quote_Value,Salesman,"=JBloggs",Days_To_Close,"<=90",Quote_Month,OR(Quote_Month="Oct-13",Quote_Month="Nov-13",Quote_Month="Dec-13"))
That formula doesn't error, it just returns a 0 value. Yet if I manually examine the data, that's not correct. I even tried using TRIM(Quote_Month) to make sure that spaces hadn't crept into the data but the fact that my extended SUM formula works indicates that the data is OK and that it's a syntax issue. Can anybody steer me in the right direction?
You can use SUMIFS like this
=SUM(SUMIFS(Quote_Value,Salesman,"JBloggs",Days_To_Close,"<=90",Quote_Month,{"Oct-13","Nov-13","Dec-13"}))
The SUMIFS function will return an "array" of 3 values (one total each for "Oct-13", "Nov-13" and "Dec-13"), so you need SUM to sum that array and give you the final result.
Be careful with this syntax, you can only have at most two criteria within the formula with "OR" conditions...and if there are two then in one you must separate the criteria with commas, in the other with semi-colons.
If you need more you might use SUMPRODUCT with MATCH, e.g. in your case
=SUMPRODUCT(Quote_Value,(Salesman="JBloggs")*(Days_To_Close<=90)*ISNUMBER(MATCH(Quote_Month,{"Oct-13","Nov-13","Dec-13"},0)))
In that version you can add any number of "OR" criteria using ISNUMBER/MATCH
You can use DSUM, which will be more flexible. Like if you want to change the name of Salesman or the Quote Month, you need not change the formula, but only some criteria cells. Please see the link below for details...Even the criteria can be formula to copied from other sheets
http://office.microsoft.com/en-us/excel-help/dsum-function-HP010342460.aspx?CTT=1
You might consider referencing the actual date/time in the source column for Quote_Month, then you could transform your OR into a couple of ANDs, something like (assuing the date's in something I've chosen to call Quote_Date)
=SUMIFS(Quote_Value,"<=90",Quote_Date,">="&DATE(2013,11,1),Quote_Date,"<="&DATE(2013,12,31),Salesman,"=JBloggs",Days_To_Close)
(I moved the interesting conditions to the front).
This approach works here because that "OR" condition is actually specifying a date range - it might not work in other cases.
Quote_Month (Worksheet!$D:$D) contains a formula (=TEXT(Worksheet!$E:$E,"mmm-yy"))to convert a date/time number from another column into a text based month reference.
You can use OR by adding + in Sumproduct. See this
=SUMPRODUCT((Quote_Value)*(Salesman="JBloggs")*(Days_To_Close<=90)*((Quote_Month="Cond1")+(Quote_Month="Cond2")+(Quote_Month="Cond3")))
ScreenShot
Speed
SUMPRODUCT is faster than SUM arrays, i.e. having {} arrays in the SUM function. SUMIFS is 30% faster than SUMPRODUCT.
{SUM(SUMIFS({}))} vs SUMPRODUCT(SUMIFS({})) both works fine, but SUMPRODUCT feels a bit easier to write without the CTRL-SHIFT-ENTER to create the {}.
Preference
I personally prefer writing SUMPRODUCT(--(ISNUMBER(MATCH(...)))) over SUMPRODUCT(SUMIFS({})) for multiple criteria.
However, if you have a drop-down menu where you want to select specific characteristics or all, SUMPRODUCT(SUMIFS()), is the only way to go. (as for selecting "all", the value should enter in "<>" + "Whatever word you want as long as it's not part of the specific characteristics".
In order to get the formula to work place the cursor inside the formula and press ctr+shift+enter and then it will work!
With the following, it is easy to link the Cell address...
=SUM(SUMIFS(FAGLL03!$I$4:$I$1048576,FAGLL03!$A$4:$A$1048576,">="&INDIRECT("A"&ROW()),FAGLL03!$A$4:$A$1048576,"<="&INDIRECT("B"&ROW()),FAGLL03!$Q$4:$Q$1048576,E$2))
Can use address / substitute / Column functions as required to use Cell addresses in full DYNAMIC.
I am using excel to look through my data, I have a matrix of 2000 columns and thousands of rows.
I want to search for some string in a specific column. I've been reading online and the Match() function is usually used for this. I am not sure of 2 things actually:
1-how to formulate the command since I have my columns as R1C1 reference style? (I mean I have numbers instead of letters as columns names)
2- I don't know how many rows I have, I just want the function to search the entire column for this string.
Here's the command I found, which doesn't solve any of the 2 problems mentioned above
=MATCH("string",A1:A100, 0)
Thanks,
Here's a simple one:
=MATCH("string",A:A,0)
However, the preferred technique is to usually create a named reference. Then you can just use the name of the range that you want to search in your MATCH() formula. Named ranges are usually easier to work with in larger projects (or projects that start small but where you want to keep some flexibility in case the workbook gets larger).
Edit: If you want to stick to R1C1, the formula might look like this instead: =MATCH("string",C1,0)