ExcelVBAにおける参照渡しと値渡しの違い

何事もそうですが、何かに取り組んでいたり勉強したりしていると「壁」というか、どうしてもわからない部分って出てくると思います。

 

例えばテキストの前半部分を読んでいてどうしてもわからない部分があったとします。そういった所は読み飛ばしてどんどん進んでいくと後半部分に書かれていることで前半部分でわからなかった所が理解できることもあります。

 

ExcelVBAでも、以前の自分は次の機能の概念や違いがわかっていませんでした。

  • 参照渡し
  • 値渡し

 

テキストを読んだ時は何となくわかったような気がするんですけど、ExcelVBAでいざコードを書いてみると何かこちらの意図通りに動いてくれないとか、例題のコードをVBE上で動かしても「なぜそうなるのか」がわかっていない時がありました。

 

ExcelVBAを勉強してきた中でなかなか理解できなかった部分は多々ありました。その中でも今回は「参照渡しと値渡しの違い」について、とある本をきっかけに理解できるようになったので備忘録という意味でも整理していってみます。

スポンサーリンク

ExcelVBAにおける参照渡しと値渡しとは

ExcelVBAにおける参照渡しと値渡しとは何か。簡単に説明すると教科書的には以下のような形になります。

  • 参照渡しは「変数そのもの」を渡すデータの渡し方
  • 値渡しは「変数の値だけ」を渡すデータの渡し方

 

これだけ見てもチンプンカンプンかと思います。以前勉強していた自分も教科書上で何度この部分を見返してもなかなかこの違いが理解できませんでした。「変数そのもの」と「変数の値だけ」という言葉を見ても「えっ?」って感じになるかと思います。

 

コードの中で、この参照渡しと値渡しが使われる前後の部分をもう少し説明すると参照渡しの結果を得られるコードにおいて、『VBAエキスパート公式テキスト ExcelVBAスタンダード』には次のように書かれています。

p.33
Sub Sample6()
Dim buf As String
buf = "Excel VBA"
Call Sample7(buf)
MsgBox buf
End Sub
Sub Sample7(msg As String)
msg = "VBAエキスパート"
End Sub

上記のコードを簡単に説明するとSample6のプロシージャでまず、文字列型のbufを宣言、そのbufに「Excel VBA」という文字列を格納します。そしてCallステートメントでSample7を呼び出します。

 

Sample7ではSample6で設定された「buf」を引数として受け取り、msgへ格納。そのmsgをSample7でmsgへ格納されたbuf(この時点ではまだbufに「Excel VBA」が格納されている)の値を「VBAエキスパート」という文字列へ変更しています。

 

処理はSample6へ戻り、Call Sample7(buf)の次の行であるMsgBox bufが実行されて、ここでSample7で設定された「VBAエキスパート」の文字列がメッセージボックスとして表示されます。

 

普通に考えるとSample7は「Subプロシージャ」なので、Sample6へ戻り値は送らず、メッセージボックスには「Excel VBA」の文字列が表示されるはずですが、実際には表示はされていません。

 

以上がテキスト上では「参照渡し」の処理となっています。もう少しわかりやすいように比較として「値渡し」の処理を引用してみます。

p.34
Sub Sample6()
Dim buf As String
buf = "Excel VBA"
Call Sample7(buf)
MsgBox buf
End Sub
Sub Sample7(ByVal msg As String)
msg = "VBAエキスパート"
End Sub

さっきのコードと違う点はSample7においてSample6で設定されたbufを受け取る時の引数の形が「Byval」になっているという点です。この部分の引数の定義に「ByVal」というキーワードをつけると「変数の値だけを受け取る」という意味になります。

 

ちなみに「参照渡し」で受け取るときは、引数の定義に「ByRef」というキーワードをつけるというのがルールになっています。ただし、この参照渡しと値渡しを使う上での注意点として次のようなものがあります。

  • 「ByRef」と「ByVal」のどちらも指定しなかった場合には、「ByRef」が指定されたものとみなされる。
  • そのため引数の定義でデータの渡し方を省略すると、その引数は「参照渡し」になる

 

以上が文章で説明したExcelVBAにおける「参照渡し」と「値渡し」の違いとなります。今はちゃんと理解できた形で書けていますが、以前の自分はこれだけでは理解するのが困難でした。ですから、この部分に関しては悩むというかしばらくの間悶々とする日々を送ることになります。

 

そういった中で気分転換というか、以前から面白そうだなと思っていた本がありまして、そっちを読んでいたら偶然答えが見つかることになります。それが

  • 『Excel VBAでIEを思いのままに操作できるプログラミング術』

という本でした。

コメント