Excel VBA

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.

Function

Excel VBAのFunctionとは?

Excelには、セルに「=SUM(A1:A5)」などの関数を入力して計算結果を取得できる仕組みがあります。これらはあらかじめExcelに備わっている“組み込み関数”ですが、VBAを使うと独自の関数を作成することができます。これを「ユーザー定義関数(UDF: User Defined Function)」と呼び、VBAの「Function」プロシージャを使用して定義します。

ユーザー定義関数は、以下のようなメリットがあります。

FunctionとSubの違い

VBAで処理を記述する方法としては「Subプロシージャ」と「Functionプロシージャ」の2種類があります。両者の大きな違いは、戻り値(返り値)を返すかどうかという点です。

Subプロシージャ

Functionプロシージャ

関数を作る際には、Functionキーワードを使い、戻り値を「Function名 = 値」の形で指定することで完結します。戻り値を返したい場合はSubではなくFunctionを使う必要があります。

ユーザー定義関数を作るための基本構文

それでは、実際にユーザー定義関数を作成する基本的な構文を示します。

VBA

Function 関数名(引数1 As データ型, 引数2 As データ型, …) As 戻り値のデータ型
	' ここに処理を記述
	
	関数名 = 戻したい値
End Function
Function 関数名(…)
関数の開始部分です。サブルーチン(Sub)と異なり、Functionキーワードを使います。関数名はExcelで呼び出す際に使われる名前になるため、わかりやすく短い名前をつけるとよいでしょう。
引数(パラメータ)
必要に応じて引数を指定します。ユーザーが計算したい元となるセル範囲や数値などを渡すのが一般的です。引数にはデータ型(Integer, Long, Double, String, Variantなど)をつけると、エラーが起こりにくくなります。
As 戻り値のデータ型
関数が戻す(返す)値のデータ型を指定します。Excelのセルで扱う値であれば、DoubleやString、Variantなどをよく使用します。
関数名 = 戻したい値
関数の最終的な計算結果や文字列を「関数名 = 値」の形で代入することで、関数が値を返すことができます。
End Function
関数の終了宣言です。

実際のコード例:単純な計算を行う関数

たとえば、2つの数値を受け取って合計を返す簡単なユーザー定義関数を作りたい場合、次のようなコードが考えられます。

VBA

Function MySum(a As Double, b As Double) As Double

	' aとbを合計して返す
	MySum = a + b
	
End Function

この例では、

セル上での呼び出し

  1. VBAエディタ(Visual Basic Editor)を開き、標準モジュールを作成する
  2. Excelのワークシートに戻り、セルに「=MySum(3, 5)」と入力してみる

ポイント : もし関数が名前定義したいシートモジュールや、このブックとは別の場所にある場合、適切に読み込めるようにする必要があります。基本的には標準モジュールに書いてあれば同一ブック内の任意のワークシートで利用可能です。

複数の引数と可変長引数

複雑な計算を行いたい場合は、引数を複数設定します。例えば、加減乗除をまとめて行うような関数を作ってみましょう。

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

といった呼び出し方ができます。

可変長引数(ParamArray)

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%で計算)

と使えます。オプション引数には初期値を設定しておくと、引数が与えられなかった場合にもスムーズに動作します。

VBAのFunctionを使うときの注意点

ワークシート関数としての制限事項

セキュリティ設定

エラーハンドリング

実用的なサンプル:指定範囲の空白セルをカウントする関数

もう少し実用的な例として、指定した範囲に空白セルがいくつあるかを数えるユーザー定義関数を作ってみます。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

使い方

  1. 標準モジュールに上記のコードを貼り付ける
  2. ワークシート上で、空白セルを数えたい範囲を引数に指定する

    VBA

    =CountBlankCells(A1:A10)
    もしA1:A10の中に空白セルが3つあれば3が返されます。

この例のように、引数をRange型として受け取ると、ユーザー定義関数内でセルの値をループ処理によってチェックすることができます。ただし、シートの編集は行わないようにし、あくまでも値を読み取って何かしらの計算結果を返すのがVBA関数の王道の使い方です。

ユーザー定義関数の管理と再利用

複数のExcelファイルで同じ関数を使いたい場合は、以下のような方法があります。

マクロ有効ブック(.xlsmファイル)をテンプレートにする
作成したユーザー定義関数を含むブックをテンプレートとして保存し、他の新規ブック作成時にそのテンプレートを利用することで再利用ができます。
アドインファイル(.xlam)を作成する
より本格的に配布したい場合は、ユーザー定義関数をまとめたモジュールをアドインにしておくとよいでしょう。アドインをインストールすると、他のブックからもその関数を呼び出すことが可能になります。

まとめ

Excel VBAのFunctionプロシージャを活用することで、標準の関数だけでは物足りない・不足している計算処理やチェック、条件分岐を柔軟に行えるようになります。初心者の方は以下の点を意識すると、よりスムーズにVBAのFunctionを使い始められます。

SubとFunctionの違い
値を返すならFunction
構文の基本
Function 関数名(...) As データ型 で始まり、関数名 = 値 で終了する
標準モジュールに記述
シートモジュールではなく、標準モジュールに定義するのが一般的
セルから呼び出し可能
=関数名(引数1, 引数2, ...) の形式で利用可能
シートの編集操作は基本NG
関数ではシートのレイアウト変更やセルの結合、選択範囲を変更するといった操作は推奨されない
再利用はアドイン化
複数のブックや社内配布などで使うときはアドイン化が便利

初めてVBAに触れる方は、「Sub」でのマクロ作成から学習を始めることが多いですが、Functionは「値を返す」という概念がある分、ややハードルが高く感じられるかもしれません。しかし、Excel本来の機能である「関数」を自作できるようになると、日常業務の効率化は飛躍的に向上します。ぜひ、ユーザー定義関数の作成をマスターし、Excelをより高度かつ柔軟に使いこなしてください。