Functionプロシージャ(ユーザー定義関数)で複数の値を返すサンプルプログラム | VBA共通

Excel VBA

VBAで作成したFunctionプロシージャ(ユーザー定義関数)で戻り値として複数の値を返すサンプルプログラムを覚書。

サンプルプログラムは、ExcelのVBAで作ってありますが、Accessでもそのまま使用できます。

スポンサーリンク

Functionプロシージャで複数の値を返す方法

Functionプロシージャで戻り値として複数の値を返す場合、配列変数を使います。

関数の呼び出し側も当然配列変数を用意して戻り値を受け取るようにします。

複数の値を返すFunctionプロシージャのサンプルプログラム

以下は、引数として被除数と除数を受け取って、商と剰余を返すFunctionプロシージャのサンプルプログラムです。

Function FuncDivision(intDividend As Integer, intDivisor As Integer) As Variant
Dim intQuotient As Integer, intRemainder As Integer
'intDividend:割られる数(分子)
'intDivisor:割る数(分母)
    If intDividend >= intDivisor Then
        '商を求める
        intQuotient = Int(intDividend / intDivisor)
        
        '剰余を求める
        intRemainder = intDividend - (intDivisor * intQuotient)
    Else
        intQuotient = 0
        intRemainder = intDividend
    End If
    
    '商と剰余を返す
    FuncDivision = Array(intQuotient, intRemainder)
End Function

関数を呼び出すサンプルプログラム

作成したFunctionプロシージャを呼び出して使用するサンプルプログラムです。

Sub sample01()
Dim arrReturn As Variant
Dim intDividend As Integer, intDivisor As Integer
intDividend = 3
intDivisor = 30
arrReturn = FuncDivision(intDividend, intDivisor)
    
    MsgBox intDividend & " 割る " & intDivisor & "の" & vbCrLf & "商は、" _
    & arrReturn(0) & vbCrLf _
    & "剰余は、" & arrReturn(1) & " です。"
           
End Sub

サンプルプログラムのポイント

Functionプロシージャのポイントとしては、以下のとおりです。

  • 戻り値として配列を使用して複数の値を返すため、FunctionをVariantで宣言している
  • 2つの値を配列で返すためArray関数を使用している。

Functionプロシージャを呼び出す側のプログラムのポイントしては以下のとおりです。

  • 戻り値を配列として受け取るため、戻り値が代入される変数(arrReturn)をVariantで宣言している
  • 戻り値の個々の値は、変数(arrReturn)にインデックス番号を指定して取り出している

複数の値を返すFunctionプロシージャまとめ

複数の値を戻り値として返すFunctionプロシージャのサンプルプログラムを作成しました。

複数の値を返したい場合は、配列で返し、配列で受け取るというのがポイントです。

コメント

  1. 通りすがりですが、
    サンプルプログラムを見て、
    2点だけ気を付けたほうがよいと思いました。
    1. Variant型ではなく、適切なデータ型を使う
    Variant型の場合、データ型が何であっても扱えるように大きめにメモリを確保してしまいます。
    無駄にメモリを確保してしまうと、スワップが生じて、ただでさえ遅いVBAがさらに遅くなることがあります。
    2. 引数は参照渡しではなく、値渡しにする
    ご存知かとは思いますが、
    VBAではメソッドへの引数の渡し方はByRef(参照渡し)とByVal(値渡し)があります。
    VBAの場合、省略した場合は参照渡しになってしまいます。
    参照渡しにすると、呼び出し側に影響を与えてしまいます。
    以下のサンプルのコードで確認できると思います。
    “`

    Option Explicit
    Public Sub Test()
    Dim intValue As Integer
    Dim intReturn As Integer
    intValue = 1
    ' 値渡しのメソッド
    intReturn = Foo(intValue)
    ' この時点では intValue は 1
    MsgBox intValue
    ' 参照渡しのメソッド
    intReturn = Bar(intValue)
    ' この時点では intValue は 9
    MsgBox intValue
    End Sub
    ' 値渡しのメソッド
    Public Function Foo(ByVal value As Integer)
    Dim result As Integer
    result = value * 2
    value = 9
    Foo = result
    End Function
    ' 参照渡しのメソッド
    Public Function Bar(ByRef value As Integer)
    Dim result As Integer
    result = value * 2
    value = 9
    Bar = result
    End Function
    

    “`
    特別な意図が無い限り、値渡しで引数を渡すべきです。
    今回のような計算処理を行う場合は特に。
    なので、
    私ならサンプルプログラムと同様のコードを書くとしたら、
    以下のようにすると思います。
    “`

    Option Explicit
    Public Sub sample01()
    Dim arrReturn() As Integer
    Dim intDividend As Integer
    Dim intDivisor As Integer
    intDividend = 3
    intDivisor = 30
    arrReturn = FuncDivision(intDividend, intDivisor)
    MsgBox intDividend & " 割る " & intDivisor & "の" & vbCrLf & "商は、" _
    & arrReturn(0) & vbCrLf _
    & "剰余は、" & arrReturn(1) & " です。"
    End Sub
    Public Function FuncDivision(ByVal intDividend As Integer, _
    ByVal intDivisor As Integer) As Integer()
    'intDividend:割られる数(分子)
    'intDivisor:割る数(分母)
    Dim result(1) As Integer
    ' 商を求める
    result(0) = Int(intDividend / intDivisor)
    ' 剰余を求める
    result(1) = intDividend Mod intDivisor
    FuncDivision = result
    End Function
    

    “`

タイトルとURLをコピーしました