ByVal と ByRef Macユーザー向け Excel VBA 入門 [08] Excel2019 for Mac
[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ウィンドウ を開く。
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コード」で置換します。
コピペ あるいは 入力 ミスチェックのため、以下画面のように VBAProject のコンパイル を行い 「VBAコードの文法チェック」が可能です。
ByVal と ByRef 、文字列操作 のサンプル
「イミディエイト ウィンドウ」にて call sample1() [return] と入力し Sample1() プロシージャを実行すると、以下2つのメッセージボックス画面を表示。
キーワードを省略した場合も ByRef (参照渡し)となり、Proc1() の引数(パラメーター)に指定した変数の変更を確認!
「イミディエイト ウィンドウ」にて call sample2() [return] と入力し Sample2() プロシージャを実行すると、以下2つのメッセージボックス画面を表示。
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つのメッセージボックス画面を表示。
キーワードを省略した場合も ByRef (参照渡し)となり、Proc3() の引数(パラメーター)に指定した変数の変更を確認!
「イミディエイト ウィンドウ」にて call sample4() [return] と入力し Sample4() プロシージャを実行すると、以下2つのメッセージボックス画面を表示。
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 も終了させます。 「作業中のブック」を保存するか確認のダイアログ画面が表示された場合は 「保存」しましょう。 「自動保存」済みの場合、保存するかどうかの確認ダイアログ画面は表示されません。
次回は、 作成した ユーザー定義関数 を他のブックから呼び出す方法 を説明します。
最後まで読んでいただき、ありがとうございます。 また、お越しくださいませ。
// アタル