複数のプロシージャ間でデータの受け渡しをするには次のようにします。
Sub Sample() Dim buf As String buf = "tanaka" ''変数に文字列"tanaka"を入れる Call Proc1(buf) ''プロシージャProc1の引数に変数を渡して呼び出す End Sub Sub Proc1(a As String) MsgBox a End Sub
これはシンプルな例ですね。では、データ(値)を受け取ったプロシージャ(ここではProc1)で値を変更したらどうなると思いますか。
実際に試してみましょう。
Sub Sample() Dim buf As String buf = "tanaka" ''変数に文字列"tanaka"を入れる Call Proc1(buf) ''プロシージャProc1の引数に変数を渡して呼び出す MsgBox buf ''変数の値を表示する End Sub Sub Proc1(a As String) a = "suzuki" ''受け取った値を"suzuki"に変える End Sub
変数bufの値が変わってしまいました。これは、「Sample」プロシージャから「Proc1」プロシージャへ変数そのものを渡したためです。このようなデータの渡し方を参照渡しと呼びます。
データの渡し方にはもう一つの方法があります。次のコードをご覧ください。
Sub Sample() Dim buf As String buf = "tanaka" ''変数に文字列"tanaka"を入れる Call Proc1(buf) ''プロシージャProc1の引数に変数を渡して呼び出す MsgBox buf ''変数の値を表示する End Sub Sub Proc1(ByVal a As String) a = "suzuki" ''受け取った値を"suzuki"に変える End Sub
今度は「Proc1」でデータを変更しても「Sample」の変数bufは変化しませんでした。このように、他のプロシージャに変数そのものを渡すのではなく、変数の値だけを渡す方法を値渡しと呼びます。
両者の違いは「Proc1」プロシージャの引数宣言です。値が変化しなかった二度目の「Proc1」は、受け取る引数の定義にByValというキーワードを付けています。これは「Proc1」の引数として受け取る変数「a」は、値渡しで受け取るという意味です。
"参照渡し"とか"値渡し"というと、渡す側に違いがあるように感じますが、実際には引数をどのように受け取るかといった、プロシージャの定義がポイントなのです。
変数の値が変わってしまった最初のコードでは、引数の定義に何も指定していません。実は、引数を参照渡しで受け取るときは、引数の定義にByRefというキーワードを付けるのが基本ルールです。
Sub Sample() Dim buf As String buf = "tanaka" ''変数に文字列"tanaka"を入れる Call Proc1(buf) ''プロシージャProc1の引数に変数を渡して呼び出す MsgBox buf ''変数の値を表示する End Sub''引数を参照渡しで受け取る Sub Proc1(ByRef a As String) a = "suzuki" ''受け取った値を"suzuki"に変える End Sub
ただし、ByRefとByValのどちらも指定しなかった場合には、ByRefが指定されたものとみなされます。引数の定義でデータの渡し方を省略すると、それは参照渡しになるということです。
参照渡しと値渡しの違いは、正確にはメモリ内で参照する場所が異なるのですが、そうした難しい話はともかく、イメージとしては次のような感じです。
参照渡しのイメージ
値渡しのイメージ
複数のプロシージャでデータを共有する方法は他にもあります。すべてのプロシージャで使用できる広域変数を使うのも手ですし、ワークシート上のセルやレジストリなどにデータを書き込んで、複数のプロシージャでそこを参照する方法もあります。どのやり方が最も優れているか…ということではなく、ケースに応じて適切な方法を使い分けるようにしましょう。