VBAでプロシージャや関数を作成していると、「引数の値が変わってしまった」「意図しない場所でデータが書き換わった」という経験をしたことはないでしょうか。
こうした問題は、引数の渡し方(ByVal / ByRef)を正しく理解していないことが原因で起きることが多いです。
VBAでは、プロシージャに値を渡すときに「ByVal」と「ByRef」という2つの方法があります。
この違いを理解していないと、処理が大きくなったときにバグの原因になったり、コードの意図が読み取りにくくなることがあります。
特に実務では、複数の値をプロシージャへ渡す場面が多く、
・売上データを処理する
・複数の設定値を関数へ渡す
・処理結果を別の処理へ渡す
といった設計をすることになります。
この記事では、
・ByValの基本
・ByRefとの違い
・複数の値を渡す方法
・実務で安全に使う設計
について、実務で保守しやすいVBAコードの考え方と合わせて解説します。
目次
✅ VBAのByValとは何か
VBAのByValは、引数を「値として渡す」指定です。
つまり、プロシージャに渡されたデータはコピーとして扱われ、元の変数には影響しません。
この仕組みを理解していないと、プロシージャの中で値を変更したときに「なぜ元の値が変わらないのか」「逆になぜ変わってしまうのか」といった混乱が起きます。
特に、チーム開発や長期運用されるVBAでは、引数の扱い方が曖昧だとコードの安全性が大きく下がります。
そのため、ByValの意味を理解しておくことは非常に重要です。
・ByValの基本構文
ByValはプロシージャの引数に指定します。
Sub SampleProcess(ByVal sales As Long)
sales = sales + 100
End Sub
このコードでは、salesは値として渡されるため、プロシージャの中で変更しても元の変数は変わりません。
・ByValの動作例
Sub MainProcess()
Dim totalSales As Long
totalSales = 1000
Call SampleProcess(totalSales)
Debug.Print totalSales
End Sub
この場合、出力される値は
1000
になります。
プロシージャ内で sales = sales + 100 を実行しても、
元の totalSales は変更されません。
・なぜByValが重要なのか
ByValは、元のデータを安全に守るための仕組みです。
例えば次のような処理があります。
・計算処理
・データ検証
・一時的な値変更
このような処理では、元データを書き換えない方が安全です。
ByValを使うことで、
元の変数を守りながら処理を実行できるようになります。
✅ VBAで複数の値を渡す基本設計
VBAのプロシージャでは、複数の値を同時に渡すことがよくあります。
実務では、1つの値だけを処理するケースは少なく、複数の設定値やデータをまとめて渡すことが一般的です。
しかし、引数が増えるほどコードは複雑になりやすく、設計を考えずに値を渡してしまうと、後からコードを読む人にとって理解しづらくなります。
そのため、複数の値を渡すときは「何を入力として渡しているのか」が明確になるように設計することが重要です。
・複数のByVal引数の構文
Sub CalculateSales(ByVal price As Double, ByVal quantity As Long)
Dim result As Double
result = price * quantity
Debug.Print result
End Sub
このように、複数の引数を並べて指定することができます。
・呼び出し例
Sub MainProcess()
Dim itemPrice As Double
Dim itemCount As Long
itemPrice = 1200
itemCount = 3
Call CalculateSales(itemPrice, itemCount)
End Sub
このようにすることで、
・価格
・数量
の2つの値をプロシージャへ渡すことができます。
・複数引数を使うメリット
複数引数を使うと、処理の意味が分かりやすくなります。
例えば、
CalculateSales(price, quantity)
という呼び出しを見るだけで、
「売上計算をしている」
ことが分かります。
これは、可読性の高いコード設計につながります。
複数の値を安全に受け渡すためには、
プロシージャの設計や呼び出し方も整理しておく必要があります。
VBAでのSub・Functionの呼び出し設計については、
次の記事で詳しく解説しています。
【VBA】標準モジュールの呼び出し方法とは|Sub・Functionの使い分けと実務設計
✅ ByValとByRefの違い
VBAでは、ByValと対になる概念として「ByRef」があります。
ByRefは、変数の参照を渡す方法です。
つまり、プロシージャ内で値を変更すると、元の変数も変更されます。
この違いを理解していないと、思わぬバグが発生します。
・ByRefの例
Sub ChangeValue(ByRef number As Long)
number = number + 100
End Sub
呼び出し側
Sub MainProcess()
Dim value As Long
value = 200
Call ChangeValue(value)
Debug.Print value
End Sub
結果
300
になります。
・ByValとByRefの使い分け
基本的な考え方は次の通りです。
ByVal
・値を変更しない
・安全な処理
・計算処理
ByRef
・値を変更する
・結果を返す
実務では、基本はByValにしておく方が安全です。
ByValとByRefの違いを理解していないと
変数の値が意図せず変更されるバグにつながることがあります。
値渡しと参照渡しの仕組みをより詳しく理解したい場合は、
次の記事も参考にしてください。
【VBA】ByVal と ByRef の違い|値渡し・参照渡しの理解を深める完全ガイド
✅ 実務で安全に使うByVal設計
VBAのコードが大きくなるほど、変数の扱い方は重要になります。
特に複数のプロシージャが連携する場合、どの処理がどのデータを変更しているのかが分からなくなることがあります。
そのため実務では、「データを書き換える処理」と「データを参照する処理」を明確に分ける設計が重要です。
ByValを使うことで、プロシージャは「入力値を受け取る処理」として安全に設計できます。
・入力値はByValで受け取る
例えば計算処理では、入力値は変更しないのが基本です。
Function CalculateTotal(ByVal price As Double, ByVal quantity As Long) As Double
CalculateTotal = price * quantity
End Function
このようにすることで、関数は
入力値 → 計算 → 結果
というシンプルな構造になります。
・コードの意図が明確になる
ByValを使うと、コードを読む人は
「この変数は変更されない」
と理解できます。
これは、保守性の高いコード設計につながります。
✅ VBAの引数設計はコード品質に直結する
VBAでは、引数の設計がコードの品質に大きく影響します。
引数の扱い方が曖昧だと、後から仕様変更をするときに問題が発生しやすくなります。
特に次のようなケースでは、引数設計が重要になります。
・複数のプロシージャが連携する処理
・業務データを扱う処理
・長期間運用されるマクロ
こうした処理では、どの変数が変更されるのかを明確にしておくことが重要です。
そのため実務では、
「基本はByVal」
という設計ルールを作ることもあります。
✅ まとめ:ByValは安全なVBA設計の基本
VBAのByValは、引数を値として渡すための仕組みです。
この指定を理解しておくことで、プロシージャ間のデータの扱いが明確になり、コードの安全性が高まります。
特に実務では、複数の値をプロシージャへ渡す場面が多く、引数設計がコード品質に大きく影響します。
今回のポイントを整理します。
・ByValは値をコピーして渡す
・プロシージャ内で変更しても元の値は変わらない
・複数の値は引数としてまとめて渡せる
・基本はByValを使う方が安全
・ByRefは値を変更する場合に使う
VBAでは、処理の内容だけでなく引数の設計も重要な要素です。
ByValを適切に使うことで、保守しやすく安全なVBAコードを作成できるようになります。