VBAで自動化 VBA一覧 セル・値の取得と貼り付け 値渡し・参照

【VBA】Function で複数の戻り値を返す方法と活用例

VBA の Function は通常、1つの戻り値を返す 仕様になっています。
しかし、場合によっては 「複数の値を返したい」 というケースがあります。

例えば、

  • 数値の計算結果とエラーステータスを返す
  • 開始日と終了日を一度に取得する
  • 複数のデータを関数から戻す

このような場合、VBA では配列・ユーザー定義型・ByRef引数を使うことで、複数の戻り値を返すことが可能 です。

本記事では、VBA で Function から複数の戻り値を返す方法とその活用例 を詳しく解説します。

Function で複数の戻り値を返す方法

方法① 配列を返す(戻り値に配列を使用)
方法② ユーザー定義型を返すType を使う)
方法③ ByRef で複数の引数を更新(関数の引数を ByRef で変更)

・配列を返す(Variant 型)

VBA の Function配列を戻り値として返す ことができます。

【VBA】セルの値を変数配列に取得:ループ処理

【例】2つの数値を加算・減算し、結果を配列で返す

Function Calculate(a As Double, b As Double) As Variant

Dim result(1) As Double
result(0) = a + b ' 加算
result(1) = a - b ' 減算
Calculate = result ' 配列を返す

End Function

Sub TestFunction()

Dim results As Variant
results = Calculate(10, 5)

Debug.Print "加算結果: " & results(0)
Debug.Print "減算結果: " & results(1)

End Sub

戻り値の Variant に配列を代入すると、複数の値を返せる!
結果を results(0), results(1) のように取得!

・ユーザー定義型(Type)を返す

VBA では、Type を使って カスタム型(ユーザー定義型)を作成し、それを戻り値として返す ことができます。

【例】長方形の面積と周囲長を返す

' ユーザー定義型の宣言(モジュールの上部に記述)
Type RectangleData

Area As Double
Perimeter As Double

End Type

Function GetRectangleData(width As Double, height As Double) As RectangleData

Dim result As RectangleData
result.Area = width * height ' 面積
result.Perimeter = 2 * (width + height) ' 周囲長
GetRectangleData = result ' ユーザー定義型を返す

End Function

Sub TestRectangle()

Dim rect As RectangleData
rect = GetRectangleData(10, 5)

Debug.Print "面積: " & rect.Area
Debug.Print "周囲長: " & rect.Perimeter

End Sub

Type を使うと、関連する複数の値を1つのオブジェクトとして管理できる!
rect.Arearect.Perimeter のように分かりやすくデータを取得できる!

・ByRef で複数の引数を更新

関数の引数を ByRef で渡すことで、複数の変数の値を関数内で変更し、実質的に複数の戻り値を持たせる ことができます。

【VBA】ByRefの基本的な使用方法

【例】最大値と最小値を取得

Sub GetMinMax(a As Double, b As Double, ByRef minVal As Double, ByRef maxVal As Double)

If a < b Then

minVal = a
maxVal = b

Else

minVal = b
maxVal = a

End If

End Sub

Sub TestMinMax()

Dim minVal As Double, maxVal As Double
GetMinMax 10, 5, minVal, maxVal

Debug.Print "最小値: " & minVal
Debug.Print "最大値: " & maxVal

End Sub

ByRef を使うと、複数の変数の値を変更できる!
値を直接変更するため、メモリ効率が良い!
関数の戻り値が不要なので、可読性が向上!

実際の活用例

【例①】日付の開始日と終了日を取得

Function GetStartEndDate() As Variant

Dim result(1) As Date
result(0) = DateSerial(2024, 1, 1) ' 開始日
result(1) = DateSerial(2024, 12, 31) ' 終了日
GetStartEndDate = result

End Function

Sub TestDateRange()

Dim dates As Variant
dates = GetStartEndDate()

Debug.Print "開始日: " & dates(0)
Debug.Print "終了日: " & dates(1)

End Sub

開始日・終了日を一度に取得!

【例②】エラーコードとメッセージを返す

Type ErrorInfo

Code As Integer
Message As String

End Type

Function ValidateNumber(n As Double) As ErrorInfo

Dim err As ErrorInfo
If n < 0 Then

err.Code = 1
err.Message = "負の数は許可されていません"

Else

err.Code = 0
err.Message = "OK"

End If

ValidateNumber = err

End Function

Sub TestError()

Dim result As ErrorInfo
result = ValidateNumber(-10)

Debug.Print "エラーコード: " & result.Code
Debug.Print "メッセージ: " & result.Message

End Sub

エラーコードとメッセージをセットで返せる!

どの方法を選ぶべきか?

方法メリットデメリットおすすめの用途
配列を返す簡単に複数の値を返せる配列の意味が分かりづらいシンプルな数値処理
ユーザー定義型を返す値の意味を明確にできるType の定義が必要複数の関連データを扱う場合
ByRef で更新メモリ効率が良い呼び出し側で変数を用意する必要あり複数の変数を直接変更したい場合

まとめ

方法適した用途
配列を返すシンプルな数値や日付のセットを返す
ユーザー定義型を返す意味のある複数のデータを返す
ByRef で更新メモリ効率を重視し、変数を直接変更したい

-VBAで自動化, VBA一覧, セル・値の取得と貼り付け, 値渡し・参照