Variant仮引数のByRefとByValの挙動違い
ツイッターで出したVBAのお題です。
Variant型は、どんなデータ型も入れることができてしまいます。
具体的なデータ型の代わりに使用することで、より柔軟にVBA記述ができるようになります。
ただしこの便利さゆえに、逆に注意しなければならない挙動もあります。
お題のツイート
Sub sample()
Dim rng1 As Range, rng2 As Range
Set rng1 = Range("A1:B1")
Set rng2 = Range("A2:B2")
Call sample_sub(rng1, rng2)
End Sub
Sub sample_sub(ByRef v1, ByVal v2)
v1 = 1
v2 = 1
MsgBox WorksheetFunction.Sum(v1, v2)
End Sub
sampleの実行結果は?
・1
・2
・3
・4
解説のツイート
ByRef、ByVal、呼ばれた関数ではどちらもRangeオブジェクトとして受け取ります。
しかし、このときByRefとByValでは一部挙動に違いが現れます。
受け取ったRangeオブジェクトに対するVBA記述によって違いが出てきます。
Set代入した場合には、
ByRefなら参照私として呼び出し元も変化しますが、
ByValなら受け取るだけであり呼び出し元は変化しません。
Range = 値
このLet代入でRangeが複数セルでも全てのセルのValueに値が入ります。
仮引数がRange型(As Range)であれば、Let代入は同じ動作となります。
しかしVariantでRangeを受け取った場合は、Let代入で挙動に違いが出てきます。
ByRefであれば、RangeのValueに値が入りますが、
ByValの場合は、Variant変数のRangeは破棄され、値そのものが変数に入ってしまいます。
これは、プロシージャー内でVariant変数を定義している場合を考えれば当然の結果として理解できます。
Set v = Rangeオブジェクト
v.Value = 1 '①
v = 1 '②
①では、Rangeオブジェクトの全てのValueに値(1)が入ります。
②では、変数vに値(1)そのものが入ります。
ByValで受け取った場合は、プロシージャー内で変数定義したことと同じになります。
Call sample_sub(rng1, rng2)
Sub sample_sub(ByRef v1, ByVal v2)
v1 = 1 '①
v2 = 1 '②
①では、Rangeオブジェクトの全てのValueに値(1)が入ります。
②では、変数vに値(1)そのものが入ります。
v2は、1がVariant/Integerとして代入されます。
結果として、
Sum(Range("A1:B1"), 1)
となるので、答えは3となります。
「VBAのVariant型について」
https://excel-ubara.com/excelvba4/EXCEL_VBA_441.html
同じテーマ「ツイッター出題回答 」の記事
100桁の正の整数値の足し算
新着記事NEW ・・・新着記事一覧を見る
TRIMRANGE関数(セル範囲をトリム:端の空白セルを除外)|エクセル入門(2024-08-30)
正規表現関数(REGEXTEST,REGEXREPLACE,REGEXEXTRACT)|エクセル入門(2024-07-02)
エクセルが起動しない、Excelが立ち上がらない|エクセル雑感(2024-04-11)
ブール型(Boolean)のis変数・フラグについて|VBA技術解説(2024-04-05)
テキストの内容によって図形を削除する|VBA技術解説(2024-04-02)
ExcelマクロVBA入門目次|エクセルの神髄(2024-03-20)
VBA10大躓きポイント(初心者が躓きやすいポイント)|VBA技術解説(2024-03-05)
テンキーのスクリーンキーボード作成|ユーザーフォーム入門(2024-02-26)
無効な前方参照か、コンパイルされていない種類への参照です。|エクセル雑感(2024-02-17)
初級脱出10問パック|VBA練習問題(2024-01-24)
アクセスランキング ・・・ ランキング一覧を見る
1.最終行の取得(End,Rows.Count)|VBA入門
2.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
3.変数宣言のDimとデータ型|VBA入門
4.繰り返し処理(For Next)|VBA入門
5.RangeとCellsの使い方|VBA入門
6.ブックを閉じる・保存(Close,Save,SaveAs)|VBA入門
7.セルのクリア(Clear,ClearContents)|VBA入門
8.メッセージボックス(MsgBox関数)|VBA入門
9.条件分岐(Select Case)|VBA入門
10.マクロとは?VBAとは?VBAでできること|VBA入門
このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。
記述には細心の注意をしたつもりですが、
間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。
掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。