3

サイズが不明な配列と、パラメーター配列を受け入れるプロシージャーがある場合、プロシージャーを変更せずに配列をパラメーター配列として渡すにはどうすればよいでしょうか?

Sub Example(sequence() As String)
    UnModifiableSub sequence
End Sub

Sub UnModifiableSub(ParamArray bar())
    ' bar(0) = sequence not bar = sequence
End Sub

私はPythonのアンパックに似た動作を見ています

def foo(*args):  # identical to ParamArray
    print(args)

x = [1,2,3,4]
foo(*x)  # what VBA can't do

Python にあるような組み込みのソリューションがないことはわかっていますが、長い switch ステートメント以外の残酷な実装は受け入れられます。

4

2 に答える 2

2

巨大な switch ステートメントは、私には残酷に思えますが、呼び出さなければならないルーチンが本当に変更不可能である場合は、それが問題になります。VBA では、これはSelect Caseステートメントです。また、VBA 配列は任意のインデックスを持つことができることを忘れないでください。そのため、シーケンス引数がどこから来ているのかわからない場合を除き、LBoundとの両方をテストする必要があります。UBound

独自のルーチンを作成できる場合は、ほとんどの場合、やりたいことを実行する方法があります。Variant次のように、 type の変数に配列を割り当てることができます。

Sub tryThis(v)
    Debug.Assert IsArray(v)
    Debug.Print v(LBound(v))
End Sub

Sub Example(sequence() As String)
    tryThis sequence
End Sub

Sub test()
    Dim s() As String

    ReDim s(1 To 2)
    s(1) = "a"
    s(2) = "b"

    Call Example(s)
End Sub

tryThis()の代わりになりますUnModifiableSub。イミディエイト ウィンドウで実行するtest()と、次の出力が得られます。

call test
a

それがあなたが望む行動だと思います。(とにかく、ある程度。誰も任意の配列インデックスを望んでいません。) もちろん、これは Python に比べて制限されています。特に、 を呼び出したい場合はtryThis()、「パラメーター」を自分で配列に入れる必要があります。それを行うことに関連するトレードオフのいくつかは、この回答と親の質問で説明されています。

(Variant 配列に対して) ParamArray を使用する利点は何ですか?

他にもいくつかの問題があります。たとえば、 a の内容をParamArrayto に渡すことはできませんtryThis()

'Doesn't work...
Sub gotcha(ParamArray pa())

    'Can't do it this way! "Invalid ParamArray use"
    Call tryThis(pa)
End Sub

変数への転送を明示的に行う必要があります。

Sub gotchaFixed(ParamArray pa())
    Dim v
    v = pa

    Call tryThis(v)
End Sub

Sub test2()
    Call gotchaFixed("a", "b")
End Sub

...

call test2
a
于 2014-09-20T00:35:12.410 に答える
1

引数を として渡すことはできないと思いParamArrayます。その性質上、それ自体に割り当てるのではなく、の要素ParamArrayマッピングします。ParamArray

呼び出し元から渡された各引数は、ParamArray 変数の要素にマップされます。したがって、ParamArray 変数には、呼び出しステートメントによって渡される引数と同じ数の要素が含まれます。

http://www.tushar-mehta.com/publish_train/xl_vba_cases/1005%20ParamArray.shtml

于 2014-09-19T15:14:20.263 に答える