I think I made a breakthrough with "ultra-dynamic" ranges. That's how I call them because not only they are dynamic; but also they refer to different ranges based on the cell address in which they are written in! Now I need to advance this breakthrough even further. Those of you using dynamic ranges in Excel, especially the dynamic-range-gurus, will be thrilled to read below and can possibly help in this advancement:
Disclaimer: If you are not familiar with dynamic ranges do not attempt to read below!
Background: Our sheet has cells with calculations on top and a pivot table below. Each cell above refers to the pivot table cells below in the same column. The first column of the pivot table (titled "Row Labels" by default) is sorted from top to bottom in descending order. Each of the next columns has the result of a different test. At one point somewhere in the middle rows of the pivot table there is a "marker line" that separates the top part of the pivot from the bottom one. Let's call the top part "Uppers" and the bottom part "Downers". Let's call both parts together "Population". Population is a non-contiguous range because the "marker line" that separates the Uppers from the Downers intervenes.
For each cell above the pivot there are calculations for the pivot column exactly below that need to refer to the Uppers or Downers or Population of the column itself.
Previously, my formulas in all of the cells above were a repetition of something like this below:
= MAX( OFFSET($A$79,$B$5+1,COLUMN()-1,$B$6,1) )
This example gives the maximum of the area of the Downers in the same column below.
Where:
A79
is the top left corner of the pivot table,B5
has the row number of the marker line (relative to A79
) to signify that our column's Downers area starts from the first row below that marker row (hence the "+1"). The formula of that cell has an XMATCH
formula to produce the resulting row number. For example if the Uppers are positive numbers and the Downers are negative numbers, all sorted in descending order, the XMATCH
is searching for the 0
row that separates the two parts of the population.COLUMN()-1
returns the current column's number for offsetting to the right and the -1 is necessary because the first column is 0 rather than 1 offset to the right, andB6
has the number of rows ("height") to the last row number of the pivot (relative to B5
) where our Downers end. The cell contains the usual COUNTA
function that counts the number of rows in the pivot table and from this number it subtracts the number of the marker row in B5
to get the "height" of the Downers range.The OFFSET...
part of the formula when copied to any cell with calculations above the pivot will always give the Downer's area in the same column.
And here we come to the "ultra"-dynamic part: I tested (and it works!) naming a range as:
ColDowners: =OFFSET($A$79,$B$5+1,COLUMN()-1,$B$6,1)
And I substituted all the cells with calculations that refer to the Downers with something like:
= MAX( ColDowners )
Miraculously, all cells with this named ultra-dynamic range, are calculated with the correct values for the Downers exactly below them in the same column! Sometimes when the Workbook is initially loaded, the cells appear with 0 values, but immediately when you hit F9 to Calculate they get the correct value (which of course is not a problem).
So this range is "dynamic" in two ways: (1) because start and end rows are dynamic (as usual) and (2) because it results to a different range depending on where it's written!!
And now for the advancement. Any dynamic-range-guru's input would be extremely valuable:
OFFSET
is a volatile function with the known performance issues. Can we replace it with two non-volatile INDEX
functions separated by a colon (":")? I know how to name a range that starts from a specific cell and ends in a different one every time (eg. =A$155:INDEX(...COLUMN()...)
). But can BOTH the start and end of the range be INDEXified [sic]? i.e. can it be something like =INDEX(...COLUMN()...):INDEX(...COLUMN()...)
. And, consequently, if we name a range with this formula, will it work?
Answers will have to exclude volatile functions like INDIRECT
and will have to be as simple as possible. The resulting range of the formula of the ultra-dynamic range will have to be different depending on which COLUMN()
it's written in in the sheet (like the OFFSET
one above) and will have to be "able" to start from a specific number of rows below A79
(the number written in B5
in the example above) and end in the one written in B6
.
The correct formula that defines an ultra-dynamic-range for replacing the 'OFFSET' formula:
=OFFSET($A$79,$B$5+1,COLUMN()-1,$B$6,1)
Is:
=INDEX($A:$XX,ROW($A$79)+$B$5+1,COLUMN()):INDEX($A:$XX,ROW($A$79)+$B$7,COLUMN())
B7
is the number of the last row of the pivot. (=Something like B5+B6
plus/minus 1 or 2 - test it for your case)If you Define a Name of a Dynamic Range with this ultra-dynamic formula, it will adapt to give you different ranges depending on the location of the cell where you copied it to!! It will always give you the same parallel range in your column and will produce different results in different columns! I tested it and it works perfectly, plus it made my calculations lightning faster since INDEX
is non-volatile (as opposed to OFFSET
).
One more tip for the example above: I also tried nested range names and they work! For example I Defined the Range for ColPopulation as:
=(ColUppers,ColDowners)
Note that this is an ultra-dynamic-nested-range-name! Of course, it can work only for simple functions (such as =MAX(ColPopulation)
) and will not work in functions such as SUMPRODUCT
that need contiguous ranges. Still, it is a very useful thing to know that you can Define Ranges by adding other range names with commas!
Great help from all involved! Thanks a lot!