Excel VBA | 関数の戻り値と ByRef の使い分け — 設計フロー(チェックリスト+コード例)

VBA
スポンサーリンク

実務シナリオ別「戻り値 vs ByRef」チェックリスト適用例集

先ほどのチェックリストを 実務でよくあるシナリオ に当てはめて、具体的なコード例をまとめました。これで「どの場面で戻り値を使うか」「どの場面でByRefを使うか」がイメージしやすくなります。


1. 売上計算(平均・最大値)

  • チェックリスト適用:
    • 主結果は1つ(平均値) → 戻り値
    • 副次結果(最大値) → ByRef
Function CalcSalesStats(ByVal sales() As Double, ByRef maxVal As Double) As Double
    Dim i As Long, sum As Double
    sum = 0
    maxVal = sales(LBound(sales))
    For i = LBound(sales) To UBound(sales)
        sum = sum + sales(i)
        If sales(i) > maxVal Then maxVal = sales(i)
    Next
    CalcSalesStats = sum / (UBound(sales) - LBound(sales) + 1)
End Function

Sub TestSales()
    Dim data(1 To 5) As Double, avg As Double, maxVal As Double
    data(1) = 100: data(2) = 200: data(3) = 150: data(4) = 300: data(5) = 250
    avg = CalcSalesStats(data, maxVal)
    Debug.Print "平均値:"; avg, "最大値:"; maxVal
End Sub
VB

2. セル参照更新(Rangeの移動)

  • チェックリスト適用:
    • 「参照を差し替えたい」 → ByRef
Sub MoveRange(ByRef r As Range)
    Set r = r.Offset(1, 0)   ' 呼び出し元も次の行を指すようになる
End Sub

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

3. 割引計算(安全設計)

  • チェックリスト適用:
    • 値は1つだけ返す → 戻り値
    • 副作用を避けたい → ByVal
Function ApplyDiscount(ByVal price As Double, ByVal rate As Double) As Double
    ApplyDiscount = price * (1 - rate)
End Function

Sub TestDiscount()
    Dim p As Double
    p = 1000
    Debug.Print ApplyDiscount(p, 0.2)   ' → 800
    Debug.Print p                       ' → 1000(元の値は変わらない)
End Sub
VB

4. 複数の統計値(平均・最大・最小)

  • チェックリスト適用:
    • 複数値返却 → ByRef
Sub CalcStats(ByVal arr() As Double, ByRef avg As Double, ByRef maxVal As Double, ByRef minVal As Double)
    Dim i As Long, sum As Double
    sum = 0
    maxVal = arr(LBound(arr))
    minVal = arr(LBound(arr))
    For i = LBound(arr) To UBound(arr)
        sum = sum + arr(i)
        If arr(i) > maxVal Then maxVal = arr(i)
        If arr(i) < minVal Then minVal = arr(i)
    Next
    avg = sum / (UBound(arr) - LBound(arr) + 1)
End Sub
VB

5. 配列の拡張(新しい配列を返す)

  • チェックリスト適用:
    • 副作用を避けたい → ByVal+戻り値
Function GrowArray(ByVal src() As Long, ByVal newSize As Long) As Long()
    Dim b() As Long, i As Long
    ReDim b(1 To newSize)
    For i = LBound(src) To UBound(src)
        b(i) = src(i)
    Next
    GrowArray = b
End Function
VB

6. セルの値と書式を同時返却

  • チェックリスト適用:
    • 複数値返却 → ByRef
Sub GetCellInfo(ByVal r As Range, ByRef val As Variant, ByRef fmt As String)
    val = r.Value
    fmt = r.NumberFormat
End Sub
VB

7. 参照破棄(リソース解放)

  • チェックリスト適用:
    • 「参照を消したい」 → ByRef
Sub ReleaseRange(ByRef r As Range)
    Set r = Nothing   ' 呼び出し元も参照が消える
End Sub
VB

✅ 総まとめ

  • 戻り値は主結果用 → 読みやすく安全。
  • ByRefは副次結果や参照差し替え用 → 意図を明示して使う。
  • 入力は必ずByVal → 呼び出し元を壊さない。
  • コメントや名前付けで意図を明示 → 「返却用」「参照変更用」と分かるように。

👉 この具体例集を「自分の業務シナリオ」に当てはめると、どこでByRefを使うべきか/避けるべきかがすぐ判断できます。

タイトルとURLをコピーしました