是否可以将数组的所有元素传递给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
在这种情况下,p2
的ParamArray不包含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中可能是不可能的。
感谢您的帮助,
迈克尔
答案 0 :(得分:6)
将ParamArray参数传递给另一个需要ParamArray参数的函数(委托ParamArray参数)。
我需要委托一个类型的函数:strf(str as string, ParamArray args() as Variant) as String
在ParamArray中的其他函数中接收的参数直接传递而不显式写入。
我发现的限制是:
代码:
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
答案 1 :(得分:4)
您可以在第二次通话时将其转换为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
答案 2 :(得分:2)
这是我的解决方案。请注意,它的一个限制是您只能将一个(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's ParamArray parameter to be
'the array of its first element.
For Each key In keys
Debug.Print key
Next key
End Sub
答案 3 :(得分:1)
尝试:
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
答案 4 :(得分:0)
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 :(得分:0)
我最强烈的需求之一是能够将 ParamArray values() As Variant
变成 String()
。
根据 OPs 问题,我还需要能够将其他函数转发到此函数,其中其他函数有一个 ParamArray
,在该函数可以之前,它也需要转换为 String()
继续处理。
这里的解决方案包括一个健壮的函数来安全地返回数组的大小:
Public Function f_uas_astrFromParamArray( _
ParamArray pr_avarValues() As Variant _
) As String()
Dim astrResult() As String
Dim avarTemp() As Variant
Dim lngSize As Long
Dim lngUBound As Long
Dim lngIndex As Long
If (IsMissing(pr_avarValues) = False) Then
If (IsArray(pr_avarValues(0)) = True) Then
avarTemp = pr_avarValues(0)
Else
avarTemp = pr_avarValues
End If
lngSize = f_lngArraySize(avarTemp)
If (lngSize > 0) Then
lngUBound = lngSize - 1
ReDim astrResult(0 To lngUBound)
For lngIndex = 0 To lngUBound
astrResult(lngIndex) = CStr(avarTemp(lngIndex))
Next lngIndex
End If
End If
f_uas_astrFromParamArray = astrResult
End Function
'Return Value:
' -1 - Not an Array
' 0 - Empty
' > 0 - Defined
Public Function f_ua_lngArraySize( _
ByRef pr_avarValues As Variant _
, Optional ByVal pv_lngDimensionOneBased As Long = 1 _
) As Long
Dim lngSize As Long: lngSize = -1 'Default to not an Array
Dim lngLBound As Long
Dim lngUBound As Long
On Error GoTo Recovery
If (IsArray(pr_avarValues) = True) Then
lngSize = 0 'Move default to Empty
lngLBound = LBound(pr_avarValues, pv_lngDimensionOneBased)
lngUBound = UBound(pr_avarValues, pv_lngDimensionOneBased)
If (lngLBound <= lngUBound) Then
lngSize = lngUBound - lngLBound + 1 'Non-Empty, so return size
End If
End If
NormalExit:
f_ua_lngArraySize = lngSize
Exit Function
Recovery:
GoTo NormalExit
End Function
答案 6 :(得分:-2)
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