Excel VBAの function(関数)プロシージャの基本
最初に押さえるポイントは「Subは命令を実行するもの」「Functionは“計算して値を返す”もの」。Functionは“入力→処理→出力(戻り値)”の流れで考えると理解しやすいです。
function と sub の違い
- 役割:
Sub: 何かを実行する(メッセージ表示やセル操作など)。戻り値はない。
Function: 計算して“値”を返す。式やセルの中で使える。 - 使いどころ:
Sub: ボタンから動かす作業系の処理。
Function: 値を作り出す処理(合計、判定、書式生成など)。
基本の書き方(戻り値の作り方)
- 構文の型:
Functionの戻り値は「関数名に代入」して決まります。
Function AddTwo(ByVal a As Long, ByVal b As Long) As Long
AddTwo = a + b ' ← 戻り値を設定
End Function
VB- 呼び出し方(VBA側):
Sub Test_AddTwo()
Dim s As Long
s = AddTwo(10, 25)
MsgBox "合計は " & s
End Sub
VB- ワークシートで使う:
標準モジュールに置いたPublic関数なら、セルで
=AddTwo(10,25)
と書けば結果が出ます(UDF: ユーザー定義関数)。
よく使う戻り値の型と例
- 数値(Long/Double):
Function CalculateTax(ByVal amount As Double, ByVal rate As Double) As Double
CalculateTax = amount * rate
End Function
VB- 真偽値(Boolean):
Function IsEven(ByVal n As Long) As Boolean
IsEven = (n Mod 2 = 0)
End Function
VB- 文字列(String):
Function FormatFullName(ByVal lastName As String, ByVal firstName As String) As String
FormatFullName = lastName & " " & firstName
End Function
VB- 日付(Date):
Function DaysBetween(ByVal startDate As Date, ByVal endDate As Date) As Long
DaysBetween = endDate - startDate
End Function
VB引数の渡し方とオプション引数
- 基本は ByVal(値渡し):
安全重視: 呼び出し元の変数が書き換わらない。
Function DoubleSafe(ByVal n As Long) As Long
DoubleSafe = n * 2
End Function
VB- ByRef(参照渡し)は例外的に:
主に“戻り値+副作用”が必要なときだけ。ただし、初心者はまずByValで十分。 - Optional(省略可能)と既定値:
使いやすさが上がります。
Function RoundFlexible(ByVal value As Double, Optional ByVal digits As Long = 0) As Double
RoundFlexible = WorksheetFunction.Round(value, digits)
End Function
VB例題で身につける
例題1:安全な割り算(ゼロ除算対策)
Function SafeDivide(ByVal numerator As Double, ByVal denominator As Double) As Variant
If denominator = 0 Then
SafeDivide = CVErr(xlErrDiv0) ' ワークシート関数で #DIV/0! を返す
Else
SafeDivide = numerator / denominator
End If
End Function
VB- ポイント: Worksheetでエラー表現が必要ならVariant+CVErrが便利。
例題2:範囲の合計(UDF)
Public Function RangeSum(ByVal target As Range) As Double
Dim cell As Range
Dim total As Double
For Each cell In target.Cells
If IsNumeric(cell.Value) Then
total = total + cell.Value
End If
Next
RangeSum = total
End Function
VB- 使い方: セルに =RangeSum(A1:A10) と入力。
例題3:採点の判定(合否)
Function PassOrFail(ByVal score As Long, Optional ByVal passLine As Long = 60) As String
If score >= passLine Then
PassOrFail = "合格"
Else
PassOrFail = "不合格"
End If
End Function
VB例題4:テキストの整形(見出し化)
Function MakeTitle(ByVal text As String, Optional ByVal width As Long = 20) As String
Dim t As String
t = Trim(text)
If Len(t) = 0 Then
MakeTitle = String(width, "-")
Else
MakeTitle = t & " " & String(Application.Max(width - Len(t) - 1, 0), "-")
End If
End Function
VBよくあるつまずきと回避策
- 戻り値の設定忘れ:
関数名に代入しないと既定値(数値なら0、文字列なら空文字など)になる。
→ 処理の最後で必ず「関数名 = 結果」を入れる。 - 型不一致(Type mismatch):
引数や戻り値の型が合わないとエラー。
→ 宣言を明確に、必要なら型変換(CLng、CDbl、CStr)。 - ワークシートから呼べない:
標準モジュールにPublic Functionとして置く。シート/ThisWorkbookのモジュールだと見えないことがある。
→ 「挿入→標準モジュール」に関数を作成。 - 副作用が強すぎる関数:
UDFはセルから呼ばれる前提なら“純粋関数(入力に対して同じ出力)”が望ましい。
→ セル変更やMsgBoxはSub側へ分離。
練習問題
- 練習1:税込計算
- 目標: 金額と税率を渡して税込金額を返す。
- ヒント: 税額を足してDoubleで返す。
Function WithTax(ByVal amount As Double, Optional ByVal taxRate As Double = 0.1) As Double
WithTax = amount * (1 + taxRate)
End Function
VB- 練習2:文字の出現回数
- 目標: 文字列中の特定文字の回数を返す。
- ヒント: ループまたはReplaceで差分を取る。
Function CountChar(ByVal text As String, ByVal ch As String) As Long
If Len(ch) <> 1 Then
CountChar = 0
Exit Function
End If
CountChar = Len(text) - Len(Replace(text, ch, ""))
End Function
VB- 練習3:範囲の平均(空白除外)
- 目標: 数字セルだけ平均を返す。数字がなければエラー返却。
Function AverageNumbers(ByVal target As Range) As Variant
Dim cell As Range, total As Double, count As Long
For Each cell In target.Cells
If IsNumeric(cell.Value) Then
total = total + cell.Value
count = count + 1
End If
Next
If count = 0 Then
AverageNumbers = CVErr(xlErrNA)
Else
AverageNumbers = total / count
End If
End Function
VBまとめのチェックリスト
- 戻り値: 関数名に代入して“必ず”設定する。
- 型選択: Long/Double/String/Boolean/Dateを目的に合わせて。
- ByVal中心: 変更が必要な場合のみByRef。
- UDFの場所: 標準モジュール+Public。
- 副作用なし: UDFは値を返すことに集中、画面操作はSubへ。
「Functionは“値を作る工場”」——入力(材料)を渡して、ルール(処理)で整え、出荷(戻り値)する。この感覚で書けると、VBAが一気に扱いやすくなります。どれか一つ、まずは自分の業務に合わせて作ってみましょう。

