Está en la página 1de 33

Understanding Array Formula Logic

87 This is a very interesting challenge. 5 things you should


98
30 I want to return the average of the 5 smallest values from the 1. Undocumented s
25 range of 25 values in column B. 2. Mechanics behin
100 3. How to view array
17 The 5 smallest values are: {2,3,10,13,13} 4. Generating variab
The average is: 8.2 5. How to avoid acc
2
33
89
49 For this example we can use an undocumented variation of the
3 SMALL function. If you look at the help topic for the function it
13 just says what you see in the yellow textbox to the right. From the Excel Hel
92
36 One thing it fails to mention is that the variable k can also be an SMALL(array,k)
13 array of k values!
58 Array is an array or
This means that if I want to return the 5 smallest values to an
55 AVERAGE function I can very easily do it like this: K is the position (fro
10
20 Remarks
45 If array is empty, SM
83 I'm a little surprised
=AVERAGE(SMALL(myrange,{1,2,3,4,5}))
that they failed to mention that ability in the If k ≤ 0 or if k exceed
70 description of the function. It's also worth noting that the formula If n is the number of
91 above is NOT an array formula. It's just a regular old function (see equals the largest va
17 the yellow cell at left). And yes, as you can see, it also works for
98 the LARGE function as well.

#NAME?
#NAME?

This formula works fine until somone comes along and says, "Hey, I've got a column of
500 values and I need to return an average of the smallest 200 and I might want to
change it to look at a variable number of smallest amounts."

Now we run into a few problems:

1. It would be a huge pain to enter an array of 200 in the form of {1,2,3...200}

2. It could potentially be an array of any amount from 1 to 500! So I'd have to create
500 different variations of the formula to handle them all (and that's just assuming only
the upper bound is changing and the lower bound is always 1).

3. Finally, even if I did attempt to create a b'zillion different formulas with all the different
possible arrays, I would still well exceed the 256 character limit for a cell formula once
the arrays started getting large.

So how do we accomplish it?

At right you'll notice a column of 500 values and a cool array formula (in the yellow cell)
that will allow you to enter the lower and upper bound of an array to feed to the Small
function to be used in an Average calculation.
So how do we accomplish it?

At right you'll notice a column of 500 values and a cool array formula (in the yellow cell)
that will allow you to enter the lower and upper bound of an array to feed to the Small
function to be used in an Average calculation.

{=AVERAGE(SMALL(mybigrange,TRANSPOSE(ROW(OFFSET($A$1,Lbound-1,,Ubound-Lbound+1)))))}

In the yellow textbox above you can see the actual array formula that I used. Notice how
it allows me to change the lower and upper bound limits for the Small function "k" array.
If I wanted to, I could use 3 and 10 for my lower and upper bounds and it would return
the array {3,4,5,6,7,8,9,10} to use in the Small function to return just the 3 thru 10 largest
items for the average calculation.

Am I an array formula genius? Not hardly! If you want to learn something about
designing array formula logic read on...

Now let's disect this array formula to see how it's really working.

First of all let's keep in mind the original simple non-array formula:

=AVERAGE(SMALL(myrange,{1,2,3,4,5}))

We are quickly faced with the following dilema when trying to convert to the more
advanced function.

How can I make a formula generate a variable sized array to replace my hardcoded
array of: {1,2,3,4,5} ?

It would require that an array is built within the formula given variables for the upper and
lower bounds of the array. That is, assuming we want to stick with the SMALL function
since it so nicely avoids the duplication problem that a "<=" solution would run up against
if attempting to use a SUMIF function.

Ranges are good proxies for 1d and 2d arrays. Although generally, people are unaware
of the link between a 2d range and a 2d array. For instance in VBA I can create a 2d
array and set the values of a range equal to it in a single line of code. People often think
they have to step thru values of an array to assign the values to a range; not so.

So, if I wanted to create a variable sized array in a cell formula I could use the OFFSET
function to mimic the size of the array that I need.

Assuming: Lbound=1 and Ubound=5


This formula would create an array of values from 1 to 5:

Just entering this formula in a cell would return the single value of 1 (the first value of the
array). To see=COLUMN(OFFSET($A$1,,Lbound-1,,Ubound-Lbound+1))
the actual array of values, in the formula editor highlight everything to the
right of the = sign and press F9. You'll see the evaluation of the formula returns the array
{1,2,3,4,5}. Which is what we were feeding to the SMALL function by hardcode in the
simpler examples. You can test with the formula in the the blue cell at right. Remember,
at this point I'm just trying to build an array to feed to the SMALL function.

To create the array, I'm simply returning all the row numbers of a variable sized range (or
array). Although, using columns is limited in that it cannot exceed an array size of 256
due to the number of columns in Excel. If you don't need more than 256 array elements
then of course this will suffice. If you want the option to do more than 256 it's just a little
Just entering this formula in a cell would return the single value of 1 (the first value of the
array). To see the actual array of values, in the formula editor highlight everything to the
right of the = sign and press F9. You'll see the evaluation of the formula returns the array
{1,2,3,4,5}. Which is what we were feeding to the SMALL function by hardcode in the
simpler examples. You can test with the formula in the the blue cell at right. Remember,
at this point I'm just trying to build an array to feed to the SMALL function.

