ByVal と ByRef Macユーザー向け Excel VBA 入門 [08] Excel2019 for Mac

ByVal and ByRef(Png)

[08] ByVal と ByRef 、プロシージャ記述のオプション指定により結果が異なる場合(2つの例)

 ByVal と ByRef 、文字列操作 と 数値操作 サンプル

文字列操作 のサンプル
数値操作 のサンプル

デフォルト ByRef のため、状況に応じて ByVal (値渡し) キーワードを付加!

(注) 引数(パラメーター)指定した変数に「呼び出し先プロシージャの結果」を反映させたい場合のみ、 ByRef (参照渡し・ポインタ渡し) 指定を用います。




 Macユーザー向け Excel VBA 入門 [08] ByVal と ByRef 

 まず、Excel メニューバーの [ヘルプ] - [更新プログラムのチェック] にて、適用されていないアップデートがあれば行ってください。


 以下4つの操作方法がよく解らない方は、 Excel VBA 入門 [06] を参照して下さい。

(1) 「空のブック」Excelファイルを新規作成にて作成後、「名前を付けて保存…」にて、「Excel マクロ有効ブック(.xlsm)」ファイル形式を選び 任意の名前で保存。

(2) ( [マクロの記録] ボタンをクリックして)マクロの保存先に「作業中のブック」を指定後 [OK] ボタンをクリックし、「マクロの記録」を開始。  マクロ名は "Sample1" にて! 

(3) 例えば「A3」セルを選択後、( [記録終了] ボタンをクリックして)「マクロの記録」を終了

(4) [マクロ] ボタンをクリックして 先ほど作成した "Sample1" マクロを選択後 [編集] ボタンをクリックし、 VBEウィンドウ を開く。

vba2019_primer[08] 04_png

 ByVal と ByRef 、プロシージャ記述のオプション指定により結果が異なる場合 


' =========================================
Sub Sample1()
    Dim buf As String    ' 文字列型の変数を宣言
    buf = "ABCDE"        ' 変数に、文字列”ABCDE”を格納
    Call Proc1(buf)      ' プロシージャProc1の引数に変数を渡して呼出
    MsgBox "Sample1: " & buf  ' 変数の値を表示
End Sub

Sub Proc1(str As String) ' 省略すると、ByRef(参照渡し・ポインタ渡し)
    str = str & "XYZ"    ' 受け取った文字列に”XYZ”を加える
    MsgBox "Proc1: " & str  ' 変数の値を表示
End Sub

' =========================================
Sub Sample2()
    Dim buf As String    ' 文字列型の変数を宣言
    buf = "ABCDE"        ' 変数に、文字列”ABCDE”を格納
    Call Proc2(buf)      ' プロシージャProc2の引数に変数を渡して呼出
    MsgBox "Sample2: " & buf  ' 変数の値を表示
End Sub

Sub Proc2(ByVal str As String)  ' 値渡し(変数のコピーが渡される)
    str = str & "XYZ"    ' 受け取った文字列に”XYZ”を加える
    MsgBox "Proc2: " & str    ' 変数の値を表示
End Sub

 [VBE ウィンドウ]-[コード ウィンドウ]内の Sub Sample1() 以下を「上記のVBEコード」で置換します。

vba2019_primer[08] 05_png

 コピペ あるいは 入力 ミスチェックのため、以下画面のように VBAProject のコンパイル を行い 「VBAコードの文法チェック」が可能です。

vba2019_primer[08] 06_png

 ByVal と ByRef 、文字列操作 のサンプル 

 「イミディエイト ウィンドウ」にて call sample1() [return] と入力し Sample1() プロシージャを実行すると、以下2つのメッセージボックス画面を表示。

vba2019_primer[08] 08_png

vba2019_primer[08] 09_png

 キーワードを省略した場合も ByRef (参照渡し)となり、Proc1() の引数(パラメーター)に指定した変数の変更を確認!


 「イミディエイト ウィンドウ」にて call sample2() [return] と入力し Sample2() プロシージャを実行すると、以下2つのメッセージボックス画面を表示。

vba2019_primer[08] 10_png

vba2019_primer[08] 11_png

 ByVal キーワードを付加した場合、Proc2() の引数(パラメーター)には 指定した変数のコピー が与えられるため、 Sample2() 内の変数は変更されず元のまま


 ByVal と ByRef 、数値操作 のサンプル 


