「ユーザー定義関数の戻り値を2つ以上にしたいな」
VBAでツール作成をしていると、複数の値に対して「同じ処理を行う」「複数の戻り値が欲しい」という時があります。
しかし、関数の戻り値は1つしかありませんし、増やすこともできません。
なので、一般的な戻り値の得方ではなく、疑似的に戻り値を複数に取得できるようにします。
そんな方法を本記事では『ByRefキーワード』を使った方法を紹介します。
「ByRefキーワード」で複数の値を返す関数を作る
ここで重要になるのは関数側の引数で指定する際に用いる『ByRefキーワード』です。
このキーワードを使って、関数での戻り値を複数にします。
【はじめに】関数への値の渡し方
まず、プロシージャーの引数の渡し方には主に下の2つがあります。
種類 | 意味 |
ByVal | 引数で値として渡す。
引数で渡した値を変更しても、呼び出し元の値には影響なし。 |
ByRef | 引数で参照によって渡す。
引数で渡した値を変更すると、呼び出し元の値も変更される。 |
「ByValキーワード」を指定して引数を渡した場合、呼び出し元で渡した値のコピーを渡します。
なので、この指定で引数を渡した場合は、関数内で渡された引数に新たな値を代入したとしても、呼び出し元には影響がありません。
ですが、関数の引数に「ByRefキーワード」を指定して引数を渡した場合、渡された引数に変化を与えると呼び出し元のその変数にも変化を反映させることができます。
コレを『参照渡し』と呼びます。
この参照渡しの仕組みを用いれば、Functionプロシージャーの引数の数だけ値を返すことができるようになります。
【確認】ByValとByRefの違い
ここでは「ByValキーワード」「ByRefキーワード」の2つの引数でどう違うのかを確認しておきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
Sub sample() Dim byVal_Str As String Dim byRef_Str As String byVal_Str = "変更前" byRef_Str = "変更前" Call func1(byVal_Str, byRef_Str) MsgBox "ByVal指定の値:" & byVal_Str & vbCrLf & _ "ByRef指定の値:" & byRef_Str End Sub |
上のコードでは6、7行目で「ByVal指定の値」「ByRef指定の値」にも”変更前”という文字列を代入しています。
この2つの変数を9行目で関数の引数として渡し、関数内で違う文字列を代入します。
その結果を11、12行目でメッセージボックスで確認するという流れにしています。
下が関数の中身になります。
1 2 3 4 5 6 |
Function func1(ByVal byVal_Str As String, ByRef byRef_Str As String) byVal_Str = "変更しました" byRef_Str = "変更しました" End Function |
1行目で「ByVal」「ByRef」の2つのキーワードでそれぞれの引数を指定しています。
そして、その引数を3、4行目で”変更しました”という文字列を新たに代入しています。
上のコードを実行した場合、下のような結果が得られます。
この結果を見てもらうとわかりますが、「ByVal」で指定した値は”変更前”と関数内の処理が反映されていません。
ですが、「ByRef」で指定した値は”変更しました”となっているので、関数内の処理が反映されています。
この「ByRef」の仕組みを利用して、関数で複数の値を戻り値にすることが可能になります。
【具体例】複数の値を返すコード
上のコードで大体理解できたかと思います。
ですが、一応、実際に「複数の値を返す」という内容でやってみます。
下のコードは「100円と500円の2つ商品の価格(消費税込み)をメッセージボックスに表示する」という内容になります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
Sub Main() Dim price1 As Long Dim price2 As Long price1 = 100 price2 = 500 Call Tax(price1, price2) MsgBox "100円の消費税込みの価格は「" & price1 & "円」、" & vbCrLf & _ "500円の価格は「" & price2 & "円」です" End Sub |
9行目で『Tax』という関数の引数に2つの変数を指定して呼び出しています。
ここで渡した変数の値が変更される予定で、それらの変数を使って11,12行目でメッセージボックスに表示させるようにしています。
そして、下がTax関数の処理内容になります。
1 2 3 4 5 6 7 8 9 10 |
Function Tax(ByRef price1 As Long, ByRef price2 As Long) Dim taxRate As Double taxRate = 0.08 price1 = price1 * (1 + taxRate) price2 = price2 * (1 + taxRate) End Function |
1行目で2つの引数をByRefキーワードで指定しています。
それらの引数に7,8行目で計算結果を代入しています。
上のコードを実行すると下のような結果が得られます。
この結果で分かるように、2つの値が変更され表示されています。
このように自作の関数で複数の戻り値を得たい場合には、関数の引数にByRefキーワード
を指定すると実現します。
1位 | 2位 | 3位 |
---|---|---|
Excel VBA 脱初心者のための集中講座 | パーフェクトExcel VBA | ExcelVBA 実戦のための技術 |
初心者~中級者 | 中級者 | 初心者~中級者 |
【初心者が手に取るべき参考書】 ・「書籍+動画」で圧倒的に理解しやすい入門書になっている。 ・丁寧で詳しい解説でボリューム感がある。 | 【より深い理解をしたい方にお勧めな参考書】 ・テーマに対して丁寧な解説・適度な深さで解説されている。 ・幅広くテーマを扱っていることから、基礎知識をあらかた網羅できる。 | 【入門書と一緒に買うべき参考書】 ・1つ1つのテーマを経験豊富なエンジニア視点で解説してくれている。 ・実践的で効果的なコードの書き方が理解できる。 |
【読んでみた一言】 正直、入門書はコレ一冊でいいかも。あとは中級者用の参考書に進むべし。 | 【読んでみた一言】 深く書かれているが、少々専門的に書かれていることから、読む前に数冊の入門書を読破したほうが良い。 | 【読んでみた一言】 基礎知識を持っている人が次のレベルに達するきっかけを与えてくれる参考書である。 |
スポンサーリンク