VBAのByValで引数を値渡しする方法をわかりやすく解説

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

ByValの概要

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

ByVal

概要 ByVal キーワードは、VBAでプロシージャ(Sub や Function)の引数を「値渡し」にするために使用されます。値渡しを指定すると、引数の値がコピーされ、関数内で変更しても元の変数には影響を与えません。

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

  • 関数やSubプロシージャに値をコピーして渡す。
  • 関数内で変更しても、呼び出し元の変数には影響しない。
  • デフォルト(ByRef)とは異なり、元の変数を保護できる。

ByValの基本的な使い方

以下の例では、変数を ByVal で渡しており、関数内で値を変更しても元の変数は影響を受けません。

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

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

解説:

  • Sub ChangeValue(ByVal x As Integer): x を値渡しで受け取る。
  • x = x * 2: 関数内では x の値を変更するが、元の変数 num には影響しない。
  • Call ChangeValue(num): 変数 num を渡すが、元の値は変化しない。

ByValとByRefの違い

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

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)。

関数の引数にByValを使う

関数の引数を ByVal にすると、元の変数の値を変更せずに処理できます。

Function Square(ByVal num As Integer) As Integer
    num = num * num
    Square = num
End Function

Sub TestByValFunction()
    Dim x As Integer
    x = 5

    MsgBox "元の値: " & x & vbCrLf & "二乗の結果: " & Square(x)
End Sub

解説:

  • Function Square(ByVal num As Integer): num を値渡しで受け取る。
  • 関数内で num を変更しても、元の変数 x には影響しない。
  • MsgBox で元の値と計算結果を表示。

オブジェクト変数とByVal

VBAでは、オブジェクト変数(Worksheet, Workbook など)を ByVal で渡すと、参照そのものはコピーされるが、オブジェクトの内容は変更可能です。

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

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

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

解説:

  • ByVal でオブジェクト変数を渡しても、オブジェクトの中身(シート名)は変更される。
  • オブジェクトの参照自体はコピーされるが、実体は同じなので、変更が反映される。

注意点

  • デフォルトはByRef: VBAでは、明示的に指定しない場合は ByRef(参照渡し)になる。
  • 元の変数を変更したくない場合にByValを使う: 値をコピーして渡すため、安全にデータを保持できる。
  • オブジェクト変数の扱いに注意: ByVal で渡しても、オブジェクトの内容は変更可能。

よくある質問

Q: ByVal を使わないとどうなりますか?
A: VBAのデフォルトは ByRef なので、引数の値が変更される可能性があります。
Q: ByVal を使うメリットは?
A: 元の変数を保護し、意図しない変更を防げるため、安全にデータを扱えます。
Q: オブジェクトを ByVal で渡すとどうなりますか?
A: オブジェクトの参照はコピーされますが、内容の変更は反映されます。

まとめ

  • ByVal は引数を値渡しにするためのキーワード。
  • 関数やSub内で値を変更しても、元の変数には影響しない。
  • デフォルト(ByRef)と異なり、データの安全性を確保できる。
  • オブジェクト変数の場合は、参照がコピーされるが、内容の変更は可能。