ある、Variant型の返り値を返す関数を作ったとします。
たとえばコレクションから先頭のデータを返すとか。
1: Function GetFirst(clctn As Collection) As Variant
2: If IsObject(clctn(1)) Then
3: Set GetFirst = clctn(1)
4: Else
5: GetFirst = clctn(1)
6: End If
7: End Function
すると、返ってくる値はObject型なのか、基本型なのかわかりません。
このときどうやって返り値を変数に代入すれば良いですか?
(ながくなるのでコメントで続き書きます)
コメント(2件)
ObjectならSetステートメントが必要なので、
適当にやると実行時エラーになってしまいます。
1: Sub UseGetFirst()
2: Dim clctn As New Collection, e As Variant
3: Call clctn.Add(New Collection)
4: e = GetFirst(clctn) 'ここでエラー
5: End Sub
もちろん、GetFirstを2回呼べばIsObjectで判定できますが、
1度しか呼びたくないことも往々にしてあるので、それはなしです。
ひとつ、無理矢理思いついたのがForEachステートメントを使う方法で
ゴリ押しすればこんなことが出来ました。
1 : Function CArray(ParamArray args() As Variant) As Variant()
2 : CArray = args
3 : End Function
4 :
5 : Sub NewUseGetFirst()
6 : Dim clctn As New Collection, e As Variant
7 : Call clctn.Add(New Collection)
8 : For Each e In CArray(GetFirst(clctn))
9 : Debug.Print TypeName(e)
10: Next e
11: End Sub
可変引数を使って配列を無理矢理作って、さらにForEachを使うと
Setせずに代入できます。
ですが、あまりにトリッキーなのでもう少し普通な方法はないものでしょうか。
1: Sub SetVariant(a As Variant, b As Variant)
2: If IsObject(b) Then
3: Set a = b
4: Else
5: Let a = b
6: End If
7: End Sub
8:
9: Sub Test()
10: Dim clctn As New Collection, e As Variant
11: Call clctn.Add(New Collection)
12: Call SetVariant(e, GetFirst(clctn))
13: Debug.Print TypeName(e)
14: End Sub
ByRef使えば、そちらで判定してしまえますね。
見た目的にもすっきりして良さげです。
これよりもっと良い方法があれば、お願いします。