To create the array, I'm simply returning all the row numbers of a variable sized range (or
array). Although, using columns is limited in that it cannot exceed an array size of 256
due to the number of columns in Excel. If you don't need more than 256 array elements
then of course this will suffice. If you want the option to do more than 256 it's just a little
trickier.

At this point, you might suggest using rows instead. That's a good idea; only a vertical
range equates to a 2d array that we would need to transpose.

For instance:

Will return a 2d array in the form of {1;2;3;4;5} (or vertical array)


That's not the same as a 1d array of {1,2,3,4,5} (or horizontal array)
See the difference in the blue cells on the right? Remember to use the F9 trick I
mentioned before to evaluate the arrays.

To convert the=ROW(OFFSET($A$1,Lbound-1,,Ubound-Lbound+1))
2d array, we could use the TRANSPOSE function on the array to convert
it for use in our formula:

You'll notice with the transpose, this now returns {1,2,3,4,5} and we can use it in our
formula! So now I guess we have the ability to create a variable sized array without the
256 limitation. I s'pose (theorhetically speaking) in this example, the array could be as
large as 65536 elements. (Although, I haven't tested it for the 5,461element limitation
that MS speaks of in the knowledge base related to the TRANSPOSE function.)

So, if =TRANSPOSE(ROW(OFFSET($A$1,Lbound-1,,Ubound-Lbound+1)))
I replace the hard-coded array in my formula with the variable array logic I'd get
something like this:

If you enter this formula as it is, it won't return the correct result. In this case you do
actually have to use Ctrl-Shift-Enter and make it a true array formula. If you enter it
properly you'll see the array brackets { } appear around the formula and it will work. See
the difference between the non-array entered result and the array entered result at right?

This is an interesting exercise in array formula logic. Hopefully during the course of the
explanation it became clear that I am no genius with regard to array formulas, I have to
build them piece-by-piece. There's no way I would have been able to just sit down and
type out that array formula answer without building it piecemeal. Hopefully you will have
=AVERAGE(SMALL(mybigrange,TRANSPOSE(ROW(OFFSET($A$1,Lbound-1,,Ubound-Lbound+1)))))
learned that you can evaluate portions of formulas with the F9 key as you work to see
what the array logic is returning. This is a very helpful (to me, invaluable) tool when
trying to build array formula logic.

Example Provided Courtesy of:


Aaron T. Blood
www.XL-Logic.com
Example Provided Courtesy of:
Aaron T. Blood
www.XL-Logic.com

Example Provided Courtesy of:

XL-Logic.com

Beware!

In this example I used the anchor cell $A$1 in much of my discussion above as the basis
for building a variable sized array. If I happen to insert a new top row, all the formulas
using the $A$1 reference will change to $A$2 which would actually damage the formula
result. Notice what happens to the blue cell formulas above if I insert a new row 1.
Yikes!

In this case, to be safe, it would probably be best to use an indirect reference to the
range A1. This way inserting rows at the top will not damage the formula results in any
way. I modified my formula in cells P39 and P40 to accomodate the INDIRECT
reference so inserting rows at row 1 won't damage my formula results.

This is one of the reasons why only truly advanced Excel users should mess around with
such formulas. Imagine if you picked up someone elses work and accidentally changed
all the formula results because you wanted to insert a few rows or columns. If you don't
know what to watch out for when you create these things the results could be
disasterous! But then again, the same could be said for VLOOKUP and HLOOKUP
functions and people use those things all the time.

Perhaps as a challenge you should think of a way to modify a VLOOKUP and HLOOKUP
function so they don't get destroyed when someone accidentally inserts a row or column
in the data table. I'd tell you how, but that's a whole other discussion...
5 things you should learn from this example:

1. Undocumented special features of the SMALL and LARGE functions.


2. Mechanics behind developing array formulas.
3. How to view array results in your formulas in the formula editor.
4. Generating variable sized arrays using range references in formulas.
5. How to avoid accidentally destroying your formulas when inserting new rows/columns.

From the Excel Help Topic for the "Small Worksheet Function"

SMALL(array,k)

Array is an array or range of numerical data for which you want to determine the k-th smallest value.

K is the position (from the smallest) in the array or range of data to return.

Remarks
If array is empty, SMALL returns the #NUM! error value.
If k ≤ 0 or if k exceeds the number of data points, SMALL returns the #NUM! error value.
If n is the number of data points in array, SMALL(array,1) equals the smallest value, and SMALL(array,n)
equals the largest value.

1 Lbound : 1 Notice how I can change the


2 Ubound : 5 lower and upper bounds to
3 return any array of small and
4 Avg Results large values to use in my
5 Smallest : 3.00 average calculations.
6 Largest : 498.00
7
8
9
10 Example Provided Courtesy of:
11
XL-Logic.com
12
13
14
15
16
17
18
19
20
21
22
23
24
d-Lbound+1)))))}
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
1 74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
Horizontal 91
1 92
93
Vertical 94
1 95
96
97
98
99
100
101
102
Horizontal 103
1 104
105
106
107
108
109
110
111
d-Lbound+1))))) 112
113
non-array 114
entered 115
1 116
117
array 118
entered 119
3 120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
e.

ay,n)

nge the
nds to
mall and
n my
.

También podría gustarte