初心者が「戻り値」と「ByRef」をどう使い分けるか迷わないように、設計判断フローをチェックリスト形式で整理しました。各ステップに対応するコード例も付けています。
設計チェックリスト
- 返す値は1つだけか?
- ✔ Yes → 関数の戻り値で返す
- ✔ No → 次へ
- 複数値を返す必要があるか?
- ✔ Yes → ByRefで返却用引数を使う
- ✔ No → 次へ
- 参照(RangeやWorksheetなど)を差し替えたいか?
- ✔ Yes → ByRefで参照を変更
- ✔ No → 次へ
- 副作用を避けたいか?
- ✔ Yes → ByVal+戻り値で安全に設計
- ✔ No → ByRefを使っても良いが、コメントで意図を明示する
コード例付きフロー
1. 値が1つだけ → 戻り値
Function AddTax(ByVal amount As Double) As Double
AddTax = amount * 1.1
End Function
Sub Test1()
Debug.Print AddTax(1000) ' → 1100
End Sub
VB2. 複数値を返す → ByRef
Sub GetCoordinates(ByRef x As Double, ByRef y As Double)
x = 10
y = 20
End Sub
Sub Test2()
Dim a As Double, b As Double
GetCoordinates a, b
Debug.Print a, b ' → 10, 20
End Sub
VB3. 参照を差し替える → ByRef
Sub MoveRange(ByRef r As Range)
Set r = r.Offset(1, 0)
End Sub
Sub Test3()
Dim rng As Range
Set rng = Sheet1.Range("A1")
MoveRange rng
rng.Value = "Shifted" ' A2 に書き込まれる
End Sub
VB4. 副作用を避けたい → 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
Sub Test4()
Dim a() As Long
ReDim a(1 To 2): a(1) = 10: a(2) = 20
a = GrowArray(a, 4)
Debug.Print UBound(a) ' → 4
End Sub
VB✅ まとめ
- 戻り値は主結果用 → 読みやすく安全。
- ByRefは副次結果や参照差し替え用 → 意図を明示して使う。
- 入力は必ずByVal → 呼び出し元を壊さない。
- コメントや名前付けで意図を明示 → 「返却用」「参照変更用」と分かるように。
👉 このチェックリストを「設計の定規」として使えば、ByRefの危険な副作用を避けつつ、必要な場面でだけ安全に活用できます。

