Excel VBA | 安全に ByRef を使う設計パターン(複数値返却や参照差し替えを明示する方法)

VBA
スポンサーリンク

ByRef は「呼び出し元の変数を直接書き換える」ため便利ですが、初心者が使うと副作用で混乱しやすいです。そこで 安全に使うための設計パターン を整理します。


1. 複数値返却パターン

目的

関数の戻り値は1つしか返せないため、複数の結果を返したいときに ByRef を使う。

Sub GetCoordinates(ByRef x As Double, ByRef y As Double)
    x = 10
    y = 20
End Sub

Sub Test()
    Dim a As Double, b As Double
    GetCoordinates a, b
    Debug.Print a, b   ' → 10, 20
End Sub
VB

ポイント

  • 「この引数は結果を返すために使う」と明示する。
  • コメントや名前付けで「返却用」であることを分かりやすくする。

2. 参照差し替えパターン

目的

呼び出し元の変数が指すオブジェクトや範囲を、意図的に別のものへ差し替える。

Sub MoveRange(ByRef r As Range)
    Set r = r.Offset(1, 0)   ' 呼び出し元も次の行を指すようになる
End Sub

Sub Test()
    Dim rng As Range
    Set rng = Sheet1.Range("A1")
    MoveRange rng
    rng.Value = "Shifted"    ' A2 に書き込まれる
End Sub
VB

ポイント

  • 「参照を差し替える」意図を明確にする。
  • コメントで「このSubは参照を変更します」と書いておくと安心。

3. 戻り値と ByRef の役割分担

目的

  • 戻り値: 主な結果を返す
  • ByRef: 追加の副次的な情報を返す

Function Divide(ByVal a As Double, ByVal b As Double, ByRef remainder As Double) As Double
    remainder = a Mod b
    Divide = a \ b
End Function

Sub Test()
    Dim q As Double, r As Double
    q = Divide(10, 3, r)
    Debug.Print q   ' → 3
    Debug.Print r   ' → 1
End Sub
VB

ポイント

  • 主結果は戻り値で返す → 読みやすい。
  • 副次的な値は ByRef → 複数返却が必要な場合に限定。

4. ByRef を「返却専用」にする

目的

呼び出し元の値を変更しないで、結果だけを返す。

Sub CalculateStats(ByVal arr() As Double, ByRef avg As Double, ByRef maxVal As Double)
    Dim i As Long, sum As Double
    sum = 0
    maxVal = arr(LBound(arr))
    For i = LBound(arr) To UBound(arr)
        sum = sum + arr(i)
        If arr(i) > maxVal Then maxVal = arr(i)
    Next
    avg = sum / (UBound(arr) - LBound(arr) + 1)
End Sub
VB

ポイント

  • 入力は必ず ByVal
  • 出力専用の引数だけ ByRef
  • 役割を分けることで副作用を防ぐ。

5. 明示的に「参照破棄」を行う場合

目的

呼び出し元の参照を意図的に消す(例: リソース解放)。

Sub ReleaseRange(ByRef r As Range)
    Set r = Nothing   ' 呼び出し元も参照が消える
End Sub
VB

ポイント

  • 「このSubを呼ぶと参照が消える」と明示する。
  • コメント必須。誤用すると Null 参照エラーになる。

まとめ指針

  • 基本は ByVal。
  • ByRef は「返却用」「参照差し替え用」に限定。
  • コメントや名前付けで意図を明示(例: ByRef resultX As Double)。
  • 戻り値と ByRef を使い分ける → 主結果は戻り値、副次結果は ByRef。
  • 参照破棄や差し替えは危険なので必ず明示的に設計。
VBA
スポンサーリンク
シェアする
@lifehackerをフォローする
スポンサーリンク
タイトルとURLをコピーしました