![](https://excel-vba.work/wp-content/themes/cocoon-master/images/b-woman.png)
サブプロシージャ等の引数には
・値渡し
・参照渡し
の2種類があります!
![](https://excel-vba.work/wp-content/themes/cocoon-master/images/b-woman.png)
引数の宣言で
・ByValとすると値渡し
・ByRefとすると参照渡し
になります!
※Valは「Value」の略で「値」を示しています。
※Refは「Reference」の略で「参照」を示しています。
※どちらも記述していない場合は「参照渡し」になります。
![「ByVal」としているため「値渡し」](https://excel-vba.work/wp-content/uploads/2021/11/vba_arg_001.png)
![「ByRef」としているため「参照渡し」](https://excel-vba.work/wp-content/uploads/2021/11/vba_arg_002.png)
![何も記述していないため「参照渡し」](https://excel-vba.work/wp-content/uploads/2021/11/vba_arg_003.png)
![](https://excel-vba.work/wp-content/themes/cocoon-master/images/b-woman.png)
ですが
・ByRef(参照渡し)としていても
・呼び出し時に「カッコ」をつけると「値渡し」になる
という裏仕様があります!
※VBAの公式サイトには上記の記載がありません(私には見つけられません)。
※ですが実際にVBAコードを実行すると分かります。
![呼び出し時に「カッコ」をつけると「値渡し」になる](https://excel-vba.work/wp-content/uploads/2021/11/vba_arg_005.png)
VBAコード
ここでは例として
・引数を「ByRef(参照渡し)」としたプロシージャ「proc」を定義
・プロシージャ「main」から引数にカッコを付けてプロシージャ「proc」を呼び出し
・プロシージャ「proc」にて書き換えられたはずの変数「name」の値を確認
します。
※「ByRef(参照渡し)」のため書き換えられたはずの変数が、書き換えられていないことを確認します。
Option Explicit
Sub main()
Dim name As String
'変数「name」に「佐藤」を設定する。
name = "佐藤"
'引数を渡してサププロシージャ「proc」を実行 ※実験のため引数にカッコを付ける。
proc (name)
'ByRef(参照渡し)のため、変数「name」は「佐藤」ではなく「ゴンザレス」が設定されているはずだが、
'裏仕様により「佐藤」が設定されている。
'この結果より、ByRefなのに「参照渡し」ではなく「値渡し」になっていることが分かる。
'値渡しが強制されていることが分かる。
MsgBox name
End Sub
'サププロシージャ「proc」
Sub proc(ByRef name As String)
'引数としてもらったnameに「ゴンザレス」を設定
'ByRef(参照渡し)のため、呼び出し元の変数「name」に「ゴンザレス」と設定されるはずだが…
name = "ゴンザレス"
End Sub
実行結果
「ゴンザレス」ではなく「佐藤」が表示されました。
※変数「name」が書き換えられていないことを確認できました。
※引数の値渡しが強制されていることを確認できました。
![実行結果](https://excel-vba.work/wp-content/uploads/2021/11/vba_arg_004.png)
参考
この「値渡しを強制する」という仕様は、VBAの公式サイトには記載がありませんが、Visual Basicの公式サイトには記載があります。
詳細は公式サイトご確認ください。
●Visual Basicの値渡しを強制について