My choice for Excel’s most evil worksheet function is INDIRECT, for reasons outlined below.
If you have a different choice you can cast your vote for your most evil function (and your favourite function) here.
So what makes INDIRECT so evil?
In no particular order here my reasons: you may have more!
The INDIRECT function is volatile, which makes any formula that contains it volatile so that they defeat Excel’s smart recalc and recalc at every calculation. And of course this ripples down the dependency chains to make all dependent formulas also recalculate: SLOW!!!
The INDIRECT function is single-threaded and so defeats Excel’s multi-threaded calculation engine:
If the argument you give INDIRECT cannot be resolved to a usable reference INDIRECT returns #Ref. The problem is that the process of attempting to resolve the reference involves looking in a very large number of places which consumes a lot of time:
(Colin Legg has a more detailed post about this problem here)
If you use INDIRECT to refer to external workbooks then they have to be open or else INDIRECT won’t work.
Error-prone & Fragile
Does not adjust when rows/columns added/deleted/moved
Because the argument to INDIRECT is text rather than a cell reference it does not automagically adjust when rows or columns are added/deleted/moved. OK its possible to build more complex INDIRECT formulas in some cases that do adjust, but they tend to get complex and error-prone.
Error-prone & Fragile
Difficult to debug
It can be very difficult to understand & debug formulas containing INDIRECT because they are often complex, and because the trace precedents tool gets blocked by a textual reference.
Error-prone & Difficult
So are there any alternatives?
INDIRECT is an extremely powerful function that is often used to create workbooks that can dynamically adjust to structural changes such as changing the ranges or worksheets or the external workbooks that are being used in formulas. Useful alternatives can be:
The CHOOSE function is not volatile and is multi-threaded and is easy to debug and maintain.
CHOOSE(Index_Num,Arg1,Arg2, … Arg254)
The first argument must resolve to a number between 1 and 254 that determines which of the following arguments is returned. The first argument could be a MATCH function that looks up a parameter in a list to get a number. The arguments to be chosen from could be defined names referring to ranges, references, formulas or values.
The drawback of the CHOOSE function is that the formula gets unwieldy when there are a large number of choices.
The Reference form of INDEX
In addition to the standard form of INDEX (=INDEX(Range, Row_Index, Column_Index) ) there is a reference form which can be used to select from multiple ranges.
The multiple ranges must be:
- Enclosed in ( )
- On the same worksheet
The drawback of this form of INDEX are that the ranges must be on the same worksheet.
If INDIRECT is being used to insulate the workbook against structural changes you could consider using VBA to modify the relevant formulas. Using Defined Names to hold frequently used formulas, and modifying the defined names may prove easier and more efficient than modifying every formula. Remember that Defined Names can also hold formulas containing relative references. For relative references I recommend using R1C1 mode and notation when creating the named relative formulas.
INDIRECT is evil because:
- Its slow
- Its fragile and easily broken
- Its hard to debug
- Its hard to understand
If you have better ideas for eliminating INDIRECT please help stamp us stamp out use of INDIRECT!