ホーム > >

VBA ByValとByRefの基本的な使用方法と区別

VBAでプロシージャまたは関数を定義するときに、変数を渡す必要がある場合は、渡す方法を指定しなければなりません。次には2種類の引数を渡す方法があります。

  • ByVal:値渡し
  • ByRef:参照渡し

この記事では、2つの方法の使い方と相違点を説明します。 プロシージャと関数の引数を渡し方法は大体同じです。この記事では、プロシージャ(Sub)を例にして使用して、両方の使い方と相違点を説明します。

ByValとByRefの基礎

プロシージャまたは関数を定義するときに、変数を渡す必要がある場合は、各引数が渡す方法を指定する必要があります。渡す方法には、ByValとByRefの2種類があります。

'ByVal 渡す方法
Sub TestSub1(ByVal msg As String)
End Sub
'ByRef 渡す方法
Sub TestSub2(ByRef msg As String)
End Sub

数値、文字列などの基本的なデータ型に対して、2種類の渡す方法の説明と相違点は次のとおりです。

  • ByVal:変数を渡すときに、変数のコピーを作成して、プロシージャまたは関数に渡します。 プロシージャと関数内の変数の変更はコピーのみ有効であり、上位のプロシージャ(親プロシージャ)の変数に影響がありません。
  • ByRef:変数を渡すときに、変数の参照アドレスをプロシージャまたは関数に渡します。 参照アドレスを渡すということは、プロシージャまたは関数内の内容を変更されると、上位のプロシージャ(親プロシージャ)の変数の値に影響を与えることを意味します。

ByVal実例

次のコードを使用してByValを実行します。

Sub Test()
Dim msg As String
msg = "main"
TestSub1 msg
Msgbox msg
End Sub

'ByVal 渡し方法
Sub TestSub1(ByVal msg As String)
msg = "val"
End Sub

まずはmsg変数を定義し、値をmainに割り当て、次にTestSub1プロシージャを呼び出し、msg変数を渡して、プロシージャ内のmsgにvalを再割り当てします。最後に、前のプロシージャに戻り、msg変数を表示します。 結果は次のようになります。msg変数の値は変更されていません。

ByRef実例

次のコードを使用してByRefを実行します。

Sub Test()
Dim msg As String
msg = "main"
TestSub2 msg
MsgBox msg
End Sub

'ByRef 渡す方法
Sub TestSub2(ByRef msg As String)
msg = "ref"
End Sub

まずmsg変数を定義し、値をmainに割り当て、次にTestSub2プロシージャを呼び出し、msg変数を渡し、プロシージャ内でrefをmsgに再割り当てします。 最後に、前のプロシージャに戻り、msg変数を表示します。 結果は次のようになり、msg変数の値が変更されました。

渡す方法を省略する

通常、渡す方法を省略するときに、デフォルト値はByValであるため、次の2つの書き方の結果は同じです。

'ByVal 渡す方法を指定する
Sub TestSub1(ByVal msg As String)
End Sub

'渡す方法を省略する
Sub TestSub1(msg As String)
End Sub

ByValとByRefを使用してオブジェクトを渡す

上記で述べたように、上記のメカニズムは、数値、文字列、論理値など、基本的なデータ型の変数を渡すのに適しています。

ByValとByRefを使用してオブジェクトを渡す場合、状況は多少異なります。オブジェクトを解説する際に、具体的な使い方と相違点について詳しく説明します。

ByValとByRefを使用して配列を渡す

プロシージャまたは関数が配列を渡す場合、参照渡しのみ使え、つまりByRef渡す方法です。ByValを使用して配列を渡そうとすると、VBAはエラーを提示します。詳細な使い方は、配列を解説するときに詳しく説明します。

まとめ

ByValとByRefは引数を渡す方法を示します。 基礎データ型の変数に対して、ByValは変数のコピーを作成し、それをプロシージャまたは関数に渡します。その後は親プロシージャの変数と関係がありません。ByRefで変数の参照渡しは始終親プロシージャの変数に接続されます。

そのため、子プロシージャまたは関数が親プロシージャの変数を誤って変更して、見つけにくい問題が発生するのを防ぐために、できるだけByVal渡す方法を使用することをお勧めします。

オブジェクト変数と配列変数の渡しは、基本的なデータ型の変数とは異なります。関連するチュートリアルで詳細を説明します。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です