Передача многомерного массива в Excel UDF в VBA
1 Christopher Tso [2010-08-07 04:36:00]
Как передать многомерные массивы или вложенные массивы в Excel UDF, которые позволяют мне ссылаться на другие диапазоны?
У меня есть UDF, определенный как "ARY", который делает то, что делает Array() в VBA, но в функции рабочего листа.
Это позволяет мне иметь формулу рабочего листа, например
= TEST1 (ARY (ARY ( "A", "B" ), "C" ))
или
= TEST1 (ARY (ARY (A1, B1), C1)
Тем не менее, я получаю Error 2015 при выполнении TEST1 в качестве функции листа. Если я выполняю TEST1 из VBA, он отлично работает и возвращает "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
vba excel
1 ответ
2 Решение jtolle [2010-08-07 17:55:00]
В общем, вы не можете этого сделать. VBA отлично вложенных массивов в качестве значений, но Excel просто нет. Это имеет смысл, потому что Excel в конечном счете должен обрабатывать любые значения, которые он получает от ваших UDF, как вещи, которые могут попасть в таблицу рабочих таблиц.
Было бы неплохо, если бы промежуточные результаты не должны были подчиняться этому ограничению. В приведенном выше примере вы не пытаетесь помещать зубчатый массив в любые ячейки; вы просто хотите создать его и передать его в "TEST1". К сожалению, Excel просто не работает. Он оценивает каждое выражение в формуле в соответствии с юридическим значением Excel и #VALUE! является "ловушкой" для "не юридической ценности". (Существуют и другие ограничения для возвращаемых массивов, кроме зубьев. Например, массивы с определенным размером также приводят к ошибке #VALUE!.
Обратите внимание, что вложенные массивы, которые имеют одинаковую длину, могут быть возвращены из UDF:
Public Function thisKindOfNestingWorks()
thisKindOfNestingWorks = Array(Array(1, 2), Array(3, 4))
End Function
Это может быть полезно, когда вы создаете список списков, которые вы на самом деле хотите получить в двумерном массиве.
Итак, вызов вашей функции ARY выше, как это должно работать очень хорошо:
=ARY(ARY(A1, B1), ARY(C1, D1))
Однако ваша функция TEST1 не сработает, так как вызов
=TEST1(ARY(ARY(A1, B1), ARY(C1, D1)))
приведет к передаче 2-D массива в TEST1, а не в 1-мерном массиве из 1-D массивов.
Вы также можете найти этот вопрос, и мой ответ на него будет полезен:
Возвращает определенный пользователем тип данных в ячейке Excel
ПОСЛЕДНЕЕ ИЗМЕНЕНИЕ:
Кстати, ваша функция "ARY" может быть намного короче. Это не имеет никакого отношения к вашему первоначальному вопросу, но стоит упомянуть:
Public Function arr(ParamArray args())
arr = args
End Function
В этом ответе есть пример использования: