変数が配列か調べるには、IsArray関数を使用します。
Sub 変数が配列か調べる() ' 純粋に配列で宣言した変数 Dim 配列変数() Debug.Print IsArray(配列変数) ' = True ' 全く配列でない変数 Dim 文字列変数 As String Debug.Print IsArray(文字列変数) ' = False ' Variantに配列を入れた場合 Dim Variant変数 Variant変数 = Array(1, 2, 3) ' = True Debug.Print IsArray(Variant変数) ' = True ' 配列を返す関数を直接入れた場合 Debug.Print IsArray(Array(1, 2, 3)) ' = True Debug.Print IsArray(Split("1,2,3", ",")) ' = True Debug.Print IsArray(Range("A1:C3").Value) ' = True Debug.Print IsArray(Range("A1:C3")) ' = True! ' Range変数を入れた場合 Dim Range変数 As Range: Set Range変数 = Range("A1:C3") Debug.Print IsArray(Range変数) ' = True! ' 配列を返すプロパティを直接入れた場合 Dim Dictionary変数 As New Dictionary Debug.Print IsArray(Dictionary変数.Items) ' = True End Sub
上記の通り変数に限らず、
関数の返り値や、配列を取得するプロパティもTrue判定してくれます。
ひとつ注意しなければならないのが、
Rangeオブジェクトが.Valueを省略してもTrueとなっている点です。
セル範囲が入っているRangeオブジェクトは、
.Valueをつけると配列、なければRangeオブジェクトを指しますが、
IsArray関数はそもそもRangeオブジェクトでもTrueを返します。
' Range変数を入れた場合 Dim Range変数 As Range: Set Range変数 = Range("A1:C3") Debug.Print IsArray(Range変数) ' = True!
しかしRangeオブジェクトはもちろん配列ではないため、
例えばUbound(Range変数)は「配列がありません」エラーを返します。
この仕様で発生するもっともありがちな事故として、
Sub エラーテスト() Call 配列の要素すべてをループする(Range("A1:C3")) ' ← .Valueを書き忘れた End Sub Sub 配列の要素すべてをループする(Arr) If IsArray(Arr) = False Then Exit Sub ' .Valueの書き忘れを検知できない Dim i As Long For i = LBound(Arr) To UBound(Arr) ' ← ここでエラー ' 配列の要素ごとの処理 Next End Sub
こんな風に.Valueを書き忘れたとしてもIsArrayを突破してしまいます。
この仕様には注意しておきましょう。
とはいえ、普通に変数に代入する
Dim Arr Arr = Range("A1:C3")
この文であれば、.Valueがなくても普通に配列が入ります。
※ 間違ってSetを書いてしまうようなことがなければ
この事故が発生するのは「関数の引数をVariantにしたとき」なので、
それもあわせて心の片隅に置いておいてください。