efficiently testing long boolean expressions in Excel - excel

Ok, lets say that I have two cells in Excel. They each contain a number. I realize that to compare the values of the numbers in these two cells, I can use a simple =[cell1]=[cell2] function. And I also realize that if I want to find the negation of a certain boolean value, I can use the =not function.
My question is simple, is there a more efficient way of coding long boolean formulas? I know in Java I could do something along the lines of ((!(cell1)&&(!(cell2)))||cell3. But in Excel that simple expression turns into something along the lines of =or(and(not(cell1),(notcell2)),cell3). Personally I like the shorter, more compact style of the java code.
Is there a short way to write boolean statements like this in Excel? Or am I doomed to use Excels clunky functions for the simplest of comparisons?
Also, this is a hypothetical question. I am just trying to figure out how to reduce the size of some of my longer boolean expressions. I don't have a specific error, just a lot of frustratingly long formulas.

Well in that case
AND(Not(cell1),NOT(cell2))
Can be replaced by:
=NOT(OR(cell1;cell2))
And, as in most of the cases you can replace AND by * and OR by + all the expression can be written like this:
NOT(cell1+cell2)+cell3

Related

Evaluate long string (>255 characters) as array

So I quite often find myself doing tasks on Excel which involve evaluating a text string as an array. Generally speaking I just use this:
Function EVAL(Ref As String)
EVAL = Evaluate(Ref)
End Function
So the formula will be, for example:
=EVAL("{"&CHAR(34)&SUBSTITUTE(TEXTJOIN(";",TRUE,MID(Index[Industries],2,LEN(Index[Industries])-2)),";",CHAR(34)&";"&CHAR(34))&CHAR(34)&"}")
The cells in this example will have contents like:
;Automotive;Rail;Energy;
;Automotive;Rail;
;Energy;
;Automotive;Aerospace;
(As it happens this is the precise problem I'm stuck on right now, though it has come up in different ways in the past.)
This has worked for me in the past, but I've been running into difficulties lately.
I have come to the conclusion it isn't working because application.evaluate, it turns out, has a character limit of 255. I've seen examples of VBA tricks to bypass this for text strings that are formulas rather than arrays, but copy-pasting those they don't seem to work for when I'm using it to interpret a text string as an array rather than as a formula.
Is there some trick to get this to work? (Or, indeed, is there some alternative method to achieve this altogether?)
Right, as per my comments, if you are using ms365, you could avoid your workbook to be xlsm just because you need to split values into an array. Make use of what is available with native functions, for example:
Formula in C2:
=TEXTSPLIT(CONCAT(A1:A4),,";",1)
Formula in D2:
=FILTERXML("<t><s>"&SUBSTITUTE(CONCAT(A1:A4),";","</s><s>")&"</s></t>","//s[node()]")
Note 1: As per time of writing you'd need to enable the BETA-channel to gain access to TEXTSPLIT(), and if I recall correctly your version (2203) is allowed to start using this function. Just google how to get access and update your Excel.
Both options can obviously be nested inside the UNIQUE() function.
Note 2: If at any point CONCAT()'s limits are reached (32767 characters, thanks #ScottCraner), maybe you can avoid using that with help of the lambda's helper function REDUCE():
=TEXTSPLIT(REDUCE("",A1:A4,LAMBDA(a,b,a&b)),,";",1)
Note 3: In case you can't update your Excel just yet, and you wonder how to use FILTERXML(), don't mind me refering you to another post I wrote a while back here.

Excel concatenation logical conditions in IF statement

How do I concatenate several conditions in Excel in the IF statement? I want to compare values in 2 different columns but mith more than 1 condition!. IF (condition 1,condition2 ; truevalue;) i dont know the sintaxis for this!
If you use purely native worksheet functions, you have to nest your if statements. It's far from ideal:
=if(condition1,X,if(condition2,Y,if(condition3,Z,A)))
Is like saying:
if (condition1) then X
else if (condition2) then Y
else if (condition3) then Z
else A
You can also define a User Defined Function (UDF) using VBA, but that has some disadvantages associated with it. It adds a lack of transparency for those who don't use VBA. It also makes your workbook a little more "suspicious" since it has embedded macros, which is a turn off for some.
Depending on how complex your conditions are, a UDF still may be the way to go.
Post some real pseudo-code to help identify which side you fall on.

String looping in VBA with similar names

Say I need write code in VBA to match the string "revenues" in a different worksheet that may show a similar string in a column range though not perfectly matching (it may be "total revenues", "rev", "ABC revenues"). What the best strategy to approach the problem?
I'd probably write a VB function that matched the (lower case-cast) strings to a list of fragments, or detected fragments in cell value. While you could also try to use Regex, I doubt that you have consistent enough input to generate a rule that would pick out most examples. You'll probably need a countermeasure to check against false positives as well.
Good Luck!

Renaming CUBEVALUE function to something shorter?

I've been using a rather long embedded CUBEVALUE() function, which is a pain to work with. It looks something like:
=IFERROR(VALUE(CUBEVALUE(arg1;arg2;arg3));CUBEVALUE(arg1;arg2;arg3))
Due to the CUBEVALUE function and its arguments, it's becoming a REALLY long function and thus not easy to work with. Since there are only 3 arguments, which are written in different cells, I'd like to create something like
=MyFunction(A1,A2,A3)
and use A1, A2 and A3 as "arg1, arg2, arg3" in the function mentioned first. This way its possible to "pull" the function so it would calculate using the input in B1:B3 and C1:C3 etc. as well.
The function works fine and can be pulled through and such, but my question is how to rename this loooong function into something more user-friendly, as it requires only 3 cells as an input and the rest of the text in the function just makes it hard to use for end-users.
Using UDF is not an option because CUBEVALUE can't be called through VBA... and any attempt to stich strings together and using the final result with INDIRECT also seems to fail..
In a similar question on this site, someone refers to using "asynchronous UDF's", but no further information was given (and what I could find seemed irrelevant).
You shouldn't really have several long cube functions. Allocate some space in hidden rows/columns or in header rows/columns to add your cubemember functions. Then throughout most of your report, you should just have cubevalue functions that reference other cells with error handling around them. Proper use of absolute and relative references are your friend.
Peter Meyers has some great tips for this here, slides 20 - 24. I have an example Excel file with cube functions on my blog here.

How to evaluate typed-out formulas in Excel

If I type the formula 1/4*pi()*($A$1)^2 as a string in a cell and assuming I have a value in $A$1, I use the following VBA function in a third cell to evaluate the formula:
Public Function E(byval TextFormula as String) as Variant
E = Evaluate(TextFormula)
End Function
Is there a way to use math characters like •, √, ¼, π, ², etc. so that my typed-out formula looks more agreeable? Even translate '[' and ']' as '(' and ')'. I can just iterate through an array replacements using REPLACE() function for the simple characters but what about the extended characters like π?
For the really sharp macro'ers...
What about showing intermediate steps (iterations) as in (2*3) + (2.5*4) evaluates to 6 + 10 in the first iteration and then 16 in the next iteration. Asside: I would want the iterations to stop just before each set of addings/subtractings because I sometimes like to know what the relative magnitudes of the individual evaluated terms are to see what part of my formula is controlling the result.
And for the mega-genius ones...
What about mixed units? Such as typing out 560{lbs}/[1.23{m}*3.4{'}] and getting my result in ###{psf} as an example. I thought that the unit could be delineated by the underscore such as 34_kN but I think a start and end delineation is required for compound units like 34{kN/m^2}. There would need to be a way to force the output to a desired unit (ie. mm instead of in) like maybe setting up your desired units ahead in your sheet and then it would at least try to convert to one of those units. I think at this stage you will be charging me for the code;)
I like using Excel for my engineering calculations because I only use simpler formulas (no calculus!) and I don't want to constantly switch between Excel and Mathcad apps but use only one.
Shawn
Those are tall orders. The following sub might give you an idea for your first question:
Sub test()
Dim R As Range
Set R = Range("A1")
R.Value = "A = pr2"
R.Characters(5, 1).Font.Name = "Symbol"
R.Characters(7, 1).Font.Superscript = True
End Sub
Run it an then look at the contents of A1
As far as your second question goes - sure you can do it, but you would need to write a full-fledged expression parser. Writing one from scratch is fairly involved (at least a couple hundred lines of code) and is probably best done by using classes to create a custom tree data type then writing a recursive descent parser to parse strings into expression trees. Doable, though I have neither the time nor the inclination to do so.
I'm not quite sure what you are driving at with your last question, though my gut reaction is that it is easier than your second question since no real parsing is required and it is easy enough to create a dictionary of conversion factors.

Resources