In Excel VBA, a Function is a type of procedure that, unlike a Sub, can accept parameters, perform calculations or processes, and return the resulting value, thereby allowing users to create their own custom worksheet functions.
Excelには、セルに「=SUM(A1:A5)」などの関数を入力して計算結果を取得できる仕組みがあります。これらはあらかじめExcelに備わっている“組み込み関数”ですが、VBAを使うと独自の関数を作成することができます。これを「ユーザー定義関数(UDF: User Defined Function)」と呼び、VBAの「Function」プロシージャを使用して定義します。
ユーザー定義関数は、以下のようなメリットがあります。
VBAで処理を記述する方法としては「Subプロシージャ」と「Functionプロシージャ」の2種類があります。両者の大きな違いは、戻り値(返り値)を返すかどうかという点です。
Subプロシージャ
Functionプロシージャ
関数を作る際には、Function
キーワードを使い、戻り値を「Function名 = 値」の形で指定することで完結します。戻り値を返したい場合はSubではなくFunctionを使う必要があります。
それでは、実際にユーザー定義関数を作成する基本的な構文を示します。
VBA
Function 関数名(引数1 As データ型, 引数2 As データ型, …) As 戻り値のデータ型
' ここに処理を記述
関数名 = 戻したい値
End Function
たとえば、2つの数値を受け取って合計を返す簡単なユーザー定義関数を作りたい場合、次のようなコードが考えられます。
VBA
Function MySum(a As Double, b As Double) As Double
' aとbを合計して返す
MySum = a + b
End Function
この例では、
a
」と「b
」という2つの数値を受け取り、MySum
」に代入しています。ポイント : もし関数が名前定義したいシートモジュールや、このブックとは別の場所にある場合、適切に読み込めるようにする必要があります。基本的には標準モジュールに書いてあれば同一ブック内の任意のワークシートで利用可能です。
複雑な計算を行いたい場合は、引数を複数設定します。例えば、加減乗除をまとめて行うような関数を作ってみましょう。
VBA
Function MathOperations(a As Double, b As Double, operationType As String) As Double
Select Case operationType
Case "ADD"
MathOperations = a + b
Case "SUB"
MathOperations = a - b
Case "MUL"
MathOperations = a * b
Case "DIV"
If b <> 0 Then
MathOperations = a / b
Else
' bが0の場合のエラー処理
MathOperations = 0
End If
Case Else
' 不明な操作種別は0を返す
MathOperations = 0
End Select
End Function
Excelのセル上で、
VBA
=MathOperations(10, 5, "ADD") ' => 15
=MathOperations(10, 5, "SUB") ' => 5
=MathOperations(10, 5, "MUL") ' => 50
=MathOperations(10, 5, "DIV") ' => 2
といった呼び出し方ができます。
ExcelのAVERAGE関数のように、引数をいくつでも指定したい場合はParamArrayを使用します。例として、複数の数値を受け取り、その合計を返す関数は次のように書けます。
VBA
Function MySumArray(ParamArray nums() As Variant) As Double
Dim total As Double
Dim i As Variant
For Each i In nums
If IsNumeric(i) Then
total = total + i
End If
Next i
MySumArray = total
End Function
セル上で、
VBA
=MySumArray(1,2,3,4,5) ' => 15
のように使えます。
関数によっては、一部の引数を指定しなくても使いたいケースがあるかもしれません。たとえば、割引率を適用するかどうかを任意で指定したい関数を考えてみましょう。このような場合はオプション引数( Optional
)を使います。
VBA
Function PriceAfterDiscount(price As Double, Optional discountRate As Double = 0) As Double
' discountRateは指定されなければ0とする
PriceAfterDiscount = price * (1 - discountRate)
End Function
この関数は、
VBA
=PriceAfterDiscount(1000) ' => 1000 (割引率が0%なのでそのまま)
=PriceAfterDiscount(1000, 0.2) ' => 800 (割引率20%で計算)
と使えます。オプション引数には初期値を設定しておくと、引数が与えられなかった場合にもスムーズに動作します。
On Error ~
構文などを使ってエラーを上手に処理しましょう。CVErr(xlErrDiv0)
など)を使う必要があります。もう少し実用的な例として、指定した範囲に空白セルがいくつあるかを数えるユーザー定義関数を作ってみます。ExcelにもCOUNTAなどの関数がありますが、空白数を簡単に返したいときに便利です。
VBA
Function CountBlankCells(TargetRange As Range) As Long
Dim rng As Range
Dim countBlank As Long
For Each rng In TargetRange
If IsEmpty(rng.Value) Or rng.Value = "" Then
countBlank = countBlank + 1
End If
Next rng
CountBlankCells = countBlank
End Function
使い方
VBA
=CountBlankCells(A1:A10)
この例のように、引数をRange型として受け取ると、ユーザー定義関数内でセルの値をループ処理によってチェックすることができます。ただし、シートの編集は行わないようにし、あくまでも値を読み取って何かしらの計算結果を返すのがVBA関数の王道の使い方です。
複数のExcelファイルで同じ関数を使いたい場合は、以下のような方法があります。
Excel VBAのFunctionプロシージャを活用することで、標準の関数だけでは物足りない・不足している計算処理やチェック、条件分岐を柔軟に行えるようになります。初心者の方は以下の点を意識すると、よりスムーズにVBAのFunctionを使い始められます。
初めてVBAに触れる方は、「Sub」でのマクロ作成から学習を始めることが多いですが、Functionは「値を返す」という概念がある分、ややハードルが高く感じられるかもしれません。しかし、Excel本来の機能である「関数」を自作できるようになると、日常業務の効率化は飛躍的に向上します。ぜひ、ユーザー定義関数の作成をマスターし、Excelをより高度かつ柔軟に使いこなしてください。