Пропустить массив в ParamArray
Можно ли передать все элементы массива в ParamArray?
Например, я хотел бы передать ParamArray другому ParamArray:
Sub test()
p1 "test", "banane", "birne"
End Sub
Sub p1(ParamArray keys() As Variant)
p2 keys 'should be the same as: p2 "test", "banane", "birne"
End Sub
Sub p2(ParamArray keys() As Variant)
Dim key As Variant
For Each key In keys
Debug.Print key 'Run-time error '13' Type mismatch (key is an array)
Next key
End Sub
В этом случае ParamArray p2
не содержит элементов keys
, но получает массив-объект keys
. Таким образом, я должен проверить, если переданы массивы:
Sub test()
p1 "test", "banane", "birne"
p2 "test", "banane", "birne"
End Sub
Sub p1(ParamArray keys() As Variant)
p2 keys
End Sub
Sub p2(ParamArray params() As Variant)
Dim keys As Variant
If IsArray(params(0)) Then
keys = params(0)
Else
keys = params
End If
Dim key As Variant
For Each key In keys
Debug.Print key
Next key
End Sub
Но это неудобно, например, по сравнению с Java:
public class VarArgs {
public static void main(String[] args) {
p1("test", "banane", "birne");
p2("test", "banane", "birne");
String[] array = {"test", "banane", "birne"};
p1(array);
p2(array);
}
public static void p1(String... strings) {
p2(strings);
}
public static void p2(String... strings) {
for (String string : strings) {
System.out.println(string);
}
}
}
В Java я не должен различать. Но это, вероятно, невозможно в VBA.
Спасибо за помощь,
Майкл
Ответы
Ответ 1
Передайте аргумент ParamArray другой функции, которая ожидает аргумент ParamArray (делегировать аргументы ParamArray).
Мне нужно делегировать функцию типа: strf(str as string, ParamArray args() as Variant) as String
аргументы, полученные в другой функции в передаче ParamArray напрямую, без явной записи.
Ограничения, которые я нашел, следующие:
- Парамагр() он может быть передан только другой функции, которая ожидает ParamArray.
- ParamArray получена в элементе 0 как Variant()
- Когда вторая функция получает его, увеличивается уровень глубины
Я не нашел удовлетворительного решения, но я написал функцию, которая отлично работает, отменяет добавленные уровни глубины и возвращает вектор с полученными аргументами.
код:
Option Explicit
Option Base 1
Public Sub PrAr1(ParamArray pa1() As Variant)
Dim arr() As Variant
arr = fn.ParamArrayDelegated(pa1)
PrAr2 pa1
End Sub
Public Sub PrAr2(ParamArray pa2() As Variant)
Dim i As Integer, arrPrms() As Variant
arrPrms = fn.ParamArrayDelegated(pa2)
For i = 0 To UBound(arrPrms)
Debug.Print s.strf("i: %0 prm: %1 ", i, arrPrms(i))
Next i
PrAr3 pa2
End Sub
Public Sub PrAr3(ParamArray pa3() As Variant)
Dim i As Integer, arrPrms() As Variant
arrPrms = fn.ParamArrayDelegated(pa3)
For i = 0 To UBound(arrPrms)
Debug.Print s.strf("i: %0 prm: %1 ", i, arrPrms(i))
Next i
End Sub
Public Function ParamArrayDelegated(ParamArray prms() As Variant) As Variant
Dim arrPrms() As Variant, arrWrk() As Variant
'When prms(0) is Array, supposed is delegated from another function
arrPrms = prms
Do While VarType(arrPrms(0)) >= vbArray And UBound(arrPrms) < 1
arrWrk = arrPrms(0)
arrPrms = arrWrk
Loop
ParamArrayDelegated = arrPrms
End Function
Ответ 2
вы можете преобразовать его в Variant
со второго вызова:
Sub test()
p1 "test", "banane", "birne"
End Sub
Sub p1(ParamArray keys() As Variant)
p2 CVar(keys) '<--| pass it as a Variant
End Sub
Sub p2(keys As Variant) '<--| accept a Variant argument
Dim key As Variant
For Each key In keys
Debug.Print key
Next key
End Sub
Ответ 3
Вот мое решение. Обратите внимание, что одно его ограничение состоит в том, что вы можете передать только один аргумент массива (Variant) в набор параметров ParamArray. Возможно, он может быть обобщен для обработки нескольких переданных массивов, но мне еще предстоит выполнить эту задачу.
Option Explicit
Sub test()
p1 "test", "banane", "birne"
p2 "test", "banane", "birne"
End Sub
Sub p1(ParamArray keys() As Variant)
Dim TempKeys As Variant
TempKeys = keys 'ParamArray isn't actually a standard Variant array, so you have to copy
'it to one in order for the added test/workaround in p2 to not crash
'Excel.
p2 TempKeys 'should be the same as: p2 "test", "banane", "birne"
End Sub
Sub p2(ParamArray keys() As Variant)
Dim key As Variant
If IsArray(keys(0)) Then keys = keys(0) 'Set this routine ParamArray parameter to be
'the array of its first element.
For Each key In keys
Debug.Print key
Next key
End Sub
Ответ 4
Sub test()
p1 "test", "banane", "birne"
End Sub
Sub p1(ParamArray keys() As Variant)
p2 keys
End Sub
Sub p2(ParamArray keys() As Variant)
Dim key As Variant
For Each key In keys
Debug.Print key(0) '<- Give an Index here.
Next key
End Sub
Ответ 5
Try:
Sub p2(ParamArray keys() As Variant)
dim myKey as Variant
If IsArray(keys(0)) Then
myKey = keys(0)
Else
myKey = keys()
End If
...
end sub
Ответ 6
paramArrays странны, но вы можете использовать обычный массив, который отлично работает
Sub test()
Dim a As Variant: a = Array("test", "banane", "birne")
p1 a
End Sub
Sub p1(keys As Variant)
p2 keys
End Sub
Sub p2(keys As Variant)
Dim key As Variant
For Each key In keys
Debug.Print key
Next key
End Sub