18

配列のすべての要素を 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が、 array-object が取得されます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 では不可能です。

助けてくれてありがとう、
マイケル

4

8 に答える 8

11

ParamArray 引数を、ParamArray 引数を期待する別の関数に渡します (ParamArray 引数をデリゲートします)。タイプの関数に委譲する必要があります: strf(str as string, ParamArray args() as Variant) as StringParamArray 内の他の関数で受け取った引数は、明示的に書き込むことなく直接渡します。私が見つけた制限は次のとおりです。

  1. ParamArray() ParamArray を予期する別の関数にのみ渡すことができます。
  2. ParamArray は要素 0 で Variant () として受信されます。
  3. 2 番目の関数がそれを受け取ると、深さのレベルが増加します。満足のいく解決策は見つかりませんでしたが、追加された深さレベルを元に戻し、受け取った引数でベクトルを返す、完全に機能する関数を作成しました。

コード:

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
于 2015-05-14T17:33:39.690 に答える
9

Variant次の 2 番目の呼び出しから に変換できます。

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
于 2016-11-05T18:34:27.813 に答える
5

これが私の解決策です。その 1 つの制限は、ParamArray パラメーター セットに渡すことができる (Variant) 配列引数は 1 つだけであることに注意してください。複数の渡された配列を処理するように一般化できる可能性がありますが、まだその必要性に遭遇していません。

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
于 2016-11-10T23:56:09.933 に答える
3

試す:

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
于 2014-11-21T12:16:38.230 に答える
-3

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
于 2014-11-10T22:54:24.320 に答える