I have in a cell two numbers "=5+4" as a text. This is a result of another operation.
I took a part of another formula and concatenated it with "equal" symbol:
= "=" & RIGHT(FORMULATEXT(V8);LEN(FORMULATEXT(V8))-SEARCH("+"; FORMULATEXT(V8)))
I want to get the result of 5+4 in a cell- which means "9" ;)
I DO NOT WANT TO USE VBA code.
my initial problem was to extract all numbers except the first one from an equation and sum in another cell: A1: "=6+5+4". A2: "9". Maybe it can be solved without VBA?
You could try (assuming only addition):
Formula in B1:
=SUM(FILTERXML("<t><s>"&SUBSTITUTE(MID(A1,2,LEN(A1)),"+","</s><s>")&"</s></t>","//s[position()>1]"))
In fact, if you don't want to use the 1st number we could also discard taking '=' into account:
=SUM(FILTERXML("<t><s>"&SUBSTITUTE(A1,"+","</s><s>")&"</s></t>","//s[position()>1]"))
And since SUM() will ignore text in the final answer, we can now even further simplify this (thanks #JosWoolley):
=SUM(FILTERXML("<t><s>"&SUBSTITUTE(A1,"+","</s><s>")&"</s></t>","//s"))
If you are always adding 2 numbers, then you can use this:
=VALUE(VALUE(MID(A1;2;SEARCH("+";A1)-2))+VALUE(MID(A1;SEARCH("+";A1)+1;9999)))
My column A is formatted as text, and all values follow same pattern: =Value1+Value2
So the formula extracts Value1 and Value2 as text with MID functions, based on the position of + symbol. Then Excel convert both values into numeric with VALUE function. Notice there are 3 values, the third one is to make sure the cell stays at standar format (in some versions of Excel, like mine 2007, when involving text formatted cells into formulas, the formulated cell autoformat itself to text format, making the formula to work just once).
As you can see in the image, it works perfectly but this is just for pattern =Value1+Value2. For different patters you'll need different formulas.
If you want to make a formula to work with all patterns, then indeed you need VBA.
Related
I am trying to come up with a excel formula to Look Up every word separated by either a space or comma in a cell, match each of the words against a list of words and return the found word in another column.
As an example:
So the ColorFamily column should be a formula
I have tried using VLOOKUP e.g.
=VLOOKUP(H3,color_family!$A$3:$A$19,1,FALSE)
But the limitation is that it does not iterate through every single word in the cell. Is it possible to do this using Excel Formula or is VBA required?
Enter as an array formula (ctrl+shift+enter):
=TEXTJOIN(" ",TRUE,IF(ISERR(FIND(color_family!$A$3:$A$19,H3)),"",color_family!$A$3:$A$19))
I couldn't make much sense of the accepted answer but here is a similar approach. This works in Excel 365, and depends on its dynamic array functionality to work.
Here is the spreadsheet layout I am working with:
I have used spaces to separate the values in the colour list but the solution could be generalised to handle commas etc.
The steps I've used to build the formula needed are:
Group valid list into a single string using TEXTJOIN: TEXTJOIN(",",TRUE,$A$7:$A$9)
Split the Colour cells into columns of words (uses dynamic array functionality). There is a write up on how to do this here: https://www.mrexcel.com/board/excel-articles/split-text-cell-into-columns-of-words.19/ e.g. for A2 this formula produces Black and Red in separate columns
TRIM(MID(SUBSTITUTE(A2," ",REPT(" ",LEN(A2))),SEQUENCE(1,LEN(A2)-LEN(SUBSTITUTE(A2," ",""))+1,1,LEN(A2)),LEN(A2)))
Use FIND to look for the text in each column above, in the valid list
If FIND returns a number (checking with ISNUMBER) return the text, otherwise ""
This is all still in separate columns so now use TEXTJOIN to combine the results together in a comma separated list.
Final formula in B2:
`=TEXTJOIN(",",TRUE,IF(ISNUMBER(FIND(TRIM(MID(SUBSTITUTE(A2," ",REPT(" ",LEN(A2))),SEQUENCE(1,LEN(A2)-LEN(SUBSTITUTE(A2," ",""))+1,1,LEN(A2)),LEN(A2))),TEXTJOIN(",",TRUE,$A$7:$A$9))),TRIM(MID(SUBSTITUTE(A2," ",REPT(" ",LEN(A2))),SEQUENCE(1,LEN(A2)-LEN(SUBSTITUTE(A2," ",""))+1,1,LEN(A2)),LEN(A2))),""))`
which can be copied into B3, B4 etc giving final result:
I'm trying to find a way to get the max number of characters after the decimal place in a given column. For example
I found this to get the max length in a column (using ctrl+shift+enter):
=MAX(LEN(A1:A5))
And this formula to get the number of characters after the decimal for a single cell:
=LEN(A1)-FIND(".",A1)
But I need to combine the two into a single formula so that I don't need another column of data. Is this possible without VBA?
Edit, one example I might encounter would be 99.999 vs 100.12 that I'd need to differentiate between and result in a length of 3 characters after the decimal.
If any of your data is the result of formulas, you may have some surprising results and need to use VBA. Otherwise, so long as the format is General, you can use
=MAX(LEN(A1:A5)-FIND(".",A1:A5&"."),0)
confirmed by holding down ctrl+shift while hitting enter
You can use Array Formulas in conjunction with some of your original suggestions to accomplish this. The formula in the example you provided would be:
{=MAX(IFERROR(LEN(B1:B3)-FIND(".",B1:B3),0))}
Some notes:
The "IFERROR" function is used to return a 0 to the MAX function if the "." is not found in the string
Array formulas can be entered into excel by entering the text "=MAX(IFERROR(LEN(B1:B3)-FIND(".",B1:B3),0))" into the formula bar and pressing ctrl+shift+enter (at which point the curly brackets will appear)
Applying this formula should yeild the following results for your sample inputs:
Sample Results
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.
I have a column of codes and I specifically want to extract ANY of these codes with Excel's IF function.
I wrote this code and it did not work: =IF(OR(O2={"6122";"6124";"6200";"6197"});1;0)
How can I use the IF function or other function to pick out any of the above codes?
EDIT: the code itself works but it does not return 1 when it hits any of the specified codes.
Check the value in cell O2. If it is text, then your formula will work. If the value in cell O2 is a number like 6122, then your formula will not work, since it is explicitly looking for a text value of "6122" and the other text values.
Data type matters. The text "6122" is not the same as the numeric value 6122.
You can alleviate the issue by coercing the value in O2 to a number and forcing a numeric comparison with
=IF(OR(O2+0={6122,6124,6200,6197}),1,0)
(if your regional settings use the semicolon ; as a list separator, please replace the commas in the above formula with semicolons)
This will work if O2 is either text or numeric. The values to compare with are numbers.
So, determine what data type is stored in cell O2 and make sure that you compare it with a suitable data type in your formula.
I've got a whole bunch of cells containing arbitrary length arrays stored as semicolon-delimited strings, ranging in length from 1 to 65 entries, like:
pcmsh15(232);pcmsh16(232);pcmsh17(136);
pcmsh12(40);
pcmsh12(40);
pcmsh12(5);pcmsh15(20);
I want a way to sum up the numbers in the parenthesis in Excel 2010 without using VBA, keeping in mind that they are arbitrary length strings, each contained in their own cell.
I've currently got a VBA function that I wrote that sums the numbers in parenthesis, but it's slowing my spreadsheet down. I know I can use Excel's SUBSTITUTE function to turn the semi-colon delimited arrays into something resembling Excel's internal array format, like
="{"&SUBSTITUTE([#[data]],";",",")&"}"
But unfortunately, Excel won't parse that as an array in SUM or COUNTIF, only as a string. One workaround I found makes a named range that references the cell with a string-formatted array, but since I also have an arbitrary number of these arrays in cells, I can't go naming every single cell.
Is something like this possible in "pure" excel functions?
You can actually do this with no VBA involved. The method is kind of ridiculous, though. But, just for fun...
In cell B4 I put one of the strings you want to "parse":
B4: pcmsh15(232);pcmsh16(232);pcmsh17(136);
Then I put the following formulas in the cells indicated:
B6: =SUBSTITUTE(B4,"pcmsh", """dummy")
B8: =SUBSTITUTE(B6,"(",""";")
B10: =SUBSTITUTE(B8,")","")
B12: =MID(B10, 1, LEN(B10)-1)
B14: ="{"&B12&"}"
That transforms the starting text into a text representation of a legal Excel array:
B14: {"dummy15";232;"dummy16";232;"dummy17";136}
You can make Excel evaluate that string and return an actual array with the following trick. Create a named formula that we'll call eval_left. Make sure cell C14 is selected when you create the named formula:
=EVALUATE(B14)
Note that the formula uses a relative reference, so if you use that name from a cell other than C14, you'll see that the B14 has changed to whatever cell is just to the left.
This uses the old Excel 4 macro function EVALUATE, which takes a string and returns the value that that string represents. Now we can put a final formula in cell C14:
C14: =SUM(eval_left)
Since SUM ignores non-numeric strings, you get the answer you want, with no VBA. (You do still get the macro warning though, because of the use of EVALUATE.)
Like I said, I consider this a just-for-fun curiousity. You're way better off using VBA for stuff like this.
EDIT:
In the unlikely event you wanted to actually do something like this, you'd run into the length limit of what EVALUATE can handle. You'd have to chop up your longer strings into less than 65 values, not use "dummy", etc., but it would still be doable.