Get multiple substrings from cell by separator - excel

I have multiple values in one cell that are ordered like this:
0#0#54232#5#123# ...
Now I want to put every single value in a separate cell. I tried working with SEARCH, FIND, LEFT, MID functions and so on, but everthing looks so fiddly and I can't get it to work. My idea was to look for every # in the text and get every substring in between. But with 20+ values in a single cell this gets very confusing by the end.
EDIT: The lengths of the values can vary

You can use FILTERXML to split the string (this solution will work on Office 365, since dynamic arrays need to be available):
=FILTERXML("<t><s>"&SUBSTITUTE(A1;"#";"</s><s>")&"</s></t>";"//s[string-length()>0]")
There has recently been a nice question here on Stackoverflow that I highly recommend to read:
Excel - Extract substring(s) from string using FILTERXML

You can use following formula (also in older excel versions):
=IFERROR(FILTERXML("<t><s>"&SUBSTITUTE($A$1;"#";"</s><s>")&"</s></t>";"//s["&ROW()&"]");"")

I've put your string in cell B3, and in cell C2, I've put following formula:
=LEFT(B3;FIND.SPEC("#";B3)-1)
In cell C3, I've put following formula:
=SUBSTITUTE(B3;C2&"#";"";1)
I've been dragging the whole thing to the right, and row 2 gave me the results you are looking for. (You might need to add some IfBlank() or IfError() but you understand what I mean)

Related

Excel AVERAGEIFS like formula which treats text as 0 and not ignore them

Is there anyway to use AVERAGEIF or a similar function that treats text value as 0 and not just ignore them. Something similar to AVERAGEA function, but with multiple criteria?
I saw a similar question here which wanted to treat blanks or empty cells as 0. The answer suggested to use array formulas to add 0 to it. Not sure if it holds for other texts as well.
If you do NOT want to count blanks, you can use:
=SUM(A1:A10)/COUNTA(A1:A10)
(If you wanted to count blanks, something like sum(rng)/rows(rng) would do it)
You can use a similar technique to include criteria for AVERAGEIF
For example, given:
If you want to average all the values in Column A where a is in Column B:
=SUMIF(B1:B10,"a",A1:A10)/COUNTIF(B1:B10,"a")
It would be similar to the other link:
=AVERAGE(IFERROR(--A1:A10,0))
It is an array formula and with Excel to confirm an array formula one must use Ctrl-Shift-Enter instead of Enter when exiting edit mode.
One Note: This will treat blanks as 0 also, so make sure it only refers to the data set desired.
Similar to Rohan's post, I personally would break it down to see how many strings are pushing down your average. But if you want it all in one cell:
That is an asterisk inside the double quotes
one cell: =SUM(E1:E10)/(COUNTIF(E1:E10,"")+COUNTIF(E1:E10,"<>*"))
break down:
Non-Numeric: COUNTIF(E1:E10,"*****")
Numeric: COUNTIF(E1:E10,"<>*")
spreadsheet link
1

Excel formula - Get first occurrence of partial string in rows above cell

