Excel VBA | 「危険な ByRef の使い方」— 初心者がよくハマる罠集

VBA
スポンサーリンク

VBA初心者が ByRef(参照渡し) を使うときに陥りやすい罠を整理しました。ByRefは便利ですが、呼び出し元の変数が直接書き換わるため、意図しない副作用が起きやすいです。


1. デフォルトが ByRef 問題

  • 罠: 引数に何も指定しないと自動的に ByRef になる。
  • 例:
Sub AddFive(n As Integer)   ' ← ByRef 扱い
    n = n + 5
End Sub

Sub Test()
    Dim x As Integer
    x = 10
    AddFive x
    Debug.Print x   ' → 15(意図せず書き換わる)
End Sub
VB
  • 解説: 「戻り値を返すつもりがないのに変数が変わる」ことが混乱の原因。
    必ず ByVal を明示する習慣をつける。

2. 複数のプロシージャで値が壊れる

  • 罠: 同じ変数を複数のSubに渡すと、どこで書き換えられたか分からなくなる。
  • 例:
Sub UpdateAll()
    Dim msg As String
    msg = "Hello"
    AppendWorld msg
    AppendExclamation msg
    Debug.Print msg   ' → "Hello World!!!"
End Sub
VB
  • 解説: 呼び出し先が次々に書き換えるため、「元の値がどこで変わったか」追えなくなる

3. 配列の構造変更(ReDim/Erase)

  • 罠: ByRefで渡した配列を ReDimErase すると、呼び出し元の配列も消える。
  • 例:
Sub ClearArray(ByRef arr() As Long)
    Erase arr
End Sub
VB
  • 解説: 呼び出し元の配列が突然消えるため、後続処理でエラーになる。
    配列の構造変更は戻り値で新しい配列を返す方が安全

4. オブジェクト参照の付け替え

  • 罠: RangeやWorksheetをByRefで渡して Set し直すと、呼び出し元の参照も変わる。
  • 例:
Sub MoveRange(ByRef r As Range)
    Set r = r.Offset(1, 0)
End Sub
VB
  • 解説: 呼び出し元の変数が意図せず別セルを指すようになる。
    「中身を変える」処理と「参照を変える」処理を混同しやすい

5. Nothing の代入で参照が消える

  • 罠: ByRefで渡したオブジェクトに Set obj = Nothing すると、呼び出し元の参照も消える。
  • 例:
Sub KillRange(ByRef r As Range)
    Set r = Nothing
End Sub
VB
  • 解説: 呼び出し元で r.Value を使おうとするとエラー。
    参照破棄は呼び出し元に影響するため危険

6. デバッグ困難な副作用

  • 罠: ByRefの副作用で「どこで値が変わったか」分からなくなる。
  • 例: 複数モジュールで同じ変数を渡し回すと、値が予期せず変わる。
  • 解説: デバッグ時に「どこで壊れたか」追跡が難しい。
    副作用を減らすために ByVal を基本にする

✅ 安全に使うための指針

  • 基本は ByVal。
  • ByRef は「返却用」「参照差し替え用」に限定。
  • コメントや名前付けで意図を明示(例: ByRef resultX As Double)。
  • 戻り値と ByRef を使い分ける → 主結果は戻り値、副次結果は ByRef。
  • 参照破棄や差し替えは危険なので必ず明示的に設計。

VBA
スポンサーリンク
シェアする
@lifehackerをフォローする
スポンサーリンク
タイトルとURLをコピーしました