【VBA】引数の参照渡し(ByRef)と値渡し(ByVal)の違いとは?

目次

はじめに

VBAでサブルーチンに引数を渡す際、「参照渡し(ByRef)」と「値渡し(ByVal)」という2つの方法があることをご存知でしょうか?この2つは似て非なるもので、違いを理解しないままでいると、「呼び出したマクロに変数を渡したら、元の値まで変わってしまった!」という予期せぬバグの原因になります。

一言で違いを説明するなら、こうです。

  • 参照渡し (ByRef): 変数そのもの(原本)を渡す。
  • 値渡し (ByVal): 変数の値だけをコピーしたもの(コピー)を渡す。

この記事では、この重要な違いを、具体的なコード例を使って分かりやすく解説します。


参照渡し (ByRef):原本を渡す

ByRef は “By Reference” の略で、「参照によって渡す」という意味です。サブルーチンに変数の「場所(メモリアドレス)」を教えるため、サブルーチン内での変更が、呼び出し元の元の変数に直接反映されます。

VBAでは、ByValByRef を省略すると、デフォルトで ByRef になります。

ByRef のサンプルコード

' === メインの実行マクロ ===
Sub Main_ByRef_Example()
    Dim originalValue As String
    originalValue = "元の値"
    
    ' 結果をC2セルに出力
    Worksheets("Sheet1").Range("C2").Value = originalValue
    
    ' サブルーチンを呼び出す
    Call ModifyValue_ByRef(originalValue)
    
    ' 呼び出し後の値をC3セルに出力
    Worksheets("Sheet1").Range("C3").Value = originalValue
End Sub


' --- ByRefで引数を受け取るサブルーチン ---
' ByRefは省略可能だが、明記すると分かりやすい
Private Sub ModifyValue_ByRef(ByRef textData As String)
    ' 受け取った引数の値を変更する
    textData = "値が変更されました"
End Sub

実行結果

Main_ByRef_Example を実行すると、以下のようになります。

  • C2セル: 元の値
  • C3セル: 値が変更されました <– 元の変数の値が変わっている!

これは、ModifyValue_ByReforiginalValue 変数の原本を直接書き換えたためです。


値渡し (ByVal):コピーを渡す

ByVal は “By Value” の略で、「値によって渡す」という意味です。サブルーチンに変数の値のコピーだけを渡すため、サブルーチン内でそのコピーをいくら変更しても、呼び出し元の元の変数には何の影響もありません

ByVal のサンプルコード

' === メインの実行マクロ ===
Sub Main_ByVal_Example()
    Dim originalValue As String
    originalValue = "元の値"
    
    ' 結果をD2セルに出力
    Worksheets("Sheet1").Range("D2").Value = originalValue
    
    ' サブルーチンを呼び出す
    Call ModifyValue_ByVal(originalValue)
    
    ' 呼び出し後の値をD3セルに出力
    Worksheets("Sheet1").Range("D3").Value = originalValue
End Sub


' --- ByValで引数を受け取るサブルーチン ---
' ByValキーワードを明記する必要がある
Private Sub ModifyValue_ByVal(ByVal textData As String)
    ' 受け取った引数(コピー)の値を変更する
    textData = "値が変更されました"
End Sub

実行結果

Main_ByVal_Example を実行すると、以下のようになります。

  • D2セル: 元の値
  • D3セル: 元の値 <– 元の変数の値は変わっていない!

これは、ModifyValue_ByValoriginalValue のコピーだけを受け取って変更したため、原本には影響がなかったことを示しています。


まとめと使い分け

参照渡し (ByRef)値渡し (ByVal)
渡すもの変数の原本(場所)変数の値のコピー
元の変数変更される変更されない
宣言方法ByRef を付けるか、省略するByVal を付ける
用途サブルーチンに値を変更して返してほしい場合元の値を保護したい場合

意図しない値の変更は、追跡が難しいバグの温床になります。そのため、サブルーチンが受け取った値を変更する必要がない場合は、安全のために常に ByVal を明記するのが、堅牢なプログラムを書くための良い習慣と言えます。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次