I have a table of fruits in Excel 2013.
I'd like to fill the "Category" column by searching from the current row to the top until the first occurrence of "::", which is the keyword for a category in the table.
If there was some way to reverse a range, I could do something like "=Match("::*"; $A6:$A$2)" to find the row. However, this is not possible.
Does anyone know how this might be accomplished using formulas?
Using your provided sample data, and assuming your data is already organized as shown in your sample, you can take advantage of that organization and use this formula in cell C2 and copy down:
=IF(LEFT(A2,2)="::","",IF(LEFT(A1,2)="::",MID(A1,4,LEN(A1)),C1))
Assuming your table is in A1, put this in C3:
=INDEX(A:A, AGGREGATE (14,6,ROW($A$1:A2)/(LEFT($A$1:A2,2)="::"),1))
And copy down.
Here's a kinda different approach. I'm just basically responding to this part of your post to prove this is possible:
If there was some way to reverse a range, I could do something like "=Match("::*"; $A6:$A$2)" to find the row. However, this is not possible.
Reversing a range is possible, it's just tricky.
As you pointed out: $A6:$A$2 won't work since this is equivalent to $A$2:$A6.
However, without getting into the nitty-gritty details, this array formula will reverse this range:
= INDEX($A$2:$A6,N(IF({1},MAX(ROW($A$2:$A6))-ROW($A$2:$A6)+1)))
Note this is an array formula, so you must press Ctrl+Shift+Enter instead of just Enter after typing this formula into a cell.
You could use this in combination with your MATCH formula to get the desired result (which tells you how many rows up the :: row is):
= MATCH("::*",INDEX($A$2:$A6,N(IF({1},MAX(ROW($A$2:$A6))-ROW($A$2:$A6)+1))),0)
(Also haha this is kinda cool: Usually you see MATCH used within INDEX to effectively get a VLOOKUP type of functionality. This is the first time I have ever seen it the opposite way of having INDEX within MATCH.)
Note that I'm not saying this is necessarily the best approach for this specific problem, just proving a point that arrays can be reversed.

COUNTIFS with greater than TODAY OR blank cell

I have a question regarding COUNTIFS. The simple boiled down version of what I am trying to do is this:
I am trying to use COUNTIFS to count the number of entries that the cell in a column is either blank or in the future (greater than today) and that is marked with an “X” in another column.
There are several other renditions in the formula but if I can get this, I can get the rest. So far, I have this:
=SUM(COUNTIFS($C$2:$C$50,{"";">"&TODAY()},$E$2:$E$50,"X"))
Excel won’t let me return out of the formula and highlights the quotation mark following the greater than symbol.
=SUM(COUNTIFS($C$2:$C$50,{"";">100"},$E$2:$E$50,"X")) works fine when I play around and test things but when I try to add in &TODAY() or reference a cell, things go sideways.
Any suggestions as to what I am doing wrong? The actual formula is quite long and there are several comparisons that are made between columns. I've seen some references to using SUMPRODUCT but haven't been able to figure it out that way either.
You can use a formula to generate the criteria array, i.e.
=SUMPRODUCT(COUNTIFS($C$2:$C$50,IF({1;0},"",">"&TODAY()),$E$2:$E$50,"X"))
I used SUMPRODUCT in this version because with SUM you'd need CTRL+SHIFT+ENTER
The IF function generates an array that resolves to something like this:
{"";">43060"}

Random string from a set of available strings in Excel but exclude specific Cell Value

I'm using Excel 2010. I'm using an INDEX and RANDBETWEEN function to lookup a list of available strings and return one of them. However, I have a specific value, D3, (in this instance but will change with each row D4, D5 etc) that I need to exclude from the random results - what is the best way to achieve this? This is my current formula:
=IFERROR(INDEX($A:$D,MATCH($B3&"|"&LEFT($C3,SEARCH("-",$C3))&L3,$A:$A,0)+RANDBETWEEN(0,S3-1),4),"")
Thanks
Please remove those code parts not relevant to your issue and reduce everything to the problem you actually need to solve. The IFERROR(), MATCH(), LEFT() and SEARCH() calls are not related to your issue but make it hard to understand your code.
To simplify, I assume:
range D1:D199 is filled with (potentially duplicate) strings
each cell in column E1:E199 is supposed to draw a random string from the whole of D1:D199, except those that are identical to the cell on its left (in D)
Copy + paste the following code into E1, then enter it as an array formula with Ctrl+Shift+Enter.
=INDEX(D:D,LARGE(IF((D1:D200<>"")*(D1:D200<>D1),ROW(D1:D200),-1),RANDBETWEEN(1,SUM((D1:D200<>"")*(D1:D200<>D1)))))
You can then copy cell E1 to E2:E199
Updated code with Dirk Reichel's suggestions.

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