参照渡し「ByRef」と値渡し「ByVal」の違い(Excel VBA)

先日、指定したフォルダ内のサブフォルダのフォルダ名を全部取得(Excel VBA)で出てきました

Call プロシージャ名(変数
↓↓↓↓
Sub プロシージャ名(引数

の流れ、難しくないですか?

Callで指定した変数を引数として受け取って、その引数をプロシージャの中で使用することができるのですが、引数の渡し方には2通りあります。
参照渡し「ByRef」と値渡し「ByVal」です。

■参照渡し「ByRef」

下記コードを実行すると・・・

Sub 参照渡しByRefをする場合()
    Dim 変数A As String
    変数A = "参照渡し変数だよ。"
    MsgBox "メッセージ1:" & 変数A '「メッセージ1:参照渡し変数だよ。」と表示される
    Call 参照渡しを受け取るよ(変数A)
    MsgBox "メッセージ4:" & 変数A '「メッセージ4:参照を変更したよ。」と表示される
End Sub

Sub 参照渡しを受け取るよ(ByRef 変数A As String)
    '「参照渡しByRefをする場合」プロシージャから
    '変数A="参照渡し変数だよ。"を引数として受け取り実行
    MsgBox "メッセージ2:" & 変数A '「メッセージ2:参照渡し変数だよ。」と表示される
    変数A = "参照を変更したよ。"
    MsgBox "メッセージ3:" & 変数A '「メッセージ3:参照を変更したよ。」と表示される
   
    '変数A=”参照を変更したよ。"と変数を変更した状態で
    '「参照渡しByRefをする場合」プロシージャに戻る
End Sub

こんな感じでメッセージが表示されます。

   変数A = “参照渡し変数だよ。”
↓↓↓↓↓↓↓↓↓↓↓↓
   変数A = “参照渡し変数だよ。”
↓↓↓↓↓↓↓↓↓↓↓↓
   変数A = “参照を変更したよ。”
↓↓↓↓↓↓↓↓↓↓↓↓
   変数A = “参照を変更したよ。”

「参照渡しByRefをする場合」プロシージャでは、

変数A = “参照渡し変数だよ。”

と変数が渡されます。そしてその変数は「参照渡しを受け取るよ」プロシージャに引き渡されて、そのまま使用することができます。

そして「参照渡しを受け取るよ」プロシージャで

変数A = “参照を変更したよ。”

と変更されてから、「参照渡しByRefをする場合」プロシージャに戻る時、変数A = “参照を変更したよ。”を

変更した状態のまま、元のプロシージャに戻ります

それが参照渡し「ByRef」の効果です。

処理開始時の値を受け取り、処理終了時の値を元のプロシージャに返します。

指定したフォルダ内のサブフォルダのフォルダ名を全部取得(Excel VBA)では、こちらの参照渡しを利用していました。

では

Call フォルダ名一覧取得(pt, ws, t_row)
↓↓↓
Sub フォルダ名一覧取得(pt As String, ws As Worksheet, t_row As Long)

としていたのですが、なぜ

Sub フォルダ名一覧取得(ByRef pt As String, ByRef ws As Worksheet, ByRef t_row As Long)

という風に「ByRef」を付けていなかったのでしょうか?

それは「ByRef」は省略してもよいことになっているので、省略していたのです。

引数の前には「ByRef」か「ByVal」のどちらかが付くことになりますが、何も付いていなかったら「ByRef」参照渡しだなぁ~と覚えておきましょう。

■スポンサーリンク

■値渡し「ByVal」

下記コードを実行すると・・・

Sub 値渡しByValをする場合()
    Dim 変数B As String
    変数B = "値渡し変数だよ。"
    MsgBox "メッセージ1:" & 変数B '「メッセージ1:値渡し変数だよ。」と表示される
    Call 値渡しを受け取るよ(変数B)
    MsgBox "メッセージ4:" & 変数B '「メッセージ4:値渡し変数だよ。」と表示される
End Sub

Sub 値渡しを受け取るよ(ByVal 変数B As String)
    '「値渡しByValをする場合」プロシージャから
    '変数B="値渡し変数だよ。"を引数として受け取り実行
    MsgBox "メッセージ2:" & 変数B '「メッセージ2:値渡し変数だよ。」と表示される
    変数B = "参照を変更したよ。"
    MsgBox "メッセージ3:" & 変数B '「メッセージ3:参照を変更したよ。」と表示される
    '変数B=”参照を変更したよ。"という変更は
    '「値渡しByValをする場合」プロシージャには返さない
End Sub

こんな感じでメッセージが表示されます。

   変数B = “値渡し変数だよ。”
↓↓↓↓↓↓↓↓↓↓↓↓
   変数B = “値渡し変数だよ。”
↓↓↓↓↓↓↓↓↓↓↓↓
   変数B = “参照を変更したよ。”
↓↓↓↓↓↓↓↓↓↓↓↓
   変数B = “値渡し変数だよ。”
「値渡しByValをする場合」プロシージャでは、

変数B =”値渡し変数だよ。”

と変数が渡されます。そしてその変数は「値渡しを受け取るよ」プロシージャに引き渡されて、使用することができます。

「値渡しを受け取るよ」プロシージャで

変数B = “参照を変更したよ。”

と変更されてから、「値渡しByValをする場合」プロシージャに戻る時、変数A = “参照を変更したよ。”という変更は

引き継がれず、元のプロシージャに戻ります

それが値渡し「ByVal」の効果です。

処理開始時の値は受け取りますが、処理終了時の値は元のプロシージャに戻しません。

以上、参照渡し「ByRef」と値渡し「ByVal」の違いでした。

【参考】

指定したフォルダ内のファイル名全てを取得(Excel VBA)
変数でよく使われる「buf」「tmp」の意味
Dir関数が取得するファイルの順番
フォルダ内のフォルダ名全てをGetAttrを使って「エラー53 ファイルが見つかりません。」を出さずに取得(Excel VBA)
GetAttrとは?「= vbDirectory」ではなく「And vbDirectory」となるビット演算の疑問
フォルダ名だけを取得したい時に出てくる 「.」 と 「..」 とは?
指定したフォルダ内とサブフォルダ内全てのファイル名を取得(Excel VBA)
CreateObject(“Scripting.FileSystemObject”) を使ってサブフォルダを取得
再帰処理とは?フォルダ内とサブフォルダ内全てのファイル名を取得(Excel VBA)

■スポンサーリンク

■ランキングに参加しています。
↓このブログを気に入っていただけましたら、ポチッとお願いします。
にほんブログ村 IT技術ブログへ
にほんブログ村