tags:

views:

59

answers:

1

How do I pass multidimensional arrays or nested arrays into an Excel UDF which allow me to reference other ranges?

I have a UDF defined as "ARY" which does what Array() does in VBA but in a worksheet function.

This allows me to have a worksheet formula like

=TEST1(ARY(ARY("A", "B"), "C"))
or
=TEST1(ARY(ARY(A1, B1), C1)

However, I get Error 2015 when executing TEST1 as a worksheet function. If I execute TEST1 from VBA, it works fine and returns "A".

Public Function TEST1(Params As Variant) As Variant
    TEST1 = Params(0)(0)
End Function

'Returns 1D ARRAY
Public Function ARY(ParamArray Params() As Variant)
    ReDim result(0 To UBound(Params)) As Variant
    Dim nextIndex As Integer
    Dim p As Variant

    nextIndex = 0

    For Each p In Params
        result(nextIndex) = p
        nextIndex = nextIndex + 1
    Next

    ARY = result
End Function
+1  A: 

In general, you can't do this. VBA is fine with nested arrays as values, but Excel just isn't. This makes sense, because Excel ultimately has to treat any values it gets from your UDFs as things that can go into the worksheet grid.

It would be nice if intermediate results didn't have to obey this restriction. In your example above, you're not trying to put a jagged array into any cells; you just want to create it and pass it to 'TEST1'. Unfortunately, Excel just doesn't work that way. It evaluates each expression in a formula to a legal Excel value, and #VALUE! is the catch-all for "not a legal value". (There are other limitations to returned arrays besides jaggedness. For example, arrays over a certain size also result in a #VALUE! error.)

Note that nested arrays that are all the same length can be passed back from UDFs:

Public Function thisKindOfNestingWorks()
    thisKindOfNestingWorks = Array(Array(1, 2), Array(3, 4))
End Function

This can be useful when you're building up some list-of-lists that you actually want coerced to a 2-D array.

So, calling your ARY function above like this should work just fine:

=ARY(ARY(A1, B1), ARY(C1, D1))

However, your TEST1 function would fail, since calling

=TEST1(ARY(ARY(A1, B1), ARY(C1, D1)))

would result in a 2-D array being passed to TEST1, not a 1-D array of 1-D arrays.

You might also find this question and my answer to it to be helpful:

http://stackoverflow.com/questions/1354046/return-a-user-defined-data-type-in-an-excel-cell

jtolle