4

I've had a glance around on the site, but advice on making Excel formulae (formulas?) more readable tends to be directed towards 'use named ranges' or 'use helper columns'. I'm not after techniques to make formulae easier to read, I'd like to create a macro to display the formulae in a more readable manner. You can skip to the end for a shortened problem description. I say this because although usually I like to explain my approach, I feel this time that my approach may be a distraction from the essence of the problem. Also, I think that the problem can be distilled down quite nicely without all the preceding background

Problem background

I have a lot of nasty nest-within-nest complicated formulae, here's one I wrote today (see Excel sample document)

![Excel Code sample

or as code:

=IFERROR(IF(Latest[Weekday Num]=5,0,M13+MAX(Table3[Lunchtime],Latest[Lunchtime])-INDEX(Table4[Out],Latest[Weekday Num]))+Table3[Time remaining]-SUMIFS(Table4[Work time],Table4[Weekday Num],">"&Latest[Weekday Num],Table4[Weekday Num],"<5")+Latest[Clocked In]-S13,"Refresh csv")

As ugly as it may be, IMO it's actually quite well constructed; IFS and SUMIFS where possible to avoid nesting of formulae, all named ranges stored in tables, helper columns used where applicable. Yet under certain circumstances it returns a buggy result and the formula is not pleasant to read through. (It's not the longest either, I have compiled formulae with several a4 pages, of code, although that was when I couldn't use vba to construct helper columns)

I would like a macro which takes this formula and splits it into a sort of tree of branching functions, where each nested function is another twig - perhaps split the components of the formula across cells in the workbook

Current approach

I have so far attempted the following approach: Columns A&B are used to split the formula into smaller parts. I define these parts as being the functions and arguments of Excel formulae, so the formula IF(A1=1,A2,B1) is split into to IF(, A1=1,, A2, and B1). I do this with the following formula in column B:

=LEFT(A2,IFERROR(MAX(1,MIN(IFERROR(FIND("(",A2),LEN(A2)+1),IFERROR(FIND(")",A2),LEN(A2)+1),FIND(",",A2))),LEN(A2)))

Meanwhile, column A looks at the last component found by column B, and chops it off the long formula (using =SUBSTITUTE(A2,B3,"",1)). So, for an original formula in A2 (as text), B2 is the first component of it (such asIF( in my example) and A3 is the formula in A2 minus the first component in B2. I drag down to iterate.

The macro

That gives me a list of the components of the formula in each of the cells of column B. My macro then decides what level each component is, and indents the component by that many cells. The level is defined as the number of open brackets preceding a component of the formula * or 'segment' in my code that haven't been closed. The macro comments explain this.

Sub DispFormula()
'takes a split-up formula and indents lines appropriately

Dim CurrLev As Integer, OBrac As Integer, CBrac As Integer
Dim Segment As Range 'each part of the split up formula
LastRow = Sheets("sheet1").Cells(Rows.Count, 2).End(xlUp).Row

Set orange = Range("B2:B" & LastRow) 'all the segments make an orange

CurrLev = 0 'the "level" of the "segment" - it's level is a measure of how many layers deep the formula is nested
            'if(a=1,b,c) is split into 4 components: `if(`, `a=1,`, `b,` & `c)` where `if(` is level 0 and all the other segments are level 1

OBrac = 0 'how many open brackets have happened/ precede a segment of the formula
CBrac = 0 'how many closed brackets have happened
On Error Resume Next
For Each Segment In orange
    If InStr(Segment, "(") <> 0 Then
        OBrac = OBrac + 1
    ElseIf InStr(Segment, ")") <> 0 Then
        CBrac = CBrac + 1
    End If
    Cells(Segment.Row, CurrLev + 3) = Segment 'copies the segment value into a column indented by a number of cells equal to the order of the segment
    CurrLev = OBrac - CBrac 'current level is how many brackets have been opened - how many have been closed,
                            'ie. the number of brackets preceding a segment which are currently open
Next Segment


End Sub

How it could be improved

That's how far I've got so far. What I really want though is for the tree of indentations to be replaced with a tree of dropdown lists. For a formula =IF(MAX(arg1,arg2)=1,arg3,MIN(arg1,arg2)) I would like to split into segments: IF(, MAX(, ARG1,, ARG2), =1,, ARG3,, MIN(, ARG1, & ARG2)) htn display them. Not like this: (as I currently am)

IF(     
    MAX(    
        ARG1,
        ARG2)
    =1, 
    ARG3,   
    MIN(    
        ARG1,
        ARG2))

But like this: (or similar)

IF(◀

Which when you click on becomes this:

IF(▼
    MAX(◀   
    =1, 
    ARG3,   
    MIN(◀

And then expanding Min to

IF(▼
    MAX(◀   
    =1, 
    ARG3,   
    MIN(▼
        ARG1,
        ARG2))

Shortened problem description


To summarise:

  • I have a formula in Excel; formulae in Excel have the general form FUNCTION(argument1, arg2, arg3...)
  • Each argument may be simple (a constant, a text string, a cell reference) or complex (another formula with its own function and arguments)
  • I would like a macro which takes an input formula, and creates some form of user interface (be it specially located cells as in my example, or some other approach) to display the function in a tree like fashion
  • That means in the first layer of the UI, I display the function, layer 2 has the arguments of the function, if the arguments are complex they will have further sub layers
  • To access the sub layers, each function can be expanded with a dropdown arrow or some other means to reveal its arguments (the 'layer' below it). Like a Reddit post where you can click on the [+] to get 1 layer deeper.
Greedo
  • 4,967
  • 2
  • 30
  • 78
  • 2
    Personally I think it is a very bad practice to use such monstrous formulas. Reserve some ancillary cells where you can put intermediary formulas. The benefits are: 1) readability and maintainability (you can name the intermediary cells with some meaningful names) 2) you will soon find that some of the parts of the formulas are shared by many cells. Then you can do this calculation only once in one intermediary cell instead of repeating in every formula. Your workbook will be smaller and faster. – HiFile.app - best file manager Jan 25 '17 at 09:33
  • 1
    There seems to be a free tool for that purpose (I haven't used tried it yet) https://www.formuladesk.com/ – iDevlop Jan 25 '17 at 09:38
  • I agree, and disagree! What I meant by _helper columns_ is what you describe as ancillary/intermediary cells. I embrace helper columns when I would otherwise be repeating a large chunk of code in my formula. I chose a bad example because in this one I do it once. But most of the code doesn't contain any repetitions. It's in those cases, *where the formula is complicated despite intermediate steps* that I want a solution. Sometimes there are just a lot of variables that need to be juggled about at once. I will update the example accordingly. – Greedo Jan 25 '17 at 09:46
  • Obviously you _could_ split up any formula between many cells, like `=(A1+A2)/A3` into `=(A1+A2)` in cell B1 and `=B1/A3` in cell B2. That gives shorter formulas, perhaps more readable. However unless I repeat code in a formula (like `=(A1+A2)/A3+(A1+A2)^A3)`, I am against splitting that formula up - it actually hinders my ability to appreciate the formula as a whole. And since there are no repeated calculations I don't think splitting it up in _that_ way would speed up the calculation either. – Greedo Jan 25 '17 at 09:50
  • cant you put what you have in a tree view control, not sure I undersrand what you are after, this could be an endless logic piece. From my side, I use a lot of helper columns in design, then sometimes leave them in, if they help explain errors, but if say last month in the current year, i'll have as a helper in design, then pull into the formula at the end. For example, http://stackoverflow.com/questions/41554272/how-do-you-generate-custom-rows-in-excel-without-vb/41554831#41554831 uses a lot of helper columns, but I wouldn't leave them all, but I'd leave them in if they help solve an issue – Nathan_Sav Jan 25 '17 at 09:51
  • Like V.K. said: if the formulas become too big to read, then make them smaller. It not only helps with your ability to read them, but that of your successor as well (been there, not nice to inherit things like this). Most times the intermediate steps have a true meaning as well, so you can label them accordingly, only further strengthening understandability. I always strive for the most simple formulas in my solutions, and my users are very thankful for it, because it enables them to follow the formula path and even adjust it themselves. Sure you get more columns, but it's worth it. – Carl Colijn Jan 25 '17 at 14:45
  • @CarlColijn Initially when I read your comment I thought - that's got to be right - surely a formula can always be sectioned off into different cells based on the true meaning of intermediate steps. So I took that long formula at the top, and considered what I was trying to do, and what steps I took to create the formula in the first place. What I now see is that sometimes you make a trade off between formula _efficiency_ (number of steps/ elements) and formula _readability_ (or specifically a formula in which you can follow the formula path). Sometimes you can't have both. – Greedo Jan 26 '17 at 13:06
  • Eg. I split my formula into 6 individual portions with their own meaning, and based on my train of logic I can see the best order to put those ideas in the formula (say A,B,C,D,E,F). However A, C and E are grouped inside an `IF()` formula, giving you 2 options. 1: split the formula up anyway, break the 1 IF into 3 to give `IF(A),B,IF(C),D,IF(E),F` - that makes the formula logical and readable. 2: leave in 1 block `IF(A,C,E),B,D,F`, makes the formula more efficient yet loses the train of the thought process. I personally tend to 2) - as readable as possible for max efficiency. Which do you use? – Greedo Jan 26 '17 at 13:17

1 Answers1

2

I use this site to work with long formulas and it has helped me alot.

It doesn't have the UI components you mention, but it does a great job of "beautifying" the output.

Excel Formula Beautifier

Nick
  • 3,454
  • 6
  • 33
  • 56