VBAのByRefで引数を参照渡しする方法をわかりやすく解説

スポンサーリンク
スポンサーリンク

ByRefの概要

引数を参照渡しする VBAの予約語

ByRef

概要 ByRef キーワードは、VBAでプロシージャ(Sub や Function)に引数を渡す際に「参照渡し」を指定するために使用されます。参照渡しにすると、引数の値を変更した場合に呼び出し元の変数にも反映されます。

わかりやすく説明 プロシージャに渡した値を変更すると、元の変数にも影響を与えるようにする指定。

  • デフォルトではVBAの引数は ByRef(参照渡し)で渡される。
  • プロシージャ内で変更した値が呼び出し元の変数にも影響を与える。
  • 値渡し(ByVal)と対比して使われることが多い。

ByRefの基本的な使い方

以下の例では、変数を ByRef で渡し、プロシージャ内で変更すると元の変数にも反映されます。

Sub ChangeValue(ByRef x As Integer)
    x = x * 2 ' 引数の値を2倍にする
End Sub

Sub TestByRef()
    Dim num As Integer
    num = 10
    
    Call ChangeValue(num) ' numを参照渡しで渡す
    
    MsgBox "変更後の値: " & num ' 結果: 変更後の値: 20
End Sub

解説:

  • Sub ChangeValue(ByRef x As Integer): x を参照渡しで受け取る。
  • x = x * 2: 受け取った値を2倍に変更。
  • Call ChangeValue(num): num を渡すと、元の変数にも変更が適用される。

ByRefとByValの違い

ByRef(参照渡し)と ByVal(値渡し)の違いを比較します。

Sub ChangeByRef(ByRef x As Integer)
    x = x + 10
End Sub

Sub ChangeByVal(ByVal x As Integer)
    x = x + 10
End Sub

Sub CompareByRefAndByVal()
    Dim num1 As Integer, num2 As Integer
    num1 = 5
    num2 = 5

    Call ChangeByRef(num1)
    Call ChangeByVal(num2)

    MsgBox "ByRef の結果: " & num1 & vbCrLf & "ByVal の結果: " & num2
End Sub

解説:

  • ByRef の場合、元の変数 num1 の値が変更される(結果: 15)。
  • ByVal の場合、関数内で変更しても元の変数 num2 には影響しない(結果: 5)。

配列をByRefで渡す

VBAでは、配列はデフォルトで ByRef で渡されるため、関数内で変更した内容がそのまま反映されます。

Sub ModifyArray(ByRef arr() As Integer)
    arr(0) = arr(0) + 100
End Sub

Sub TestArrayByRef()
    Dim numbers(2) As Integer
    numbers(0) = 10

    Call ModifyArray(numbers)
    
    MsgBox "配列の先頭要素: " & numbers(0) ' 結果: 110
End Sub

解説:

  • 配列は ByRef で渡されるため、関数内での変更がそのまま元の配列に影響する。
  • arr(0) = arr(0) + 100 の処理が numbers(0) にも反映される。

オブジェクト変数とByRef

VBAのオブジェクト変数(Worksheet, Workbook など)はデフォルトで ByRef で渡されます。

Sub ChangeSheetName(ByRef ws As Worksheet)
    ws.Name = "新しい名前"
End Sub

Sub TestObjectByRef()
    Dim ws As Worksheet
    Set ws = ThisWorkbook.Sheets(1)

    Call ChangeSheetName(ws)
    
    MsgBox "変更後のシート名: " & ws.Name
End Sub

解説:

  • オブジェクト変数(ws)は ByRef で渡されるため、シート名の変更が反映される。
  • Set ws = ThisWorkbook.Sheets(1) により、特定のシートを操作対象にする。

注意点

  • デフォルトはByRef: VBAでは、明示的に指定しなくても基本的に ByRef で渡される。
  • 変更を意図しない場合はByValを使う: 参照渡しのため、関数内で変更すると元の変数も変わるので注意。
  • 配列はByRef渡しが標準: 配列のデータを変更する関数を作るときは、元のデータが影響を受けることを考慮する。

よくある質問

Q: ByRef は明示的に指定しなくても機能しますか?
A: はい、VBAのデフォルトの引数の渡し方は ByRef です。ただし、明示的に書くとコードの可読性が向上します。
Q: ByRef で渡したくない場合はどうすればいいですか?
A: ByVal を使うことで、値渡し(コピー)で処理できます。
Q: ByRef はオブジェクト変数にも適用されますか?
A: はい、オブジェクト変数もデフォルトで ByRef で渡されるため、関数内で変更すると元のオブジェクトに影響を与えます。

まとめ

  • ByRef は引数を参照渡しするためのキーワードで、デフォルトの挙動でもある。
  • 関数やSubプロシージャ内で引数の値を変更すると、元の変数も変更される。
  • 配列やオブジェクトは ByRef で渡されるため、関数内での変更がそのまま適用される。
  • 意図しない変更を防ぐためには、ByVal を使用すると安全。