' =========================================
Sub Sample3()
    Dim num As Integer   ' 整数型の変数を宣言
    num = 0              ' 変数に、 0 をセット
    Call Proc3(num)      ' プロシージャProc3の引数に変数を渡して呼出
    MsgBox "Sample3: " & num  ' 変数の値を表示
End Sub

Sub Proc3(num As Integer)   ' 省略すると、ByRef(参照渡し・ポインタ渡し)
    num = num + 1           ' 変数をインクリメント(+1する)
    MsgBox "Proc3: " & num  ' 変数の値を表示
End Sub

' =========================================
Sub Sample4()
    Dim num As Integer   ' 整数型の変数を宣言
    num = 0              ' 変数に、 0 をセット
    Call Proc4(num)      ' プロシージャProc4の引数に変数を渡して呼出
    MsgBox "Sample4: " & num  ' 変数の値を表示
End Sub

Sub Proc4(ByVal num As Integer)  ' 値渡し(変数のコピーが渡される)
    num = num + 1           ' 変数をインクリメント(+1する)
    MsgBox "Proc4: " & num  ' 変数の値を表示
End Sub

 [VBE ウィンドウ]-[コード ウィンドウ]内にて、 Sub Proc2 〜 End Sub 直後に「上記のVBEコード」を付け加えます。


 コピペ あるいは 入力 ミスチェックのため、先程のように VBAProject のコンパイル を行い 「VBAコードの文法チェック」が可能です。


 「イミディエイト ウィンドウ」にて call sample3() [return] と入力し Sample3() プロシージャを実行すると、以下2つのメッセージボックス画面を表示。

vba2019_primer[08] 12_png

vba2019_primer[08] 13_png

 キーワードを省略した場合も ByRef (参照渡し)となり、Proc3() の引数(パラメーター)に指定した変数の変更を確認!


 「イミディエイト ウィンドウ」にて call sample4() [return] と入力し Sample4() プロシージャを実行すると、以下2つのメッセージボックス画面を表示。

vba2019_primer[08] 14_png

vba2019_primer[08] 15_png

 ByVal キーワードを付加した場合、Proc4() の引数(パラメーター)には 指定した変数のコピー が与えられるため、 Sample4() 内の変数は変更されず元のまま


 デフォルト ByRef のため、状況に応じて ByVal (値渡し) キーワードを付加! 

 キーワードを省略した場合 ByRef (参照渡し・ポインタ渡し) となるため、状況に応じて ByVal (値渡し) キーワードを付加する必要があります。

 ほとんどのプログラム言語では「値渡し」がデフォルト(省略値)ですが、なぜか Visual Basic 6.0 と VBA は「参照渡し」がデフォルトになっています。

 「値渡し」をデフォルトにする理由は関数やプロシージャを一種のブラックボックスと考え、呼び出し元の変数が 呼び出し先にて勝手に変更されないようにするためです。
(不具合の発生を減らす努力を続ける事で)将来的にバグ回避に繋がりますので...

 事実、最新の Visual Basic である VB.NET ( Visual Basic .NET ) では、 C# 等の他言語との互換性のため「値渡し」がデフォルトに変更されました。

 結論として VBA では できる限り ByVal キーワードを付加して 呼び出し元の変数が勝手に変更されないようにし、敢えて 呼び出し元の変数に 呼び出し先プロシージャの結果を反映させたい場合のみ ByRef (参照渡し・ポインタ渡し)を用いるべき です。

 なお、Function プロシージャの結果として返される変数は一つだけですが、プロシージャの引数(パラメーター)は複数指定できるので、ByRef を用いて 複数の結果を返すことも可能です。

 Function プロシージャの結果として返される変数に、 配列や ユーザー定義型(構造体) を指定するほうが一般的ですが…

 配列や ユーザー定義型(構造体) の説明は、また後日させて頂きます。



 [command] + [Q] にてまず VBE を終了し、Excel のウィンドウ内を選択して [command] + [Q] にて Excel も終了させます。 「作業中のブック」を保存するか確認のダイアログ画面が表示された場合は 「保存」しましょう。 「自動保存」済みの場合、保存するかどうかの確認ダイアログ画面は表示されません。

 次回は、 作成した ユーザー定義関数 を他のブックから呼び出す方法 を説明します。





広告
  




Macブログ ランキング アイコン
最後まで読んでいただき、ありがとうございます。 また、お越しくださいませ。
// アタル
For follow LINE Reader Group!Subscribe to this blog on Feedly!

Next Post Previous Post
No Comment
Add Comment
comment url