【ExcelVBA】プロシージャの引数2(値渡しと参照渡し)
プロシージャの引数2(値渡しと参照渡し)
引数を使ってプロシージャにデータを渡す方法は、大きく分けて「値渡し」と「参照渡し」の2種類があります。
前回紹介したのは、「参照渡し」です。今回は2つの方法を比較しながら違いについて紹介していきます。
値渡し
まずは、「値渡し」のサンプルプログラムを見てみましょう。
前回までと大きくことなるのは、「testByVal」プロシージャの引数の前に「ByVal」キーワードが付いているところです。
このキーワードを引数の前に付けることで、「値渡し」になります。
'' 値渡しのサンプル Sub VBA基礎第22回_1() Dim buf As Integer buf = 1 Call testByVal(buf) Debug.Print buf End Sub Sub testByVal(ByVal x As Integer) x = x + 10 End Sub
処理の流れを見ていきましょう。
まず、呼び出し元で変数「buf」に「1」が代入されます。(プログラム5行目)
次に「testByVal」プロシージャが呼び出されます。このとき、引数に「buf」を指定していますので、変数「x」に「10」が代入されてプロシージャを実行します。(プログラム6行目)
呼び出されたプロシージャ側で変数「x」の値をプラス10します。(プログラム14行目)
プロシージャの処理が全て完了したので、呼び出し元に戻ります。
呼び出し元で変数「buf」を出力します。
変数「buf」の値は変わっていないため、最初に代入した「1」がイミディエイトウィンドウに表示されます。(プログラム8行目)
参照渡し
次に「参照渡し」のプログラムを見てみましょう。プロシージャ名を変更していますが、注目していただきたいのは、キーワードが「ByRef」に変わったところです。
'' 参照渡しのサンプル Sub VBA基礎第22回_2() Dim buf As Integer buf = 1 Call testByRef(buf) Debug.Print buf End Sub Sub testByRef(ByRef x As Integer) y = y + 10 End Sub
実行結果はイミディエイトウィンドウに「11」と表示されます。「値渡し」のときと実行結果が変わっていますね。
処理の流れを見ていきましょう。
まず、呼び出し元で変数「buf」に「1」が代入されます。(プログラム5行目)
※ここは「値渡し」と同じです。
次に「testByRef」プロシージャが呼び出されます。このとき、引数に「buf」を指定しています。(プログラム6行目)
※ここは「値渡し」と同じです。ここから先が変わります。
ただし、この変数「x」は呼び出し元の変数「buf」と実質的に同じ箱となります。そのため、変数「x」には変数「buf」と同じ値である「1」が保存されているように見えます。実際には同じ箱になるので変数名が異なるだけで、同じ変数と考えることもできます。
1つの箱(変数)にラベルが2つ付いている(「buf」と「x」)と考えて頂いてもOKです。
呼び出されたプロシージャ側で変数「x」の値をプラス10します。(プログラム14行目)
※ここは「値渡し」と同じです。ここから先が変わります。
「参照渡し」では、変数「buf」と変数「x」は同じものなので、変数「buf」の値もプラス10されたように見えます。
実際には、同じ箱(変数)のため、変数「x」と変数「buf」の値がそれぞれプラスされたと考えるのは誤りです。
プロシージャの処理が全て完了したので、呼び出し元に戻ります。
※ここは「値渡し」と同じです。
呼び出し元で変数「buf」を出力します。
変数「buf」の値はプロシージャの中でプラス10されているため、「11」がイミディエイトウィンドウに表示されます。(プログラム8行目)
最後に、引数の前に「ByRef」も「ByVal」もどちらも指定しなかった場合には、「ByRef」が指定されたものとみなされます。
まとめ
引数を使ってプロシージャにデータを渡す方法は、大きく分けて「値渡し」と「参照渡し」の2種類がある。
引数の定義をするときに、「値渡し」であれば「ByVal」を、「参照渡し」であれば「ByRef」を指定する。
どちらも指定していない場合には参照渡しである「ByRef」が指定されたものとみなされる。
確認問題
以下の「○○○」に当てはまる文言を解答してください。
引数の定義をするときに、「値渡し」であれば「○○○」を、「参照渡し」であれば「○○○」を指定する。
どちらも指定していない場合には参照渡しである「○○○」が指定されたものとみなされる。
「○○○」では、プロシージャ内で引数の値を変更したときに、その呼び出し元でもその変更が反映する。
次回は、プロシージャの引数3です。