How to pass arguments between procedures ByRef,ByVal Excel(Excel) Macro(VBA)

Excel Macro (VBA)
The article contains advertisements.

プロシージャを分けた場合の引数の渡し方を書きます。

下の記事でコードを書く際はプロシージャを分けた方が読みやすく、加工がしやすくなることを記載しました。

What is an Excel (Excel) Macro (VBA) Module and Procedure?

しかし、今度はプロシージャを分けることによる問題も出てきます。

それが引数の渡し方です。

引数の引き渡し方

まず引数が引き渡されていないコードを用意しました。


Sub 朝()
    Dim aisatsu As String
    aisatsu = "おはようございます"
    Call 表示
End Sub

Sub 表示()
    MsgBox aisatsu
End Sub

このコードは「朝」というプロシージャで「aisatsu」に「おはようございます」という言葉を格納し、「表示」というプロシージャで「aisatsu」に格納された言葉をメッセージボックスで表示させています。

「朝」を実行してみます。

メッセージボックスは表示されましたが、中身は何も表示されませんでした。

これは「朝」というプロシージャで「aisatsu」という変数に「おはようございます」という言葉を格納したのですが、同じ「aisatsu」という変数でも「表示」というプロシージャでは「aisatsu」に何も格納されていないため、何も表示されませんでした。

次にこのように修正してみました。


Sub 朝()
    Dim aisatsu As String
    aisatsu = "おはようございます"
    Call 表示(aisatsu)
End Sub

Sub 表示(ByVal aisatsu As String)
    MsgBox aisatsu
End Sub

もう一度「朝」を実行してみます。

きちんと引数が引き渡されました。

ByValとByRefの使い分け

  • ByVal (値渡し)
  • ByRef(参照渡し)

ByValは渡されたプロシージャの中で値の変更ができませんので、値が変わってしまっては困るような場面で使います。

ByRefは渡されたプロシージャの中で値の変更ができますので、値をどんどん変更していく必要がある場面で使います。

言葉では難しいので具体的に違いを見てみましょう。

ByVal(値渡し)

「表示」というプロシージャの中を少し変えて、「朝」の中で「表示」を2回連続で呼び出しています。


Sub 朝()
    Dim aisatsu As String
    aisatsu = "おはようございます"
    Call 表示(aisatsu)
    Call 表示(aisatsu)
End Sub

Sub 表示(ByVal aisatsu As String)
    MsgBox aisatsu
    aisatsu = "こんにちは"
End Sub

「朝」を実行してみます。

「OK」を押すと

もう一度同じ言葉が出てきました。

「朝」のプロシージャから持ってきた引数を「表示」の中でいくら変更しても「朝」のプロシージャに戻った時には変更内容が引き継がれていないことがわかります。

ByRef(参照渡し)

次に「ByVal」を「ByRef」に変えてみます。


Sub 朝()
    Dim aisatsu As String
    aisatsu = "おはようございます"
    Call 表示(aisatsu)
    Call 表示(aisatsu)
End Sub

Sub 表示(ByRef aisatsu As String)
    MsgBox aisatsu
    aisatsu = "こんにちは"
End Sub

これで「朝」を実行してみると

そして

言葉を変えることができました。

ByVal,ByRefの省略

ちなみに「ByVal」と「ByRef」は省略することもできます。

省略するとどうなるのでしょうか。


Sub 朝()
    Dim aisatsu As String
    aisatsu = "おはようございます"
    Call 表示(aisatsu)
    Call 表示(aisatsu)
End Sub

Sub 表示( aisatsu As String)
    MsgBox aisatsu
    aisatsu = "こんにちは"
End Sub

実行してみます。

そして

となりました。

つまり省略すると「ByRef」と同じということがわかりました。

Comment

Copied title and URL