【VBA】配列とオブジェクトを引数にする方法とその注意点

こんな人に向けた記事です。

  • 配列orオブジェクトを引数とするやり方が知りたい
  • 配列を渡そうとしてエラーが起こって困っている
  • ちょっと手の込んだマクロを組みたい

今回はVBAで配列とオブジェクトを引数として渡す方法を紹介します。
オブジェクトは変数と同じ感覚で引き渡しできるのですが、配列は意識して書かないと構文エラーになります。

それでは、配列とオブジェクトを渡すときのやり方とその注意点を見ていきましょう。

①配列の渡し方

配列を引数として渡す場合は、注意して書いていかないと構文エラーになってしまいます。
構文エラーとしないためには、()をつけて書く必要があります。

例えば、arrという配列を引き渡す場合、呼び出す側と呼ばれる側の両方でarrの後ろに()を付ける必要があります。

  • 呼び出し側:Call サブジェクト名(arr())
  • 呼ばれる側:Sub サブジェクト名(arr())

このように、配列を引き渡す場合は()を付けると覚えておけば構文エラーを防げます。

【注意点】Variant型の配列は変数扱い

ちょっと気を付けておいて欲しいのはVariat型の変数から作成した配列は変数扱いされることです。

シート上のデータを一括して取得したいときに、次のようにVariant型の変数にデータを格納する方法を使うと思います。

Dim varArr As Variant
varArr = Range("A1:C3").Value

この変数varArrを引き渡す場合には、()が要りません。

通常の変数と同じ扱いとなるため注意しておきましょう。

【注意点】配列は値渡しできない

VBAの仕様として、配列は参照渡しのみで値渡しができないようになっています。
変数の感覚で値渡しにしていると構文エラーになるので、覚えておきましょう。

②オブジェクトの渡し方

オブジェクトを渡す場合は配列と違って、あまり気を付けることは少ない。

Call サブジェクト名(オブジェクト)

こんな形で、変数を引き渡す場合と同じような書き方をすれば問題なく渡すことができる。

【注意点】オブジェクトは値渡しもできる

勘違いしている人も多いかもしれないが、オブジェクトは配列と違って値渡しもすることができる。
値渡しすると引き渡したプロシージャ 内でオブジェクトを変更しても、元のプロシージャのオブジェクトは影響を受けない。

実際に、WorkSheetオブジェクトを値渡しした場合と参照渡しした場合の違いを確認するコードを書いてみた。
それぞれ呼び出し先のプロシージャ内で、WorkSheetオブジェクトにSetを行っている。

Option Explicit
Sub MainSub()
  Dim ShtRef As Worksheet:Set ShtRef = ThisWorkbook.Sheets("Sheet1")
  Dim ShtVal As Worksheet:Set ShtVal = ThisWorkbook.Sheets("Sheet1")
  Call 参照渡し(ShtRef)
  Call 値渡し(ShtVal)
  Debug.Print ShtRef.Name 'Sheet2
  Debug.Print ShtVal.Name 'Sheet1
End Sub

Private Sub 参照渡し(ByRef sht)
  Set sht = ThisWorkbook.Sheets("Sheet2") 'Sheet2をセット
End Sub

Private Sub 値渡し(ByVal sht As Worksheet)
  Set sht = ThisWorkbook.Sheets("Sheet2") 'Sheet2をセット
End Sub

ShtRefは参照渡し、ShtValは値渡ししている。

プロシージャを呼び出した後を見ると、参照渡ししたShtRefはSheet2に変わっているし、値渡ししたShtValはSheet1のままだ。

あまりオブジェクトを変更することは無いけれど、エラー回避を考えると値渡しを使用しておく方が無難で良さそうだ。

プチ情報:引数の読み方は?

最後にちょっとした情報を。

引数の読み方は分かりますか?
これ「いんすう」ではなく「ひきすう」と呼びます。
私は最初「いんすう」だと思っていました。

パソコンで変換しようとしても、「ひきすう」だと変換できますが、「いんすう」だと変換できません。

あまり口に出すことはないと思いますが、いつか役立つ、かも?

他の「VBA」の記事はこちらからどうぞ